作者 郭盛
1 个管道 的构建 通过 耗费 2 秒

添加项目

正在显示 100 个修改的文件 包含 4721 行增加0 行删除

要显示太多修改。

为保证性能只显示 100 of 100+ 个文件。

  1 +{
  2 + "directory" : "public/assets/libs",
  3 + "ignoredDependencies": [
  4 + "file-saver",
  5 + "html2canvas",
  6 + "jspdf",
  7 + "jspdf-autotable"
  8 + ]
  9 +}
  1 +[app]
  2 +debug = false
  3 +trace = false
  4 +
  5 +[database]
  6 +hostname = 127.0.0.1
  7 +database = fastadmin
  8 +username = root
  9 +password = root
  10 +hostport = 3306
  11 +prefix = fa_
  1 +.idea/
  2 +runtime/
  1 +# ���� stages
  2 +stages:
  3 + - pull
  4 +
  5 +# ���� job
  6 +job1:
  7 + stage: pull
  8 + script:
  9 + - cd /alidata/www/fast/trace
  10 + - git pull
  1 +Apache License
  2 +Version 2.0, January 2004
  3 +http://www.apache.org/licenses/
  4 +
  5 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
  6 +
  7 +1. Definitions.
  8 +
  9 +"License" shall mean the terms and conditions for use, reproduction, and
  10 +distribution as defined by Sections 1 through 9 of this document.
  11 +
  12 +"Licensor" shall mean the copyright owner or entity authorized by the copyright
  13 +owner that is granting the License.
  14 +
  15 +"Legal Entity" shall mean the union of the acting entity and all other entities
  16 +that control, are controlled by, or are under common control with that entity.
  17 +For the purposes of this definition, "control" means (i) the power, direct or
  18 +indirect, to cause the direction or management of such entity, whether by
  19 +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
  20 +outstanding shares, or (iii) beneficial ownership of such entity.
  21 +
  22 +"You" (or "Your") shall mean an individual or Legal Entity exercising
  23 +permissions granted by this License.
  24 +
  25 +"Source" form shall mean the preferred form for making modifications, including
  26 +but not limited to software source code, documentation source, and configuration
  27 +files.
  28 +
  29 +"Object" form shall mean any form resulting from mechanical transformation or
  30 +translation of a Source form, including but not limited to compiled object code,
  31 +generated documentation, and conversions to other media types.
  32 +
  33 +"Work" shall mean the work of authorship, whether in Source or Object form, made
  34 +available under the License, as indicated by a copyright notice that is included
  35 +in or attached to the work (an example is provided in the Appendix below).
  36 +
  37 +"Derivative Works" shall mean any work, whether in Source or Object form, that
  38 +is based on (or derived from) the Work and for which the editorial revisions,
  39 +annotations, elaborations, or other modifications represent, as a whole, an
  40 +original work of authorship. For the purposes of this License, Derivative Works
  41 +shall not include works that remain separable from, or merely link (or bind by
  42 +name) to the interfaces of, the Work and Derivative Works thereof.
  43 +
  44 +"Contribution" shall mean any work of authorship, including the original version
  45 +of the Work and any modifications or additions to that Work or Derivative Works
  46 +thereof, that is intentionally submitted to Licensor for inclusion in the Work
  47 +by the copyright owner or by an individual or Legal Entity authorized to submit
  48 +on behalf of the copyright owner. For the purposes of this definition,
  49 +"submitted" means any form of electronic, verbal, or written communication sent
  50 +to the Licensor or its representatives, including but not limited to
  51 +communication on electronic mailing lists, source code control systems, and
  52 +issue tracking systems that are managed by, or on behalf of, the Licensor for
  53 +the purpose of discussing and improving the Work, but excluding communication
  54 +that is conspicuously marked or otherwise designated in writing by the copyright
  55 +owner as "Not a Contribution."
  56 +
  57 +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
  58 +of whom a Contribution has been received by Licensor and subsequently
  59 +incorporated within the Work.
  60 +
  61 +2. Grant of Copyright License.
  62 +
  63 +Subject to the terms and conditions of this License, each Contributor hereby
  64 +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
  65 +irrevocable copyright license to reproduce, prepare Derivative Works of,
  66 +publicly display, publicly perform, sublicense, and distribute the Work and such
  67 +Derivative Works in Source or Object form.
  68 +
  69 +3. Grant of Patent License.
  70 +
  71 +Subject to the terms and conditions of this License, each Contributor hereby
  72 +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
  73 +irrevocable (except as stated in this section) patent license to make, have
  74 +made, use, offer to sell, sell, import, and otherwise transfer the Work, where
  75 +such license applies only to those patent claims licensable by such Contributor
  76 +that are necessarily infringed by their Contribution(s) alone or by combination
  77 +of their Contribution(s) with the Work to which such Contribution(s) was
  78 +submitted. If You institute patent litigation against any entity (including a
  79 +cross-claim or counterclaim in a lawsuit) alleging that the Work or a
  80 +Contribution incorporated within the Work constitutes direct or contributory
  81 +patent infringement, then any patent licenses granted to You under this License
  82 +for that Work shall terminate as of the date such litigation is filed.
  83 +
  84 +4. Redistribution.
  85 +
  86 +You may reproduce and distribute copies of the Work or Derivative Works thereof
  87 +in any medium, with or without modifications, and in Source or Object form,
  88 +provided that You meet the following conditions:
  89 +
  90 +You must give any other recipients of the Work or Derivative Works a copy of
  91 +this License; and
  92 +You must cause any modified files to carry prominent notices stating that You
  93 +changed the files; and
  94 +You must retain, in the Source form of any Derivative Works that You distribute,
  95 +all copyright, patent, trademark, and attribution notices from the Source form
  96 +of the Work, excluding those notices that do not pertain to any part of the
  97 +Derivative Works; and
  98 +If the Work includes a "NOTICE" text file as part of its distribution, then any
  99 +Derivative Works that You distribute must include a readable copy of the
  100 +attribution notices contained within such NOTICE file, excluding those notices
  101 +that do not pertain to any part of the Derivative Works, in at least one of the
  102 +following places: within a NOTICE text file distributed as part of the
  103 +Derivative Works; within the Source form or documentation, if provided along
  104 +with the Derivative Works; or, within a display generated by the Derivative
  105 +Works, if and wherever such third-party notices normally appear. The contents of
  106 +the NOTICE file are for informational purposes only and do not modify the
  107 +License. You may add Your own attribution notices within Derivative Works that
  108 +You distribute, alongside or as an addendum to the NOTICE text from the Work,
  109 +provided that such additional attribution notices cannot be construed as
  110 +modifying the License.
  111 +You may add Your own copyright statement to Your modifications and may provide
  112 +additional or different license terms and conditions for use, reproduction, or
  113 +distribution of Your modifications, or for any such Derivative Works as a whole,
  114 +provided Your use, reproduction, and distribution of the Work otherwise complies
  115 +with the conditions stated in this License.
  116 +
  117 +5. Submission of Contributions.
  118 +
  119 +Unless You explicitly state otherwise, any Contribution intentionally submitted
  120 +for inclusion in the Work by You to the Licensor shall be under the terms and
  121 +conditions of this License, without any additional terms or conditions.
  122 +Notwithstanding the above, nothing herein shall supersede or modify the terms of
  123 +any separate license agreement you may have executed with Licensor regarding
  124 +such Contributions.
  125 +
  126 +6. Trademarks.
  127 +
  128 +This License does not grant permission to use the trade names, trademarks,
  129 +service marks, or product names of the Licensor, except as required for
  130 +reasonable and customary use in describing the origin of the Work and
  131 +reproducing the content of the NOTICE file.
  132 +
  133 +7. Disclaimer of Warranty.
  134 +
  135 +Unless required by applicable law or agreed to in writing, Licensor provides the
  136 +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
  137 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
  138 +including, without limitation, any warranties or conditions of TITLE,
  139 +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
  140 +solely responsible for determining the appropriateness of using or
  141 +redistributing the Work and assume any risks associated with Your exercise of
  142 +permissions under this License.
  143 +
  144 +8. Limitation of Liability.
  145 +
  146 +In no event and under no legal theory, whether in tort (including negligence),
  147 +contract, or otherwise, unless required by applicable law (such as deliberate
  148 +and grossly negligent acts) or agreed to in writing, shall any Contributor be
  149 +liable to You for damages, including any direct, indirect, special, incidental,
  150 +or consequential damages of any character arising as a result of this License or
  151 +out of the use or inability to use the Work (including but not limited to
  152 +damages for loss of goodwill, work stoppage, computer failure or malfunction, or
  153 +any and all other commercial damages or losses), even if such Contributor has
  154 +been advised of the possibility of such damages.
  155 +
  156 +9. Accepting Warranty or Additional Liability.
  157 +
  158 +While redistributing the Work or Derivative Works thereof, You may choose to
  159 +offer, and charge a fee for, acceptance of support, warranty, indemnity, or
  160 +other liability obligations and/or rights consistent with this License. However,
  161 +in accepting such obligations, You may act only on Your own behalf and on Your
  162 +sole responsibility, not on behalf of any other Contributor, and only if You
  163 +agree to indemnify, defend, and hold each Contributor harmless for any liability
  164 +incurred by, or claims asserted against, such Contributor by reason of your
  165 +accepting any such warranty or additional liability.
  166 +
  167 +END OF TERMS AND CONDITIONS
  168 +
  169 +APPENDIX: How to apply the Apache License to your work
  170 +
  171 +To apply the Apache License to your work, attach the following boilerplate
  172 +notice, with the fields enclosed by brackets "{}" replaced with your own
  173 +identifying information. (Don't include the brackets!) The text should be
  174 +enclosed in the appropriate comment syntax for the file format. We also
  175 +recommend that a file or class name and description of purpose be included on
  176 +the same "printed page" as the copyright notice for easier identification within
  177 +third-party archives.
  178 +
  179 + Copyright 2017 Karson
  180 +
  181 + Licensed under the Apache License, Version 2.0 (the "License");
  182 + you may not use this file except in compliance with the License.
  183 + You may obtain a copy of the License at
  184 +
  185 + http://www.apache.org/licenses/LICENSE-2.0
  186 +
  187 + Unless required by applicable law or agreed to in writing, software
  188 + distributed under the License is distributed on an "AS IS" BASIS,
  189 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  190 + See the License for the specific language governing permissions and
  191 + limitations under the License.
  1 +FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。
  2 +
  3 +
  4 +## **主要特性**
  5 +
  6 +* 基于`Auth`验证的权限管理系统
  7 + * 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
  8 + * 支持单管理员多角色
  9 + * 支持管理子级数据或个人数据
  10 +* 强大的一键生成功能
  11 + * 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单、回收站等
  12 + * 一键压缩打包JS和CSS文件,一键CDN静态资源部署
  13 + * 一键生成控制器菜单和规则
  14 + * 一键生成API接口文档
  15 +* 完善的前端功能组件开发
  16 + * 基于`AdminLTE`二次开发
  17 + * 基于`Bootstrap`开发,自适应手机、平板、PC
  18 + * 基于`RequireJS`进行JS模块管理,按需加载
  19 + * 基于`Less`进行样式开发
  20 + * 基于`Bower`进行前端组件包管理
  21 +* 强大的插件扩展功能,在线安装卸载升级插件
  22 +* 通用的会员模块和API模块
  23 +* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
  24 +* 二级域名部署支持,同时域名支持绑定到插件
  25 +* 多语言支持,服务端及客户端支持
  26 +* 强大的第三方模块支持([CMS](https://www.fastadmin.net/store/cms.html)[博客](https://www.fastadmin.net/store/blog.html)[知识付费问答](https://www.fastadmin.net/store/ask.html))
  27 +* 整合第三方短信接口(阿里云、腾讯云短信)
  28 +* 无缝整合第三方云存储(七牛、阿里云OSS、又拍云)功能
  29 +* 第三方富文本编辑器支持(Summernote、Kindeditor、百度编辑器)
  30 +* 第三方登录(QQ、微信、微博)整合
  31 +* 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付
  32 +* 丰富的插件应用市场
  33 +
  34 +## **安装使用**
  35 +
  36 +https://doc.fastadmin.net
  37 +
  38 +## **在线演示**
  39 +
  40 +https://demo.fastadmin.net
  41 +
  42 +用户名:admin
  43 +
  44 +密 码:123456
  45 +
  46 +提 示:演示站数据无法进行修改,请下载源码安装体验全部功能
  47 +
  48 +## **界面截图**
  49 +![控制台](https://gitee.com/uploads/images/2017/0411/113717_e99ff3e7_10933.png "控制台")
  50 +
  51 +## **问题反馈**
  52 +
  53 +在使用中有任何问题,请使用以下联系方式联系我们
  54 +
  55 +交流社区: https://forum.fastadmin.net
  56 +
  57 +QQ群: [636393962](https://jq.qq.com/?_wv=1027&k=487PNBb)() [708784003](https://jq.qq.com/?_wv=1027&k=5ObjtwM)(满) [964776039](https://jq.qq.com/?_wv=1027&k=59qjU2P)(3群)
  58 +
  59 +Email: (karsonzhang#163.com, 把#换成@)
  60 +
  61 +Github: https://github.com/karsonzhang/fastadmin
  62 +
  63 +Gitee: https://gitee.com/karson/fastadmin
  64 +
  65 +## **特别鸣谢**
  66 +
  67 +感谢以下的项目,排名不分先后
  68 +
  69 +ThinkPHP:http://www.thinkphp.cn
  70 +
  71 +AdminLTE:https://adminlte.io
  72 +
  73 +Bootstrap:http://getbootstrap.com
  74 +
  75 +jQuery:http://jquery.com
  76 +
  77 +Bootstrap-table:https://github.com/wenzhixin/bootstrap-table
  78 +
  79 +Nice-validator: https://validator.niceue.com
  80 +
  81 +SelectPage: https://github.com/TerryZ/SelectPage
  82 +
  83 +
  84 +## **版权信息**
  85 +
  86 +FastAdmin遵循Apache2开源协议发布,并提供免费使用。
  87 +
  88 +本项目包含的第三方源码和二进制文件之版权信息另行标注。
  89 +
  90 +版权所有Copyright © 2017-2019 by FastAdmin (https://www.fastadmin.net)
  91 +
  92 +All rights reserved。
  1 +<?php
  2 +
  3 +namespace addons\alisms;
  4 +
  5 +use think\Addons;
  6 +
  7 +/**
  8 + * Alisms
  9 + */
  10 +class Alisms extends Addons
  11 +{
  12 +
  13 + /**
  14 + * 插件安装方法
  15 + * @return bool
  16 + */
  17 + public function install()
  18 + {
  19 + return true;
  20 + }
  21 +
  22 + /**
  23 + * 插件卸载方法
  24 + * @return bool
  25 + */
  26 + public function uninstall()
  27 + {
  28 + return true;
  29 + }
  30 +
  31 + /**
  32 + * 短信发送行为
  33 + * @param $params
  34 + * @return boolean
  35 + */
  36 + public function smsSend(&$params)
  37 + {
  38 + $config = get_addon_config('alisms');
  39 + $alisms = new library\Alisms();
  40 + $result = $alisms->mobile($params->mobile)
  41 + ->template($config['template'][$params->event])
  42 + ->param(['code' => $params->code])
  43 + ->send();
  44 + return $result;
  45 + }
  46 +
  47 + /**
  48 + * 短信发送通知
  49 + * @param $params
  50 + * @return boolean
  51 + */
  52 + public function smsNotice(&$params)
  53 + {
  54 + $alisms = library\Alisms::instance();
  55 + if (is_array($params['msg'])) {
  56 + $param = $params['msg'];
  57 + } else {
  58 + parse_str($params['msg'], $param);
  59 + }
  60 + $param = $param ? $param : [];
  61 + $result = $alisms->mobile($params['mobile'])
  62 + ->template($params['template'])
  63 + ->param($param)
  64 + ->send();
  65 + return $result;
  66 + }
  67 +
  68 + /**
  69 + * 检测验证是否正确
  70 + * @param $params
  71 + * @return boolean
  72 + */
  73 + public function smsCheck(&$params)
  74 + {
  75 + return true;
  76 + }
  77 +}
  1 +<?php
  2 +
  3 +return array (
  4 + 0 =>
  5 + array (
  6 + 'name' => 'key',
  7 + 'title' => '应用key',
  8 + 'type' => 'string',
  9 + 'content' =>
  10 + array (
  11 + ),
  12 + 'value' => 'LTAI4FupvnHZFwiE1ikEpfg2',
  13 + 'rule' => 'required',
  14 + 'msg' => '',
  15 + 'tip' => '',
  16 + 'ok' => '',
  17 + 'extend' => '',
  18 + ),
  19 + 1 =>
  20 + array (
  21 + 'name' => 'secret',
  22 + 'title' => '密钥secret',
  23 + 'type' => 'string',
  24 + 'content' =>
  25 + array (
  26 + ),
  27 + 'value' => 'F9UpeTZxWmBWmZxkxXkSZeAsI5Kise',
  28 + 'rule' => 'required',
  29 + 'msg' => '',
  30 + 'tip' => '',
  31 + 'ok' => '',
  32 + 'extend' => '',
  33 + ),
  34 + 2 =>
  35 + array (
  36 + 'name' => 'sign',
  37 + 'title' => '签名',
  38 + 'type' => 'string',
  39 + 'content' =>
  40 + array (
  41 + ),
  42 + 'value' => '溯源驿站',
  43 + 'rule' => 'required',
  44 + 'msg' => '',
  45 + 'tip' => '',
  46 + 'ok' => '',
  47 + 'extend' => '',
  48 + ),
  49 + 3 =>
  50 + array (
  51 + 'name' => 'template',
  52 + 'title' => '短信模板',
  53 + 'type' => 'array',
  54 + 'content' =>
  55 + array (
  56 + ),
  57 + 'value' =>
  58 + array (
  59 + 'register' => 'SMS_173344545',
  60 + ),
  61 + 'rule' => 'required',
  62 + 'msg' => '',
  63 + 'tip' => '',
  64 + 'ok' => '',
  65 + 'extend' => '',
  66 + ),
  67 + 4 =>
  68 + array (
  69 + 'name' => '__tips__',
  70 + 'title' => '温馨提示',
  71 + 'type' => 'string',
  72 + 'content' =>
  73 + array (
  74 + ),
  75 + 'value' => '应用key和密钥你可以通过 https://ak-console.aliyun.com/?spm=a2c4g.11186623.2.13.fd315777PX3tjy#/accesskey 获取',
  76 + 'rule' => 'required',
  77 + 'msg' => '',
  78 + 'tip' => '',
  79 + 'ok' => '',
  80 + 'extend' => '',
  81 + ),
  82 +);
  1 +<?php
  2 +
  3 +namespace addons\alisms\controller;
  4 +
  5 +use think\addons\Controller;
  6 +
  7 +/**
  8 + * 阿里短信
  9 + */
  10 +class Index extends Controller
  11 +{
  12 +
  13 + protected $model = null;
  14 +
  15 + public function _initialize()
  16 + {
  17 + if (!\app\admin\library\Auth::instance()->id) {
  18 + $this->error('暂无权限浏览');
  19 + }
  20 + parent::_initialize();
  21 + }
  22 +
  23 + public function index()
  24 + {
  25 + return $this->view->fetch();
  26 + }
  27 +
  28 + public function send()
  29 + {
  30 + $config = get_addon_config('alisms');
  31 + $mobile = $this->request->post('mobile');
  32 + $template = $this->request->post('template');
  33 + $sign = $this->request->post('sign');
  34 + if (!$mobile || !$template) {
  35 + $this->error('手机号、模板ID不能为空');
  36 + }
  37 + $sign = $sign ? $sign : $config['sign'];
  38 + $param = (array)json_decode($this->request->post('param', '', 'trim'));
  39 + $alisms = new \addons\alisms\library\Alisms();
  40 + $ret = $alisms->mobile($mobile)
  41 + ->template($template)
  42 + ->sign($sign)
  43 + ->param($param)
  44 + ->send();
  45 + if ($ret) {
  46 + $this->success("发送成功");
  47 + } else {
  48 + $this->error("发送失败!失败原因:" . $alisms->getError());
  49 + }
  50 + }
  51 +
  52 +}
  1 +name = alisms
  2 +title = 阿里短信发送
  3 +intro = 阿里短信发送插件
  4 +author = Karson
  5 +website = https://www.fastadmin.net
  6 +version = 1.0.6
  7 +state = 1
  8 +url = /addons/alisms
  1 +<?php
  2 +
  3 +namespace addons\alisms\library;
  4 +
  5 +/**
  6 + * 阿里大于SMS短信发送
  7 + */
  8 +class Alisms
  9 +{
  10 + private $_params = [];
  11 + public $error = '';
  12 + protected $config = [];
  13 + protected static $instance;
  14 +
  15 + public function __construct($options = [])
  16 + {
  17 + if ($config = get_addon_config('alisms')) {
  18 + $this->config = array_merge($this->config, $config);
  19 + }
  20 + $this->config = array_merge($this->config, is_array($options) ? $options : []);
  21 + }
  22 +
  23 + /**
  24 + * 单例
  25 + * @param array $options 参数
  26 + * @return Alisms
  27 + */
  28 + public static function instance($options = [])
  29 + {
  30 + if (is_null(self::$instance)) {
  31 + self::$instance = new static($options);
  32 + }
  33 +
  34 + return self::$instance;
  35 + }
  36 +
  37 + /**
  38 + * 设置签名
  39 + * @param string $sign
  40 + * @return Alisms
  41 + */
  42 + public function sign($sign = '')
  43 + {
  44 + $this->_params['SignName'] = $sign;
  45 + return $this;
  46 + }
  47 +
  48 + /**
  49 + * 设置参数
  50 + * @param array $param
  51 + * @return Alisms
  52 + */
  53 + public function param(array $param = [])
  54 + {
  55 + foreach ($param as $k => &$v) {
  56 + $v = (string)$v;
  57 + }
  58 + unset($v);
  59 + $this->_params['TemplateParam'] = json_encode($param);
  60 + return $this;
  61 + }
  62 +
  63 + /**
  64 + * 设置模板
  65 + * @param string $code 短信模板
  66 + * @return Alisms
  67 + */
  68 + public function template($code = '')
  69 + {
  70 + $this->_params['TemplateCode'] = $code;
  71 + return $this;
  72 + }
  73 +
  74 + /**
  75 + * 接收手机
  76 + * @param string $mobile 手机号码
  77 + * @return Alisms
  78 + */
  79 + public function mobile($mobile = '')
  80 + {
  81 + $this->_params['PhoneNumbers'] = $mobile;
  82 + return $this;
  83 + }
  84 +
  85 + /**
  86 + * 立即发送
  87 + * @return boolean
  88 + */
  89 + public function send()
  90 + {
  91 + $this->error = '';
  92 + $params = $this->_params();
  93 + $params['Signature'] = $this->_signed($params);
  94 + $response = $this->_curl($params);
  95 + if ($response !== false) {
  96 + $res = (array)json_decode($response, true);
  97 + if (isset($res['Code']) && $res['Code'] == 'OK') {
  98 + return true;
  99 + }
  100 + $this->error = isset($res['Message']) ? $res['Message'] : 'InvalidResult';
  101 + } else {
  102 + $this->error = 'InvalidResult';
  103 + }
  104 + return false;
  105 + }
  106 +
  107 + /**
  108 + * 获取错误信息
  109 + * @return string
  110 + */
  111 + public function getError()
  112 + {
  113 + return $this->error;
  114 + }
  115 +
  116 + private function _params()
  117 + {
  118 + return array_merge([
  119 + 'AccessKeyId' => $this->config['key'],
  120 + 'SignName' => isset($this->config['sign']) ? $this->config['sign'] : '',
  121 + 'Action' => 'SendSms',
  122 + 'Format' => 'JSON',
  123 + 'Version' => '2017-05-25',
  124 + 'SignatureVersion' => '1.0',
  125 + 'SignatureMethod' => 'HMAC-SHA1',
  126 + 'SignatureNonce' => uniqid(),
  127 + 'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
  128 + ], $this->_params);
  129 + }
  130 +
  131 + private function percentEncode($string)
  132 + {
  133 + $string = urlencode($string);
  134 + $string = preg_replace('/\+/', '%20', $string);
  135 + $string = preg_replace('/\*/', '%2A', $string);
  136 + $string = preg_replace('/%7E/', '~', $string);
  137 + return $string;
  138 + }
  139 +
  140 + private function _signed($params)
  141 + {
  142 + $sign = $this->config['secret'];
  143 + ksort($params);
  144 + $canonicalizedQueryString = '';
  145 + foreach ($params as $key => $value) {
  146 + $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
  147 + }
  148 + $stringToSign = 'GET&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
  149 + $signature = base64_encode(hash_hmac('sha1', $stringToSign, $sign . '&', true));
  150 + return $signature;
  151 + }
  152 +
  153 + private function _curl($params)
  154 + {
  155 + $uri = 'http://dysmsapi.aliyuncs.com/?' . http_build_query($params);
  156 + $ch = curl_init();
  157 + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  158 + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  159 + curl_setopt($ch, CURLOPT_URL, $uri);
  160 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  161 + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
  162 + curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.98 Safari/537.36");
  163 + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  164 + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  165 + $reponse = curl_exec($ch);
  166 + curl_close($ch);
  167 + return $reponse;
  168 + }
  169 +}
  1 +<!DOCTYPE html>
  2 +<html>
  3 +<head>
  4 + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
  5 + <title>阿里云通信短信发送示例 - FastAdmin</title>
  6 +
  7 + <!-- Bootstrap Core CSS -->
  8 + <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  9 +
  10 + <!-- Custom CSS -->
  11 + <link href="__CDN__/assets/css/frontend.css" rel="stylesheet">
  12 +
  13 + <!-- Plugin CSS -->
  14 + <link href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  15 + <link href="https://cdn.staticfile.org/simple-line-icons/2.4.1/css/simple-line-icons.min.css" rel="stylesheet">
  16 +
  17 + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  18 + <!--[if lt IE 9]>
  19 + <script src="https://cdn.staticfile.org/html5shiv/3.7.3/html5shiv.min.js"></script>
  20 + <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
  21 + <![endif]-->
  22 +</head>
  23 +<body>
  24 +<div class="container">
  25 + <div class="well" style="margin-top:30px;">
  26 + <form class="form-horizontal" action="{:addon_url('alisms/index/send')}" method="POST">
  27 + <fieldset>
  28 + <legend>阿里云通信短信发送</legend>
  29 + <div class="form-group">
  30 + <label class="col-lg-2 control-label">手机号</label>
  31 + <div class="col-lg-10">
  32 + <input type="text" class="form-control" name="mobile" placeholder="手机号">
  33 + </div>
  34 + </div>
  35 + <div class="form-group">
  36 + <label class="col-lg-2 control-label">消息模板ID</label>
  37 + <div class="col-lg-10">
  38 + <input type="text" class="form-control" name="template" placeholder="消息模板ID,从阿里云通信获得,通常是:SMS_114000000这种格式">
  39 + </div>
  40 + </div>
  41 + <div class="form-group">
  42 + <label class="col-lg-2 control-label">签名</label>
  43 + <div class="col-lg-10">
  44 + <input type="text" class="form-control" name="sign" placeholder="消息模板(可以留空,留空使用后台插件管理中的配置)">
  45 + </div>
  46 + </div>
  47 + <div class="form-group">
  48 + <label class="col-lg-2 control-label">模板变量参数</label>
  49 + <div class="col-lg-10">
  50 + <textarea name="param" class="form-control" cols="30" rows="10" placeholder='必须是JSON字符串,如{"name":"李明"}'></textarea>
  51 + </div>
  52 + </div>
  53 + <div class="form-group">
  54 + <div class="col-lg-10 col-lg-offset-2">
  55 + <button type="submit" class="btn btn-primary">发送</button>
  56 + <button type="reset" class="btn btn-default">重置</button>
  57 + </div>
  58 + </div>
  59 + </fieldset>
  60 + </form>
  61 + </div>
  62 +</div>
  63 +<!-- jQuery -->
  64 +<script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
  65 +
  66 +<!-- Bootstrap Core JavaScript -->
  67 +<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
  68 +
  69 +<script type="text/javascript">
  70 + $(function () {
  71 +
  72 + });
  73 +</script>
  74 +</body>
  75 +</html>
  1 +<?php
  2 +
  3 +namespace addons\command;
  4 +
  5 +use app\common\library\Menu;
  6 +use think\Addons;
  7 +
  8 +/**
  9 + * 在线命令插件
  10 + */
  11 +class Command extends Addons
  12 +{
  13 +
  14 + /**
  15 + * 插件安装方法
  16 + * @return bool
  17 + */
  18 + public function install()
  19 + {
  20 + $menu = [
  21 + [
  22 + 'name' => 'command',
  23 + 'title' => '在线命令管理',
  24 + 'icon' => 'fa fa-terminal',
  25 + 'sublist' => [
  26 + ['name' => 'command/index', 'title' => '查看'],
  27 + ['name' => 'command/add', 'title' => '添加'],
  28 + ['name' => 'command/detail', 'title' => '详情'],
  29 + ['name' => 'command/execute', 'title' => '运行'],
  30 + ['name' => 'command/del', 'title' => '删除'],
  31 + ['name' => 'command/multi', 'title' => '批量更新'],
  32 + ]
  33 + ]
  34 + ];
  35 + Menu::create($menu);
  36 + return true;
  37 + }
  38 +
  39 + /**
  40 + * 插件卸载方法
  41 + * @return bool
  42 + */
  43 + public function uninstall()
  44 + {
  45 + Menu::delete('command');
  46 + return true;
  47 + }
  48 +
  49 + /**
  50 + * 插件启用方法
  51 + * @return bool
  52 + */
  53 + public function enable()
  54 + {
  55 + Menu::enable('command');
  56 + return true;
  57 + }
  58 +
  59 + /**
  60 + * 插件禁用方法
  61 + * @return bool
  62 + */
  63 + public function disable()
  64 + {
  65 + Menu::disable('command');
  66 + return true;
  67 + }
  68 +
  69 +}
  1 +<?php
  2 +
  3 +namespace app\admin\controller;
  4 +
  5 +use app\common\controller\Backend;
  6 +use think\Config;
  7 +use think\console\Input;
  8 +use think\Db;
  9 +use think\Exception;
  10 +
  11 +/**
  12 + * 在线命令管理
  13 + *
  14 + * @icon fa fa-circle-o
  15 + */
  16 +class Command extends Backend
  17 +{
  18 +
  19 + /**
  20 + * Command模型对象
  21 + */
  22 + protected $model = null;
  23 + protected $noNeedRight = ['get_controller_list', 'get_field_list'];
  24 +
  25 + public function _initialize()
  26 + {
  27 + parent::_initialize();
  28 + $this->model = model('Command');
  29 + $this->view->assign("statusList", $this->model->getStatusList());
  30 + }
  31 +
  32 + /**
  33 + * 添加
  34 + */
  35 + public function add()
  36 + {
  37 +
  38 + $tableList = [];
  39 + $list = \think\Db::query("SHOW TABLES");
  40 + foreach ($list as $key => $row) {
  41 + $tableList[reset($row)] = reset($row);
  42 + }
  43 +
  44 + $this->view->assign("tableList", $tableList);
  45 + return $this->view->fetch();
  46 + }
  47 +
  48 + /**
  49 + * 获取字段列表
  50 + * @internal
  51 + */
  52 + public function get_field_list()
  53 + {
  54 + $dbname = Config::get('database.database');
  55 + $prefix = Config::get('database.prefix');
  56 + $table = $this->request->request('table');
  57 + //从数据库中获取表字段信息
  58 + $sql = "SELECT * FROM `information_schema`.`columns` "
  59 + . "WHERE TABLE_SCHEMA = ? AND table_name = ? "
  60 + . "ORDER BY ORDINAL_POSITION";
  61 + //加载主表的列
  62 + $columnList = Db::query($sql, [$dbname, $table]);
  63 + $fieldlist = [];
  64 + foreach ($columnList as $index => $item) {
  65 + $fieldlist[] = $item['COLUMN_NAME'];
  66 + }
  67 + $this->success("", null, ['fieldlist' => $fieldlist]);
  68 + }
  69 +
  70 + /**
  71 + * 获取控制器列表
  72 + * @internal
  73 + */
  74 + public function get_controller_list()
  75 + {
  76 + $adminPath = dirname(__DIR__) . DS;
  77 + $controllerDir = $adminPath . 'controller' . DS;
  78 + $files = new \RecursiveIteratorIterator(
  79 + new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
  80 + );
  81 + $list = [];
  82 + foreach ($files as $name => $file) {
  83 + if (!$file->isDir()) {
  84 + $filePath = $file->getRealPath();
  85 + $name = str_replace($controllerDir, '', $filePath);
  86 + $name = str_replace(DS, "/", $name);
  87 + $list[] = ['id' => $name, 'name' => $name];
  88 + }
  89 + }
  90 + $pageNumber = $this->request->request("pageNumber");
  91 + $pageSize = $this->request->request("pageSize");
  92 + return json(['list' => array_slice($list, ($pageNumber - 1) * $pageSize, $pageSize), 'total' => count($list)]);
  93 + }
  94 +
  95 + /**
  96 + * 详情
  97 + */
  98 + public function detail($ids)
  99 + {
  100 + $row = $this->model->get($ids);
  101 + if (!$row)
  102 + $this->error(__('No Results were found'));
  103 + $this->view->assign("row", $row);
  104 + return $this->view->fetch();
  105 + }
  106 +
  107 + /**
  108 + * 执行
  109 + */
  110 + public function execute($ids)
  111 + {
  112 + $row = $this->model->get($ids);
  113 + if (!$row)
  114 + $this->error(__('No Results were found'));
  115 + $result = $this->doexecute($row['type'], json_decode($row['params'], true));
  116 + $this->success("", null, ['result' => $result]);
  117 + }
  118 +
  119 + /**
  120 + * 执行命令
  121 + */
  122 + public function command($action = '')
  123 + {
  124 + $commandtype = $this->request->request("commandtype");
  125 + $params = $this->request->request();
  126 + $allowfields = [
  127 + 'crud' => 'table,controller,model,fields,force,local,delete,menu',
  128 + 'menu' => 'controller,delete',
  129 + 'min' => 'module,resource,optimize',
  130 + 'api' => 'url,module,output,template,force,title,author,class,language',
  131 + ];
  132 + $argv = [];
  133 + $allowfields = isset($allowfields[$commandtype]) ? explode(',', $allowfields[$commandtype]) : [];
  134 + $allowfields = array_filter(array_intersect_key($params, array_flip($allowfields)));
  135 + if (isset($params['local']) && !$params['local']) {
  136 + $allowfields['local'] = $params['local'];
  137 + } else {
  138 + unset($allowfields['local']);
  139 + }
  140 + foreach ($allowfields as $key => $param) {
  141 + $argv[] = "--{$key}=" . (is_array($param) ? implode(',', $param) : $param);
  142 + }
  143 + if ($commandtype == 'crud') {
  144 + $extend = 'setcheckboxsuffix,enumradiosuffix,imagefield,filefield,intdatesuffix,switchsuffix,citysuffix,selectpagesuffix,selectpagessuffix,ignorefields,sortfield,editorsuffix,headingfilterfield';
  145 + $extendArr = explode(',', $extend);
  146 + foreach ($params as $index => $item) {
  147 + if (in_array($index, $extendArr)) {
  148 + foreach (explode(',', $item) as $key => $value) {
  149 + if ($value) {
  150 + $argv[] = "--{$index}={$value}";
  151 + }
  152 + }
  153 + }
  154 + }
  155 + $isrelation = (int)$this->request->request('isrelation');
  156 + if ($isrelation && isset($params['relation'])) {
  157 + foreach ($params['relation'] as $index => $relation) {
  158 + foreach ($relation as $key => $value) {
  159 + $argv[] = "--{$key}=" . (is_array($value) ? implode(',', $value) : $value);
  160 + }
  161 + }
  162 + }
  163 + } else if ($commandtype == 'menu') {
  164 + if (isset($params['allcontroller']) && $params['allcontroller']) {
  165 + $argv[] = "--controller=all-controller";
  166 + } else {
  167 + foreach (explode(',', $params['controllerfile']) as $index => $param) {
  168 + if ($param) {
  169 + $argv[] = "--controller=" . substr($param, 0, -4);
  170 + }
  171 + }
  172 + }
  173 + } else if ($commandtype == 'min') {
  174 +
  175 + } else if ($commandtype == 'api') {
  176 +
  177 + } else {
  178 +
  179 + }
  180 + if ($action == 'execute') {
  181 + $result = $this->doexecute($commandtype, $argv);
  182 + $this->success("", null, ['result' => $result]);
  183 + } else {
  184 + $this->success("", null, ['command' => "php think {$commandtype} " . implode(' ', $argv)]);
  185 + }
  186 +
  187 + return;
  188 + }
  189 +
  190 + protected function doexecute($commandtype, $argv)
  191 + {
  192 + $commandName = "\\app\\admin\\command\\" . ucfirst($commandtype);
  193 + $input = new Input($argv);
  194 + $output = new \addons\command\library\Output();
  195 + $command = new $commandName($commandtype);
  196 + $data = [
  197 + 'type' => $commandtype,
  198 + 'params' => json_encode($argv),
  199 + 'command' => "php think {$commandtype} " . implode(' ', $argv),
  200 + 'executetime' => time(),
  201 + ];
  202 + $this->model->save($data);
  203 + try {
  204 + $command->run($input, $output);
  205 + $result = implode("\n", $output->getMessage());
  206 + $this->model->status = 'successed';
  207 + } catch (Exception $e) {
  208 + $result = implode("\n", $output->getMessage()) . "\n";
  209 + $result .= $e->getMessage();
  210 + $this->model->status = 'failured';
  211 + }
  212 + $result = trim($result);
  213 + $this->model->content = $result;
  214 + $this->model->save();
  215 + return $result;
  216 + }
  217 +
  218 +
  219 +}
  1 +<?php
  2 +
  3 +return [
  4 + 'Id' => 'ID',
  5 + 'Type' => '类型',
  6 + 'Params' => '参数',
  7 + 'Command' => '命令',
  8 + 'Content' => '返回结果',
  9 + 'Executetime' => '执行时间',
  10 + 'Createtime' => '创建时间',
  11 + 'Updatetime' => '更新时间',
  12 + 'Execute again' => '再次执行',
  13 + 'Successed' => '成功',
  14 + 'Failured' => '失败',
  15 + 'Status' => '状态'
  16 +];
  1 +<?php
  2 +
  3 +namespace app\admin\model;
  4 +
  5 +use think\Model;
  6 +
  7 +class Command extends Model
  8 +{
  9 + // 表名
  10 + protected $name = 'command';
  11 +
  12 + // 自动写入时间戳字段
  13 + protected $autoWriteTimestamp = 'int';
  14 +
  15 + // 定义时间戳字段名
  16 + protected $createTime = 'createtime';
  17 + protected $updateTime = 'updatetime';
  18 +
  19 + // 追加属性
  20 + protected $append = [
  21 + 'executetime_text',
  22 + 'type_text',
  23 + 'status_text'
  24 + ];
  25 +
  26 +
  27 + public function getStatusList()
  28 + {
  29 + return ['successed' => __('Successed'), 'failured' => __('Failured')];
  30 + }
  31 +
  32 +
  33 + public function getExecutetimeTextAttr($value, $data)
  34 + {
  35 + $value = $value ? $value : $data['executetime'];
  36 + return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
  37 + }
  38 +
  39 + public function getTypeTextAttr($value, $data)
  40 + {
  41 + $value = $value ? $value : $data['type'];
  42 + $list = ['crud' => '一键生成CRUD', 'menu' => '一键生成菜单', 'min' => '一键压缩打包', 'api' => '一键生成文档'];
  43 + return isset($list[$value]) ? $list[$value] : '';
  44 + }
  45 +
  46 + public function getStatusTextAttr($value, $data)
  47 + {
  48 + $value = $value ? $value : $data['status'];
  49 + $list = $this->getStatusList();
  50 + return isset($list[$value]) ? $list[$value] : '';
  51 + }
  52 +
  53 + protected function setExecutetimeAttr($value)
  54 + {
  55 + return $value && !is_numeric($value) ? strtotime($value) : $value;
  56 + }
  57 +
  58 +
  59 +}
  1 +<?php
  2 +
  3 +namespace app\admin\validate;
  4 +
  5 +use think\Validate;
  6 +
  7 +class Command extends Validate
  8 +{
  9 + /**
  10 + * 验证规则
  11 + */
  12 + protected $rule = [
  13 + ];
  14 + /**
  15 + * 提示消息
  16 + */
  17 + protected $message = [
  18 + ];
  19 + /**
  20 + * 验证场景
  21 + */
  22 + protected $scene = [
  23 + 'add' => [],
  24 + 'edit' => [],
  25 + ];
  26 +
  27 +}
  1 +<style>
  2 + .relation-item {margin-top:10px;}
  3 + legend {padding-bottom:5px;font-size:14px;font-weight:600;}
  4 + label {font-weight:normal;}
  5 + .form-control{padding:6px 8px;}
  6 + #extend-zone .col-xs-2 {margin-top:10px;padding-right:0;}
  7 + #extend-zone .col-xs-2:nth-child(6n+0) {padding-right:15px;}
  8 +</style>
  9 +<div class="panel panel-default panel-intro">
  10 + <div class="panel-heading">
  11 + <ul class="nav nav-tabs">
  12 + <li class="active"><a href="#crud" data-toggle="tab">{:__('一键生成CRUD')}</a></li>
  13 + <li><a href="#menu" data-toggle="tab">{:__('一键生成菜单')}</a></li>
  14 + <li><a href="#min" data-toggle="tab">{:__('一键压缩打包')}</a></li>
  15 + <li><a href="#api" data-toggle="tab">{:__('一键生成API文档')}</a></li>
  16 + </ul>
  17 + </div>
  18 + <div class="panel-body">
  19 + <div id="myTabContent" class="tab-content">
  20 + <div class="tab-pane fade active in" id="crud">
  21 + <div class="row">
  22 + <div class="col-xs-12">
  23 + <form role="form">
  24 + <input type="hidden" name="commandtype" value="crud" />
  25 + <div class="form-group">
  26 + <div class="row">
  27 + <div class="col-xs-3">
  28 + <input checked="" name="isrelation" type="hidden" value="0">
  29 + <label class="control-label" data-toggle="tooltip" title="当前只支持生成1对1关联模型,选中后请配置关联表和字段">
  30 + <input name="isrelation" type="checkbox" value="1">
  31 + 关联模型
  32 + </label>
  33 + </div>
  34 + <div class="col-xs-3">
  35 + <input checked="" name="local" type="hidden" value="1">
  36 + <label class="control-label" data-toggle="tooltip" title="默认模型生成在application/admin/model目录下,选中后将生成在application/common/model目录下">
  37 + <input name="local" type="checkbox" value="0"> 全局模型类
  38 + </label>
  39 + </div>
  40 + <div class="col-xs-3">
  41 + <input checked="" name="delete" type="hidden" value="0">
  42 + <label class="control-label" data-toggle="tooltip" title="删除CRUD生成的相关文件">
  43 + <input name="delete" type="checkbox" value="1"> 删除模式
  44 + </label>
  45 + </div>
  46 + <div class="col-xs-3">
  47 + <input checked="" name="force" type="hidden" value="0">
  48 + <label class="control-label" data-toggle="tooltip" title="选中后,如果已经存在同名文件将被覆盖。如果是删除将不再提醒">
  49 + <input name="force" type="checkbox" value="1">
  50 + 强制覆盖模式
  51 + </label>
  52 + </div>
  53 + <!--
  54 + <div class="col-xs-3">
  55 + <input checked="" name="menu" type="hidden" value="0">
  56 + <label class="control-label" data-toggle="tooltip" title="选中后,将同时生成后台菜单规则">
  57 + <input name="menu" type="checkbox" value="1">
  58 + 生成菜单
  59 + </label>
  60 + </div>
  61 + -->
  62 + </div>
  63 + </div>
  64 + <div class="form-group">
  65 + <legend>主表设置</legend>
  66 + <div class="row">
  67 + <div class="col-xs-3">
  68 + <label>请选择主表</label>
  69 + {:build_select('table',$tableList,null,['class'=>'form-control selectpicker']);}
  70 + </div>
  71 + <div class="col-xs-3">
  72 + <label>自定义控制器名</label>
  73 + <input type="text" class="form-control" name="controller" data-toggle="tooltip" title="默认根据表名自动生成,如果需要放在二级目录请手动填写" placeholder="支持目录层级,以/分隔">
  74 + </div>
  75 + <div class="col-xs-3">
  76 + <label>自定义模型名</label>
  77 + <input type="text" class="form-control" name="model" data-toggle="tooltip" title="默认根据表名自动生成" placeholder="不支持目录层级">
  78 + </div>
  79 + <div class="col-xs-3">
  80 + <label>请选择显示字段(默认全部)</label>
  81 + <select name="fields[]" id="fields" multiple style="height:30px;" class="form-control selectpicker"></select>
  82 + </div>
  83 +
  84 + </div>
  85 +
  86 + </div>
  87 +
  88 + <div class="form-group hide" id="relation-zone">
  89 + <legend>关联表设置</legend>
  90 +
  91 + <div class="row" style="margin-top:15px;">
  92 + <div class="col-xs-12">
  93 + <a href="javascript:;" class="btn btn-primary btn-sm btn-newrelation" data-index="1">追加关联模型</a>
  94 + </div>
  95 + </div>
  96 + </div>
  97 +
  98 + <hr>
  99 + <div class="form-group" id="extend-zone">
  100 + <legend>字段识别设置 <span style="font-size:12px;font-weight: normal;">(与之匹配的字段都将生成相应组件)</span></legend>
  101 + <div class="row">
  102 + <div class="col-xs-2">
  103 + <label>复选框后缀</label>
  104 + <input type="text" class="form-control" name="setcheckboxsuffix" placeholder="默认为set类型" />
  105 + </div>
  106 + <div class="col-xs-2">
  107 + <label>单选框后缀</label>
  108 + <input type="text" class="form-control" name="enumradiosuffix" placeholder="默认为enum类型" />
  109 + </div>
  110 + <div class="col-xs-2">
  111 + <label>图片类型后缀</label>
  112 + <input type="text" class="form-control" name="imagefield" placeholder="默认为image,images,avatar,avatars" />
  113 + </div>
  114 + <div class="col-xs-2">
  115 + <label>文件类型后缀</label>
  116 + <input type="text" class="form-control" name="filefield" placeholder="默认为file,files" />
  117 + </div>
  118 + <div class="col-xs-2">
  119 + <label>日期时间后缀</label>
  120 + <input type="text" class="form-control" name="intdatesuffix" placeholder="默认为time" />
  121 + </div>
  122 + <div class="col-xs-2">
  123 + <label>开关后缀</label>
  124 + <input type="text" class="form-control" name="switchsuffix" placeholder="默认为switch" />
  125 + </div>
  126 + <div class="col-xs-2">
  127 + <label>城市选择后缀</label>
  128 + <input type="text" class="form-control" name="citysuffix" placeholder="默认为city" />
  129 + </div>
  130 + <div class="col-xs-2">
  131 + <label>动态下拉后缀(单)</label>
  132 + <input type="text" class="form-control" name="selectpagesuffix" placeholder="默认为_id" />
  133 + </div>
  134 + <div class="col-xs-2">
  135 + <label>动态下拉后缀(多)</label>
  136 + <input type="text" class="form-control" name="selectpagessuffix" placeholder="默认为_ids" />
  137 + </div>
  138 + <div class="col-xs-2">
  139 + <label>忽略的字段</label>
  140 + <input type="text" class="form-control" name="ignorefields" placeholder="默认无" />
  141 + </div>
  142 + <div class="col-xs-2">
  143 + <label>排序字段</label>
  144 + <input type="text" class="form-control" name="sortfield" placeholder="默认为weigh" />
  145 + </div>
  146 + <div class="col-xs-2">
  147 + <label>富文本编辑器</label>
  148 + <input type="text" class="form-control" name="editorsuffix" placeholder="默认为content" />
  149 + </div>
  150 + <div class="col-xs-2">
  151 + <label>选项卡过滤字段</label>
  152 + <input type="text" class="form-control" name="headingfilterfield" placeholder="默认为status" />
  153 + </div>
  154 +
  155 + </div>
  156 +
  157 + </div>
  158 +
  159 + <div class="form-group">
  160 + <legend>生成命令行</legend>
  161 + <textarea class="form-control" data-toggle="tooltip" title="如果在线执行命令失败,可以将命令复制到命令行进行执行" rel="command" rows="1" placeholder="请点击生成命令行"></textarea>
  162 + </div>
  163 +
  164 + <div class="form-group">
  165 + <legend>返回结果</legend>
  166 + <textarea class="form-control" rel="result" rows="5" placeholder="请点击立即执行"></textarea>
  167 + </div>
  168 +
  169 + <div class="form-group">
  170 + <button type="button" class="btn btn-info btn-embossed btn-command">{:__('生成命令行')}</button>
  171 + <button type="button" class="btn btn-success btn-embossed btn-execute">{:__('立即执行')}</button>
  172 + </div>
  173 +
  174 + </form>
  175 + </div>
  176 + </div>
  177 + </div>
  178 + <div class="tab-pane fade" id="menu">
  179 + <div class="row">
  180 + <div class="col-xs-12">
  181 + <form role="form">
  182 + <input type="hidden" name="commandtype" value="menu" />
  183 + <div class="form-group">
  184 + <div class="row">
  185 + <div class="col-xs-3">
  186 + <input checked="" name="allcontroller" type="hidden" value="0">
  187 + <label class="control-label">
  188 + <input name="allcontroller" data-toggle="collapse" data-target="#controller" type="checkbox" value="1"> 一键生成全部控制器
  189 + </label>
  190 + </div>
  191 + <div class="col-xs-3">
  192 + <input checked="" name="delete" type="hidden" value="0">
  193 + <label class="control-label">
  194 + <input name="delete" type="checkbox" value="1"> 删除模式
  195 + </label>
  196 + </div>
  197 + <div class="col-xs-3">
  198 + <input checked="" name="force" type="hidden" value="0">
  199 + <label class="control-label">
  200 + <input name="force" type="checkbox" value="1"> 强制覆盖模式
  201 + </label>
  202 + </div>
  203 + </div>
  204 + </div>
  205 +
  206 + <div class="form-group in" id="controller">
  207 + <legend>控制器设置</legend>
  208 +
  209 + <div class="row" style="margin-top:15px;">
  210 + <div class="col-xs-12">
  211 + <input type="text" name="controllerfile" class="form-control selectpage" style="width:720px;" data-source="command/get_controller_list" data-multiple="true" name="controller" placeholder="请选择控制器" />
  212 + </div>
  213 + </div>
  214 + </div>
  215 +
  216 + <div class="form-group">
  217 + <legend>生成命令行</legend>
  218 + <textarea class="form-control" rel="command" rows="1" placeholder="请点击生成命令行"></textarea>
  219 + </div>
  220 +
  221 + <div class="form-group">
  222 + <legend>返回结果</legend>
  223 + <textarea class="form-control" rel="result" rows="5" placeholder="请点击立即执行"></textarea>
  224 + </div>
  225 +
  226 + <div class="form-group">
  227 + <button type="button" class="btn btn-info btn-embossed btn-command">{:__('生成命令行')}</button>
  228 + <button type="button" class="btn btn-success btn-embossed btn-execute">{:__('立即执行')}</button>
  229 + </div>
  230 +
  231 + </form>
  232 + </div>
  233 + </div>
  234 + </div>
  235 + <div class="tab-pane fade" id="min">
  236 + <div class="row">
  237 + <div class="col-xs-12">
  238 + <form role="form">
  239 + <input type="hidden" name="commandtype" value="min" />
  240 + <div class="form-group">
  241 + <legend>基础设置</legend>
  242 + <div class="row">
  243 + <div class="col-xs-3">
  244 + <label>请选择压缩模块</label>
  245 + <select name="module" class="form-control selectpicker">
  246 + <option value="all" selected>全部</option>
  247 + <option value="backend">后台Backend</option>
  248 + <option value="frontend">前台Frontend</option>
  249 + </select>
  250 + </div>
  251 + <div class="col-xs-3">
  252 + <label>请选择压缩资源</label>
  253 + <select name="resource" class="form-control selectpicker">
  254 + <option value="all" selected>全部</option>
  255 + <option value="js">JS</option>
  256 + <option value="css">CSS</option>
  257 + </select>
  258 + </div>
  259 + <div class="col-xs-3">
  260 + <label>请选择压缩模式</label>
  261 + <select name="optimize" class="form-control selectpicker">
  262 + <option value=""></option>
  263 + <option value="uglify">uglify</option>
  264 + <option value="closure">closure</option>
  265 + </select>
  266 + </div>
  267 + </div>
  268 + </div>
  269 +
  270 + <div class="form-group in">
  271 + <legend>控制器设置</legend>
  272 +
  273 + <div class="row" style="margin-top:15px;">
  274 + <div class="col-xs-12">
  275 +
  276 + </div>
  277 + </div>
  278 + </div>
  279 +
  280 + <div class="form-group">
  281 + <legend>生成命令行</legend>
  282 + <textarea class="form-control" rel="command" rows="1" placeholder="请点击生成命令行"></textarea>
  283 + </div>
  284 +
  285 + <div class="form-group">
  286 + <legend>返回结果</legend>
  287 + <textarea class="form-control" rel="result" rows="5" placeholder="请点击立即执行"></textarea>
  288 + </div>
  289 +
  290 + <div class="form-group">
  291 + <button type="button" class="btn btn-info btn-embossed btn-command">{:__('生成命令行')}</button>
  292 + <button type="button" class="btn btn-success btn-embossed btn-execute">{:__('立即执行')}</button>
  293 + </div>
  294 +
  295 + </form>
  296 + </div>
  297 + </div>
  298 + </div>
  299 + <div class="tab-pane fade" id="api">
  300 + <div class="row">
  301 + <div class="col-xs-12">
  302 + <form role="form">
  303 + <input type="hidden" name="commandtype" value="api" />
  304 + <div class="form-group">
  305 + <div class="row">
  306 + <div class="col-xs-3">
  307 + <input checked="" name="force" type="hidden" value="0">
  308 + <label class="control-label">
  309 + <input name="force" type="checkbox" value="1">
  310 + 覆盖模式
  311 + </label>
  312 + </div>
  313 + </div>
  314 + </div>
  315 + <div class="form-group">
  316 + <legend>文档设置</legend>
  317 + <div class="row">
  318 + <div class="col-xs-3">
  319 + <label>请输入接口URL</label>
  320 + <input type="text" name="url" class="form-control" placeholder="API URL,可留空" />
  321 + </div>
  322 + <div class="col-xs-3">
  323 + <label>接口生成文件</label>
  324 + <input type="text" name="output" class="form-control" placeholder="留空则使用api.html" />
  325 + </div>
  326 + <div class="col-xs-3">
  327 + <label>模板文件</label>
  328 + <input type="text" name="template" class="form-control" placeholder="如果不清楚请留空" />
  329 + </div>
  330 + </div>
  331 + <div class="row" style="margin-top:10px;">
  332 + <div class="col-xs-3">
  333 + <label>文档标题</label>
  334 + <input type="text" name="title" class="form-control" placeholder="默认为FastAdmin" />
  335 + </div>
  336 + <div class="col-xs-3">
  337 + <label>文档作者</label>
  338 + <input type="text" name="author" class="form-control" placeholder="默认为FastAdmin" />
  339 + </div>
  340 + <div class="col-xs-3">
  341 + <label>文档语言</label>
  342 + <select name="language" class="form-control">
  343 + <option value="" selected>请选择语言</option>
  344 + <option value="zh-cn">中文</option>
  345 + <option value="en">英文</option>
  346 + </select>
  347 + </div>
  348 + </div>
  349 + </div>
  350 +
  351 + <div class="form-group">
  352 + <legend>生成命令行</legend>
  353 + <textarea class="form-control" rel="command" rows="1" placeholder="请点击生成命令行"></textarea>
  354 + </div>
  355 +
  356 + <div class="form-group">
  357 + <legend>返回结果</legend>
  358 + <textarea class="form-control" rel="result" rows="5" placeholder="请点击立即执行"></textarea>
  359 + </div>
  360 +
  361 + <div class="form-group">
  362 + <button type="button" class="btn btn-info btn-embossed btn-command">{:__('生成命令行')}</button>
  363 + <button type="button" class="btn btn-success btn-embossed btn-execute">{:__('立即执行')}</button>
  364 + </div>
  365 +
  366 + </form>
  367 + </div>
  368 + </div>
  369 + </div>
  370 + </div>
  371 + </div>
  372 +</div>
  373 +<script id="relationtpl" type="text/html">
  374 + <div class="row relation-item">
  375 + <div class="col-xs-2">
  376 + <label>请选择关联表</label>
  377 + <select name="relation[<%=index%>][relation]" class="form-control relationtable"></select>
  378 + </div>
  379 + <div class="col-xs-2">
  380 + <label>请选择关联类型</label>
  381 + <select name="relation[<%=index%>][relationmode]" class="form-control relationmode"></select>
  382 + </div>
  383 + <div class="col-xs-2">
  384 + <label>关联外键</label>
  385 + <select name="relation[<%=index%>][relationforeignkey]" class="form-control relationforeignkey"></select>
  386 + </div>
  387 + <div class="col-xs-2">
  388 + <label>关联主键</label>
  389 + <select name="relation[<%=index%>][relationprimarykey]" class="form-control relationprimarykey"></select>
  390 + </div>
  391 + <div class="col-xs-2">
  392 + <label>请选择显示字段</label>
  393 + <select name="relation[<%=index%>][relationfields][]" multiple class="form-control relationfields"></select>
  394 + </div>
  395 + <div class="col-xs-2">
  396 + <label>&nbsp;</label>
  397 + <a href="javascript:;" class="btn btn-danger btn-block btn-removerelation">移除</a>
  398 + </div>
  399 + </div>
  400 +</script>
  1 +<table class="table table-striped">
  2 + <thead>
  3 + <tr>
  4 + <th>{:__('Title')}</th>
  5 + <th>{:__('Content')}</th>
  6 + </tr>
  7 + </thead>
  8 + <tbody>
  9 + <tr>
  10 + <td>{:__('Type')}</td>
  11 + <td>{$row.type}({$row.type_text})</td>
  12 + </tr>
  13 + <tr>
  14 + <td>{:__('Params')}</td>
  15 + <td>{$row.params}</td>
  16 + </tr>
  17 + <tr>
  18 + <td>{:__('Command')}</td>
  19 + <td>{$row.command}</td>
  20 + </tr>
  21 + <tr>
  22 + <td>{:__('Content')}</td>
  23 + <td>
  24 + <textarea class="form-control" name="" id="" cols="60" rows="10">{$row.content}</textarea>
  25 + </td>
  26 + </tr>
  27 + <tr>
  28 + <td>{:__('Executetime')}</td>
  29 + <td>{$row.executetime|datetime}</td>
  30 + </tr>
  31 + <tr>
  32 + <td>{:__('Status')}</td>
  33 + <td>{$row.status_text}</td>
  34 + </tr>
  35 + </tbody>
  36 +</table>
  37 +<div class="hide layer-footer">
  38 + <label class="control-label col-xs-12 col-sm-2"></label>
  39 + <div class="col-xs-12 col-sm-8">
  40 + <button type="reset" class="btn btn-primary btn-embossed btn-close" onclick="Layer.closeAll();">{:__('Close')}</button>
  41 + </div>
  42 +</div>
  1 +<div class="panel panel-default panel-intro">
  2 + {:build_heading()}
  3 +
  4 + <div class="panel-body">
  5 + <div id="myTabContent" class="tab-content">
  6 + <div class="tab-pane fade active in" id="one">
  7 + <div class="widget-body no-padding">
  8 + <div id="toolbar" class="toolbar">
  9 + <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
  10 + <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('command/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
  11 + <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('command/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
  12 +
  13 + </div>
  14 + <table id="table" class="table table-striped table-bordered table-hover"
  15 + data-operate-detail="{:$auth->check('command/detail')}"
  16 + data-operate-execute="{:$auth->check('command/execute')}"
  17 + data-operate-del="{:$auth->check('command/del')}"
  18 + width="100%">
  19 + </table>
  20 + </div>
  21 + </div>
  22 +
  23 + </div>
  24 + </div>
  25 +</div>
  1 +<?php
  2 +
  3 +return [
  4 +];
  1 +<?php
  2 +
  3 +namespace addons\command\controller;
  4 +
  5 +use think\addons\Controller;
  6 +
  7 +class Index extends Controller
  8 +{
  9 +
  10 + public function index()
  11 + {
  12 + $this->error("当前插件暂无前台页面");
  13 + }
  14 +
  15 +}
  1 +name = command
  2 +title = 在线命令
  3 +intro = 可在线执行FastAdmin的命令行相关命令
  4 +author = Karson
  5 +website = http://www.fastadmin.net
  6 +version = 1.0.5
  7 +state = 1
  8 +url = /addons/command.html
  1 +CREATE TABLE IF NOT EXISTS `__PREFIX__command` (
  2 + `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
  3 + `type` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '类型',
  4 + `params` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '参数',
  5 + `command` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '命令',
  6 + `content` text COMMENT '返回结果',
  7 + `executetime` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '执行时间',
  8 + `createtime` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '创建时间',
  9 + `updatetime` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '更新时间',
  10 + `status` enum('successed','failured') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'failured' COMMENT '状态',
  11 + PRIMARY KEY (`id`) USING BTREE
  12 +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '在线命令表' ROW_FORMAT = Compact;
  1 +<?php
  2 +
  3 +namespace addons\command\library;
  4 +
  5 +/**
  6 + * Class Output
  7 + */
  8 +class Output extends \think\console\Output
  9 +{
  10 +
  11 + protected $message = [];
  12 +
  13 + public function __construct($driver = 'console')
  14 + {
  15 + parent::__construct($driver);
  16 + }
  17 +
  18 + protected function block($style, $message)
  19 + {
  20 + $this->message[] = $message;
  21 + }
  22 +
  23 + public function getMessage()
  24 + {
  25 + return $this->message;
  26 + }
  27 +
  28 +}
  1 +define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function ($, undefined, Backend, Table, Form, Template) {
  2 +
  3 + var Controller = {
  4 + index: function () {
  5 + // 初始化表格参数配置
  6 + Table.api.init({
  7 + extend: {
  8 + index_url: 'command/index',
  9 + add_url: 'command/add',
  10 + edit_url: '',
  11 + del_url: 'command/del',
  12 + multi_url: 'command/multi',
  13 + table: 'command',
  14 + }
  15 + });
  16 +
  17 + var table = $("#table");
  18 +
  19 + // 初始化表格
  20 + table.bootstrapTable({
  21 + url: $.fn.bootstrapTable.defaults.extend.index_url,
  22 + pk: 'id',
  23 + sortName: 'id',
  24 + columns: [
  25 + [
  26 + {checkbox: true},
  27 + {field: 'id', title: __('Id')},
  28 + {field: 'type', title: __('Type'), formatter: Table.api.formatter.search},
  29 + {field: 'type_text', title: __('Type')},
  30 + {
  31 + field: 'command', title: __('Command'), formatter: function (value, row, index) {
  32 + return '<input type="text" class="form-control" value="' + value + '">';
  33 + }
  34 + },
  35 + {
  36 + field: 'executetime',
  37 + title: __('Executetime'),
  38 + operate: 'RANGE',
  39 + addclass: 'datetimerange',
  40 + formatter: Table.api.formatter.datetime
  41 + },
  42 + {
  43 + field: 'createtime',
  44 + title: __('Createtime'),
  45 + operate: 'RANGE',
  46 + addclass: 'datetimerange',
  47 + formatter: Table.api.formatter.datetime
  48 + },
  49 + {
  50 + field: 'updatetime',
  51 + title: __('Updatetime'),
  52 + operate: 'RANGE',
  53 + addclass: 'datetimerange',
  54 + formatter: Table.api.formatter.datetime
  55 + },
  56 + {
  57 + field: 'status',
  58 + title: __('Status'),
  59 + table: table,
  60 + custom: {"successed": 'success', "failured": 'danger'},
  61 + searchList: {"successed": __('Successed'), "failured": __('Failured')},
  62 + formatter: Table.api.formatter.status
  63 + },
  64 + {
  65 + field: 'operate',
  66 + title: __('Operate'),
  67 + buttons: [
  68 + {
  69 + name: 'execute',
  70 + title: __('Execute again'),
  71 + text: __('Execute again'),
  72 + url: 'command/execute',
  73 + icon: 'fa fa-repeat',
  74 + classname: 'btn btn-success btn-xs btn-execute btn-ajax',
  75 + success: function (data) {
  76 + Layer.alert("<textarea class='form-control' cols='60' rows='5'>" + data.result + "</textarea>", {
  77 + title: __("执行结果"),
  78 + shadeClose: true
  79 + });
  80 + table.bootstrapTable('refresh');
  81 + return false;
  82 + }
  83 + },
  84 + {
  85 + name: 'execute',
  86 + title: __('Detail'),
  87 + text: __('Detail'),
  88 + url: 'command/detail',
  89 + icon: 'fa fa-list',
  90 + classname: 'btn btn-info btn-xs btn-execute btn-dialog'
  91 + }
  92 + ],
  93 + table: table,
  94 + events: Table.api.events.operate,
  95 + formatter: Table.api.formatter.operate
  96 + }
  97 + ]
  98 + ]
  99 + });
  100 +
  101 + // 为表格绑定事件
  102 + Table.api.bindevent(table);
  103 + },
  104 + add: function () {
  105 + require(['bootstrap-select', 'bootstrap-select-lang']);
  106 + var mainfields = [];
  107 + var relationfields = {};
  108 + var maintable = [];
  109 + var relationtable = [];
  110 + var relationmode = ["belongsto", "hasone"];
  111 +
  112 + var renderselect = function (select, data) {
  113 + var html = [];
  114 + for (var i = 0; i < data.length; i++) {
  115 + html.push("<option value='" + data[i] + "'>" + data[i] + "</option>");
  116 + }
  117 + $(select).html(html.join(""));
  118 + select.trigger("change");
  119 + if (select.data("selectpicker")) {
  120 + select.selectpicker('refresh');
  121 + }
  122 + return select;
  123 + };
  124 +
  125 + $("select[name=table] option").each(function () {
  126 + maintable.push($(this).val());
  127 + });
  128 + $(document).on('change', "input[name='isrelation']", function () {
  129 + $("#relation-zone").toggleClass("hide", !$(this).prop("checked"));
  130 + });
  131 + $(document).on('change', "select[name='table']", function () {
  132 + var that = this;
  133 + Fast.api.ajax({
  134 + url: "command/get_field_list",
  135 + data: {table: $(that).val()},
  136 + }, function (data, ret) {
  137 + mainfields = data.fieldlist;
  138 + $("#relation-zone .relation-item").remove();
  139 + renderselect($("#fields"), mainfields);
  140 + return false;
  141 + });
  142 + return false;
  143 + });
  144 + $(document).on('click', "a.btn-newrelation", function () {
  145 + var that = this;
  146 + var index = parseInt($(that).data("index")) + 1;
  147 + var content = Template("relationtpl", {index: index});
  148 + content = $(content.replace(/\[index\]/, index));
  149 + $(this).data("index", index);
  150 + $(content).insertBefore($(that).closest(".row"));
  151 + $('select', content).selectpicker();
  152 + var exists = [$("select[name='table']").val()];
  153 + $("select.relationtable").each(function () {
  154 + exists.push($(this).val());
  155 + });
  156 + relationtable = [];
  157 + $.each(maintable, function (i, j) {
  158 + if ($.inArray(j, exists) < 0) {
  159 + relationtable.push(j);
  160 + }
  161 + });
  162 + renderselect($("select.relationtable", content), relationtable);
  163 + $("select.relationtable", content).trigger("change");
  164 + });
  165 + $(document).on('click', "a.btn-removerelation", function () {
  166 + $(this).closest(".row").remove();
  167 + });
  168 + $(document).on('change', "#relation-zone select.relationmode", function () {
  169 + var table = $("select.relationtable", $(this).closest(".row")).val();
  170 + var that = this;
  171 + Fast.api.ajax({
  172 + url: "command/get_field_list",
  173 + data: {table: table},
  174 + }, function (data, ret) {
  175 + renderselect($(that).closest(".row").find("select.relationprimarykey"), $(that).val() == 'belongsto' ? data.fieldlist : mainfields);
  176 + renderselect($(that).closest(".row").find("select.relationforeignkey"), $(that).val() == 'hasone' ? data.fieldlist : mainfields);
  177 + return false;
  178 + });
  179 + });
  180 + $(document).on('change', "#relation-zone select.relationtable", function () {
  181 + var that = this;
  182 + Fast.api.ajax({
  183 + url: "command/get_field_list",
  184 + data: {table: $(that).val()},
  185 + }, function (data, ret) {
  186 + renderselect($(that).closest(".row").find("select.relationmode"), relationmode);
  187 + renderselect($(that).closest(".row").find("select.relationfields"), mainfields)
  188 + renderselect($(that).closest(".row").find("select.relationforeignkey"), data.fieldlist)
  189 + renderselect($(that).closest(".row").find("select.relationfields"), data.fieldlist)
  190 + return false;
  191 + });
  192 + });
  193 + $(document).on('click', ".btn-command", function () {
  194 + var form = $(this).closest("form");
  195 + var textarea = $("textarea[rel=command]", form);
  196 + textarea.val('');
  197 + Fast.api.ajax({
  198 + url: "command/command/action/command",
  199 + data: form.serialize(),
  200 + }, function (data, ret) {
  201 + textarea.val(data.command);
  202 + return false;
  203 + });
  204 + });
  205 + $(document).on('click', ".btn-execute", function () {
  206 + var form = $(this).closest("form");
  207 + var textarea = $("textarea[rel=result]", form);
  208 + textarea.val('');
  209 + Fast.api.ajax({
  210 + url: "command/command/action/execute",
  211 + data: form.serialize(),
  212 + }, function (data, ret) {
  213 + textarea.val(data.result);
  214 + window.parent.$(".toolbar .btn-refresh").trigger('click');
  215 + top.window.Fast.api.refreshmenu();
  216 + return false;
  217 + }, function () {
  218 + window.parent.$(".toolbar .btn-refresh").trigger('click');
  219 + });
  220 + });
  221 + $("select[name='table']").trigger("change");
  222 + Controller.api.bindevent();
  223 + },
  224 + edit: function () {
  225 + Controller.api.bindevent();
  226 + },
  227 + api: {
  228 + bindevent: function () {
  229 + Form.api.bindevent($("form[role=form]"));
  230 + }
  231 + }
  232 + };
  233 + return Controller;
  234 +});
  1 +<?php
  2 +
  3 +namespace addons\nkeditor;
  4 +
  5 +use app\common\library\Menu;
  6 +use think\Addons;
  7 +
  8 +/**
  9 + * 富文本编辑器插件
  10 + */
  11 +class Nkeditor extends Addons
  12 +{
  13 +
  14 + /**
  15 + * 插件安装方法
  16 + * @return bool
  17 + */
  18 + public function install()
  19 + {
  20 +
  21 + return true;
  22 + }
  23 +
  24 + /**
  25 + * 插件卸载方法
  26 + * @return bool
  27 + */
  28 + public function uninstall()
  29 + {
  30 +
  31 + return true;
  32 + }
  33 +
  34 + /**
  35 + * 插件启用方法
  36 + * @return bool
  37 + */
  38 + public function enable()
  39 + {
  40 +
  41 + return true;
  42 + }
  43 +
  44 + /**
  45 + * 插件禁用方法
  46 + * @return bool
  47 + */
  48 + public function disable()
  49 + {
  50 +
  51 + return true;
  52 + }
  53 +
  54 + /**
  55 + * @param $params
  56 + */
  57 + public function configInit(&$params)
  58 + {
  59 + $config = $this->getConfig();
  60 + $params['nkeditor'] = ['theme' => $config['theme'], 'wordimageserver' => $config['wordimageserver']];
  61 + }
  62 +
  63 +}
  1 +# NKeditor
  2 +NKedtior是基于 kindeditor 进行二次开发的项目
  3 +kindeditor 是一款优秀的开源在线编辑器。轻量级且功能强大,代码量却不到百度的ueditor编辑器的一半。可惜已经4年没有更新了,由于业务的需求我们在kindeditor的基础上开发了 NKeditor, 主要做了一下工作:
  4 +1. 调整编辑器和弹出 dialog 的样式,美化了UI
  5 +2. 重写图片上传和批量图片上传插件,使用 html5 上传代替了 flash,实现了待上传图片预览,优化用户体验
  6 +3. 修复一些已知的bug,如 ajax 提交无法获取内容等
  7 +4. 新增涂鸦等功能
  8 +
  9 +再次感谢 kindeditor 的开发者,为我们提供了如此优秀的在线编辑器,让我们能在前人的基础上继续贡献自己的微薄之力。
  10 +
  11 +# 开源说明
  12 +本插件基于Nkeditor进行二次开发,修改的核心文件已开源于 https://gitee.com/karson/kindeditor
  13 +
  14 +# 特别感谢
  15 +[Kindeditor](https://gitee.com/luolonghao/kindeditor)
  16 +[Nkeditor](https://gitee.com/blackfox/kindeditor)
  17 +
  1 +
  2 +.ke-container-black .ke-toolbar .ke-icon-remoteimage {
  3 + background-image: url(../img/download.png);
  4 + background-size: 16px 16px;
  5 +}
  1 +define(['nkeditor-core'], function (Nkeditor) {
  2 + Nkeditor.plugin('multiimage', function (K) {
  3 + var self = this, name = 'multiimage', lang = self.lang(name + '.'),
  4 + allowImages = K.undef(self.allowImages, false);
  5 +
  6 + var click = function () {
  7 +
  8 + var html = [
  9 + '<div class="ke-dialog-content-inner">',
  10 + '<div class="ke-dialog-row ke-clearfix">',
  11 + '<div class=""><div class="ke-inline-block ke-upload-button">' +
  12 + '<form class="ke-upload-area ke-form nice-validator n-default" method="post" enctype="multipart/form-data" style="width: 266px;margin:50px auto;">' +
  13 + '<span class="ke-button-common"><input type="button" class="ke-button-common ke-button" value="批量上传图片" style="width:128px;"></span><input type="file" class="ke-upload-file" name="imgFiles" multiple style="width:128px;left:0;right:inherit" tabindex="-1">' +
  14 + '<span class="ke-button-common" style="margin-left:10px;"><input type="button" class="ke-button-common ke-button ke-select-image" style="width:128px;" value="从图片空间选择"></span>' +
  15 + '</form>' +
  16 + '</div></span></div>',
  17 + '</div>',
  18 + '</div>'
  19 + ].join('');
  20 + var dialog = self.createDialog({
  21 + name: name,
  22 + width: 450,
  23 + height: 260,
  24 + title: self.lang(name),
  25 + body: html,
  26 + noBtn: {
  27 + name: self.lang('no'),
  28 + click: function (e) {
  29 + self.hideDialog().focus();
  30 + }
  31 + }
  32 + }),
  33 + div = dialog.div;
  34 + $("input[name=imgFiles]", div).change(function () {
  35 + dialog.showLoading();
  36 + var files = $(this).prop('files');
  37 + $.each(files, function (i, file) {
  38 + self.beforeUpload.call(self, function (data) {
  39 + self.exec('insertimage', Fast.api.cdnurl(data.data.url));
  40 + }, file);
  41 + });
  42 + setTimeout(function () {
  43 + self.hideDialog().focus();
  44 + }, 0);
  45 + });
  46 + $(".ke-select-image", div).click(function () {
  47 + self.loadPlugin('filemanager', function () {
  48 + self.plugin.filemanagerDialog({
  49 + dirName: 'image',
  50 + multiple: true,
  51 + clickFn: function (urls) {
  52 + $.each(urls, function(i, url){
  53 + self.exec('insertimage', url);
  54 + });
  55 + }
  56 + });
  57 + });
  58 + self.hideDialog().focus();
  59 + // parent.Fast.api.open("general/attachment/select?element_id=&multiple=true&mimetype=*", __('Choose'), {
  60 + // callback: function (data) {
  61 + // var urlArr = data.url.split(/\,/);
  62 + // $.each(urlArr, function () {
  63 + // var url = Fast.api.cdnurl(this);
  64 + // self.exec('insertimage', url);
  65 + // });
  66 + // }
  67 + // });
  68 + });
  69 + };
  70 + self.clickToolbar(name, click);
  71 + });
  72 +
  73 + return Nkeditor;
  74 +});
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +* Arabic Translation By daif alotaibi (http://daif.net/)
  9 +*******************************************************************************/
  10 +
  11 +KindEditor.lang({
  12 + source : 'عرض المصدر',
  13 + preview : 'معاينة الصفحة',
  14 + undo : 'تراجع(Ctrl+Z)',
  15 + redo : 'إعادة التراجع(Ctrl+Y)',
  16 + cut : 'قص(Ctrl+X)',
  17 + copy : 'نسخ(Ctrl+C)',
  18 + paste : 'لصق(Ctrl+V)',
  19 + plainpaste : 'لصق كنص عادي',
  20 + wordpaste : 'لصق من مايكروسفت ورد',
  21 + selectall : 'تحديد الكل',
  22 + justifyleft : 'محاذاه لليسار',
  23 + justifycenter : 'محاذاه للوسط',
  24 + justifyright : 'محاذاه لليمين',
  25 + justifyfull : 'محاذاه تلقائية',
  26 + insertorderedlist : 'قائمة مرقمه',
  27 + insertunorderedlist : 'قائمة نقطية',
  28 + indent : 'إزاحه النص',
  29 + outdent : 'إلغاء الازاحة',
  30 + subscript : 'أسفل النص',
  31 + superscript : 'أعلى النص',
  32 + formatblock : 'Paragraph format',
  33 + fontname : 'نوع الخط',
  34 + fontsize : 'حجم الخط',
  35 + forecolor : 'لون النص',
  36 + hilitecolor : 'لون خلفية النص',
  37 + bold : 'عريض(Ctrl+B)',
  38 + italic : 'مائل(Ctrl+I)',
  39 + underline : 'خط تحت النص(Ctrl+U)',
  40 + strikethrough : 'خط على النص',
  41 + removeformat : 'إزالة التنسيق',
  42 + image : 'إدراج صورة',
  43 + multiimage : 'Multi image',
  44 + flash : 'إدراج فلاش',
  45 + media : 'إدراج وسائط متعددة',
  46 + table : 'إدراج جدول',
  47 + tablecell : 'خلية',
  48 + hr : 'إدراج خط أفقي',
  49 + emoticons : 'إدراج وجه ضاحك',
  50 + link : 'رابط',
  51 + unlink : 'إزالة الرابط',
  52 + fullscreen : 'محرر ملئ الشاشة',
  53 + about : 'حول',
  54 + print : 'طباعة',
  55 + filemanager : 'مدير الملفات',
  56 + code : 'إدراج نص برمجي',
  57 + map : 'خرائط قووقل',
  58 + baidumap : 'خرائط قووقل',
  59 + lineheight : 'إرتفاع السطر',
  60 + clearhtml : 'مسح كود HTML',
  61 + pagebreak : 'إدراج فاصل صفحات',
  62 + quickformat : 'تنسيق سريع',
  63 + insertfile : 'إدراج ملف',
  64 + template : 'إدراج قالب',
  65 + anchor : 'رابط',
  66 + yes : 'موافق',
  67 + no : 'إلغاء',
  68 + close : 'إغلاق',
  69 + editImage : 'خصائص الصورة',
  70 + deleteImage : 'حذفالصورة',
  71 + editFlash : 'خصائص الفلاش',
  72 + deleteFlash : 'حذف الفلاش',
  73 + editMedia : 'خصائص الوسائط',
  74 + deleteMedia : 'حذف الوسائط',
  75 + editLink : 'خصائص الرابط',
  76 + deleteLink : 'إزالة الرابط',
  77 + editAnchor : 'Anchor properties',
  78 + deleteAnchor : 'Delete Anchor',
  79 + tableprop : 'خصائص الجدول',
  80 + tablecellprop : 'خصائص الخلية',
  81 + tableinsert : 'إدراج جدول',
  82 + tabledelete : 'حذف جدول',
  83 + tablecolinsertleft : 'إدراج عمود لليسار',
  84 + tablecolinsertright : 'إدراج عمود لليسار',
  85 + tablerowinsertabove : 'إدراج صف للأعلى',
  86 + tablerowinsertbelow : 'إدراج صف للأسفل',
  87 + tablerowmerge : 'دمج للأسفل',
  88 + tablecolmerge : 'دمج لليمين',
  89 + tablerowsplit : 'تقسم الصف',
  90 + tablecolsplit : 'تقسيم العمود',
  91 + tablecoldelete : 'حذف العمود',
  92 + tablerowdelete : 'حذف الصف',
  93 + noColor : 'إفتراضي',
  94 + pleaseSelectFile : 'Please select file.',
  95 + invalidImg : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: jpg,gif,bmp,png",
  96 + invalidMedia : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
  97 + invalidWidth : "العرض يجب أن يكون رقم.",
  98 + invalidHeight : "الإرتفاع يجب أن يكون رقم.",
  99 + invalidBorder : "عرض الحد يجب أن يكون رقم.",
  100 + invalidUrl : "الرجاء إدخال رابط حيح.",
  101 + invalidRows : 'صفوف غير صحيح.',
  102 + invalidCols : 'أعمدة غير صحيحة.',
  103 + invalidPadding : 'The padding must be number.',
  104 + invalidSpacing : 'The spacing must be number.',
  105 + invalidJson : 'Invalid JSON string.',
  106 + uploadSuccess : 'تم رفع الملف بنجاح.',
  107 + cutError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+X).',
  108 + copyError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+C).',
  109 + pasteError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+V).',
  110 + ajaxLoading : 'Loading ...',
  111 + uploadLoading : 'Uploading ...',
  112 + uploadError : 'Upload Error',
  113 + 'plainpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.',
  114 + 'wordpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.',
  115 + 'code.pleaseInput' : 'Please input code.',
  116 + 'link.url' : 'الرابط',
  117 + 'link.linkType' : 'الهدف',
  118 + 'link.newWindow' : 'نافذة جديدة',
  119 + 'link.selfWindow' : 'نفس النافذة',
  120 + 'flash.url' : 'الرابط',
  121 + 'flash.width' : 'العرض',
  122 + 'flash.height' : 'الإرتفاع',
  123 + 'flash.upload' : 'رفع',
  124 + 'flash.viewServer' : 'أستعراض',
  125 + 'media.url' : 'الرابط',
  126 + 'media.width' : 'العرض',
  127 + 'media.height' : 'الإرتفاع',
  128 + 'media.autostart' : 'تشغيل تلقائي',
  129 + 'media.upload' : 'رفع',
  130 + 'media.viewServer' : 'أستعراض',
  131 + 'image.remoteImage' : 'إدراج الرابط',
  132 + 'image.localImage' : 'رفع',
  133 + 'image.remoteUrl' : 'الرابط',
  134 + 'image.localUrl' : 'الملف',
  135 + 'image.size' : 'الحجم',
  136 + 'image.width' : 'العرض',
  137 + 'image.height' : 'الإرتفاع',
  138 + 'image.resetSize' : 'إستعادة الأبعاد',
  139 + 'image.align' : 'محاذاة',
  140 + 'image.defaultAlign' : 'الإفتراضي',
  141 + 'image.leftAlign' : 'اليسار',
  142 + 'image.rightAlign' : 'اليمين',
  143 + 'image.imgTitle' : 'العنوان',
  144 + 'image.upload' : 'أستعراض',
  145 + 'image.viewServer' : 'أستعراض',
  146 + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
  147 + 'multiimage.startUpload' : 'Start upload',
  148 + 'multiimage.clearAll' : 'Clear all',
  149 + 'multiimage.insertAll' : 'Insert all',
  150 + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
  151 + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
  152 + 'multiimage.zeroByteFile' : 'Zero byte file.',
  153 + 'multiimage.invalidFiletype' : 'Invalid file type.',
  154 + 'multiimage.unknownError' : 'Unknown upload error.',
  155 + 'multiimage.pending' : 'Pending ...',
  156 + 'multiimage.uploadError' : 'Upload error',
  157 + 'filemanager.emptyFolder' : 'فارغ',
  158 + 'filemanager.moveup' : 'المجلد الأب',
  159 + 'filemanager.viewType' : 'العرض: ',
  160 + 'filemanager.viewImage' : 'مصغرات',
  161 + 'filemanager.listImage' : 'قائمة',
  162 + 'filemanager.orderType' : 'الترتيب: ',
  163 + 'filemanager.fileName' : 'بالإسم',
  164 + 'filemanager.fileSize' : 'بالحجم',
  165 + 'filemanager.fileType' : 'بالنوع',
  166 + 'insertfile.url' : 'الرابط',
  167 + 'insertfile.title' : 'العنوان',
  168 + 'insertfile.upload' : 'رفع',
  169 + 'insertfile.viewServer' : 'أستعراض',
  170 + 'table.cells' : 'خلايا',
  171 + 'table.rows' : 'صفوف',
  172 + 'table.cols' : 'أعمدة',
  173 + 'table.size' : 'الأبعاد',
  174 + 'table.width' : 'العرض',
  175 + 'table.height' : 'الإرتفاع',
  176 + 'table.percent' : '%',
  177 + 'table.px' : 'px',
  178 + 'table.space' : 'الخارج',
  179 + 'table.padding' : 'الداخل',
  180 + 'table.spacing' : 'الفراغات',
  181 + 'table.align' : 'محاذاه',
  182 + 'table.textAlign' : 'افقى',
  183 + 'table.verticalAlign' : 'رأسي',
  184 + 'table.alignDefault' : 'إفتراضي',
  185 + 'table.alignLeft' : 'يسار',
  186 + 'table.alignCenter' : 'وسط',
  187 + 'table.alignRight' : 'يمين',
  188 + 'table.alignTop' : 'أعلى',
  189 + 'table.alignMiddle' : 'منتصف',
  190 + 'table.alignBottom' : 'أسفل',
  191 + 'table.alignBaseline' : 'Baseline',
  192 + 'table.border' : 'الحدود',
  193 + 'table.borderWidth' : 'العرض',
  194 + 'table.borderColor' : 'اللون',
  195 + 'table.backgroundColor' : 'الخلفية',
  196 + 'map.address' : 'العنوان: ',
  197 + 'map.search' : 'بحث',
  198 + 'baidumap.address' : 'العنوان: ',
  199 + 'baidumap.search' : 'بحث',
  200 + 'baidumap.insertDynamicMap' : 'Dynamic Map',
  201 + 'anchor.name' : 'إسم الرابط',
  202 + 'formatblock.formatBlock' : {
  203 + h1 : 'عنوان 1',
  204 + h2 : 'عنوان 2',
  205 + h3 : 'عنوان 3',
  206 + h4 : 'عنوان 4',
  207 + p : 'عادي'
  208 + },
  209 + 'fontname.fontName' : {
  210 + 'Arial' : 'Arial',
  211 + 'Arial Black' : 'Arial Black',
  212 + 'Comic Sans MS' : 'Comic Sans MS',
  213 + 'Courier New' : 'Courier New',
  214 + 'Garamond' : 'Garamond',
  215 + 'Georgia' : 'Georgia',
  216 + 'Tahoma' : 'Tahoma',
  217 + 'Times New Roman' : 'Times New Roman',
  218 + 'Trebuchet MS' : 'Trebuchet MS',
  219 + 'Verdana' : 'Verdana'
  220 + },
  221 + 'lineheight.lineHeight' : [
  222 + {'1' : 'إرتفاع السطر 1'},
  223 + {'1.5' : 'إرتفاع السطر 1.5'},
  224 + {'2' : 'إرتفاع السطر 2'},
  225 + {'2.5' : 'إرتفاع السطر 2.5'},
  226 + {'3' : 'إرتفاع السطر 3'}
  227 + ],
  228 + 'template.selectTemplate' : 'قالب',
  229 + 'template.replaceContent' : 'إستبدال المحتوى الحالي',
  230 + 'template.fileList' : {
  231 + '1.html' : 'صورة ونص',
  232 + '2.html' : 'جدول',
  233 + '3.html' : 'قائمة'
  234 + }
  235 +}, 'ar');
  236 +
  237 +KindEditor.each(KindEditor.options.items, function(i, name) {
  238 + if (name == 'baidumap') {
  239 + KindEditor.options.items[i] = 'map';
  240 + }
  241 +});
  242 +KindEditor.options.langType = 'ar';
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +KindEditor.lang({
  11 + source : 'Source',
  12 + preview : 'Preview',
  13 + undo : 'Undo(Ctrl+Z)',
  14 + redo : 'Redo(Ctrl+Y)',
  15 + cut : 'Cut(Ctrl+X)',
  16 + copy : 'Copy(Ctrl+C)',
  17 + paste : 'Paste(Ctrl+V)',
  18 + plainpaste : 'Paste as plain text',
  19 + wordpaste : 'Paste from Word',
  20 + selectall : 'Select all',
  21 + justifyleft : 'Align left',
  22 + justifycenter : 'Align center',
  23 + justifyright : 'Align right',
  24 + justifyfull : 'Align full',
  25 + insertorderedlist : 'Ordered list',
  26 + insertunorderedlist : 'Unordered list',
  27 + indent : 'Increase indent',
  28 + outdent : 'Decrease indent',
  29 + subscript : 'Subscript',
  30 + superscript : 'Superscript',
  31 + formatblock : 'Paragraph format',
  32 + fontname : 'Font family',
  33 + fontsize : 'Font size',
  34 + forecolor : 'Text color',
  35 + hilitecolor : 'Highlight color',
  36 + bold : 'Bold(Ctrl+B)',
  37 + italic : 'Italic(Ctrl+I)',
  38 + underline : 'Underline(Ctrl+U)',
  39 + strikethrough : 'Strikethrough',
  40 + removeformat : 'Remove format',
  41 + image : 'Image',
  42 + multiimage : 'Multi image',
  43 + flash : 'Flash',
  44 + media : 'Embeded media',
  45 + table : 'Table',
  46 + tablecell : 'Cell',
  47 + hr : 'Insert horizontal line',
  48 + emoticons : 'Insert emoticon',
  49 + link : 'Link',
  50 + unlink : 'Unlink',
  51 + fullscreen : 'Toggle fullscreen mode',
  52 + about : 'About',
  53 + print : 'Print',
  54 + filemanager : 'File Manager',
  55 + code : 'Insert code',
  56 + map : 'Google Maps',
  57 + baidumap : 'Baidu Maps',
  58 + lineheight : 'Line height',
  59 + clearhtml : 'Clear HTML code',
  60 + pagebreak : 'Insert Page Break',
  61 + quickformat : 'Quick Format',
  62 + insertfile : 'Insert file',
  63 + template : 'Insert Template',
  64 + anchor : 'Anchor',
  65 + yes : 'OK',
  66 + no : 'Cancel',
  67 + close : 'Close',
  68 + editImage : 'Image properties',
  69 + deleteImage : 'Delete image',
  70 + editFlash : 'Flash properties',
  71 + deleteFlash : 'Delete flash',
  72 + editMedia : 'Media properties',
  73 + deleteMedia : 'Delete media',
  74 + editLink : 'Link properties',
  75 + deleteLink : 'Unlink',
  76 + editAnchor : 'Anchor properties',
  77 + deleteAnchor : 'Delete Anchor',
  78 + tableprop : 'Table properties',
  79 + tablecellprop : 'Cell properties',
  80 + tableinsert : 'Insert table',
  81 + tabledelete : 'Delete table',
  82 + tablecolinsertleft : 'Insert column left',
  83 + tablecolinsertright : 'Insert column right',
  84 + tablerowinsertabove : 'Insert row above',
  85 + tablerowinsertbelow : 'Insert row below',
  86 + tablerowmerge : 'Merge down',
  87 + tablecolmerge : 'Merge right',
  88 + tablerowsplit : 'Split row',
  89 + tablecolsplit : 'Split column',
  90 + tablecoldelete : 'Delete column',
  91 + tablerowdelete : 'Delete row',
  92 + noColor : 'Default',
  93 + pleaseSelectFile : 'Please select file.',
  94 + invalidImg : "Please type valid URL.\nAllowed file extension: jpg,gif,bmp,png",
  95 + invalidMedia : "Please type valid URL.\nAllowed file extension: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
  96 + invalidWidth : "The width must be number.",
  97 + invalidHeight : "The height must be number.",
  98 + invalidBorder : "The border must be number.",
  99 + invalidUrl : "Please type valid URL.",
  100 + invalidRows : 'Invalid rows.',
  101 + invalidCols : 'Invalid columns.',
  102 + invalidPadding : 'The padding must be number.',
  103 + invalidSpacing : 'The spacing must be number.',
  104 + invalidJson : 'Invalid JSON string.',
  105 + uploadSuccess : 'Upload success.',
  106 + cutError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+X) instead.',
  107 + copyError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+C) instead.',
  108 + pasteError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+V) instead.',
  109 + ajaxLoading : 'Loading ...',
  110 + uploadLoading : 'Uploading ...',
  111 + uploadError : 'Upload Error',
  112 + 'plainpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.',
  113 + 'wordpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.',
  114 + 'code.pleaseInput' : 'Please input code.',
  115 + 'link.url' : 'URL',
  116 + 'link.linkType' : 'Target',
  117 + 'link.newWindow' : 'New window',
  118 + 'link.selfWindow' : 'Same window',
  119 + 'flash.url' : 'URL',
  120 + 'flash.width' : 'Width',
  121 + 'flash.height' : 'Height',
  122 + 'flash.upload' : 'Upload',
  123 + 'flash.viewServer' : 'Browse',
  124 + 'media.url' : 'URL',
  125 + 'media.width' : 'Width',
  126 + 'media.height' : 'Height',
  127 + 'media.autostart' : 'Auto start',
  128 + 'media.upload' : 'Upload',
  129 + 'media.viewServer' : 'Browse',
  130 + 'image.remoteImage' : 'Insert URL',
  131 + 'image.localImage' : 'Upload',
  132 + 'image.remoteUrl' : 'URL',
  133 + 'image.localUrl' : 'File',
  134 + 'image.size' : 'Size',
  135 + 'image.width' : 'Width',
  136 + 'image.height' : 'Height',
  137 + 'image.resetSize' : 'Reset dimensions',
  138 + 'image.align' : 'Align',
  139 + 'image.defaultAlign' : 'Default',
  140 + 'image.leftAlign' : 'Left',
  141 + 'image.rightAlign' : 'Right',
  142 + 'image.imgTitle' : 'Title',
  143 + 'image.upload' : 'Browse',
  144 + 'image.viewServer' : 'Browse',
  145 + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
  146 + 'multiimage.startUpload' : 'Start upload',
  147 + 'multiimage.clearAll' : 'Clear all',
  148 + 'multiimage.insertAll' : 'Insert all',
  149 + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
  150 + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
  151 + 'multiimage.zeroByteFile' : 'Zero byte file.',
  152 + 'multiimage.invalidFiletype' : 'Invalid file type.',
  153 + 'multiimage.unknownError' : 'Unknown upload error.',
  154 + 'multiimage.pending' : 'Pending ...',
  155 + 'multiimage.uploadError' : 'Upload error',
  156 + 'filemanager.emptyFolder' : 'Blank',
  157 + 'filemanager.moveup' : 'Parent folder',
  158 + 'filemanager.viewType' : 'Display: ',
  159 + 'filemanager.viewImage' : 'Thumbnails',
  160 + 'filemanager.listImage' : 'List',
  161 + 'filemanager.orderType' : 'Sorting: ',
  162 + 'filemanager.fileName' : 'By name',
  163 + 'filemanager.fileSize' : 'By size',
  164 + 'filemanager.fileType' : 'By type',
  165 + 'insertfile.url' : 'URL',
  166 + 'insertfile.title' : 'Title',
  167 + 'insertfile.upload' : 'Upload',
  168 + 'insertfile.viewServer' : 'Browse',
  169 + 'table.cells' : 'Cells',
  170 + 'table.rows' : 'Rows',
  171 + 'table.cols' : 'Columns',
  172 + 'table.size' : 'Dimensions',
  173 + 'table.width' : 'Width',
  174 + 'table.height' : 'Height',
  175 + 'table.percent' : '%',
  176 + 'table.px' : 'px',
  177 + 'table.space' : 'Space',
  178 + 'table.padding' : 'Padding',
  179 + 'table.spacing' : 'Spacing',
  180 + 'table.align' : 'Align',
  181 + 'table.textAlign' : 'Horizontal',
  182 + 'table.verticalAlign' : 'Vertical',
  183 + 'table.alignDefault' : 'Default',
  184 + 'table.alignLeft' : 'Left',
  185 + 'table.alignCenter' : 'Center',
  186 + 'table.alignRight' : 'Right',
  187 + 'table.alignTop' : 'Top',
  188 + 'table.alignMiddle' : 'Middle',
  189 + 'table.alignBottom' : 'Bottom',
  190 + 'table.alignBaseline' : 'Baseline',
  191 + 'table.border' : 'Border',
  192 + 'table.borderWidth' : 'Width',
  193 + 'table.borderColor' : 'Color',
  194 + 'table.backgroundColor' : 'Background',
  195 + 'map.address' : 'Address: ',
  196 + 'map.search' : 'Search',
  197 + 'baidumap.address' : 'Address: ',
  198 + 'baidumap.search' : 'Search',
  199 + 'baidumap.insertDynamicMap' : 'Dynamic Map',
  200 + 'anchor.name' : 'Anchor name',
  201 + 'formatblock.formatBlock' : {
  202 + h1 : 'Heading 1',
  203 + h2 : 'Heading 2',
  204 + h3 : 'Heading 3',
  205 + h4 : 'Heading 4',
  206 + p : 'Normal'
  207 + },
  208 + 'fontname.fontName' : {
  209 + 'Arial' : 'Arial',
  210 + 'Arial Black' : 'Arial Black',
  211 + 'Comic Sans MS' : 'Comic Sans MS',
  212 + 'Courier New' : 'Courier New',
  213 + 'Garamond' : 'Garamond',
  214 + 'Georgia' : 'Georgia',
  215 + 'Tahoma' : 'Tahoma',
  216 + 'Times New Roman' : 'Times New Roman',
  217 + 'Trebuchet MS' : 'Trebuchet MS',
  218 + 'Verdana' : 'Verdana'
  219 + },
  220 + 'lineheight.lineHeight' : [
  221 + {'1' : 'Line height 1'},
  222 + {'1.5' : 'Line height 1.5'},
  223 + {'2' : 'Line height 2'},
  224 + {'2.5' : 'Line height 2.5'},
  225 + {'3' : 'Line height 3'}
  226 + ],
  227 + 'template.selectTemplate' : 'Template',
  228 + 'template.replaceContent' : 'Replace current content',
  229 + 'template.fileList' : {
  230 + '1.html' : 'Image and Text',
  231 + '2.html' : 'Table',
  232 + '3.html' : 'List'
  233 + }
  234 +}, 'en');
  235 +
  236 +//自动加载代码美化的js插件
  237 +// KindEditor.loadScript(KindEditor.options.pluginsPath+"code/prettify.js");
  238 +// KindEditor.each(KindEditor.options.items, function(i, name) {
  239 +// if (name == 'code') {
  240 +// KindEditor.options.items[i] = 'map';
  241 +// }
  242 +// });
  243 +KindEditor.options.langType = 'en';
  1 +/*******************************************************************************
  2 +* @author 您的名字 お名前
  3 +*******************************************************************************/
  4 +
  5 +KindEditor.lang({
  6 + source : 'HTMLコード',
  7 + preview : 'プレビュー',
  8 + undo : '戻る(Ctrl+Z)',
  9 + redo : '進む(Ctrl+Y)',
  10 + cut : 'カット(Ctrl+X)',
  11 + copy : 'コピー(Ctrl+C)',
  12 + paste : '貼り付け(Ctrl+V)',
  13 + plainpaste : 'フォーマットされていないテキストとして貼り付ける',
  14 + wordpaste : '「word」ドからペースト',
  15 + selectall : 'すべて選択(Ctrl+A)',
  16 + justifyleft : '左揃え',
  17 + justifycenter : '中央揃え',
  18 + justifyright : '右揃え',
  19 + justifyfull : '両端揃え',
  20 + insertorderedlist : '番号',
  21 + insertunorderedlist : '箇条書き',
  22 + indent : 'インデントを増やす',
  23 + outdent : 'インデントを減らす',
  24 + subscript : '下付き',
  25 + superscript : '上付き',
  26 + formatblock : '段落',
  27 + fontname : 'フォント',
  28 + fontsize : 'フォントサイズ',
  29 + forecolor : 'フォントカラー',
  30 + hilitecolor : 'テキストの背景',
  31 + bold : '太字(Ctrl+B)',
  32 + italic : '斜体(Ctrl+I)',
  33 + underline : '下線(Ctrl+U)',
  34 + strikethrough : '取り消し線',
  35 + removeformat : 'フォーマットを削除',
  36 + image : '画像',
  37 + multiimage : '一括画像アップロード',
  38 + flash : 'Flash',
  39 + media : 'ビデオとオーディオ',
  40 + table : 'テーブル',
  41 + tablecell : 'セル',
  42 + hr : '水平線を挿入する',
  43 + emoticons : '絵文字を挿入する',
  44 + link : 'ハイパーリンク',
  45 + unlink : 'ハイパーリンクをキャンセル',
  46 + fullscreen : 'フルスクリーン表示',
  47 + about : 'について',
  48 + print : 'プリント(Ctrl+P)',
  49 + filemanager : 'ファイルスペース',
  50 + code : 'プログラムコードを挿入',
  51 + map : 'Googleマップ',
  52 + baidumap : 'Baiduマップ',
  53 + lineheight : '行間隔',
  54 + clearhtml : 'HTMLコードをクリア',
  55 + pagebreak : 'ページ区切りの挿入',
  56 + quickformat : 'ワンクリックレイアウト',
  57 + insertfile : 'ファイルの挿入',
  58 + template : 'テンプレートの挿入',
  59 + anchor : 'アンカー',
  60 + yes : 'はい',
  61 + no : 'いいえ',
  62 + close : '閉じる',
  63 + editImage : 'イメージプロパティ',
  64 + deleteImage : 'イメージを削除',
  65 + editFlash : 'Flashプロパティ',
  66 + deleteFlash : 'Flashを削除',
  67 + editMedia : 'ビデオとオーディオのプロパティ',
  68 + deleteMedia : 'ビデオとオーディオを削除',
  69 + editLink : 'ハイパーリンク属性',
  70 + deleteLink : 'ハイパーリンクを削除',
  71 + editAnchor : 'アンカー属性',
  72 + deleteAnchor : 'アンカーを削除',
  73 + tableprop : 'テーブル属性',
  74 + tablecellprop : 'セル属性',
  75 + tableinsert : 'テーブルを挿入',
  76 + tabledelete : 'テーブルを削除',
  77 + tablecolinsertleft : '左に列を挿入する',
  78 + tablecolinsertright : '右に列を挿入する',
  79 + tablerowinsertabove : '上に行を挿入する',
  80 + tablerowinsertbelow : '下に行を挿入する',
  81 + tablerowmerge : '下にセルをマージする',
  82 + tablecolmerge : '右にセルをマージする',
  83 + tablerowsplit : '行を分割',
  84 + tablecolsplit : '列を分割',
  85 + tablecoldelete : '列を削除',
  86 + tablerowdelete : '行を削除',
  87 + noColor : '色なし',
  88 + pleaseSelectFile : 'ファイルを選択してください。',
  89 + invalidImg : "有効なURLアドレスを入力してください。\ n jpg、gif、bmp、png形式のみが許可されています。",
  90 + invalidMedia : "有効なURLアドレスを入力してください。swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb形式のみが許可されています。",
  91 + invalidWidth : "幅は数字でなければなりません。",
  92 + invalidHeight : "高さは数字でなければなりません。",
  93 + invalidBorder : "ボーダーは数字でなければなりません。",
  94 + invalidUrl : "有効なURLアドレスを入力してください。",
  95 + invalidRows : '行数は必須項目で、0以上の数字を入力してください。',
  96 + invalidCols : '列数は必須項目で、0以上の数字を入力してください。',
  97 + invalidPadding : 'マージンは数字でなければなりません。',
  98 + invalidSpacing : 'スペースは数字でなければなりません。',
  99 + invalidJson : 'サーバーエラー。',
  100 + uploadSuccess : 'アップロード成功。',
  101 + cutError : 'ブラウザのセキュリティ設定によってカット操作を使用できないので、ショートカットキー(Ctrl + X)を使用してください。',
  102 + copyError : 'ブラウザのセキュリティ設定によってコピー操作をできないので、ショートカットキー(Ctrl + C)を使用してください。',
  103 + pasteError : 'ブラウザのセキュリティ設定によって貼り付け操作をできないので、ショートカットキー(Ctrl + V)を使用してください。',
  104 + ajaxLoading : '読み込み中、お待ちください...',
  105 + uploadLoading : 'アップロード、しばらくお待ちください...',
  106 + uploadError : 'アップロードエラー',
  107 + 'plainpaste.comment' : 'ショートカットキー(Ctrl + V)でコンテンツを下のボックスに貼り付けてください。',
  108 + 'wordpaste.comment' : 'ショートカットキー(Ctrl + V)でコンテンツを下のボックスに貼り付けてください。',
  109 + 'code.pleaseInput' : 'プログラムコードを入力してください。 ',
  110 + 'link.url' : 'URL',
  111 + 'link.linkType' : 'タイプを開く',
  112 + 'link.newWindow' : '新しいウィンドウ',
  113 + 'link.selfWindow' : '現在のウィンドウ',
  114 + 'flash.url' : 'URL',
  115 + 'flash.width' : '幅',
  116 + 'flash.height' : '高さ',
  117 + 'flash.upload' : 'アップロード',
  118 + 'flash.viewServer' : 'ファイルスペース',
  119 + 'media.url' : 'URL',
  120 + 'media.width' : '幅',
  121 + 'media.height' : '高さ',
  122 + 'media.autostart' : '自動再生',
  123 + 'media.upload' : 'アップロード',
  124 + 'media.viewServer' : 'ファイルスペース',
  125 + 'image.remoteImage' : 'ネットワークイメージ',
  126 + 'image.localImage' : 'ローカルアップロード',
  127 + 'image.remoteUrl' : 'イメージアドレス ',
  128 + 'image.localUrl' : 'アップロードファイル',
  129 + 'image.size' : 'イメージサイズ',
  130 + 'image.width' : '幅',
  131 + 'image.height' : '高さ',
  132 + 'image.resetSize' : 'リセットサイズ',
  133 + 'image.align' : '配置',
  134 + 'image.defaultAlign' : 'デフォルト',
  135 + 'image.leftAlign' : '左揃え',
  136 + 'image.rightAlign' : '右揃え',
  137 + 'image.imgTitle' : '画像の説明',
  138 + 'image.upload' : 'ブラウズ...',
  139 + 'image.viewServer' : 'イメージスペース',
  140 + 'multiimage.uploadDesc' : 'ユーザーが<%= uploadLimit%>画像を同時にアップロードできますが、画像の容量は<%= sizeLimit%>を超えることができません',
  141 + 'multiimage.startUpload' : 'アップロード',
  142 + 'multiimage.clearAll' : 'すべてクリア',
  143 + 'multiimage.insertAll' : 'すべて挿入',
  144 + 'multiimage.queueLimitExceeded' : 'ファイルの数が上限を超えています。',
  145 + 'multiimage.fileExceedsSizeLimit' : 'ファイルサイズが制限を超えています。',
  146 + 'multiimage.zeroByteFile' : '空のファイルをアップロードできません。 ',
  147 + 'multiimage.invalidFiletype' : 'ファイル形式は正しくありません。',
  148 + 'multiimage.unknownError' : 'エラー、アップロードできません。',
  149 + 'multiimage.pending' : 'アップロード待ち',
  150 + 'multiimage.uploadError' : 'アップロード失敗',
  151 + 'filemanager.emptyFolder' : '空のフォルダ',
  152 + 'filemanager.moveup' : '前のフォルダに移動',
  153 + 'filemanager.viewType' : '表示モード:',
  154 + 'filemanager.viewImage' : 'サムネイル',
  155 + 'filemanager.listImage' : '詳細',
  156 + 'filemanager.orderType' : '並べ替え:',
  157 + 'filemanager.fileName' : 'ネーム',
  158 + 'filemanager.fileSize' : 'サイズ',
  159 + 'filemanager.fileType' : 'タイプ',
  160 + 'insertfile.url' : 'URL',
  161 + 'insertfile.title' : 'ファイルの説明',
  162 + 'insertfile.upload' : 'アップロード',
  163 + 'insertfile.viewServer' : 'ファイルスペース',
  164 + 'table.cells' : 'セル番号',
  165 + 'table.rows' : '行数',
  166 + 'table.cols' : '列数',
  167 + 'table.size' : 'サイズ',
  168 + 'table.width' : '幅',
  169 + 'table.height' : '高さ',
  170 + 'table.percent' : '%',
  171 + 'table.px' : 'px',
  172 + 'table.space' : 'テーブルスペース',
  173 + 'table.padding' : 'パッディング',
  174 + 'table.spacing' : 'スペース',
  175 + 'table.align' : '配置',
  176 + 'table.textAlign' : '水平配置',
  177 + 'table.verticalAlign' : '垂直配置',
  178 + 'table.alignDefault' : 'デフォルト',
  179 + 'table.alignLeft' : '左揃え',
  180 + 'table.alignCenter' : '中央揃え',
  181 + 'table.alignRight' : '右揃え',
  182 + 'table.alignTop' : 'トップ',
  183 + 'table.alignMiddle' : 'ミドル',
  184 + 'table.alignBottom' : 'ボトム',
  185 + 'table.alignBaseline' : 'ベースライン',
  186 + 'table.border' : 'ボーダー',
  187 + 'table.borderWidth' : 'ボーダー',
  188 + 'table.borderColor' : 'カラー',
  189 + 'table.backgroundColor' : '背景色',
  190 + 'map.address' : 'アドレス: ',
  191 + 'map.search' : '検索',
  192 + 'baidumap.address' : 'アドレス: ',
  193 + 'baidumap.search' : '検索',
  194 + 'baidumap.insertDynamicMap' : 'ダイナミックマップの挿入',
  195 + 'anchor.name' : 'アンカー名',
  196 +
  197 + 'formatblock.formatBlock' : {
  198 + h1 : '見出し1',
  199 + h2 : '見出し2',
  200 + h3 : '見出し3',
  201 + h4 : '見出し4',
  202 + p : '正 文'
  203 + },
  204 + 'fontname.fontName' : {
  205 + 'SimSun' : '明朝体',
  206 + 'NSimSun' : '新宋体',
  207 + 'FangSong_GB2312' : '仿宋_GB2312',
  208 + 'KaiTi_GB2312' : '楷書体_GB2312',
  209 + 'SimHei' : 'ゴチック体',
  210 + 'Microsoft YaHei' : 'Msyh',
  211 + 'Arial' : 'Arial',
  212 + 'Arial Black' : 'Arial Black',
  213 + 'Times New Roman' : 'Times New Roman',
  214 + 'Courier New' : 'Courier New',
  215 + 'Tahoma' : 'Tahoma',
  216 + 'Verdana' : 'Verdana'
  217 + },
  218 + 'lineheight.lineHeight' : [
  219 + {'1' : '行間1倍'},
  220 + {'1.5' : '行間1.5倍'},
  221 + {'2' : '行間2倍'},
  222 + {'2.5' : '行間2.5倍'},
  223 + {'3' : '行間3倍'}
  224 + ],
  225 + 'template.selectTemplate' : 'オプションテンプレート',
  226 + 'template.replaceContent' : '現在のコンテンツを置き換える',
  227 + 'template.fileList' : {
  228 + '1.html' : 'イメージとテキスト',
  229 + '2.html' : '表',
  230 + '3.html' : '段落番号'
  231 + }
  232 +}, 'ja-JP');
  233 +
  234 +KindEditor.options.langType = 'ja-JP';
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Composite <ukjinplant@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +KindEditor.lang({
  11 + source : '소스',
  12 + preview : '미리보기',
  13 + undo : '작업취소(Ctrl+Z)',
  14 + redo : '작업재개(Ctrl+Y)',
  15 + cut : '잘라내기(Ctrl+X)',
  16 + copy : '복사(Ctrl+C)',
  17 + paste : '붙여넣기(Ctrl+V)',
  18 + plainpaste : '일반 텍스트로 붙여넣기',
  19 + wordpaste : '워드 문서로 붙여넣기',
  20 + selectall : '전체 선택',
  21 + justifyleft : '왼쪽 정렬',
  22 + justifycenter : '가운데 정렬',
  23 + justifyright : '오른쪽 정렬',
  24 + justifyfull : '양쪽 정렬',
  25 + insertorderedlist : '순서 목록',
  26 + insertunorderedlist : '비순서 목록',
  27 + indent : '들여쓰기',
  28 + outdent : '내어쓰기',
  29 + subscript : '아랫첨자',
  30 + superscript : '윗첨자',
  31 + formatblock : '문단 형식',
  32 + fontname : '글꼴',
  33 + fontsize : '글자 크기',
  34 + forecolor : '글자색',
  35 + hilitecolor : '강조색',
  36 + bold : '굵게(Ctrl+B)',
  37 + italic : '이텔릭(Ctrl+I)',
  38 + underline : '빝줄(Ctrl+U)',
  39 + strikethrough : '취소선',
  40 + removeformat : '형식 제거',
  41 + image : '이미지 추가',
  42 + multiimage : '여러 이미지 추가',
  43 + flash : '플래시 추가',
  44 + media : '미디어 추가',
  45 + table : '표',
  46 + tablecell : '열',
  47 + hr : '구분선 추가',
  48 + emoticons : '이모티콘 추가',
  49 + link : '링크',
  50 + unlink : '링크 제거',
  51 + fullscreen : '전체 화면 모드',
  52 + about : '이 에디터는...',
  53 + print : '인쇄',
  54 + filemanager : '파일 관리자',
  55 + code : '코드 추가',
  56 + map : '구글 맵 추가',
  57 + baidumap : '바이두 맵 추가',
  58 + lineheight : '행 간격',
  59 + clearhtml : 'HTML 코드 정리',
  60 + pagebreak : '페이지 구분 추가',
  61 + quickformat : '빠른 형식',
  62 + insertfile : '파일 추가',
  63 + template : '템플릿 추가',
  64 + anchor : '책갈피',
  65 + yes : '확인',
  66 + no : '취소',
  67 + close : '닫기',
  68 + editImage : '이미지 속성',
  69 + deleteImage : '이미지 삭제',
  70 + editFlash : '플래시 속성',
  71 + deleteFlash : '플래시 삭제',
  72 + editMedia : '미디어 속성',
  73 + deleteMedia : '미디어 삭제',
  74 + editLink : '링크 속성',
  75 + deleteLink : '링크 삭제',
  76 + editAnchor : 'Anchor properties',
  77 + deleteAnchor : 'Delete Anchor',
  78 + tableprop : '표 속성',
  79 + tablecellprop : '열 속성',
  80 + tableinsert : '표 추가',
  81 + tabledelete : '표 삭제',
  82 + tablecolinsertleft : '왼쪽으로 열 추가',
  83 + tablecolinsertright : '오른쪽으로 열 추가',
  84 + tablerowinsertabove : '위쪽으로 열 추가',
  85 + tablerowinsertbelow : '아래쪽으로 열 추가',
  86 + tablerowmerge : '아래로 병합',
  87 + tablecolmerge : '오른쪽으로 병합',
  88 + tablerowsplit : '행 나누기',
  89 + tablecolsplit : '열 나누기',
  90 + tablecoldelete : '열 삭제',
  91 + tablerowdelete : '행 삭제',
  92 + noColor : '기본색',
  93 + pleaseSelectFile : '파일 선택',
  94 + invalidImg : "올바른 주소를 입력하세요.\njpg,gif,bmp,png 형식이 가능합니다.",
  95 + invalidMedia : "올바른 주소를 입력하세요.\nswf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb 형식이 가능합니다.",
  96 + invalidWidth : "넓이 값은 숫자여야 합니다.",
  97 + invalidHeight : "높이 값은 숫자여야 합니다.",
  98 + invalidBorder : "굵기 값은 숫자여야 합니다.",
  99 + invalidUrl : "올바른 주소를 입력하세요.",
  100 + invalidRows : '올바른 행이 아닙니다.',
  101 + invalidCols : '올바른 열이 아닙니다.',
  102 + invalidPadding : '안쪽 여백 값은 숫자여야 합니다.',
  103 + invalidSpacing : '간격 길이 값은 숫자여야 합니다.',
  104 + invalidJson : '올바른 JSON 형식이 아닙니다.',
  105 + uploadSuccess : '업로드가 완료되었습니다.',
  106 + cutError : '브라우저가 잘라내기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
  107 + copyError : '브라우저가 복사 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
  108 + pasteError : '브라우저가 붙여넣기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)',
  109 + ajaxLoading : '불러오는 중 ...',
  110 + uploadLoading : '업로드 중 ...',
  111 + uploadError : '업로드 오류',
  112 + 'plainpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 텍스트를 붙여넣으세요.',
  113 + 'wordpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 워드 텍스트를 붙여넣으세요.',
  114 + 'code.pleaseInput' : 'Please input code.',
  115 + 'link.url' : '주소',
  116 + 'link.linkType' : '창',
  117 + 'link.newWindow' : '새 창',
  118 + 'link.selfWindow' : '현재 창',
  119 + 'flash.url' : '주소',
  120 + 'flash.width' : '넓이',
  121 + 'flash.height' : '높이',
  122 + 'flash.upload' : '업로드',
  123 + 'flash.viewServer' : '찾아보기',
  124 + 'media.url' : '주소',
  125 + 'media.width' : '넓이',
  126 + 'media.height' : '높이',
  127 + 'media.autostart' : '자동 시작',
  128 + 'media.upload' : '업로드',
  129 + 'media.viewServer' : '찾아보기',
  130 + 'image.remoteImage' : '외부 이미지',
  131 + 'image.localImage' : '내부 이미지',
  132 + 'image.remoteUrl' : '주소',
  133 + 'image.localUrl' : '파일',
  134 + 'image.size' : '크기',
  135 + 'image.width' : '넓이',
  136 + 'image.height' : '높이',
  137 + 'image.resetSize' : '기본 크기로',
  138 + 'image.align' : '정렬',
  139 + 'image.defaultAlign' : '기본',
  140 + 'image.leftAlign' : '왼쪽',
  141 + 'image.rightAlign' : '오른쪽',
  142 + 'image.imgTitle' : '제목',
  143 + 'image.upload' : '찾아보기',
  144 + 'image.viewServer' : '찾아보기',
  145 + 'multiimage.uploadDesc' : '최대 이미지 개수: <%=uploadLimit%>개, 개당 이미지 크기: <%=sizeLimit%>',
  146 + 'multiimage.startUpload' : '업로드 시작',
  147 + 'multiimage.clearAll' : '모두 삭제',
  148 + 'multiimage.insertAll' : '모두 삽입',
  149 + 'multiimage.queueLimitExceeded' : '업로드 개수가 초과되었습니다.',
  150 + 'multiimage.fileExceedsSizeLimit' : '업로드 크기가 초과되었습니다.',
  151 + 'multiimage.zeroByteFile' : '파일 크기가 없습니다.',
  152 + 'multiimage.invalidFiletype' : '올바른 이미지가 아닙니다.',
  153 + 'multiimage.unknownError' : '알 수 없는 업로드 오류가 발생하였습니다.',
  154 + 'multiimage.pending' : '처리 중 ...',
  155 + 'multiimage.uploadError' : '업로드 오류',
  156 + 'filemanager.emptyFolder' : '빈 폴더',
  157 + 'filemanager.moveup' : '위로',
  158 + 'filemanager.viewType' : '보기 방식: ',
  159 + 'filemanager.viewImage' : '미리 보기',
  160 + 'filemanager.listImage' : '목록',
  161 + 'filemanager.orderType' : '정렬 방식: ',
  162 + 'filemanager.fileName' : '이름별',
  163 + 'filemanager.fileSize' : '크기별',
  164 + 'filemanager.fileType' : '종류별',
  165 + 'insertfile.url' : '주소',
  166 + 'insertfile.title' : '제목',
  167 + 'insertfile.upload' : '업로드',
  168 + 'insertfile.viewServer' : '찾아보기',
  169 + 'table.cells' : '열',
  170 + 'table.rows' : '행',
  171 + 'table.cols' : '열',
  172 + 'table.size' : '표 크기',
  173 + 'table.width' : '넓이',
  174 + 'table.height' : '높이',
  175 + 'table.percent' : '%',
  176 + 'table.px' : 'px',
  177 + 'table.space' : '간격',
  178 + 'table.padding' : '안쪽여백',
  179 + 'table.spacing' : '간격',
  180 + 'table.align' : '정렬',
  181 + 'table.textAlign' : '수직',
  182 + 'table.verticalAlign' : '수평',
  183 + 'table.alignDefault' : '기본',
  184 + 'table.alignLeft' : '왼쪽',
  185 + 'table.alignCenter' : '가운데',
  186 + 'table.alignRight' : '오른쪽',
  187 + 'table.alignTop' : '위쪽',
  188 + 'table.alignMiddle' : '중간',
  189 + 'table.alignBottom' : '아래쪽',
  190 + 'table.alignBaseline' : '글자기준',
  191 + 'table.border' : '테두리',
  192 + 'table.borderWidth' : '크기',
  193 + 'table.borderColor' : '색상',
  194 + 'table.backgroundColor' : '배경',
  195 + 'map.address' : '주소: ',
  196 + 'map.search' : '검색',
  197 + 'baidumap.address' : '주소: ',
  198 + 'baidumap.search' : '검색',
  199 + 'baidumap.insertDynamicMap' : '동적 지도',
  200 + 'anchor.name' : '책갈피명',
  201 + 'formatblock.formatBlock' : {
  202 + h1 : '제목 1',
  203 + h2 : '제목 2',
  204 + h3 : '제목 3',
  205 + h4 : '제목 4',
  206 + p : '본문'
  207 + },
  208 + 'fontname.fontName' : {
  209 + 'Gulim' : '굴림',
  210 + 'Dotum' : '돋움',
  211 + 'Batang' : '바탕',
  212 + 'Gungsuh' : '궁서',
  213 + 'Malgun Gothic' : '맑은 고딕',
  214 + 'Arial' : 'Arial',
  215 + 'Arial Black' : 'Arial Black',
  216 + 'Comic Sans MS' : 'Comic Sans MS',
  217 + 'Courier New' : 'Courier New',
  218 + 'Garamond' : 'Garamond',
  219 + 'Georgia' : 'Georgia',
  220 + 'Tahoma' : 'Tahoma',
  221 + 'Times New Roman' : 'Times New Roman',
  222 + 'Trebuchet MS' : 'Trebuchet MS',
  223 + 'Verdana' : 'Verdana'
  224 + },
  225 + 'lineheight.lineHeight' : [
  226 + {'1' : '행간 1'},
  227 + {'1.5' : '행간 1.5'},
  228 + {'2' : '행간 2'},
  229 + {'2.5' : '행간 2.5'},
  230 + {'3' : '행간 3'}
  231 + ],
  232 + 'template.selectTemplate' : '템플릿',
  233 + 'template.replaceContent' : '내용 바꾸기',
  234 + 'template.fileList' : {
  235 + '1.html' : '이미지와 텍스트',
  236 + '2.html' : '표',
  237 + '3.html' : '목록'
  238 + }
  239 +}, 'ko');
  240 +
  241 +KindEditor.each(KindEditor.options.items, function(i, name) {
  242 + if (name == 'baidumap') {
  243 + KindEditor.options.items[i] = 'map';
  244 + }
  245 +});
  246 +KindEditor.options.langType = 'ko';
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +* Translated to Russian by Valery Votintsev (http://codersclub.org/)
  9 +*******************************************************************************/
  10 +
  11 +KindEditor.lang({
  12 + source : 'Source',
  13 + preview : 'Preview',
  14 + undo : 'Отмена(Ctrl+Z)',
  15 + redo : 'Повтор(Ctrl+Y)',
  16 + cut : 'Вырезать(Ctrl+X)',
  17 + copy : 'Копировать(Ctrl+C)',
  18 + paste : 'Вставить(Ctrl+V)',
  19 + plainpaste : 'Вставить как простой текст',
  20 + wordpaste : 'Вставить из Word',
  21 + selectall : 'Выбрать все',
  22 + justifyleft : 'Выравнивание влево',
  23 + justifycenter : 'Выравнивание по центру',
  24 + justifyright : 'Выравнивание вправо',
  25 + justifyfull : 'Выравнивание по обеим сторонам',
  26 + insertorderedlist : 'Нумерованый список',
  27 + insertunorderedlist : 'Ненумерованый список',
  28 + indent : 'Добавить отступ',
  29 + outdent : 'Убрать отступ',
  30 + subscript : 'Надстрочный',
  31 + superscript : 'Подстрочный',
  32 + formatblock : 'Формат параграфа',
  33 + fontname : 'Шрифт',
  34 + fontsize : 'Размер',
  35 + forecolor : 'Цвет текста',
  36 + hilitecolor : 'Цвет фона',
  37 + bold : 'Жирный(Ctrl+B)',
  38 + italic : 'Наклонный(Ctrl+I)',
  39 + underline : 'Подчёркнутый(Ctrl+U)',
  40 + strikethrough : 'Перечёркнутый',
  41 + removeformat : 'Удалить формат',
  42 + image : 'Изображение',
  43 + multiimage : 'Мульти-загрузка',
  44 + flash : 'Flash',
  45 + media : 'Встроенные данные',
  46 + table : 'Таблица',
  47 + tablecell : 'Ячейка',
  48 + hr : 'Горизонтальный разделитель',
  49 + emoticons : 'Смайл',
  50 + link : 'Ссылка',
  51 + unlink : 'Убрать ссылку',
  52 + fullscreen : 'На весь экран',
  53 + about : 'О программе',
  54 + print : 'Печать',
  55 + filemanager : 'Файлы',
  56 + code : 'Код',
  57 + map : 'Карта Google',
  58 + baidumap : 'Карта Baidu',
  59 + lineheight : 'Межстрочный интервал',
  60 + clearhtml : 'Очистить HTML код',
  61 + pagebreak : 'Разрыв страницы',
  62 + quickformat : 'Быстрый формат',
  63 + insertfile : 'Вставить файл',
  64 + template : 'Вставить шаблон',
  65 + anchor : 'Якорь',
  66 + yes : 'OK',
  67 + no : 'Отмена',
  68 + close : 'Закрыть',
  69 + editImage : 'Свойства изображения',
  70 + deleteImage : 'Удалить изображение',
  71 + editFlash : 'Свойства Flash',
  72 + deleteFlash : 'Удалить Flash',
  73 + editMedia : 'Свойства Media',
  74 + deleteMedia : 'Удалить Media',
  75 + editLink : 'Свойства ссылки',
  76 + deleteLink : 'Удалить ссылку',
  77 + editAnchor : 'Anchor properties',
  78 + deleteAnchor : 'Delete Anchor',
  79 + tableprop : 'Свойства таблицы',
  80 + tablecellprop : 'Свойства ячейки',
  81 + tableinsert : 'Вставить таблицу',
  82 + tabledelete : 'Удалить таблицу',
  83 + tablecolinsertleft : 'Добавить столбец слева',
  84 + tablecolinsertright : 'Добавить столбец справа',
  85 + tablerowinsertabove : 'Добавить строку выше',
  86 + tablerowinsertbelow : 'Добавить строку ниже',
  87 + tablerowmerge : 'Объединить вниз',
  88 + tablecolmerge : 'Объединить вправо',
  89 + tablerowsplit : 'Разделить строку',
  90 + tablecolsplit : 'Разделить столбец',
  91 + tablecoldelete : 'Удалить столбец',
  92 + tablerowdelete : 'Удалить строку',
  93 + noColor : 'По умолчанию',
  94 + pleaseSelectFile : 'Выберите файл.',
  95 + invalidImg : "Укажите корректный URL изображения.\nРазрешённые форматы: jpg,gif,bmp,png",
  96 + invalidMedia : "Укажите корректный тип медиа-объекта.\nРазрешённые типы: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb",
  97 + invalidWidth : "Ширина должна быть числом.",
  98 + invalidHeight : "Высота должна быть числом.",
  99 + invalidBorder : "Ширина рамки должна быть числом.",
  100 + invalidUrl : "Укажите корректный URL.",
  101 + invalidRows : 'Неверные строки.',
  102 + invalidCols : 'Неверные столбцы.',
  103 + invalidPadding : 'padding должен быть числом.',
  104 + invalidSpacing : 'spacing должен быть числом.',
  105 + invalidJson : 'Неверная JSON строка.',
  106 + uploadSuccess : 'Загрузка завершена.',
  107 + cutError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+X).',
  108 + copyError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+C).',
  109 + pasteError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+V).',
  110 + ajaxLoading : 'Загрузка ...',
  111 + uploadLoading : 'Загрузка ...',
  112 + uploadError : 'Сбой загрузки',
  113 + 'plainpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).',
  114 + 'wordpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).',
  115 + 'code.pleaseInput' : 'Введите код.',
  116 + 'link.url' : 'URL',
  117 + 'link.linkType' : 'Открывать ссылку',
  118 + 'link.newWindow' : 'в новом окне',
  119 + 'link.selfWindow' : 'в том же окне',
  120 + 'flash.url' : 'URL',
  121 + 'flash.width' : 'Ширина',
  122 + 'flash.height' : 'Высота',
  123 + 'flash.upload' : 'Загрузить',
  124 + 'flash.viewServer' : 'Выбрать',
  125 + 'media.url' : 'URL',
  126 + 'media.width' : 'Ширина',
  127 + 'media.height' : 'Высота',
  128 + 'media.autostart' : 'Автостарт',
  129 + 'media.upload' : 'Загрузить',
  130 + 'media.viewServer' : 'Выбрать',
  131 + 'image.remoteImage' : 'Вставить URL изображения',
  132 + 'image.localImage' : 'Загрузить',
  133 + 'image.remoteUrl' : 'URL',
  134 + 'image.localUrl' : 'Файл',
  135 + 'image.size' : 'Размер',
  136 + 'image.width' : 'Ширина',
  137 + 'image.height' : 'Высота',
  138 + 'image.resetSize' : 'Сбросить размеры',
  139 + 'image.align' : 'Выравнивание',
  140 + 'image.defaultAlign' : 'По умолчанию',
  141 + 'image.leftAlign' : 'Влево',
  142 + 'image.rightAlign' : 'Вправо',
  143 + 'image.imgTitle' : 'Название',
  144 + 'image.upload' : 'Загрузить',
  145 + 'image.viewServer' : 'Выбрать',
  146 + 'multiimage.uploadDesc' : 'Максимальное кол-во изображений: <%=uploadLimit%>, Максимальный размер одного изображения: <%=sizeLimit%>',
  147 + 'multiimage.startUpload' : 'Начать загрузку',
  148 + 'multiimage.clearAll' : 'Очистить все',
  149 + 'multiimage.insertAll' : 'Вставить все',
  150 + 'multiimage.queueLimitExceeded' : 'Превышен лимит очереди.',
  151 + 'multiimage.fileExceedsSizeLimit' : 'Превышен максимальный размер файла.',
  152 + 'multiimage.zeroByteFile' : 'Файл нулевой длины.',
  153 + 'multiimage.invalidFiletype' : 'Недопустимый тип файла.',
  154 + 'multiimage.unknownError' : 'Непредвиденная ошибка загрузки.',
  155 + 'multiimage.pending' : 'Ожидает ...',
  156 + 'multiimage.uploadError' : 'Ошибка загрузки',
  157 + 'filemanager.emptyFolder' : 'Папка пуста',
  158 + 'filemanager.moveup' : 'Наверх',
  159 + 'filemanager.viewType' : 'Тип показа: ',
  160 + 'filemanager.viewImage' : 'Превьюшки',
  161 + 'filemanager.listImage' : 'Список',
  162 + 'filemanager.orderType' : 'Сортировка: ',
  163 + 'filemanager.fileName' : 'По имени',
  164 + 'filemanager.fileSize' : 'По размеру',
  165 + 'filemanager.fileType' : 'По типу',
  166 + 'insertfile.url' : 'URL',
  167 + 'insertfile.title' : 'Название',
  168 + 'insertfile.upload' : 'Загрузить',
  169 + 'insertfile.viewServer' : 'Выбрать',
  170 + 'table.cells' : 'Ячейки',
  171 + 'table.rows' : 'Строки',
  172 + 'table.cols' : 'Столбцы',
  173 + 'table.size' : 'Размеры',
  174 + 'table.width' : 'Ширина',
  175 + 'table.height' : 'Высота',
  176 + 'table.percent' : '%',
  177 + 'table.px' : 'px',
  178 + 'table.space' : 'Space',
  179 + 'table.padding' : 'Padding',
  180 + 'table.spacing' : 'Spacing',
  181 + 'table.align' : 'Выравнивание',
  182 + 'table.textAlign' : 'По горизонтали',
  183 + 'table.verticalAlign' : 'По вертикали',
  184 + 'table.alignDefault' : 'По умолчанию',
  185 + 'table.alignLeft' : 'Влево',
  186 + 'table.alignCenter' : 'По центру',
  187 + 'table.alignRight' : 'Вправо',
  188 + 'table.alignTop' : 'Вверх',
  189 + 'table.alignMiddle' : 'Посередине',
  190 + 'table.alignBottom' : 'Вниз',
  191 + 'table.alignBaseline' : 'По базовой линии',
  192 + 'table.border' : 'Рамка',
  193 + 'table.borderWidth' : 'Ширина',
  194 + 'table.borderColor' : 'Цвет',
  195 + 'table.backgroundColor' : 'Цвет фона',
  196 + 'map.address' : 'Адрес: ',
  197 + 'map.search' : 'Поиск',
  198 + 'baidumap.address' : 'Адрес: ',
  199 + 'baidumap.search' : 'Поиск',
  200 + 'baidumap.insertDynamicMap' : 'Динамическая карта',
  201 + 'anchor.name' : 'Имя якоря',
  202 + 'formatblock.formatBlock' : {
  203 + h1 : 'Заголовок 1',
  204 + h2 : 'Заголовок 2',
  205 + h3 : 'Заголовок 3',
  206 + h4 : 'Заголовок 4',
  207 + p : 'Обычный текст'
  208 + },
  209 + 'fontname.fontName' : {
  210 + 'Arial' : 'Arial',
  211 + 'Arial Black' : 'Arial Black',
  212 + 'Comic Sans MS' : 'Comic Sans MS',
  213 + 'Courier New' : 'Courier New',
  214 + 'Garamond' : 'Garamond',
  215 + 'Georgia' : 'Georgia',
  216 + 'Tahoma' : 'Tahoma',
  217 + 'Times New Roman' : 'Times New Roman',
  218 + 'Trebuchet MS' : 'Trebuchet MS',
  219 + 'Verdana' : 'Verdana'
  220 + },
  221 + 'lineheight.lineHeight' : [
  222 + {'1' : '1'},
  223 + {'1.5' : '1.5'},
  224 + {'2' : '2'},
  225 + {'2.5' : '2.5'},
  226 + {'3' : '3'}
  227 + ],
  228 + 'template.selectTemplate' : 'Шаблон',
  229 + 'template.replaceContent' : 'Заменить текущий шаблон',
  230 + 'template.fileList' : {
  231 + '1.html' : 'Текст и изображения',
  232 + '2.html' : 'Таблица',
  233 + '3.html' : 'Список'
  234 + }
  235 +}, 'en');
  236 +
  237 +KindEditor.each(KindEditor.options.items, function(i, name) {
  238 + if (name == 'baidumap') {
  239 + KindEditor.options.items[i] = 'map';
  240 + }
  241 +});
  242 +KindEditor.options.langType = 'ru';
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +KindEditor.lang({
  11 + source : 'HTML代码',
  12 + preview : '预览',
  13 + undo : '后退(Ctrl+Z)',
  14 + redo : '前进(Ctrl+Y)',
  15 + cut : '剪切(Ctrl+X)',
  16 + copy : '复制(Ctrl+C)',
  17 + paste : '粘贴(Ctrl+V)',
  18 + plainpaste : '粘贴为无格式文本',
  19 + wordpaste : '从Word粘贴',
  20 + selectall : '全选(Ctrl+A)',
  21 + justifyleft : '左对齐',
  22 + justifycenter : '居中',
  23 + justifyright : '右对齐',
  24 + justifyfull : '两端对齐',
  25 + insertorderedlist : '编号',
  26 + insertunorderedlist : '项目符号',
  27 + indent : '增加缩进',
  28 + outdent : '减少缩进',
  29 + subscript : '下标',
  30 + superscript : '上标',
  31 + formatblock : '段落',
  32 + fontname : '字体',
  33 + fontsize : '文字大小',
  34 + forecolor : '文字颜色',
  35 + hilitecolor : '文字背景',
  36 + bold : '粗体(Ctrl+B)',
  37 + italic : '斜体(Ctrl+I)',
  38 + underline : '下划线(Ctrl+U)',
  39 + strikethrough : '删除线',
  40 + removeformat : '删除格式',
  41 + image : '图片',
  42 + multiimage : '批量图片上传',
  43 + graft : '涂鸦',
  44 + flash : 'Flash',
  45 + media : '视音频',
  46 + table : '表格',
  47 + tablecell : '单元格',
  48 + hr : '插入横线',
  49 + emoticons : '插入表情',
  50 + link : '超级链接',
  51 + unlink : '取消超级链接',
  52 + fullscreen : '全屏显示',
  53 + about : '关于',
  54 + print : '打印(Ctrl+P)',
  55 + filemanager : '文件空间',
  56 + code : '插入程序代码',
  57 + quote : '插入引用',
  58 + map : 'Google地图',
  59 + baidumap : '百度地图',
  60 + lineheight : '行距',
  61 + clearhtml : '清理HTML代码',
  62 + pagebreak : '插入分页符',
  63 + quickformat : '一键排版',
  64 + insertfile : '插入文件',
  65 + template : '插入模板',
  66 + anchor : '锚点',
  67 + yes : '确定',
  68 + no : '取消',
  69 + close : '关闭',
  70 + editImage : '图片属性',
  71 + deleteImage : '删除图片',
  72 + editFlash : 'Flash属性',
  73 + deleteFlash : '删除Flash',
  74 + editMedia : '视音频属性',
  75 + deleteMedia : '删除视音频',
  76 + editLink : '超级链接属性',
  77 + deleteLink : '取消超级链接',
  78 + editAnchor : '锚点属性',
  79 + deleteAnchor : '删除锚点',
  80 + tableprop : '表格属性',
  81 + tablecellprop : '单元格属性',
  82 + tableinsert : '插入表格',
  83 + tabledelete : '删除表格',
  84 + tablecolinsertleft : '左侧插入列',
  85 + tablecolinsertright : '右侧插入列',
  86 + tablerowinsertabove : '上方插入行',
  87 + tablerowinsertbelow : '下方插入行',
  88 + tablerowmerge : '向下合并单元格',
  89 + tablecolmerge : '向右合并单元格',
  90 + tablerowsplit : '拆分行',
  91 + tablecolsplit : '拆分列',
  92 + tablecoldelete : '删除列',
  93 + tablerowdelete : '删除行',
  94 + noColor : '无颜色',
  95 + pleaseSelectFile : '请选择文件。',
  96 + invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。",
  97 + invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",
  98 + invalidWidth : "宽度必须为数字。",
  99 + invalidHeight : "高度必须为数字。",
  100 + invalidBorder : "边框必须为数字。",
  101 + invalidUrl : "请输入有效的URL地址。",
  102 + invalidRows : '行数为必选项,只允许输入大于0的数字。',
  103 + invalidCols : '列数为必选项,只允许输入大于0的数字。',
  104 + invalidPadding : '边距必须为数字。',
  105 + invalidSpacing : '间距必须为数字。',
  106 + invalidJson : '服务器发生故障。',
  107 + uploadSuccess : '上传成功。',
  108 + cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。',
  109 + copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。',
  110 + pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。',
  111 + ajaxLoading : '加载中,请稍候 ...',
  112 + uploadLoading : '上传中,请稍候 ...',
  113 + uploadError : '上传错误',
  114 +
  115 + 'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
  116 + 'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。',
  117 + 'code.pleaseInput' : '请输入程序代码。',
  118 + 'link.url' : 'URL',
  119 + 'link.linkType' : '打开类型',
  120 + 'link.newWindow' : '新窗口',
  121 + 'link.selfWindow' : '当前窗口',
  122 + 'flash.url' : 'URL',
  123 + 'flash.width' : '宽度',
  124 + 'flash.height' : '高度',
  125 + 'flash.upload' : '上传',
  126 + 'flash.viewServer' : '文件空间',
  127 + 'media.url' : 'URL',
  128 + 'media.width' : '宽度',
  129 + 'media.height' : '高度',
  130 + 'media.autostart' : '自动播放',
  131 + 'media.upload' : '上传',
  132 + 'media.viewServer' : '文件空间',
  133 + 'image.remoteImage' : '网络图片',
  134 + 'image.localImage' : '本地上传',
  135 + 'image.remoteUrl' : '图片地址',
  136 + 'image.localUrl' : '上传文件',
  137 + 'image.size' : '图片大小',
  138 + 'image.width' : '宽',
  139 + 'image.height' : '高',
  140 + 'image.resetSize' : '重置大小',
  141 + 'image.align' : '对齐方式',
  142 + 'image.defaultAlign' : '默认方式',
  143 + 'image.leftAlign' : '左对齐',
  144 + 'image.rightAlign' : '右对齐',
  145 + 'image.imgTitle' : '图片说明',
  146 + 'image.upload' : '浏览...',
  147 + 'image.viewServer' : '图片空间',
  148 +
  149 + 'multiimage.title' : '多图上传',
  150 + 'multiimage.uploadDesc' : '共选择了 <%=numSelect%> 张图片,共 <%=totalSize%>, 还可以添加 <%=numLeft%> 张图片.',
  151 + 'multiimage.startUpload' : '开始上传',
  152 + 'multiimage.noListUrl' : '无法获取图片,请先配置 fileManagerJson.',
  153 + 'multiimage.noSearchUrl' : '无法进行图片搜索,请先配置 imageSearchJson.',
  154 + 'multiimage.noDataText' : '(⊙o⊙)亲,没有多数据了。',
  155 + 'multiimage.closeText' : '关闭对话框',
  156 + 'multiimage.confirmBtnText' : '确定',
  157 + 'multiimage.cancelBtnText' : '取消',
  158 + 'multiimage.loadMoreData' : '往下拉动滚动条可以加载更多数据.',
  159 + 'multiimage.depJQueryError' : '文件管理插件依赖 jQuery, 请先引入 jQuery.',
  160 + 'multiimage.localUpload' : '本地上传',
  161 + 'multiimage.fileServer' : '文件服务器',
  162 + 'multiimage.imgSearch' : '图片搜索',
  163 + 'multiimage.selectFile' : '点击选择图片',
  164 + 'multiimage.continueAdd' : '继续添加',
  165 + 'multiimage.searchBtn' : '搜索一下',
  166 + 'multiimage.searchPlaceholder' : '请输入搜索关键词',
  167 + 'multiimage.searchClear' : '清空搜索',
  168 + 'multiimage.noFileAdded' : '请至少添加一个文件!',
  169 + 'multiimage.uploading' : '正在上传',
  170 + 'multiimage.fileNotUpload' : '您还有文件没有上传!',
  171 + 'multiimage.uploadLimit' : '您本次最多上传 <%=uploadLimit%> 个文件.',
  172 + 'multiimage.sizeLimit' : '文件大小不能超过 <%=sizeLimit%> KB.',
  173 + 'multiimage.invalidExt' : '非法的文件后缀 <%=invalidExt%>.',
  174 + 'multiimage.remove' : '删除',
  175 + 'multiimage.rotateRight' : '向右旋转',
  176 + 'multiimage.rotateLeft' : '向左旋转',
  177 + 'multiimage.uploadFail' : '发生异常,上传失败!',
  178 + 'multiimage.noFileSelected' : '请至少选择一个文件或一张图片.',
  179 +
  180 + 'filemanager.noDataText' : '(⊙o⊙)亲,没有多数据了。',
  181 + 'filemanager.title' : '文件服务器',
  182 + 'filemanager.noListUrl' : '无法获取图片,请先配置 fileManagerJson.',
  183 + 'filemanager.closeText' : '关闭对话框',
  184 + 'filemanager.confirmBtnText' : '确定',
  185 + 'filemanager.cancelBtnText' : '取消',
  186 + 'filemanager.loadMoreData' : '往下拉动滚动条可以加载更多数据.',
  187 + 'filemanager.depJQueryError' : '文件管理插件依赖 jQuery, 请先引入 jQuery.',
  188 + 'filemanager.fileType' : '类型',
  189 +
  190 + 'graft.btnText' : '保存并插入涂鸦',
  191 + 'graft.uploadSuccess' : '涂鸦上传成功',
  192 + 'graft.uploadFaild' : '涂鸦上传失败',
  193 + 'graft.empty' : '您没有在画布上绘制任何图像',
  194 +
  195 + 'insertfile.url' : 'URL',
  196 + 'insertfile.title' : '文件说明',
  197 + 'insertfile.upload' : '上传',
  198 + 'insertfile.viewServer' : '文件空间',
  199 + 'table.cells' : '单元格数',
  200 + 'table.rows' : '行数',
  201 + 'table.cols' : '列数',
  202 + 'table.size' : '大小',
  203 + 'table.width' : '宽度',
  204 + 'table.height' : '高度',
  205 + 'table.percent' : '%',
  206 + 'table.px' : 'px',
  207 + 'table.space' : '边距间距',
  208 + 'table.padding' : '边距',
  209 + 'table.spacing' : '间距',
  210 + 'table.align' : '对齐方式',
  211 + 'table.textAlign' : '水平对齐',
  212 + 'table.verticalAlign' : '垂直对齐',
  213 + 'table.alignDefault' : '默认',
  214 + 'table.alignLeft' : '左对齐',
  215 + 'table.alignCenter' : '居中',
  216 + 'table.alignRight' : '右对齐',
  217 + 'table.alignTop' : '顶部',
  218 + 'table.alignMiddle' : '中部',
  219 + 'table.alignBottom' : '底部',
  220 + 'table.alignBaseline' : '基线',
  221 + 'table.border' : '边框',
  222 + 'table.borderWidth' : '宽度',
  223 + 'table.borderColor' : '颜色',
  224 + 'table.backgroundColor' : '背景颜色',
  225 + 'map.address' : '地址: ',
  226 + 'map.search' : '搜索',
  227 + 'baidumap.address' : '地址: ',
  228 + 'baidumap.search' : '搜索',
  229 + 'baidumap.insertDynamicMap' : '插入动态地图',
  230 + 'anchor.name' : '锚点名称',
  231 + 'formatblock.formatBlock' : {
  232 + h1 : '标题 1',
  233 + h2 : '标题 2',
  234 + h3 : '标题 3',
  235 + h4 : '标题 4',
  236 + p : '正 文'
  237 + },
  238 + 'fontname.fontName' : {
  239 + 'SimSun' : '宋体',
  240 + 'NSimSun' : '新宋体',
  241 + 'FangSong' : '仿宋',
  242 + 'KaiTi' : '楷体',
  243 + 'SimHei' : '黑体',
  244 + 'Microsoft YaHei' : '微软雅黑',
  245 + 'Arial' : 'Arial',
  246 + 'Arial Black' : 'Arial Black',
  247 + 'Times New Roman' : 'Times New Roman',
  248 + 'Courier New' : 'Courier New',
  249 + 'Tahoma' : 'Tahoma',
  250 + 'Verdana' : 'Verdana'
  251 + },
  252 + 'lineheight.lineHeight' : [
  253 + {'1' : '单倍行距'},
  254 + {'1.5' : '1.5倍行距'},
  255 + {'2' : '2倍行距'},
  256 + {'2.5' : '2.5倍行距'},
  257 + {'3' : '3倍行距'}
  258 + ],
  259 + 'template.selectTemplate' : '可选模板',
  260 + 'template.replaceContent' : '替换当前内容',
  261 + 'template.fileList' : {
  262 + '1.html' : '图片和文字',
  263 + '2.html' : '表格',
  264 + '3.html' : '项目编号'
  265 + }
  266 +}, 'zh-CN');
  267 +KindEditor.options.langType = 'zh-CN';
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +KindEditor.lang({
  11 + source : '原始碼',
  12 + preview : '預覽',
  13 + undo : '復原(Ctrl+Z)',
  14 + redo : '重複(Ctrl+Y)',
  15 + cut : '剪下(Ctrl+X)',
  16 + copy : '複製(Ctrl+C)',
  17 + paste : '貼上(Ctrl+V)',
  18 + plainpaste : '貼為純文字格式',
  19 + wordpaste : '自Word貼上',
  20 + selectall : '全選(Ctrl+A)',
  21 + justifyleft : '靠左對齊',
  22 + justifycenter : '置中',
  23 + justifyright : '靠右對齊',
  24 + justifyfull : '左右對齊',
  25 + insertorderedlist : '編號清單',
  26 + insertunorderedlist : '項目清單',
  27 + indent : '增加縮排',
  28 + outdent : '減少縮排',
  29 + subscript : '下標',
  30 + superscript : '上標',
  31 + formatblock : '標題',
  32 + fontname : '字體',
  33 + fontsize : '文字大小',
  34 + forecolor : '文字顏色',
  35 + hilitecolor : '背景顏色',
  36 + bold : '粗體(Ctrl+B)',
  37 + italic : '斜體(Ctrl+I)',
  38 + underline : '底線(Ctrl+U)',
  39 + strikethrough : '刪除線',
  40 + removeformat : '清除格式',
  41 + image : '影像',
  42 + multiimage : '批量影像上傳',
  43 + flash : 'Flash',
  44 + media : '多媒體',
  45 + table : '表格',
  46 + tablecell : '儲存格',
  47 + hr : '插入水平線',
  48 + emoticons : '插入表情',
  49 + link : '超連結',
  50 + unlink : '移除超連結',
  51 + fullscreen : '最大化',
  52 + about : '關於',
  53 + print : '列印(Ctrl+P)',
  54 + filemanager : '瀏覽伺服器',
  55 + code : '插入程式代碼',
  56 + map : 'Google地圖',
  57 + baidumap : 'Baidu地圖',
  58 + lineheight : '行距',
  59 + clearhtml : '清理HTML代碼',
  60 + pagebreak : '插入分頁符號',
  61 + quickformat : '快速排版',
  62 + insertfile : '插入文件',
  63 + template : '插入樣板',
  64 + anchor : '錨點',
  65 + yes : '確定',
  66 + no : '取消',
  67 + close : '關閉',
  68 + editImage : '影像屬性',
  69 + deleteImage : '刪除影像',
  70 + editFlash : 'Flash屬性',
  71 + deleteFlash : '删除Flash',
  72 + editMedia : '多媒體屬性',
  73 + deleteMedia : '删除多媒體',
  74 + editLink : '超連結屬性',
  75 + deleteLink : '移除超連結',
  76 + editAnchor : '锚点属性',
  77 + deleteAnchor : '删除锚点',
  78 + tableprop : '表格屬性',
  79 + tablecellprop : '儲存格屬性',
  80 + tableinsert : '插入表格',
  81 + tabledelete : '刪除表格',
  82 + tablecolinsertleft : '向左插入列',
  83 + tablecolinsertright : '向右插入列',
  84 + tablerowinsertabove : '向上插入欄',
  85 + tablerowinsertbelow : '下方插入欄',
  86 + tablerowmerge : '向下合併單元格',
  87 + tablecolmerge : '向右合併單元格',
  88 + tablerowsplit : '分割欄',
  89 + tablecolsplit : '分割列',
  90 + tablecoldelete : '删除列',
  91 + tablerowdelete : '删除欄',
  92 + noColor : '自動',
  93 + pleaseSelectFile : '請選擇文件。',
  94 + invalidImg : "請輸入有效的URL。\n只允許jpg,gif,bmp,png格式。",
  95 + invalidMedia : "請輸入有效的URL。\n只允許swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",
  96 + invalidWidth : "寬度必須是數字。",
  97 + invalidHeight : "高度必須是數字。",
  98 + invalidBorder : "邊框必須是數字。",
  99 + invalidUrl : "請輸入有效的URL。",
  100 + invalidRows : '欄數是必須輸入項目,只允許輸入大於0的數字。',
  101 + invalidCols : '列數是必須輸入項目,只允許輸入大於0的數字。',
  102 + invalidPadding : '內距必須是數字。',
  103 + invalidSpacing : '間距必須是數字。',
  104 + invalidJson : '伺服器發生故障。',
  105 + uploadSuccess : '上傳成功。',
  106 + cutError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+X)完成。',
  107 + copyError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+C)完成。',
  108 + pasteError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+V)完成。',
  109 + ajaxLoading : '加載中,請稍候 ...',
  110 + uploadLoading : '上傳中,請稍候 ...',
  111 + uploadError : '上傳錯誤',
  112 + 'plainpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。',
  113 + 'wordpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。',
  114 + 'code.pleaseInput' : 'Please input code.',
  115 + 'link.url' : 'URL',
  116 + 'link.linkType' : '打開類型',
  117 + 'link.newWindow' : '新窗口',
  118 + 'link.selfWindow' : '本頁窗口',
  119 + 'flash.url' : 'URL',
  120 + 'flash.width' : '寬度',
  121 + 'flash.height' : '高度',
  122 + 'flash.upload' : '上傳',
  123 + 'flash.viewServer' : '瀏覽',
  124 + 'media.url' : 'URL',
  125 + 'media.width' : '寬度',
  126 + 'media.height' : '高度',
  127 + 'media.autostart' : '自動播放',
  128 + 'media.upload' : '上傳',
  129 + 'media.viewServer' : '瀏覽',
  130 + 'image.remoteImage' : '網絡影像',
  131 + 'image.localImage' : '上傳影像',
  132 + 'image.remoteUrl' : '影像URL',
  133 + 'image.localUrl' : '影像URL',
  134 + 'image.size' : '影像大小',
  135 + 'image.width' : '寬度',
  136 + 'image.height' : '高度',
  137 + 'image.resetSize' : '原始大小',
  138 + 'image.align' : '對齊方式',
  139 + 'image.defaultAlign' : '未設定',
  140 + 'image.leftAlign' : '向左對齊',
  141 + 'image.rightAlign' : '向右對齊',
  142 + 'image.imgTitle' : '影像說明',
  143 + 'image.upload' : '瀏覽...',
  144 + 'image.viewServer' : '瀏覽...',
  145 + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>',
  146 + 'multiimage.startUpload' : 'Start upload',
  147 + 'multiimage.clearAll' : 'Clear all',
  148 + 'multiimage.insertAll' : 'Insert all',
  149 + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.',
  150 + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.',
  151 + 'multiimage.zeroByteFile' : 'Zero byte file.',
  152 + 'multiimage.invalidFiletype' : 'Invalid file type.',
  153 + 'multiimage.unknownError' : 'Unknown upload error.',
  154 + 'multiimage.pending' : 'Pending ...',
  155 + 'multiimage.uploadError' : 'Upload error',
  156 + 'filemanager.emptyFolder' : '空文件夾',
  157 + 'filemanager.moveup' : '至上一級文件夾',
  158 + 'filemanager.viewType' : '顯示方式:',
  159 + 'filemanager.viewImage' : '縮略圖',
  160 + 'filemanager.listImage' : '詳細信息',
  161 + 'filemanager.orderType' : '排序方式:',
  162 + 'filemanager.fileName' : '名稱',
  163 + 'filemanager.fileSize' : '大小',
  164 + 'filemanager.fileType' : '類型',
  165 + 'insertfile.url' : 'URL',
  166 + 'insertfile.title' : '文件說明',
  167 + 'insertfile.upload' : '上傳',
  168 + 'insertfile.viewServer' : '瀏覽',
  169 + 'table.cells' : '儲存格數',
  170 + 'table.rows' : '欄數',
  171 + 'table.cols' : '列數',
  172 + 'table.size' : '表格大小',
  173 + 'table.width' : '寬度',
  174 + 'table.height' : '高度',
  175 + 'table.percent' : '%',
  176 + 'table.px' : 'px',
  177 + 'table.space' : '內距間距',
  178 + 'table.padding' : '內距',
  179 + 'table.spacing' : '間距',
  180 + 'table.align' : '對齊方式',
  181 + 'table.textAlign' : '水平對齊',
  182 + 'table.verticalAlign' : '垂直對齊',
  183 + 'table.alignDefault' : '未設定',
  184 + 'table.alignLeft' : '向左對齊',
  185 + 'table.alignCenter' : '置中',
  186 + 'table.alignRight' : '向右對齊',
  187 + 'table.alignTop' : '靠上',
  188 + 'table.alignMiddle' : '置中',
  189 + 'table.alignBottom' : '靠下',
  190 + 'table.alignBaseline' : '基線',
  191 + 'table.border' : '表格邊框',
  192 + 'table.borderWidth' : '邊框',
  193 + 'table.borderColor' : '顏色',
  194 + 'table.backgroundColor' : '背景顏色',
  195 + 'map.address' : '住所: ',
  196 + 'map.search' : '尋找',
  197 + 'baidumap.address' : '住所: ',
  198 + 'baidumap.search' : '尋找',
  199 + 'baidumap.insertDynamicMap' : '插入動態地圖',
  200 + 'anchor.name' : '錨點名稱',
  201 + 'formatblock.formatBlock' : {
  202 + h1 : '標題 1',
  203 + h2 : '標題 2',
  204 + h3 : '標題 3',
  205 + h4 : '標題 4',
  206 + p : '一般'
  207 + },
  208 + 'fontname.fontName' : {
  209 + 'MingLiU' : '細明體',
  210 + 'PMingLiU' : '新細明體',
  211 + 'DFKai-SB' : '標楷體',
  212 + 'SimSun' : '宋體',
  213 + 'NSimSun' : '新宋體',
  214 + 'FangSong' : '仿宋體',
  215 + 'Arial' : 'Arial',
  216 + 'Arial Black' : 'Arial Black',
  217 + 'Times New Roman' : 'Times New Roman',
  218 + 'Courier New' : 'Courier New',
  219 + 'Tahoma' : 'Tahoma',
  220 + 'Verdana' : 'Verdana'
  221 + },
  222 + 'lineheight.lineHeight' : [
  223 + {'1' : '单倍行距'},
  224 + {'1.5' : '1.5倍行距'},
  225 + {'2' : '2倍行距'},
  226 + {'2.5' : '2.5倍行距'},
  227 + {'3' : '3倍行距'}
  228 + ],
  229 + 'template.selectTemplate' : '可選樣板',
  230 + 'template.replaceContent' : '取代當前內容',
  231 + 'template.fileList' : {
  232 + '1.html' : '影像和文字',
  233 + '2.html' : '表格',
  234 + '3.html' : '项目清單'
  235 + }
  236 +}, 'zh-TW');
  237 +
  238 +KindEditor.each(KindEditor.options.items, function(i, name) {
  239 + if (name == 'baidumap') {
  240 + KindEditor.options.items[i] = 'map';
  241 + }
  242 +});
  243 +KindEditor.options.langType = 'zh-TW';
此 diff 太大无法显示。
此 diff 太大无法显示。
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +KindEditor.plugin('anchor', function(K) {
  11 + var self = this, name = 'anchor', lang = self.lang(name + '.');
  12 + self.plugin.anchor = {
  13 + edit : function() {
  14 + var html = ['<div class="ke-dialog-content-inner">',
  15 + '<div class="ke-dialog-row ke-clearfix">',
  16 + '<label for="keName">' + lang.name + ':</label>',
  17 + '<input class="ke-input-text" type="text" id="keName" name="name" value="" style="width:100px;" />',
  18 + '</div>',
  19 + '</div>'].join('');
  20 + var dialog = self.createDialog({
  21 + name : name,
  22 + width : 300,
  23 + title : self.lang(name),
  24 + body : html,
  25 + yesBtn : {
  26 + name : self.lang('yes'),
  27 + click : function(e) {
  28 + self.insertHtml('<a name="' + nameBox.val() + '">').hideDialog().focus();
  29 + }
  30 + }
  31 + });
  32 + var div = dialog.div,
  33 + nameBox = K('input[name="name"]', div);
  34 + var img = self.plugin.getSelectedAnchor();
  35 + if (img) {
  36 + nameBox.val(unescape(img.attr('data-ke-name')));
  37 + }
  38 + nameBox[0].focus();
  39 + nameBox[0].select();
  40 + },
  41 + 'delete' : function() {
  42 + self.plugin.getSelectedAnchor().remove();
  43 + }
  44 + };
  45 + self.clickToolbar(name, self.plugin.anchor.edit);
  46 +});
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +KindEditor.plugin('autoheight', function(K) {
  11 + var self = this;
  12 +
  13 + if (!self.autoHeightMode) {
  14 + return;
  15 + }
  16 +
  17 + var minHeight;
  18 +
  19 + function hideScroll() {
  20 + var edit = self.edit;
  21 + var body = edit.doc.body;
  22 + edit.iframe[0].scroll = 'no';
  23 + body.style.overflowY = 'hidden';
  24 + }
  25 +
  26 + function resetHeight() {
  27 + if(self.fullscreenMode){
  28 + return;
  29 + }
  30 + var edit = self.edit;
  31 + var body = edit.doc.body;
  32 + edit.iframe.height(minHeight);
  33 + self.resize(null, Math.max((K.IE ? body.scrollHeight : body.offsetHeight) + 76, minHeight));
  34 + }
  35 +
  36 + function init() {
  37 + minHeight = K.removeUnit(self.height);
  38 +
  39 + self.edit.afterChange(resetHeight);
  40 + if(!self.fullscreenMode){
  41 + hideScroll();
  42 + }
  43 + resetHeight();
  44 + }
  45 +
  46 + if (self.isCreated) {
  47 + init();
  48 + } else {
  49 + self.afterCreate(init);
  50 + }
  51 +});
  52 +
  53 +/*
  54 +* 如何实现真正的自动高度?
  55 +* 修改编辑器高度之后,再次获取body内容高度时,最小值只会是当前iframe的设置高度,这样就导致高度只增不减。
  56 +* 所以每次获取body内容高度之前,先将iframe的高度重置为最小高度,这样就能获取body的实际高度。
  57 +* 由此就实现了真正的自动高度
  58 +* 测试:chrome、firefox、IE9、IE8
  59 +* */
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +// Baidu Maps: http://dev.baidu.com/wiki/map/index.php?title=%E9%A6%96%E9%A1%B5
  11 +
  12 +KindEditor.plugin('baidumap', function(K) {
  13 + var self = this, name = 'baidumap', lang = self.lang(name + '.');
  14 + var mapWidth = K.undef(self.mapWidth, 558);
  15 + var mapHeight = K.undef(self.mapHeight, 360);
  16 + self.clickToolbar(name, function() {
  17 + var html = ['<div class="ke-dialog-content-inner" style="padding-top: 0">',
  18 + '<div class="ke-dialog-row ke-clearfix">',
  19 + // right start
  20 + '<div class="ke-header">' + lang.address,
  21 + '<input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ',
  22 + '<span>',
  23 + '<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" style="line-height:22px;padding:0 10px;" />',
  24 + '</span>',
  25 + '<input type="checkbox" id="keInsertDynamicMap" name="insertDynamicMap" class="checkbox" value="1" style="display:inline-block;" /> <label for="keInsertDynamicMap">' + lang.insertDynamicMap + '</label>',
  26 + '</div>',
  27 + '</div>',
  28 +
  29 + //map iframe
  30 + '<div class="ke-map" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></div>',
  31 + '</div>'].join('');
  32 + var dialog = self.createDialog({
  33 + name : name,
  34 + width : mapWidth + 42,
  35 + title : self.lang(name),
  36 + body : html,
  37 + yesBtn : {
  38 + name : self.lang('yes'),
  39 + click : function(e) {
  40 + var map = win.map;
  41 + var centerObj = map.getCenter();
  42 + var center = centerObj.lng + ',' + centerObj.lat;
  43 + var zoom = map.getZoom();
  44 + var url = [checkbox[0].checked ? self.pluginsPath + 'baidumap/index.html' : 'https://api.map.baidu.com/staticimage',
  45 + '?center=' + encodeURIComponent(center),
  46 + '&zoom=' + encodeURIComponent(zoom),
  47 + '&width=' + mapWidth,
  48 + '&height=' + mapHeight,
  49 + '&markers=' + encodeURIComponent(center),
  50 + '&markerStyles=' + encodeURIComponent('l,A')].join('');
  51 + if (checkbox[0].checked) {
  52 + self.insertHtml('<iframe src="' + url + '" frameborder="0" style="width:' + (mapWidth + 2) + 'px;height:' + (mapHeight + 2) + 'px;"></iframe>');
  53 + } else {
  54 + self.exec('insertimage', url);
  55 + }
  56 + self.hideDialog().focus();
  57 + }
  58 + },
  59 + beforeRemove : function() {
  60 + searchBtn.remove();
  61 + if (doc) {
  62 + doc.write('');
  63 + }
  64 + iframe.remove();
  65 + }
  66 + });
  67 + var div = dialog.div,
  68 + addressBox = K('[name="address"]', div),
  69 + searchBtn = K('[name="searchBtn"]', div),
  70 + checkbox = K('[name="insertDynamicMap"]', dialog.div),
  71 + win, doc;
  72 + var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'baidumap/map.html" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></iframe>');
  73 + function ready() {
  74 + win = iframe[0].contentWindow;
  75 + doc = K.iframeDoc(iframe);
  76 + }
  77 + iframe.bind('load', function() {
  78 + iframe.unbind('load');
  79 + if (K.IE) {
  80 + ready();
  81 + } else {
  82 + setTimeout(ready, 0);
  83 + }
  84 + });
  85 + K('.ke-map', div).replaceWith(iframe);
  86 + // search map
  87 + searchBtn.click(function() {
  88 + win.search(addressBox.val());
  89 + });
  90 + });
  91 +});
  1 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 +<html xmlns="http://www.w3.org/1999/xhtml">
  3 +<head>
  4 + <meta charset="utf-8"/>
  5 + <meta name="keywords" content="百度地图,百度地图API,百度地图自定义工具,百度地图所见即所得工具"/>
  6 + <meta name="description" content="百度地图API自定义地图,帮助用户在可视化操作下生成百度地图"/>
  7 + <title>百度地图API自定义地图</title>
  8 + <!--引用百度地图API-->
  9 + <style type="text/css">
  10 + html, body {
  11 + margin: 0;
  12 + padding: 0;
  13 + }
  14 +
  15 + .iw_poi_title {
  16 + color: #CC5522;
  17 + font-size: 14px;
  18 + font-weight: bold;
  19 + overflow: hidden;
  20 + padding-right: 13px;
  21 + white-space: nowrap
  22 + }
  23 +
  24 + .iw_poi_content {
  25 + font: 12px arial, sans-serif;
  26 + overflow: visible;
  27 + padding-top: 4px;
  28 + white-space: -moz-pre-wrap;
  29 + word-wrap: break-word
  30 + }
  31 + </style>
  32 + <script type="text/javascript" src="//api.map.baidu.com/api?key=&v=1.1&services=true"></script>
  33 +</head>
  34 +
  35 +<body onload="initMap();">
  36 +<!--百度地图容器-->
  37 +<div style="width:697px;height:550px;border:#ccc solid 1px;" id="dituContent"></div>
  38 +</body>
  39 +<script type="text/javascript">
  40 + function getParam(name) {
  41 + return location.href.match(new RegExp('[?&]' + name + '=([^?&]+)', 'i')) ? decodeURIComponent(RegExp.$1) : '';
  42 + }
  43 +
  44 + var centerParam = getParam('center');
  45 + var zoomParam = getParam('zoom');
  46 + var widthParam = getParam('width');
  47 + var heightParam = getParam('height');
  48 + var markersParam = getParam('markers');
  49 + var markerStylesParam = getParam('markerStyles');
  50 +
  51 + //创建和初始化地图函数:
  52 + function initMap() {
  53 + // [FF]切换模式后报错
  54 + if (!window.BMap) {
  55 + return;
  56 + }
  57 + var dituContent = document.getElementById('dituContent');
  58 + dituContent.style.width = widthParam + 'px';
  59 + dituContent.style.height = heightParam + 'px';
  60 +
  61 + createMap();//创建地图
  62 + setMapEvent();//设置地图事件
  63 + addMapControl();//向地图添加控件
  64 +
  65 + // 创建标注
  66 + var markersArr = markersParam.split(',');
  67 + var point = new BMap.Point(markersArr[0], markersArr[1]);
  68 + var marker = new BMap.Marker(point);
  69 + map.addOverlay(marker); // 将标注添加到地图中
  70 + }
  71 +
  72 + //创建地图函数:
  73 + function createMap() {
  74 + var map = new BMap.Map("dituContent");//在百度地图容器中创建一个地图
  75 + var centerArr = centerParam.split(',');
  76 + var point = new BMap.Point(centerArr[0], centerArr[1]);//定义一个中心点坐标
  77 + map.centerAndZoom(point, zoomParam);//设定地图的中心点和坐标并将地图显示在地图容器中
  78 + window.map = map;//将map变量存储在全局
  79 + }
  80 +
  81 + //地图事件设置函数:
  82 + function setMapEvent() {
  83 + map.enableDragging();//启用地图拖拽事件,默认启用(可不写)
  84 + map.enableScrollWheelZoom();//启用地图滚轮放大缩小
  85 + map.enableDoubleClickZoom();//启用鼠标双击放大,默认启用(可不写)
  86 + map.enableKeyboard();//启用键盘上下左右键移动地图
  87 + }
  88 +
  89 + //地图控件添加函数:
  90 + function addMapControl() {
  91 + //向地图中添加缩放控件
  92 + var ctrl_nav = new BMap.NavigationControl({anchor: BMAP_ANCHOR_TOP_LEFT, type: BMAP_NAVIGATION_CONTROL_LARGE});
  93 + map.addControl(ctrl_nav);
  94 + //向地图中添加缩略图控件
  95 + var ctrl_ove = new BMap.OverviewMapControl({anchor: BMAP_ANCHOR_BOTTOM_RIGHT, isOpen: 1});
  96 + map.addControl(ctrl_ove);
  97 + //向地图中添加比例尺控件
  98 + var ctrl_sca = new BMap.ScaleControl({anchor: BMAP_ANCHOR_BOTTOM_LEFT});
  99 + map.addControl(ctrl_sca);
  100 + }
  101 +</script>
  102 +</html>
  1 +<!doctype html>
  2 +<html>
  3 +<head>
  4 + <meta charset="utf-8"/>
  5 + <title>Baidu Maps</title>
  6 + <style>
  7 + html {
  8 + height: 100%
  9 + }
  10 +
  11 + body {
  12 + height: 100%;
  13 + margin: 0;
  14 + padding: 0;
  15 + background-color: #FFF
  16 + }
  17 + </style>
  18 + <script charset="utf-8" src="//api.map.baidu.com/api?v=1.3"></script>
  19 + <script>
  20 + var map, geocoder;
  21 +
  22 + function initialize() {
  23 + map = new BMap.Map('map_canvas');
  24 + var point = new BMap.Point(114.025974, 22.546054);
  25 + map.centerAndZoom(point, 11);
  26 + map.addControl(new BMap.NavigationControl());
  27 + map.enableScrollWheelZoom();
  28 +
  29 + var gc = new BMap.Geocoder();
  30 + gc.getLocation(point, function (rs) {
  31 + var addComp = rs.addressComponents;
  32 + var address = [addComp.city].join('');
  33 + parent.document.getElementById("kindeditor_plugin_map_address").value = address;
  34 + });
  35 + }
  36 +
  37 + function search(address) {
  38 + if (!map) return;
  39 + var local = new BMap.LocalSearch(map, {
  40 + renderOptions: {
  41 + map: map,
  42 + autoViewport: true,
  43 + selectFirstResult: false
  44 + }
  45 + });
  46 + local.search(address);
  47 + }
  48 + </script>
  49 +</head>
  50 +<body onload="initialize();">
  51 +<div id="map_canvas" style="width:100%; height:100%"></div>
  52 +</body>
  53 +</html>
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +KindEditor.plugin('clearhtml', function(K) {
  11 + var self = this, name = 'clearhtml';
  12 + self.clickToolbar(name, function() {
  13 + self.focus();
  14 + var html = self.html();
  15 + html = html.replace(/(<script[^>]*>)([\s\S]*?)(<\/script>)/ig, '');
  16 + html = html.replace(/(<style[^>]*>)([\s\S]*?)(<\/style>)/ig, '');
  17 + html = K.formatHtml(html, {
  18 + a : ['href', 'target'],
  19 + embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'],
  20 + img : ['src', 'width', 'height', 'border', 'alt', 'title', '.width', '.height'],
  21 + table : ['border'],
  22 + 'td,th' : ['rowspan', 'colspan'],
  23 + 'div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : []
  24 + });
  25 + self.html(html);
  26 + self.cmd.selection(true);
  27 + self.addBookmark();
  28 + });
  29 +});
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +// google code prettify: http://google-code-prettify.googlecode.com/
  11 +// http://google-code-prettify.googlecode.com/
  12 +
  13 +KindEditor.plugin('code', function(K) {
  14 + var self = this, name = 'code';
  15 + self.clickToolbar(name, function() {
  16 + var lang = self.lang(name + '.'),
  17 + html = ['<div style="margin: 0px 20px;">',
  18 + '<div class="ke-dialog-row">',
  19 + '<select class="ke-select" style="margin-bottom: 5px;">',
  20 + '<option value="javascript">JavaScript</option>',
  21 + '<option value="html">HTML</option>',
  22 + '<option value="css">CSS</option>',
  23 + '<option value="php">PHP</option>',
  24 + '<option value="perl">Perl</option>',
  25 + '<option value="python">Python</option>',
  26 + '<option value="ruby">Ruby</option>',
  27 + '<option value="java">Java</option>',
  28 + '<option value="go">Go</option>',
  29 + '<option value="asp">ASP/VB</option>',
  30 + '<option value="csharp">C#</option>',
  31 + '<option value="cpp">C/C++</option>',
  32 + '<option value="cs">C#</option>',
  33 + '<option value="bash">Shell</option>',
  34 + '<option value="sql">SQL</option>',
  35 + '<option value="markup">Other</option>',
  36 + '</select>',
  37 + '</div>',
  38 + '<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>',
  39 + '</div>'].join(''),
  40 + dialog = self.createDialog({
  41 + name : name,
  42 + width : 450,
  43 + title : self.lang(name),
  44 + body : html,
  45 + yesBtn : {
  46 + name : self.lang('yes'),
  47 + click : function(e) {
  48 + var type = K('.ke-select', dialog.div).val(),
  49 + code = textarea.val(),
  50 + cls = type === '' ? '' : 'language-' + type,
  51 + html = '<pre class="' + cls + '"><code>' + K.escape(code) + '</code></pre> <br/>';
  52 + if (K.trim(code) === '') {
  53 + K.options.errorMsgHandler(lang.pleaseInput, "error");
  54 + textarea[0].focus();
  55 + return;
  56 + }
  57 + self.insertHtml(html).hideDialog().focus();
  58 + }
  59 + }
  60 + }),
  61 + textarea = K('textarea', dialog.div);
  62 + textarea[0].focus();
  63 + });
  64 +});
  1 +/**
  2 + * @author yangjian
  3 + * @since 18-9-11 下午9:02.
  4 + */
  5 +
  6 +// function _bindEvent(el, type, fn) {
  7 +// if (el.addEventListener){
  8 +// el.addEventListener(type, fn);
  9 +// } else if (el.attachEvent){
  10 +// el.attachEvent('on' + type, fn);
  11 +// }
  12 +// }
  13 +// _bindEvent(document.body, "DOMNodeInserted", function(e) {
  14 +// var className = e.target.className;
  15 +// if (className && className.indexOf("language-") != -1) {
  16 +// Prism.highlightElement(e.target);
  17 +// }
  18 +// })
  1 +/* PrismJS 1.15.0
  2 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+csharp+bash+cpp+aspnet+ruby+markup-templating+go+markdown+php+python+sass+yaml&plugins=line-highlight+line-numbers+toolbar+highlight-keywords+show-language+copy-to-clipboard */
  3 +/**
  4 + * prism.js default theme for JavaScript, CSS and HTML
  5 + * Based on dabblet (http://dabblet.com)
  6 + * @author Lea Verou
  7 + */
  8 +
  9 +code[class*="language-"],
  10 +pre[class*="language-"] {
  11 + color: black;
  12 + background: none;
  13 + text-shadow: 0 1px white;
  14 + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
  15 + text-align: left;
  16 + white-space: pre;
  17 + word-spacing: normal;
  18 + word-break: normal;
  19 + word-wrap: normal;
  20 + line-height: 1.5;
  21 +
  22 + -moz-tab-size: 4;
  23 + -o-tab-size: 4;
  24 + tab-size: 4;
  25 +
  26 + -webkit-hyphens: none;
  27 + -moz-hyphens: none;
  28 + -ms-hyphens: none;
  29 + hyphens: none;
  30 +}
  31 +
  32 +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
  33 +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
  34 + text-shadow: none;
  35 + background: #b3d4fc;
  36 +}
  37 +
  38 +pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
  39 +code[class*="language-"]::selection, code[class*="language-"] ::selection {
  40 + text-shadow: none;
  41 + background: #b3d4fc;
  42 +}
  43 +
  44 +@media print {
  45 + code[class*="language-"],
  46 + pre[class*="language-"] {
  47 + text-shadow: none;
  48 + }
  49 +}
  50 +
  51 +/* Code blocks */
  52 +pre[class*="language-"] {
  53 + padding: 1em;
  54 + margin: .5em 0;
  55 + overflow: auto;
  56 +}
  57 +
  58 +:not(pre) > code[class*="language-"],
  59 +pre[class*="language-"] {
  60 + background: #f5f2f0;
  61 +}
  62 +
  63 +/* Inline code */
  64 +:not(pre) > code[class*="language-"] {
  65 + padding: .1em;
  66 + border-radius: .3em;
  67 + white-space: normal;
  68 +}
  69 +
  70 +.token.comment,
  71 +.token.prolog,
  72 +.token.doctype,
  73 +.token.cdata {
  74 + color: slategray;
  75 +}
  76 +
  77 +.token.punctuation {
  78 + color: #999;
  79 +}
  80 +
  81 +.namespace {
  82 + opacity: .7;
  83 +}
  84 +
  85 +.token.property,
  86 +.token.tag,
  87 +.token.boolean,
  88 +.token.number,
  89 +.token.constant,
  90 +.token.symbol,
  91 +.token.deleted {
  92 + color: #905;
  93 +}
  94 +
  95 +.token.selector,
  96 +.token.attr-name,
  97 +.token.string,
  98 +.token.char,
  99 +.token.builtin,
  100 +.token.inserted {
  101 + color: #690;
  102 +}
  103 +
  104 +.token.operator,
  105 +.token.entity,
  106 +.token.url,
  107 +.language-css .token.string,
  108 +.style .token.string {
  109 + color: #9a6e3a;
  110 + background: hsla(0, 0%, 100%, .5);
  111 +}
  112 +
  113 +.token.atrule,
  114 +.token.attr-value,
  115 +.token.keyword {
  116 + color: #07a;
  117 +}
  118 +
  119 +.token.function,
  120 +.token.class-name {
  121 + color: #DD4A68;
  122 +}
  123 +
  124 +.token.regex,
  125 +.token.important,
  126 +.token.variable {
  127 + color: #e90;
  128 +}
  129 +
  130 +.token.important,
  131 +.token.bold {
  132 + font-weight: bold;
  133 +}
  134 +.token.italic {
  135 + font-style: italic;
  136 +}
  137 +
  138 +.token.entity {
  139 + cursor: help;
  140 +}
  141 +
  142 +pre[data-line] {
  143 + position: relative;
  144 + padding: 1em 0 1em 3em;
  145 +}
  146 +
  147 +.line-highlight {
  148 + position: absolute;
  149 + left: 0;
  150 + right: 0;
  151 + padding: inherit 0;
  152 + margin-top: 1em; /* Same as .prism’s padding-top */
  153 +
  154 + background: hsla(24, 20%, 50%,.08);
  155 + background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
  156 +
  157 + pointer-events: none;
  158 +
  159 + line-height: inherit;
  160 + white-space: pre;
  161 +}
  162 +
  163 + .line-highlight:before,
  164 + .line-highlight[data-end]:after {
  165 + content: attr(data-start);
  166 + position: absolute;
  167 + top: .4em;
  168 + left: .6em;
  169 + min-width: 1em;
  170 + padding: 0 .5em;
  171 + background-color: hsla(24, 20%, 50%,.4);
  172 + color: hsl(24, 20%, 95%);
  173 + font: bold 65%/1.5 sans-serif;
  174 + text-align: center;
  175 + vertical-align: .3em;
  176 + border-radius: 999px;
  177 + text-shadow: none;
  178 + box-shadow: 0 1px white;
  179 + }
  180 +
  181 + .line-highlight[data-end]:after {
  182 + content: attr(data-end);
  183 + top: auto;
  184 + bottom: .4em;
  185 + }
  186 +
  187 +.line-numbers .line-highlight:before,
  188 +.line-numbers .line-highlight:after {
  189 + content: none;
  190 +}
  191 +
  192 +pre[class*="language-"].line-numbers {
  193 + position: relative;
  194 + padding-left: 3.8em;
  195 + counter-reset: linenumber;
  196 +}
  197 +
  198 +pre[class*="language-"].line-numbers > code {
  199 + position: relative;
  200 + white-space: inherit;
  201 +}
  202 +
  203 +.line-numbers .line-numbers-rows {
  204 + position: absolute;
  205 + pointer-events: none;
  206 + top: 0;
  207 + font-size: 100%;
  208 + left: -3.8em;
  209 + width: 3em; /* works for line-numbers below 1000 lines */
  210 + letter-spacing: -1px;
  211 + border-right: 1px solid #999;
  212 +
  213 + -webkit-user-select: none;
  214 + -moz-user-select: none;
  215 + -ms-user-select: none;
  216 + user-select: none;
  217 +
  218 +}
  219 +
  220 + .line-numbers-rows > span {
  221 + pointer-events: none;
  222 + display: block;
  223 + counter-increment: linenumber;
  224 + }
  225 +
  226 + .line-numbers-rows > span:before {
  227 + content: counter(linenumber);
  228 + color: #999;
  229 + display: block;
  230 + padding-right: 0.8em;
  231 + text-align: right;
  232 + }
  233 +
  234 +div.code-toolbar {
  235 + position: relative;
  236 +}
  237 +
  238 +div.code-toolbar > .toolbar {
  239 + position: absolute;
  240 + top: .3em;
  241 + right: .2em;
  242 + transition: opacity 0.3s ease-in-out;
  243 + opacity: 0;
  244 +}
  245 +
  246 +div.code-toolbar:hover > .toolbar {
  247 + opacity: 1;
  248 +}
  249 +
  250 +div.code-toolbar > .toolbar .toolbar-item {
  251 + display: inline-block;
  252 +}
  253 +
  254 +div.code-toolbar > .toolbar a {
  255 + cursor: pointer;
  256 +}
  257 +
  258 +div.code-toolbar > .toolbar button {
  259 + background: none;
  260 + border: 0;
  261 + color: inherit;
  262 + font: inherit;
  263 + line-height: normal;
  264 + overflow: visible;
  265 + padding: 0;
  266 + -webkit-user-select: none; /* for button */
  267 + -moz-user-select: none;
  268 + -ms-user-select: none;
  269 +}
  270 +
  271 +div.code-toolbar > .toolbar a,
  272 +div.code-toolbar > .toolbar button,
  273 +div.code-toolbar > .toolbar span {
  274 + color: #bbb;
  275 + font-size: .8em;
  276 + padding: 0 .5em;
  277 + background: #f5f2f0;
  278 + background: rgba(224, 224, 224, 0.2);
  279 + box-shadow: 0 2px 0 0 rgba(0,0,0,0.2);
  280 + border-radius: .5em;
  281 +}
  282 +
  283 +div.code-toolbar > .toolbar a:hover,
  284 +div.code-toolbar > .toolbar a:focus,
  285 +div.code-toolbar > .toolbar button:hover,
  286 +div.code-toolbar > .toolbar button:focus,
  287 +div.code-toolbar > .toolbar span:hover,
  288 +div.code-toolbar > .toolbar span:focus {
  289 + color: inherit;
  290 + text-decoration: none;
  291 +}
  292 +
  1 +/* PrismJS 1.15.0
  2 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+csharp+bash+cpp+aspnet+ruby+markup-templating+go+markdown+php+python+sass+yaml&plugins=line-highlight+line-numbers+toolbar+highlight-keywords+show-language+copy-to-clipboard */
  3 +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-([\w-]+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,disableWorkerMessageHandler:_self.Prism&&_self.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof r?new r(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function(e,t){var r=n.util.type(e);switch(t=t||{},r){case"Object":if(t[n.util.objId(e)])return t[n.util.objId(e)];var a={};t[n.util.objId(e)]=a;for(var l in e)e.hasOwnProperty(l)&&(a[l]=n.util.clone(e[l],t));return a;case"Array":if(t[n.util.objId(e)])return t[n.util.objId(e)];var a=[];return t[n.util.objId(e)]=a,e.forEach(function(e,r){a[r]=n.util.clone(e,t)}),a}return e}},languages:{extend:function(e,t){var r=n.util.clone(n.languages[e]);for(var a in t)r[a]=t[a];return r},insertBefore:function(e,t,r,a){a=a||n.languages;var l=a[e];if(2==arguments.length){r=arguments[1];for(var i in r)r.hasOwnProperty(i)&&(l[i]=r[i]);return l}var o={};for(var s in l)if(l.hasOwnProperty(s)){if(s==t)for(var i in r)r.hasOwnProperty(i)&&(o[i]=r[i]);o[s]=l[s]}var u=a[e];return a[e]=o,n.languages.DFS(n.languages,function(t,n){n===u&&t!=e&&(this[t]=o)}),o},DFS:function(e,t,r,a){a=a||{};for(var l in e)e.hasOwnProperty(l)&&(t.call(e,l,e[l],r||l),"Object"!==n.util.type(e[l])||a[n.util.objId(e[l])]?"Array"!==n.util.type(e[l])||a[n.util.objId(e[l])]||(a[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,l,a)):(a[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,null,a)))}},plugins:{},highlightAll:function(e,t){n.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,r){var a={callback:r,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};n.hooks.run("before-highlightall",a);for(var l,i=a.elements||e.querySelectorAll(a.selector),o=0;l=i[o++];)n.highlightElement(l,t===!0,a.callback)},highlightElement:function(t,r,a){for(var l,i,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(l=(o.className.match(e)||[,""])[1].toLowerCase(),i=n.languages[l]),t.className=t.className.replace(e,"").replace(/\s+/g," ")+" language-"+l,t.parentNode&&(o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+l));var s=t.textContent,u={element:t,language:l,grammar:i,code:s};if(n.hooks.run("before-sanity-check",u),!u.code||!u.grammar)return u.code&&(n.hooks.run("before-highlight",u),u.element.textContent=u.code,n.hooks.run("after-highlight",u)),n.hooks.run("complete",u),void 0;if(n.hooks.run("before-highlight",u),r&&_self.Worker){var g=new Worker(n.filename);g.onmessage=function(e){u.highlightedCode=e.data,n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,a&&a.call(u.element),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},g.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else u.highlightedCode=n.highlight(u.code,u.grammar,u.language),n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,a&&a.call(t),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},highlight:function(e,t,a){var l={code:e,grammar:t,language:a};return n.hooks.run("before-tokenize",l),l.tokens=n.tokenize(l.code,l.grammar),n.hooks.run("after-tokenize",l),r.stringify(n.util.encode(l.tokens),l.language)},matchGrammar:function(e,t,r,a,l,i,o){var s=n.Token;for(var u in r)if(r.hasOwnProperty(u)&&r[u]){if(u==o)return;var g=r[u];g="Array"===n.util.type(g)?g:[g];for(var c=0;c<g.length;++c){var h=g[c],f=h.inside,d=!!h.lookbehind,m=!!h.greedy,p=0,y=h.alias;if(m&&!h.pattern.global){var v=h.pattern.toString().match(/[imuy]*$/)[0];h.pattern=RegExp(h.pattern.source,v+"g")}h=h.pattern||h;for(var b=a,k=l;b<t.length;k+=t[b].length,++b){var w=t[b];if(t.length>e.length)return;if(!(w instanceof s)){if(m&&b!=t.length-1){h.lastIndex=k;var _=h.exec(e);if(!_)break;for(var j=_.index+(d?_[1].length:0),P=_.index+_[0].length,A=b,x=k,O=t.length;O>A&&(P>x||!t[A].type&&!t[A-1].greedy);++A)x+=t[A].length,j>=x&&(++b,k=x);if(t[b]instanceof s)continue;I=A-b,w=e.slice(k,x),_.index-=k}else{h.lastIndex=0;var _=h.exec(w),I=1}if(_){d&&(p=_[1]?_[1].length:0);var j=_.index+p,_=_[0].slice(p),P=j+_.length,N=w.slice(0,j),S=w.slice(P),C=[b,I];N&&(++b,k+=N.length,C.push(N));var E=new s(u,f?n.tokenize(_,f):_,y,_,m);if(C.push(E),S&&C.push(S),Array.prototype.splice.apply(t,C),1!=I&&n.matchGrammar(e,t,r,b,k,!0,u),i)break}else if(i)break}}}}},tokenize:function(e,t){var r=[e],a=t.rest;if(a){for(var l in a)t[l]=a[l];delete t.rest}return n.matchGrammar(e,r,t,0,0,!1),r},hooks:{all:{},add:function(e,t){var r=n.hooks.all;r[e]=r[e]||[],r[e].push(t)},run:function(e,t){var r=n.hooks.all[e];if(r&&r.length)for(var a,l=0;a=r[l++];)a(t)}}},r=n.Token=function(e,t,n,r,a){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length,this.greedy=!!a};if(r.stringify=function(e,t,a){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return r.stringify(n,t,e)}).join("");var l={type:e.type,content:r.stringify(e.content,t,a),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:a};if(e.alias){var i="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run("wrap",l);var o=Object.keys(l.attributes).map(function(e){return e+'="'+(l.attributes[e]||"").replace(/"/g,"&quot;")+'"'}).join(" ");return"<"+l.tag+' class="'+l.classes.join(" ")+'"'+(o?" "+o:"")+">"+l.content+"</"+l.tag+">"},!_self.document)return _self.addEventListener?(n.disableWorkerMessageHandler||_self.addEventListener("message",function(e){var t=JSON.parse(e.data),r=t.language,a=t.code,l=t.immediateClose;_self.postMessage(n.highlight(a,n.languages[r],r)),l&&_self.close()},!1),_self.Prism):_self.Prism;var a=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return a&&(n.filename=a.src,n.manual||a.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
  4 +Prism.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:/<!DOCTYPE[\s\S]+?>/i,cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/(^|[^\\])["']/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&amp;/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup;
  5 +Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.languages.css,Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css",greedy:!0}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));
  6 +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(?:true|false)\b/,"function":/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/};
  7 +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},/\b(?:as|async|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/],number:/\b(?:(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+)n?|\d+n|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,"function":/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\(|\.(?:apply|bind|call)\()/,operator:/-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[[^\]\r\n]+]|\\.|[^\/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,alias:"function"},constant:/\b[A-Z][A-Z\d_]*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\${[^}]+}/,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<script[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript",greedy:!0}}),Prism.languages.js=Prism.languages.javascript;
  8 +Prism.languages.c=Prism.languages.extend("clike",{keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*\/%&|^!=<>]=?/,number:/(?:\b0x[\da-f]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,alias:"property",inside:{string:{pattern:/(#\s*include\s*)(?:<.+?>|("|')(?:\\?.)+?\2)/,lookbehind:!0},directive:{pattern:/(#\s*)\b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,lookbehind:!0,alias:"keyword"}}},constant:/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete Prism.languages.c["class-name"],delete Prism.languages.c["boolean"];
  9 +Prism.languages.csharp=Prism.languages.extend("clike",{keyword:/\b(?:abstract|add|alias|as|ascending|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|descending|do|double|dynamic|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|from|get|global|goto|group|if|implicit|in|int|interface|internal|into|is|join|let|lock|long|namespace|new|null|object|operator|orderby|out|override|params|partial|private|protected|public|readonly|ref|remove|return|sbyte|sealed|select|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|value|var|virtual|void|volatile|where|while|yield)\b/,string:[{pattern:/@("|')(?:\1\1|\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0},{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*?\1/,greedy:!0}],"class-name":[{pattern:/\b[A-Z]\w*(?:\.\w+)*\b(?=\s+\w+)/,inside:{punctuation:/\./}},{pattern:/(\[)[A-Z]\w*(?:\.\w+)*\b/,lookbehind:!0,inside:{punctuation:/\./}},{pattern:/(\b(?:class|interface)\s+[A-Z]\w*(?:\.\w+)*\s*:\s*)[A-Z]\w*(?:\.\w+)*\b/,lookbehind:!0,inside:{punctuation:/\./}},{pattern:/((?:\b(?:class|interface|new)\s+)|(?:catch\s+\())[A-Z]\w*(?:\.\w+)*\b/,lookbehind:!0,inside:{punctuation:/\./}}],number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)f?/i}),Prism.languages.insertBefore("csharp","class-name",{"generic-method":{pattern:/\w+\s*<[^>\r\n]+?>\s*(?=\()/,inside:{"function":/^\w+/,"class-name":{pattern:/\b[A-Z]\w*(?:\.\w+)*\b/,inside:{punctuation:/\./}},keyword:Prism.languages.csharp.keyword,punctuation:/[<>(),.:]/}},preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(\s*#)\b(?:define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}}),Prism.languages.dotnet=Prism.languages.csharp;
  10 +!function(e){var t={variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\([^)]+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},/\$(?:[\w#?*!@]+|\{[^}]+\})/i]};e.languages.bash={shebang:{pattern:/^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/,alias:"important"},comment:{pattern:/(^|[^"{\\])#.*/,lookbehind:!0},string:[{pattern:/((?:^|[^<])<<\s*)["']?(\w+?)["']?\s*\r?\n(?:[\s\S])*?\r?\n\2/,lookbehind:!0,greedy:!0,inside:t},{pattern:/(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/,greedy:!0,inside:t}],variable:t.variable,"function":{pattern:/(^|[\s;|&])(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|[\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&])(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|[\s;|&])/,lookbehind:!0},"boolean":{pattern:/(^|[\s;|&])(?:true|false)(?=$|[\s;|&])/,lookbehind:!0},operator:/&&?|\|\|?|==?|!=?|<<<?|>>|<=?|>=?|=~/,punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];]/};var a=t.variable[1].inside;a.string=e.languages.bash.string,a["function"]=e.languages.bash["function"],a.keyword=e.languages.bash.keyword,a["boolean"]=e.languages.bash["boolean"],a.operator=e.languages.bash.operator,a.punctuation=e.languages.bash.punctuation,e.languages.shell=e.languages.bash}(Prism);
  11 +Prism.languages.cpp=Prism.languages.extend("c",{keyword:/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(?:true|false)\b/,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*\/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),Prism.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)\w+/i,lookbehind:!0}}),Prism.languages.insertBefore("cpp","string",{"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}});
  12 +Prism.languages.aspnet=Prism.languages.extend("markup",{"page-directive tag":{pattern:/<%\s*@.*%>/i,inside:{"page-directive tag":/<%\s*@\s*(?:Assembly|Control|Implements|Import|Master(?:Type)?|OutputCache|Page|PreviousPageType|Reference|Register)?|%>/i,rest:Prism.languages.markup.tag.inside}},"directive tag":{pattern:/<%.*%>/i,inside:{"directive tag":/<%\s*?[$=%#:]{0,2}|%>/i,rest:Prism.languages.csharp}}}),Prism.languages.aspnet.tag.pattern=/<(?!%)\/?[^\s>\/]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,Prism.languages.insertBefore("inside","punctuation",{"directive tag":Prism.languages.aspnet["directive tag"]},Prism.languages.aspnet.tag.inside["attr-value"]),Prism.languages.insertBefore("aspnet","comment",{"asp comment":/<%--[\s\S]*?--%>/}),Prism.languages.insertBefore("aspnet",Prism.languages.javascript?"script":"tag",{"asp script":{pattern:/(<script(?=.*runat=['"]?server['"]?)[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.csharp||{}}});
  13 +!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m,greedy:!0}],keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:n}}]}(Prism);
  14 +Prism.languages["markup-templating"]={},Object.defineProperties(Prism.languages["markup-templating"],{buildPlaceholders:{value:function(e,t,n,a){e.language===t&&(e.tokenStack=[],e.code=e.code.replace(n,function(n){if("function"==typeof a&&!a(n))return n;for(var r=e.tokenStack.length;-1!==e.code.indexOf("___"+t.toUpperCase()+r+"___");)++r;return e.tokenStack[r]=n,"___"+t.toUpperCase()+r+"___"}),e.grammar=Prism.languages.markup)}},tokenizePlaceholders:{value:function(e,t){if(e.language===t&&e.tokenStack){e.grammar=Prism.languages[t];var n=0,a=Object.keys(e.tokenStack),r=function(o){if(!(n>=a.length))for(var i=0;i<o.length;i++){var g=o[i];if("string"==typeof g||g.content&&"string"==typeof g.content){var c=a[n],s=e.tokenStack[c],l="string"==typeof g?g:g.content,p=l.indexOf("___"+t.toUpperCase()+c+"___");if(p>-1){++n;var f,u=l.substring(0,p),_=new Prism.Token(t,Prism.tokenize(s,e.grammar,t),"language-"+t,s),k=l.substring(p+("___"+t.toUpperCase()+c+"___").length);if(u||k?(f=[u,_,k].filter(function(e){return!!e}),r(f)):f=_,"string"==typeof g?Array.prototype.splice.apply(o,[i,1].concat(f)):g.content=f,n>=a.length)break}}else g.content&&"string"!=typeof g.content&&r(g.content)}};r(e.tokens)}}}});
  15 +Prism.languages.go=Prism.languages.extend("clike",{keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,builtin:/\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/,"boolean":/\b(?:_|iota|nil|true|false)\b/,operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,number:/(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,string:{pattern:/(["'`])(\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0}}),delete Prism.languages.go["class-name"];
  16 +Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},code:[{pattern:/^(?: {4}|\t).+/m,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*(?:\r?\n|\r)(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*$|__$/}},italic:{pattern:/(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.languages.markdown.url,Prism.languages.markdown.italic.inside.url=Prism.languages.markdown.url,Prism.languages.markdown.bold.inside.italic=Prism.languages.markdown.italic,Prism.languages.markdown.italic.inside.bold=Prism.languages.markdown.bold;
  17 +!function(e){e.languages.php=e.languages.extend("clike",{keyword:/\b(?:and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0}}),e.languages.insertBefore("php","string",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),e.languages.insertBefore("php","keyword",{delimiter:{pattern:/\?>|<\?(?:php|=)?/i,alias:"important"},variable:/\$+(?:\w+\b|(?={))/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),e.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}});var n={pattern:/{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/,lookbehind:!0,inside:{rest:e.languages.php}};e.languages.insertBefore("php","string",{"nowdoc-string":{pattern:/<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/,greedy:!0,alias:"string",inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},"heredoc-string":{pattern:/<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i,greedy:!0,alias:"string",inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:n}},"single-quoted-string":{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0,alias:"string"},"double-quoted-string":{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,alias:"string",inside:{interpolation:n}}}),delete e.languages.php.string,e.hooks.add("before-tokenize",function(n){if(/(?:<\?php|<\?)/gi.test(n.code)){var t=/(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/gi;e.languages["markup-templating"].buildPlaceholders(n,"php",t)}}),e.hooks.add("after-tokenize",function(n){e.languages["markup-templating"].tokenizePlaceholders(n,"php")})}(Prism);
  18 +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},"triple-quoted-string":{pattern:/("""|''')[\s\S]+?\1/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},"function":{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},keyword:/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,"boolean":/\b(?:True|False|None)\b/,number:/(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,punctuation:/[{}[\];(),.:]/};
  19 +!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var a=/\$[-\w]+|#\{\$[-\w]+\}/,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:a,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:a,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,delete e.languages.sass.selector,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism);
  20 +Prism.languages.yaml={scalar:{pattern:/([\-:]\s*(?:![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/,lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:/(\s*(?:^|[:\-,[{\r\n?])[ \t]*(?:![^\s]+)?[ \t]*)[^\r\n{[\]},#\s]+?(?=\s*:\s)/,lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?)(?=[ \t]*(?:$|,|]|}))/m,lookbehind:!0,alias:"number"},"boolean":{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:true|false)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},"null":{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:null|~)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},string:{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)("|')(?:(?!\2)[^\\\r\n]|\\.)*\2(?=[ \t]*(?:$|,|]|}))/m,lookbehind:!0,greedy:!0},number:{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,lookbehind:!0},tag:/![^\s]+/,important:/[&*][\w]+/,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./};
  21 +!function(){function e(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function t(e,t){return t=" "+t+" ",(" "+e.className+" ").replace(/[\n\t]/g," ").indexOf(t)>-1}function n(e,n,i){n="string"==typeof n?n:e.getAttribute("data-line");for(var o,l=n.replace(/\s+/g,"").split(","),a=+e.getAttribute("data-line-offset")||0,s=r()?parseInt:parseFloat,d=s(getComputedStyle(e).lineHeight),u=t(e,"line-numbers"),c=0;o=l[c++];){var p=o.split("-"),m=+p[0],f=+p[1]||m,h=e.querySelector('.line-highlight[data-range="'+o+'"]')||document.createElement("div");if(h.setAttribute("aria-hidden","true"),h.setAttribute("data-range",o),h.className=(i||"")+" line-highlight",u&&Prism.plugins.lineNumbers){var g=Prism.plugins.lineNumbers.getLine(e,m),y=Prism.plugins.lineNumbers.getLine(e,f);g&&(h.style.top=g.offsetTop+"px"),y&&(h.style.height=y.offsetTop-g.offsetTop+y.offsetHeight+"px")}else h.setAttribute("data-start",m),f>m&&h.setAttribute("data-end",f),h.style.top=(m-a-1)*d+"px",h.textContent=new Array(f-m+2).join(" \n");u?e.appendChild(h):(e.querySelector("code")||e).appendChild(h)}}function i(){var t=location.hash.slice(1);e(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var i=(t.match(/\.([\d,-]+)$/)||[,""])[1];if(i&&!document.getElementById(t)){var r=t.slice(0,t.lastIndexOf(".")),o=document.getElementById(r);o&&(o.hasAttribute("data-line")||o.setAttribute("data-line",""),n(o,i,"temporary "),document.querySelector(".temporary.line-highlight").scrollIntoView())}}if("undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector){var r=function(){var e;return function(){if("undefined"==typeof e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding=0,t.style.border=0,t.innerHTML="&nbsp;<br />&nbsp;",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e}}(),o=0;Prism.hooks.add("before-sanity-check",function(t){var n=t.element.parentNode,i=n&&n.getAttribute("data-line");if(n&&i&&/pre/i.test(n.nodeName)){var r=0;e(".line-highlight",n).forEach(function(e){r+=e.textContent.length,e.parentNode.removeChild(e)}),r&&/^( \n)+$/.test(t.code.slice(-r))&&(t.code=t.code.slice(0,-r))}}),Prism.hooks.add("complete",function l(e){var r=e.element.parentNode,a=r&&r.getAttribute("data-line");if(r&&a&&/pre/i.test(r.nodeName)){clearTimeout(o);var s=Prism.plugins.lineNumbers,d=e.plugins&&e.plugins.lineNumbers;t(r,"line-numbers")&&s&&!d?Prism.hooks.add("line-numbers",l):(n(r,a),o=setTimeout(i,1))}}),window.addEventListener("hashchange",i),window.addEventListener("resize",function(){var e=document.querySelectorAll("pre[data-line]");Array.prototype.forEach.call(e,function(e){n(e)})})}}();
  22 +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var e="line-numbers",t=/\n(?!$)/g,n=function(e){var n=r(e),s=n["white-space"];if("pre-wrap"===s||"pre-line"===s){var l=e.querySelector("code"),i=e.querySelector(".line-numbers-rows"),a=e.querySelector(".line-numbers-sizer"),o=l.textContent.split(t);a||(a=document.createElement("span"),a.className="line-numbers-sizer",l.appendChild(a)),a.style.display="block",o.forEach(function(e,t){a.textContent=e||"\n";var n=a.getBoundingClientRect().height;i.children[t].style.height=n+"px"}),a.textContent="",a.style.display="none"}},r=function(e){return e?window.getComputedStyle?getComputedStyle(e):e.currentStyle||null:null};window.addEventListener("resize",function(){Array.prototype.forEach.call(document.querySelectorAll("pre."+e),n)}),Prism.hooks.add("complete",function(e){if(e.code){var r=e.element.parentNode,s=/\s*\bline-numbers\b\s*/;if(r&&/pre/i.test(r.nodeName)&&(s.test(r.className)||s.test(e.element.className))&&!e.element.querySelector(".line-numbers-rows")){s.test(e.element.className)&&(e.element.className=e.element.className.replace(s," ")),s.test(r.className)||(r.className+=" line-numbers");var l,i=e.code.match(t),a=i?i.length+1:1,o=new Array(a+1);o=o.join("<span></span>"),l=document.createElement("span"),l.setAttribute("aria-hidden","true"),l.className="line-numbers-rows",l.innerHTML=o,r.hasAttribute("data-start")&&(r.style.counterReset="linenumber "+(parseInt(r.getAttribute("data-start"),10)-1)),e.element.appendChild(l),n(r),Prism.hooks.run("line-numbers",e)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0}),Prism.plugins.lineNumbers={getLine:function(t,n){if("PRE"===t.tagName&&t.classList.contains(e)){var r=t.querySelector(".line-numbers-rows"),s=parseInt(t.getAttribute("data-start"),10)||1,l=s+(r.children.length-1);s>n&&(n=s),n>l&&(n=l);var i=n-s;return r.children[i]}}}}}();
  23 +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var t=[],e={},n=function(){};Prism.plugins.toolbar={};var a=Prism.plugins.toolbar.registerButton=function(n,a){var o;o="function"==typeof a?a:function(t){var e;return"function"==typeof a.onClick?(e=document.createElement("button"),e.type="button",e.addEventListener("click",function(){a.onClick.call(this,t)})):"string"==typeof a.url?(e=document.createElement("a"),e.href=a.url):e=document.createElement("span"),e.textContent=a.text,e},t.push(e[n]=o)},o=Prism.plugins.toolbar.hook=function(a){var o=a.element.parentNode;if(o&&/pre/i.test(o.nodeName)&&!o.parentNode.classList.contains("code-toolbar")){var r=document.createElement("div");r.classList.add("code-toolbar"),o.parentNode.insertBefore(r,o),r.appendChild(o);var i=document.createElement("div");i.classList.add("toolbar"),document.body.hasAttribute("data-toolbar-order")&&(t=document.body.getAttribute("data-toolbar-order").split(",").map(function(t){return e[t]||n})),t.forEach(function(t){var e=t(a);if(e){var n=document.createElement("div");n.classList.add("toolbar-item"),n.appendChild(e),i.appendChild(n)}}),r.appendChild(i)}};a("label",function(t){var e=t.element.parentNode;if(e&&/pre/i.test(e.nodeName)&&e.hasAttribute("data-label")){var n,a,o=e.getAttribute("data-label");try{a=document.querySelector("template#"+o)}catch(r){}return a?n=a.content:(e.hasAttribute("data-url")?(n=document.createElement("a"),n.href=e.getAttribute("data-url")):n=document.createElement("span"),n.textContent=o),n}}),Prism.hooks.add("complete",o)}}();
  24 +!function(){"undefined"!=typeof self&&!self.Prism||"undefined"!=typeof global&&!global.Prism||Prism.hooks.add("wrap",function(e){"keyword"===e.type&&e.classes.push("keyword-"+e.content)})}();
  25 +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){if(!Prism.plugins.toolbar)return console.warn("Show Languages plugin loaded before Toolbar plugin."),void 0;var e={html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",css:"CSS",clike:"C-like",javascript:"JavaScript",abap:"ABAP",actionscript:"ActionScript",apacheconf:"Apache Configuration",apl:"APL",applescript:"AppleScript",arff:"ARFF",asciidoc:"AsciiDoc",asm6502:"6502 Assembly",aspnet:"ASP.NET (C#)",autohotkey:"AutoHotkey",autoit:"AutoIt",shell:"Shell",basic:"BASIC",csharp:"C#",cpp:"C++",coffeescript:"CoffeeScript",csp:"Content-Security-Policy","css-extras":"CSS Extras",django:"Django/Jinja2",erb:"ERB",fsharp:"F#",gedcom:"GEDCOM",glsl:"GLSL",graphql:"GraphQL",http:"HTTP",hpkp:"HTTP Public-Key-Pins",hsts:"HTTP Strict-Transport-Security",ichigojam:"IchigoJam",inform7:"Inform 7",json:"JSON",jsonp:"JSONP",latex:"LaTeX",livescript:"LiveScript",lolcode:"LOLCODE","markup-templating":"Markup templating",matlab:"MATLAB",mel:"MEL",n4js:"N4JS",nasm:"NASM",nginx:"nginx",nsis:"NSIS",objectivec:"Objective-C",ocaml:"OCaml",opencl:"OpenCL",parigp:"PARI/GP",objectpascal:"Object Pascal",php:"PHP","php-extras":"PHP Extras",plsql:"PL/SQL",powershell:"PowerShell",properties:".properties",protobuf:"Protocol Buffers",q:"Q (kdb+ database)",jsx:"React JSX",tsx:"React TSX",renpy:"Ren'py",rest:"reST (reStructuredText)",sas:"SAS",sass:"Sass (Sass)",scss:"Sass (Scss)",sql:"SQL",soy:"Soy (Closure Template)",tap:"TAP",tt2:"Template Toolkit 2",typescript:"TypeScript",vbnet:"VB.Net",vhdl:"VHDL",vim:"vim","visual-basic":"Visual Basic",wasm:"WebAssembly",wiki:"Wiki markup",xeoracube:"XeoraCube",xojo:"Xojo (REALbasic)",xquery:"XQuery",yaml:"YAML"};Prism.plugins.toolbar.registerButton("show-language",function(a){var t=a.element.parentNode;if(t&&/pre/i.test(t.nodeName)){var s=t.getAttribute("data-language")||e[a.language]||a.language&&a.language.substring(0,1).toUpperCase()+a.language.substring(1);if(s){var i=document.createElement("span");return i.textContent=s,i}}})}}();
  26 +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){if(!Prism.plugins.toolbar)return console.warn("Copy to Clipboard plugin loaded before Toolbar plugin."),void 0;var o=window.ClipboardJS||void 0;o||"function"!=typeof require||(o=require("clipboard"));var e=[];if(!o){var t=document.createElement("script"),n=document.querySelector("head");t.onload=function(){if(o=window.ClipboardJS)for(;e.length;)e.pop()()},t.src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js",n.appendChild(t)}Prism.plugins.toolbar.registerButton("copy-to-clipboard",function(t){function n(){var e=new o(i,{text:function(){return t.code}});e.on("success",function(){i.textContent="Copied!",r()}),e.on("error",function(){i.textContent="Press Ctrl+C to copy",r()})}function r(){setTimeout(function(){i.textContent="Copy"},5e3)}var i=document.createElement("a");return i.textContent="Copy",o?n():e.push(n),i})}}();
  1 +/*******************************************************************************
  2 +* KindEditor - WYSIWYG HTML Editor for Internet
  3 +* Copyright (C) 2006-2011 kindsoft.net
  4 +*
  5 +* @author Roddy <luolonghao@gmail.com>
  6 +* @site http://www.kindsoft.net/
  7 +* @licence http://www.kindsoft.net/license.php
  8 +*******************************************************************************/
  9 +
  10 +KindEditor.plugin('emoticons', function(K) {
  11 + var self = this, name = 'emoticons',
  12 + path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'),
  13 + allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons,
  14 + currentPageNum = 1;
  15 + self.clickToolbar(name, function() {
  16 + var rows = 5, cols = 9, total = 135, startNum = 0,
  17 + cells = rows * cols, pages = Math.ceil(total / cells),
  18 + colsHalf = Math.floor(cols / 2),
  19 + wrapperDiv = K('<div class="ke-plugin-emoticons"></div>'),
  20 + elements = [],
  21 + menu = self.createMenu({
  22 + name : name,
  23 + beforeRemove : function() {
  24 + removeEvent();
  25 + }
  26 + });
  27 + menu.div.append(wrapperDiv);
  28 + var previewDiv, previewImg;
  29 + if (allowPreview) {
  30 + previewDiv = K('<div class="ke-preview"></div>').css('right', 0);
  31 + previewImg = K('<img class="ke-preview-img" src="' + path + startNum + '.gif" />');
  32 + wrapperDiv.append(previewDiv);
  33 + previewDiv.append(previewImg);
  34 + }
  35 + function bindCellEvent(cell, j, num) {
  36 + if (previewDiv) {
  37 + cell.mouseover(function() {
  38 + if (j > colsHalf) {
  39 + previewDiv.css('left', 0);
  40 + previewDiv.css('right', '');
  41 + } else {
  42 + previewDiv.css('left', '');
  43 + previewDiv.css('right', 0);
  44 + }
  45 + previewImg.attr('src', path + num + '.gif');
  46 + K(this).addClass('ke-on');
  47 + });
  48 + } else {
  49 + cell.mouseover(function() {
  50 + K(this).addClass('ke-on');
  51 + });
  52 + }
  53 + cell.mouseout(function() {
  54 + K(this).removeClass('ke-on');
  55 + });
  56 + cell.click(function(e) {
  57 + self.insertHtml('<img src="' + path + num + '.gif" border="0" alt="" />').hideMenu().focus();
  58 + e.stop();
  59 + });
  60 + }
  61 + function createEmoticonsTable(pageNum, parentDiv) {
  62 + var table = document.createElement('table');
  63 + parentDiv.append(table);
  64 + if (previewDiv) {
  65 + K(table).mouseover(function() {
  66 + previewDiv.show('block');
  67 + });
  68 + K(table).mouseout(function() {
  69 + previewDiv.hide();
  70 + });
  71 + elements.push(K(table));
  72 + }
  73 + table.className = 'ke-table';
  74 + table.cellPadding = 0;
  75 + table.cellSpacing = 0;
  76 + table.border = 0;
  77 + var num = (pageNum - 1) * cells + startNum;
  78 + for (var i = 0; i < rows; i++) {
  79 + var row = table.insertRow(i);
  80 + for (var j = 0; j < cols; j++) {
  81 + var cell = K(row.insertCell(j));
  82 + cell.addClass('ke-cell');
  83 + bindCellEvent(cell, j, num);
  84 + var span = K('<span class="ke-img"></span>')
  85 + .css('background-position', '-' + (24 * num) + 'px 0px')
  86 + .css('background-image', 'url(' + path + 'static.gif)');
  87 + cell.append(span);
  88 + elements.push(cell);
  89 + num++;
  90 + }
  91 + }
  92 + return table;
  93 + }
  94 + var table = createEmoticonsTable(currentPageNum, wrapperDiv);
  95 + function removeEvent() {
  96 + K.each(elements, function() {
  97 + this.unbind();
  98 + });
  99 + }
  100 + var pageDiv;
  101 + function bindPageEvent(el, pageNum) {
  102 + el.click(function(e) {
  103 + removeEvent();
  104 + table.parentNode.removeChild(table);
  105 + pageDiv.remove();
  106 + table = createEmoticonsTable(pageNum, wrapperDiv);
  107 + createPageTable(pageNum);
  108 + currentPageNum = pageNum;
  109 + e.stop();
  110 + });
  111 + }
  112 + function createPageTable(currentPageNum) {
  113 + pageDiv = K('<div class="ke-page"></div>');
  114 + wrapperDiv.append(pageDiv);
  115 + for (var pageNum = 1; pageNum <= pages; pageNum++) {
  116 + if (currentPageNum !== pageNum) {
  117 + var a = K('<a href="javascript:;">[' + pageNum + ']</a>');
  118 + bindPageEvent(a, pageNum);
  119 + pageDiv.append(a);
  120 + elements.push(a);
  121 + } else {
  122 + pageDiv.append(K('@[' + pageNum + ']'));
  123 + }
  124 + pageDiv.append(K('@&nbsp;'));
  125 + }
  126 + }
  127 + createPageTable(currentPageNum);
  128 + });
  129 +});