From 960a67884a84a6b7cc85a8a19c39371aaf603e86 Mon Sep 17 00:00:00 2001 From: thanatos Date: Thu, 9 Sep 2021 13:16:00 +0800 Subject: [PATCH 01/27] fix dao class commit & commit api doc 15.5 --- .gitignore | 2 + db/update15.5.sql | 0 framework/base/model.class.php | 2 +- framework/base/router.class.php | 2 +- lib/base/dao/dao.class.php | 92 ++++++++++++++++----------------- www/index.php | 1 + 6 files changed, 51 insertions(+), 48 deletions(-) create mode 100644 db/update15.5.sql diff --git a/.gitignore b/.gitignore index ad25ba4508..8f707427dc 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,7 @@ tmp/extension/* .gitignore .DS_Store vendor/ +docker +.docker-sync composer.lock diff --git a/db/update15.5.sql b/db/update15.5.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/framework/base/model.class.php b/framework/base/model.class.php index 0ce7ba892f..205418f893 100644 --- a/framework/base/model.class.php +++ b/framework/base/model.class.php @@ -63,7 +63,7 @@ class baseModel * $dao对象,用于访问或者更新数据库。 * The $dao object, used to access or update database. * - * @var object + * @var dao * @access public */ public $dao; diff --git a/framework/base/router.class.php b/framework/base/router.class.php index 998053506b..065305ab15 100644 --- a/framework/base/router.class.php +++ b/framework/base/router.class.php @@ -422,7 +422,7 @@ class baseRouter * @param string $className 应用类名,如果对router类做了扩展,需要指定类名。When extends router class, you should pass in the child router class name. * @static * @access public - * @return object the app object + * @return static the app object */ public static function createApp($appName = 'demo', $appRoot = '', $className = '') { diff --git a/lib/base/dao/dao.class.php b/lib/base/dao/dao.class.php index 6582467881..58ef1d5c5d 100644 --- a/lib/base/dao/dao.class.php +++ b/lib/base/dao/dao.class.php @@ -322,7 +322,7 @@ class baseDAO * * @param string $fields * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function select($fields = '*') { @@ -339,7 +339,7 @@ class baseDAO * * @param string $distinctField * @access public - * @return void + * @return int */ public function count($distinctField = '') { @@ -388,7 +388,7 @@ class baseDAO * * @param string $table * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function update($table) { @@ -404,7 +404,7 @@ class baseDAO * The delete method, call sql::delete(). * * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function delete() { @@ -420,7 +420,7 @@ class baseDAO * * @param string $table * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function insert($table) { @@ -437,7 +437,7 @@ class baseDAO * * @param string $table * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function replace($table) { @@ -454,7 +454,7 @@ class baseDAO * * @param string $table * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function from($table) { @@ -469,7 +469,7 @@ class baseDAO * * @param string $fields * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function fields($fields) { @@ -483,7 +483,7 @@ class baseDAO * * @param string $alias * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function alias($alias) { @@ -498,7 +498,7 @@ class baseDAO * * @param object $data the data object or array * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function data($data, $skipFields = '') { @@ -646,7 +646,7 @@ class baseDAO * * @param object $dbh * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function dbh($dbh) { @@ -707,7 +707,7 @@ class baseDAO * @param object $pager * @param string $distinctField * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function page($pager, $distinctField = '') { @@ -957,7 +957,7 @@ class baseDAO * @param string $funcName the function name to be called * @param array $funcArgs the params * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function __call($funcName, $funcArgs) { @@ -1034,7 +1034,7 @@ class baseDAO * @param string $funcName the check rule * @param string $condition the condition * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function check($fieldName, $funcName, $condition = '') { @@ -1115,7 +1115,7 @@ class baseDAO * @param string $fieldName * @param string $funcName * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function checkIF($condition, $fieldName, $funcName) { @@ -1136,7 +1136,7 @@ class baseDAO * @param string $fields the fields to check, join with , * @param string $funcName * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function batchCheck($fields, $funcName) { @@ -1158,7 +1158,7 @@ class baseDAO * @param string $fields * @param string $funcName * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function batchCheckIF($condition, $fields, $funcName) { @@ -1179,7 +1179,7 @@ class baseDAO * * @param string $skipFields fields to skip checking * @access public - * @return object the dao object self. + * @return static the dao object self. */ public function autoCheck($skipFields = '') { @@ -1607,7 +1607,7 @@ class baseSQL * * @param int $count * @access public - * @return object the sql object. + * @return static the sql object. */ public function markLeft($count = 1) { @@ -1623,7 +1623,7 @@ class baseSQL * * @param int $count * @access public - * @return object the sql object. + * @return static the sql object. */ public function markRight($count = 1) { @@ -1639,7 +1639,7 @@ class baseSQL * * @param string $set * @access public - * @return object the sql object. + * @return static the sql object. */ public function set($set) { @@ -1663,7 +1663,7 @@ class baseSQL * * @param string $table * @access public - * @return object the sql object. + * @return static the sql object. */ public function from($table) { @@ -1677,7 +1677,7 @@ class baseSQL * * @param string $alias * @access public - * @return object the sql object. + * @return static the sql object. */ public function alias($alias) { @@ -1691,7 +1691,7 @@ class baseSQL * * @param string $table * @access public - * @return object the sql object. + * @return static the sql object. */ public function leftJoin($table) { @@ -1705,7 +1705,7 @@ class baseSQL * * @param string $condition * @access public - * @return object the sql object. + * @return static the sql object. */ public function on($condition) { @@ -1719,7 +1719,7 @@ class baseSQL * * @param bool $condition * @access public - * @return object the sql object. + * @return static the sql object. */ public function beginIF($condition) { @@ -1733,7 +1733,7 @@ class baseSQL * End the condition judge. * * @access public - * @return object the sql object. + * @return static the sql object. */ public function fi() { @@ -1750,7 +1750,7 @@ class baseSQL * @param string $arg2 the operator * @param string $arg3 the value * @access public - * @return object the sql object. + * @return static the sql object. */ public function where($arg1, $arg2 = null, $arg3 = null) { @@ -1776,7 +1776,7 @@ class baseSQL * * @param string $condition * @access public - * @return object the sql object. + * @return static the sql object. */ public function andWhere($condition, $addMark = false) { @@ -1792,7 +1792,7 @@ class baseSQL * * @param bool $condition * @access public - * @return object the sql object. + * @return static the sql object. */ public function orWhere($condition) { @@ -1807,7 +1807,7 @@ class baseSQL * * @param string $value * @access public - * @return object the sql object. + * @return static the sql object. */ public function eq($value) { @@ -1822,7 +1822,7 @@ class baseSQL * * @param string $value * @access public - * @return void the sql object. + * @return static the sql object. */ public function ne($value) { @@ -1837,7 +1837,7 @@ class baseSQL * * @param string $value * @access public - * @return object the sql object. + * @return static the sql object. */ public function gt($value) { @@ -1852,7 +1852,7 @@ class baseSQL * * @param string $value * @access public - * @return object the sql object. + * @return static the sql object. */ public function ge($value) { @@ -1867,7 +1867,7 @@ class baseSQL * * @param mixed $value * @access public - * @return object the sql object. + * @return static the sql object. */ public function lt($value) { @@ -1882,7 +1882,7 @@ class baseSQL * * @param mixed $value * @access public - * @return object the sql object. + * @return static the sql object. */ public function le($value) { @@ -1898,7 +1898,7 @@ class baseSQL * @param string $min * @param string $max * @access public - * @return object the sql object. + * @return static the sql object. */ public function between($min, $max) { @@ -1915,7 +1915,7 @@ class baseSQL * * @param string|array $ids ','分割的字符串或者数组 list string by ',' or an array * @access public - * @return object the sql object. + * @return static the sql object. */ public function in($ids) { @@ -1930,7 +1930,7 @@ class baseSQL * * @param string|array $ids list string by ',' or an array * @access public - * @return object the sql object. + * @return static the sql object. */ public function notin($ids) { @@ -1945,7 +1945,7 @@ class baseSQL * * @param string $string * @access public - * @return object the sql object. + * @return static the sql object. */ public function like($string) { @@ -1960,7 +1960,7 @@ class baseSQL * * @param string $string * @access public - * @return object the sql object. + * @return static the sql object. */ public function notLike($string) { @@ -1975,7 +1975,7 @@ class baseSQL * * @param string $order * @access public - * @return object the sql object. + * @return static the sql object. */ public function orderBy($order) { @@ -2030,7 +2030,7 @@ class baseSQL * * @param string $limit * @access public - * @return object the sql object. + * @return static the sql object. */ public function limit($limit) { @@ -2054,7 +2054,7 @@ class baseSQL * * @param string $groupBy * @access public - * @return object the sql object. + * @return static the sql object. */ public function groupBy($groupBy) { @@ -2074,7 +2074,7 @@ class baseSQL * * @param string $having * @access public - * @return object the sql object. + * @return static the sql object. */ public function having($having) { @@ -2088,7 +2088,7 @@ class baseSQL * Get the sql string. * * @access public - * @return string + * @return static */ public function get() { diff --git a/www/index.php b/www/index.php index 040483f53f..2185236106 100644 --- a/www/index.php +++ b/www/index.php @@ -36,6 +36,7 @@ $app = router::createApp('pms', dirname(dirname(__FILE__)), 'router'); /* installed or not. */ if(!isset($config->installed) or !$config->installed) die(header('location: install.php')); + /* Run the app. */ $common = $app->loadCommon(); From cefac14189b319005737911e05598a02cd9cc800 Mon Sep 17 00:00:00 2001 From: thanatos Date: Thu, 9 Sep 2021 16:28:31 +0800 Subject: [PATCH 02/27] finish api doc table --- db/update15.5.sql | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/db/update15.5.sql b/db/update15.5.sql index e69de29bb2..8db7b80d23 100644 --- a/db/update15.5.sql +++ b/db/update15.5.sql @@ -0,0 +1,95 @@ +ALTER TABLE `zt_doclib` + ADD COLUMN `desc` text NULL AFTER `collector`; + +CREATE TABLE `zt_interfacelib_release` +( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `doclib` int UNSIGNED NOT NULL DEFAULT 0, + `version` varchar(255) NOT NULL DEFAULT '', + `snap` mediumtext NOT NULL, + `addedBy` varchar(30) NOT NULL DEFAULT 0, + `addedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) + +CREATE TABLE `zt_interface` +( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `product` varchar(255) NOT NULL DEFAULT '', + `lib` int UNSIGNED NOT NULL DEFAULT 0, + `module` int UNSIGNED NOT NULL DEFAULT 0, + `title` varchar(100) NOT NULL DEFAULT '', + `path` varchar(255) NOT NULL DEFAULT '', + `protocol` varchar(10) NOT NULL DEFAULT '', + `method` varchar(10) NOT NULL DEFAULT '', + `requestType` varchar(100) NOT NULL DEFAULT '', + `responseType` varchar(100) NOT NULL DEFAULT '', + `status` varchar(20) NOT NULL DEFAULT '', + `owner` int UNSIGNED NOT NULl DEFAULT 0, + `desc` varchar(255) NOT NULL DEFAULT '', + `version` smallint UNSIGNED NOT NULL DEFAULT 0, + `params` text NULL, + `commonParams` text NULL, + `addedBy` varchar(30) NOT NULL DEFAULT 0, + `addedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `editEdBy` varchar(30) NOT NULL DEFAULT 0, + `editedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `deleted` enum(0, 1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) +); + +CREATE TABLE `zt_interface_spec` +( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `doc` int UNSIGNED NOT NULL DEFAULT 0, + `module` int UNSIGNED NOT NULL DEFAULT 0, + `title` varchar(100) NOT NULL DEFAULT '', + `path` varchar(255) NOT NULL DEFAULT '', + `agreement` enum('http','https') NOT NULL, + `method` varchar(10) NOT NULL DEFAULT '', + `requestFormat` varchar(100) NOT NULL DEFAULT '', + `responseFormat` varchar(100) NOT NULL DEFAULT '', + `status` tinyint UNSIGNED NOT NULL DEFAULT 0, + `owner` int UNSIGNED NOT NULl DEFAULT 0, + `desc` varchar(255) NOT NULL DEFAULT '', + `version` smallint UNSIGNED NOT NULL DEFAULT 0, + `params` text NULL, + `addedBy` varchar(30) NOT NULL DEFAULT 0, + `addedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +); + +create table `zt_interface_const` +( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `doclib` int UNSIGNED NOT NULL DEFAULT 0, + `field` varchar(50) NOT NULL DEFAULT '', + `scope` varchar(50) NOT NULL DEFAULT '', + `type` varchar(20) NOT NULL DEFAULT '', + `default` varchar(1000) NOT NULL DEFAULT '', + `required` tinyint UNSIGNED NOT NULL DEFAULT 0, + `desc` varchar(255) NOT NULL DEFAULT 0, + `version` smallint UNSIGNED NOT NULL DEFAULT 0, + `addedBy` varchar(30) NOT NULL DEFAULT 0, + `addedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `editEdBy` varchar(30) NOT NULL DEFAULT 0, + `editedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `deletedDate` datetime NULL, + PRIMARY KEY (`id`) +) + +create table `zt_interface_const_spec` +( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `doclib` int UNSIGNED NOT NULL DEFAULT 0, + `field` varchar(50) NOT NULL DEFAULT '', + `scope` varchar(50) NOT NULL DEFAULT '', + `type` varchar(20) NOT NULL DEFAULT '', + `default` varchar(1000) NOT NULL DEFAULT '', + `required` tinyint UNSIGNED NOT NULL DEFAULT 0, + `desc` varchar(255) NOT NULL DEFAULT 0, + `version` smallint UNSIGNED NOT NULL DEFAULT 0, + `addedBy` varchar(30) NOT NULL DEFAULT 0, + `addedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) From 0d116021dbda76e600c7a8d51865f3012465f74d Mon Sep 17 00:00:00 2001 From: thanatos Date: Thu, 16 Sep 2021 16:10:49 +0800 Subject: [PATCH 03/27] finish api doc. first commit --- .editorconfig | 18 - config/filter.php | 219 +- config/zentaopms.php | 3 + db/update15.5.sql | 28 +- framework/base/control.class.php | 163 +- lib/base/dao/dao.class.php | 95 +- lib/base/filter/filter.class.php | 470 +- module/api/config.php | 17 + module/api/control.php | 435 +- module/api/css/common.css | 98 + module/api/css/create.css | 17 + module/api/css/createlib.css | 5 + module/api/css/edit.css | 17 + module/api/css/index.css | 124 + module/api/js/common.js | 163 + module/api/js/create.js | 80 + module/api/js/createlib.js | 13 + module/api/js/edit.js | 87 + module/api/js/index.js | 116 + module/api/lang/zh-cn.php | 132 +- module/api/model.php | 199 +- module/api/view/content.html.php | 145 + module/api/view/create.html.php | 220 + module/api/view/createlib.html.php | 81 + module/api/view/edit.html.php | 216 + module/api/view/index.html.php | 95 + module/common/lang/common.php | 1 + module/common/lang/menu.php | 132 +- module/common/lang/zh-cn.php | 60 +- module/common/lang/zh-tw.php | 1 + module/doc/control.php | 223 +- module/doc/model.php | 588 +- module/doc/view/tablecontents.html.php | 2 +- module/tree/control.php | 8 + module/tree/view/browse.html.php | 4 + www/js/zui/min.js | 7263 +++++++++++++++++++++++- 36 files changed, 10599 insertions(+), 939 deletions(-) delete mode 100644 .editorconfig create mode 100644 module/api/config.php create mode 100644 module/api/css/common.css create mode 100644 module/api/css/create.css create mode 100644 module/api/css/createlib.css create mode 100644 module/api/css/edit.css create mode 100644 module/api/css/index.css create mode 100644 module/api/js/common.js create mode 100644 module/api/js/create.js create mode 100644 module/api/js/createlib.js create mode 100644 module/api/js/edit.js create mode 100644 module/api/js/index.js create mode 100644 module/api/view/content.html.php create mode 100644 module/api/view/create.html.php create mode 100644 module/api/view/createlib.html.php create mode 100644 module/api/view/edit.html.php create mode 100644 module/api/view/index.html.php diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index aa0ecea19a..0000000000 --- a/.editorconfig +++ /dev/null @@ -1,18 +0,0 @@ -# EditorConfig is awesome: https://EditorConfig.org - -# top-most EditorConfig file -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 4 -trim_trailing_whitespace = true - -[*.md] -trim_trailing_whitespace = false - -[*.yml] -indent_size = 2 diff --git a/config/filter.php b/config/filter.php index 54198ff2d5..73c0b303ce 100644 --- a/config/filter.php +++ b/config/filter.php @@ -1,6 +1,6 @@ rules = new stdclass(); +$filter = new stdclass(); +$filter->rules = new stdclass(); $filter->rules->md5 = '/^[a-z0-9]{32}$/'; $filter->rules->base64 = '/^[a-zA-Z0-9\+\/\=]+$/'; $filter->rules->checked = '/^[0-9,\-]+$/'; @@ -13,13 +13,13 @@ $filter->rules->word = '/^\w+$/'; $filter->rules->paramName = '/^[a-zA-Z0-9_\.]+$/'; $filter->rules->paramValue = '/^[a-zA-Z0-9=_,`#+\^\/\.%\|\x7f-\xff\-]+$/'; -$filter->default = new stdclass(); +$filter->default = new stdclass(); $filter->default->moduleName = 'code'; $filter->default->methodName = 'code'; $filter->default->paramName = 'reg::paramName'; $filter->default->paramValue = 'reg::paramValue'; -$filter->default->get['onlybody'] = 'equal::yes'; +$filter->default->get['onlybody'] = 'equal::yes'; $filter->default->get['HTTP_X_REQUESTED_WITH'] = 'equal::XMLHttpRequest'; $filter->default->cookie['lang'] = 'reg::lang'; @@ -33,6 +33,7 @@ $filter->my = new stdclass(); $filter->bug = new stdclass(); $filter->caselib = new stdclass(); $filter->doc = new stdclass(); +$filter->api = new stdclass(); $filter->product = new stdclass(); $filter->branch = new stdclass(); $filter->qa = new stdclass(); @@ -63,87 +64,90 @@ $filter->gitlab = new stdclass(); $filter->mr = new stdclass(); $filter->ci = new stdclass(); -$filter->block->default = new stdclass(); -$filter->block->main = new stdclass(); -$filter->my->work = new stdclass(); -$filter->my->contribute = new stdclass(); -$filter->bug->batchcreate = new stdclass(); -$filter->bug->browse = new stdclass(); -$filter->bug->default = new stdclass(); -$filter->bug->create = new stdclass(); -$filter->bug->export = new stdclass(); -$filter->caselib->create = new stdclass(); -$filter->doc->create = new stdclass(); -$filter->doc->browse = new stdclass(); -$filter->doc->alllibs = new stdclass(); -$filter->doc->objectlibs = new stdclass(); -$filter->doc->showfiles = new stdclass(); -$filter->doc->default = new stdclass(); -$filter->mail->ztcloud = new stdclass(); -$filter->mail->batchdelete = new stdclass(); -$filter->misc->checkupdate = new stdclass(); -$filter->file->download = new stdclass(); -$filter->product->browse = new stdclass(); -$filter->product->default = new stdclass(); -$filter->product->index = new stdclass(); -$filter->product->export = new stdclass(); -$filter->product->project = new stdclass(); -$filter->branch->default = new stdclass(); -$filter->program->default = new stdclass(); -$filter->program->pgmproject = new stdclass(); -$filter->program->prjbrowse = new stdclass(); -$filter->program->project = new stdclass(); -$filter->program->browse = new stdclass(); -$filter->program->export = new stdclass(); -$filter->program->pgmbrowse = new stdclass(); -$filter->program->export = new stdclass(); -$filter->program->ajaxgetdropmenu = new stdclass(); -$filter->project->default = new stdclass(); -$filter->project->browse = new stdclass(); -$filter->project->story = new stdclass(); -$filter->project->export = new stdclass(); -$filter->project->task = new stdclass(); -$filter->projectstory->story = new stdclass(); -$filter->qa->default = new stdclass(); -$filter->story->create = new stdclass(); -$filter->story->export = new stdclass(); -$filter->story->batchcreate = new stdclass(); -$filter->sso->getbindusers = new stdclass(); -$filter->sso->gettodolist = new stdclass(); -$filter->sso->getuserpairs = new stdclass(); -$filter->sso->login = new stdclass(); -$filter->sso->logout = new stdclass(); -$filter->git->cat = new stdclass(); -$filter->git->diff = new stdclass(); -$filter->svn->cat = new stdclass(); -$filter->svn->diff = new stdclass(); -$filter->task->create = new stdclass(); -$filter->task->export = new stdclass(); -$filter->execution->story = new stdclass(); -$filter->testcase->default = new stdclass(); -$filter->testcase->create = new stdclass(); -$filter->testcase->browse = new stdclass(); -$filter->testcase->export = new stdclass(); -$filter->testcase->groupcase = new stdclass(); -$filter->testreport->default = new stdclass(); -$filter->testsuite->default = new stdclass(); -$filter->testsuite->library = new stdclass(); -$filter->testtask->default = new stdclass(); -$filter->testtask->browse = new stdclass(); -$filter->testtask->cases = new stdclass(); -$filter->todo->export = new stdclass(); -$filter->upgrade->license = new stdclass(); -$filter->user->login = new stdclass(); -$filter->user->edit = new stdclass(); -$filter->webhook->bind = new stdclass(); -$filter->user->ajaxgetmore = new stdclass(); -$filter->repo->ajaxsynccommit = new stdclass(); -$filter->search->index = new stdclass(); -$filter->gitlab->webhook = new stdclass(); -$filter->gitlab->importissue = new stdclass(); -$filter->mr->diff = new stdclass(); -$filter->ci->checkCompileStatus = new stdclass(); -$filter->execution->export = new stdclass(); +$filter->block->default = new stdclass(); +$filter->block->main = new stdclass(); +$filter->my->work = new stdclass(); +$filter->my->contribute = new stdclass(); +$filter->bug->batchcreate = new stdclass(); +$filter->bug->browse = new stdclass(); +$filter->bug->default = new stdclass(); +$filter->bug->create = new stdclass(); +$filter->bug->export = new stdclass(); +$filter->caselib->create = new stdclass(); +$filter->doc->create = new stdclass(); +$filter->doc->browse = new stdclass(); +$filter->doc->alllibs = new stdclass(); +$filter->doc->objectlibs = new stdclass(); +$filter->doc->showfiles = new stdclass(); +$filter->doc->default = new stdclass(); +$filter->api->index = new stdClass(); +$filter->api->create = new stdClass(); +$filter->api->edit = new stdClass(); +$filter->mail->ztcloud = new stdclass(); +$filter->mail->batchdelete = new stdclass(); +$filter->misc->checkupdate = new stdclass(); +$filter->file->download = new stdclass(); +$filter->product->browse = new stdclass(); +$filter->product->default = new stdclass(); +$filter->product->index = new stdclass(); +$filter->product->export = new stdclass(); +$filter->product->project = new stdclass(); +$filter->branch->default = new stdclass(); +$filter->program->default = new stdclass(); +$filter->program->pgmproject = new stdclass(); +$filter->program->prjbrowse = new stdclass(); +$filter->program->project = new stdclass(); +$filter->program->browse = new stdclass(); +$filter->program->export = new stdclass(); +$filter->program->pgmbrowse = new stdclass(); +$filter->program->export = new stdclass(); +$filter->program->ajaxgetdropmenu = new stdclass(); +$filter->project->default = new stdclass(); +$filter->project->browse = new stdclass(); +$filter->project->story = new stdclass(); +$filter->project->export = new stdclass(); +$filter->project->task = new stdclass(); +$filter->projectstory->story = new stdclass(); +$filter->qa->default = new stdclass(); +$filter->story->create = new stdclass(); +$filter->story->export = new stdclass(); +$filter->story->batchcreate = new stdclass(); +$filter->sso->getbindusers = new stdclass(); +$filter->sso->gettodolist = new stdclass(); +$filter->sso->getuserpairs = new stdclass(); +$filter->sso->login = new stdclass(); +$filter->sso->logout = new stdclass(); +$filter->git->cat = new stdclass(); +$filter->git->diff = new stdclass(); +$filter->svn->cat = new stdclass(); +$filter->svn->diff = new stdclass(); +$filter->task->create = new stdclass(); +$filter->task->export = new stdclass(); +$filter->execution->story = new stdclass(); +$filter->testcase->default = new stdclass(); +$filter->testcase->create = new stdclass(); +$filter->testcase->browse = new stdclass(); +$filter->testcase->export = new stdclass(); +$filter->testcase->groupcase = new stdclass(); +$filter->testreport->default = new stdclass(); +$filter->testsuite->default = new stdclass(); +$filter->testsuite->library = new stdclass(); +$filter->testtask->default = new stdclass(); +$filter->testtask->browse = new stdclass(); +$filter->testtask->cases = new stdclass(); +$filter->todo->export = new stdclass(); +$filter->upgrade->license = new stdclass(); +$filter->user->login = new stdclass(); +$filter->user->edit = new stdclass(); +$filter->webhook->bind = new stdclass(); +$filter->user->ajaxgetmore = new stdclass(); +$filter->repo->ajaxsynccommit = new stdclass(); +$filter->search->index = new stdclass(); +$filter->gitlab->webhook = new stdclass(); +$filter->gitlab->importissue = new stdclass(); +$filter->mr->diff = new stdclass(); +$filter->ci->checkCompileStatus = new stdclass(); +$filter->execution->export = new stdclass(); $filter->my->work->cookie['pagerMyTask'] = 'int'; $filter->my->work->cookie['pagerMyRequirement'] = 'int'; @@ -173,7 +177,7 @@ $filter->bug->create->cookie['preBranch'] = 'int'; $filter->bug->create->cookie['lastBugModule'] = 'int'; $filter->bug->export->cookie['checkedItem'] = 'reg::checked'; -$filter->caselib->create->cookie['lastLibCaseModule'] = 'int'; +$filter->caselib->create->cookie['lastLibCaseModule'] = 'int'; $filter->doc->create->cookie['lastDocModule'] = 'int'; $filter->doc->browse->cookie['browseType'] = 'reg::browseType'; @@ -182,6 +186,17 @@ $filter->doc->objectlibs->cookie['browseType'] = 'reg::browseType'; $filter->doc->default->cookie['from'] = 'code'; $filter->doc->default->cookie['product'] = 'int'; $filter->doc->showfiles->cookie['docFilesViewType'] = 'code'; +$filter->api->index->get['libID'] = 'int'; +$filter->api->index->get['module'] = 'int'; +$filter->api->index->get['apiID'] = 'int'; +$filter->api->index->get['version'] = 'int'; +$filter->api->create->get['libID'] = 'int'; +$filter->api->create->get['module'] = 'int'; +$filter->api->create->get['apiID'] = 'int'; +$filter->api->edit->get['libID'] = 'int'; +$filter->api->edit->get['module'] = 'int'; +$filter->api->edit->get['apiID'] = 'int'; + $filter->file->download->cookie[$config->sessionVar] = 'code'; @@ -209,22 +224,22 @@ $filter->program->browse->cookie['showClosed'] = 'code'; $filter->program->export->cookie['checkedItem'] = 'reg::checked'; $filter->program->ajaxgetdropmenu->cookie['showClosed'] = 'code'; -$filter->project->default->cookie['lastProject'] = 'int'; -$filter->project->default->cookie['lastPRJ'] = 'int'; -$filter->project->default->cookie['projectMode'] = 'code'; -$filter->project->browse->cookie['involved'] = 'code'; -$filter->project->browse->cookie['projectType'] = 'code'; -$filter->project->story->cookie['storyModuleParam'] = 'int'; -$filter->project->story->cookie['storyPreProjectID'] = 'int'; -$filter->project->story->cookie['storyProductParam'] = 'int'; -$filter->project->story->cookie['storyBranchParam'] = 'reg::checked'; -$filter->project->story->cookie['projectStoryOrder'] = 'reg::orderBy'; -$filter->project->task->cookie['moduleBrowseParam'] = 'int'; -$filter->project->task->cookie['preProjectID'] = 'int'; -$filter->project->task->cookie['productBrowseParam'] = 'int'; -$filter->project->task->cookie['projectTaskOrder'] = 'reg::orderBy'; -$filter->project->task->cookie['windowWidth'] = 'int'; -$filter->project->export->cookie['checkedItem'] = 'reg::checked'; +$filter->project->default->cookie['lastProject'] = 'int'; +$filter->project->default->cookie['lastPRJ'] = 'int'; +$filter->project->default->cookie['projectMode'] = 'code'; +$filter->project->browse->cookie['involved'] = 'code'; +$filter->project->browse->cookie['projectType'] = 'code'; +$filter->project->story->cookie['storyModuleParam'] = 'int'; +$filter->project->story->cookie['storyPreProjectID'] = 'int'; +$filter->project->story->cookie['storyProductParam'] = 'int'; +$filter->project->story->cookie['storyBranchParam'] = 'reg::checked'; +$filter->project->story->cookie['projectStoryOrder'] = 'reg::orderBy'; +$filter->project->task->cookie['moduleBrowseParam'] = 'int'; +$filter->project->task->cookie['preProjectID'] = 'int'; +$filter->project->task->cookie['productBrowseParam'] = 'int'; +$filter->project->task->cookie['projectTaskOrder'] = 'reg::orderBy'; +$filter->project->task->cookie['windowWidth'] = 'int'; +$filter->project->export->cookie['checkedItem'] = 'reg::checked'; $filter->projectstory->story->cookie['storyModuleParam'] = 'int'; $filter->projectstory->story->cookie['pagerProductBrowse'] = 'int'; diff --git a/config/zentaopms.php b/config/zentaopms.php index 57f78af9c1..0da887595d 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -193,6 +193,9 @@ define('TABLE_ACL', '`' . $config->db->prefix . 'acl`'); define('TABLE_DOCLIB', '`' . $config->db->prefix . 'doclib`'); define('TABLE_DOC', '`' . $config->db->prefix . 'doc`'); +define('TABLE_API', '`' . $config->db->prefix . 'api`'); +define('TABLE_API_SPEC', '`' . $config->db->prefix . 'apispec`'); + define('TABLE_MODULE', '`' . $config->db->prefix . 'module`'); define('TABLE_ACTION', '`' . $config->db->prefix . 'action`'); diff --git a/db/update15.5.sql b/db/update15.5.sql index 8db7b80d23..ae9e11ef01 100644 --- a/db/update15.5.sql +++ b/db/update15.5.sql @@ -1,7 +1,7 @@ ALTER TABLE `zt_doclib` ADD COLUMN `desc` text NULL AFTER `collector`; -CREATE TABLE `zt_interfacelib_release` +CREATE TABLE `zt_api_lib_release` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT, `doclib` int UNSIGNED NOT NULL DEFAULT 0, @@ -12,7 +12,7 @@ CREATE TABLE `zt_interfacelib_release` PRIMARY KEY (`id`) ) -CREATE TABLE `zt_interface` +CREATE TABLE `zt_api` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT, `product` varchar(255) NOT NULL DEFAULT '', @@ -29,37 +29,39 @@ CREATE TABLE `zt_interface` `desc` varchar(255) NOT NULL DEFAULT '', `version` smallint UNSIGNED NOT NULL DEFAULT 0, `params` text NULL, + `response` text NULL, `commonParams` text NULL, `addedBy` varchar(30) NOT NULL DEFAULT 0, - `addedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `addedDate` datetime NOT NULL, `editEdBy` varchar(30) NOT NULL DEFAULT 0, - `editedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `deleted` enum(0, 1) NOT NULL DEFAULT 0, + `editedDate` datetime NOT NULL, + `deleted` enum('0', '1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ); -CREATE TABLE `zt_interface_spec` +CREATE TABLE `zt_apispec` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT, `doc` int UNSIGNED NOT NULL DEFAULT 0, `module` int UNSIGNED NOT NULL DEFAULT 0, `title` varchar(100) NOT NULL DEFAULT '', `path` varchar(255) NOT NULL DEFAULT '', - `agreement` enum('http','https') NOT NULL, + `protocol` varchar(10) NOT NULL DEFAULT '', `method` varchar(10) NOT NULL DEFAULT '', - `requestFormat` varchar(100) NOT NULL DEFAULT '', - `responseFormat` varchar(100) NOT NULL DEFAULT '', + `requestType` varchar(100) NOT NULL DEFAULT '', + `responseType` varchar(100) NOT NULL DEFAULT '', `status` tinyint UNSIGNED NOT NULL DEFAULT 0, - `owner` int UNSIGNED NOT NULl DEFAULT 0, + `owner` varchar(255) NOT NULl DEFAULT 0, `desc` varchar(255) NOT NULL DEFAULT '', `version` smallint UNSIGNED NOT NULL DEFAULT 0, `params` text NULL, + `response` text NULL, `addedBy` varchar(30) NOT NULL DEFAULT 0, - `addedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `addedDate` datetime NULL, PRIMARY KEY (`id`) ); -create table `zt_interface_const` +create table `zt_api_const` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT, `doclib` int UNSIGNED NOT NULL DEFAULT 0, @@ -78,7 +80,7 @@ create table `zt_interface_const` PRIMARY KEY (`id`) ) -create table `zt_interface_const_spec` +create table `zt_api_const_spec` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT, `doclib` int UNSIGNED NOT NULL DEFAULT 0, diff --git a/framework/base/control.class.php b/framework/base/control.class.php index 086d748364..94733c2f3b 100644 --- a/framework/base/control.class.php +++ b/framework/base/control.class.php @@ -1,4 +1,5 @@ view = new stdclass(); - $this->view->app = $app; - $this->view->lang = $lang; - $this->view->config = $config; - $this->view->common = $common; - $this->view->title = ''; + $this->view = new stdclass(); + $this->view->app = $app; + $this->view->lang = $lang; + $this->view->config = $config; + $this->view->common = $common; + $this->view->title = ''; /** * 设置超级变量,从$app引用过来。 @@ -252,7 +253,7 @@ class baseControl * 设置方法名。 * Set the method name. * - * @param string $methodName 方法名,如果为空,则从$app中获取。The method name, if empty, get it from $app. + * @param string $methodName 方法名,如果为空,则从$app中获取。The method name, if empty, get it from $app. * @access public * @return void */ @@ -265,21 +266,21 @@ class baseControl * 加载指定模块的model文件。 * Load the model file of one module. * - * @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name. - * @param string $appName The app name, if empty, use current app's name. + * @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name. + * @param string $appName The app name, if empty, use current app's name. * @access public * @return object|bool 如果没有model文件,返回false,否则返回model对象。If no model file, return false, else return the model object. */ public function loadModel($moduleName = '', $appName = '') { if(empty($moduleName)) $moduleName = $this->moduleName; - if(empty($appName)) $appName = $this->appName; + if(empty($appName)) $appName = $this->appName; global $loadedModels; if(isset($loadedModels[$appName][$moduleName])) { $this->$moduleName = $loadedModels[$appName][$moduleName]; - $this->dao = $this->$moduleName->dao; + $this->dao = $this->$moduleName->dao; return $this->$moduleName; } @@ -301,10 +302,10 @@ class baseControl * 如果没有扩展文件,model类名是$moduleName + 'model',如果有扩展,还需要增加ext前缀。 * If no extension file, model class name is $moduleName + 'model', else with 'ext' as the prefix. */ - $modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model'; + $modelClass = class_exists('ext' . $appName . $moduleName . 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model'; if(!class_exists($modelClass)) { - $modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model'; + $modelClass = class_exists('ext' . $moduleName . 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model'; if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true); } @@ -313,8 +314,8 @@ class baseControl * Init the model object thus you can try $this->$moduleName to access it. Also assign the $dao object as a member of control object. */ $loadedModels[$appName][$moduleName] = new $modelClass($appName); - $this->$moduleName = $loadedModels[$appName][$moduleName]; - $this->dao = $this->$moduleName->dao; + $this->$moduleName = $loadedModels[$appName][$moduleName]; + $this->dao = $this->$moduleName->dao; return $this->$moduleName; } @@ -364,8 +365,8 @@ class baseControl * 设置视图文件:主视图文件,扩展视图文件, 站点扩展视图文件,以及钩子脚本。 * Set view files: the main file, extension view file, site extension view file and hook files. * - * @param string $moduleName module name - * @param string $methodName method name + * @param string $moduleName module name + * @param string $methodName method name * @access public * @return string the view file */ @@ -392,7 +393,7 @@ class baseControl $commonExtHookFiles = glob($viewExtPath['common'] . $this->devicePrefix . $methodName . ".*.{$viewType}.hook.php"); $siteExtHookFiles = empty($viewExtPath['site']) ? '' : glob($viewExtPath['site'] . $this->devicePrefix . $methodName . ".*.{$viewType}.hook.php"); - $extHookFiles = array_merge((array) $commonExtHookFiles, (array) $siteExtHookFiles); + $extHookFiles = array_merge((array)$commonExtHookFiles, (array)$siteExtHookFiles); } if(!empty($extHookFiles)) return array('viewFile' => $viewFile, 'hookFiles' => $extHookFiles); @@ -403,7 +404,7 @@ class baseControl * 获取某一个视图文件的扩展。 * Get the extension file of an view. * - * @param string $viewFile + * @param string $viewFile * @access public * @return string|bool If extension view file exists, return the path. Else return fasle. */ @@ -425,7 +426,7 @@ class baseControl } } - $extPath = dirname(dirname(realpath($viewFile))) . '/ext/view/'; + $extPath = dirname(dirname(realpath($viewFile))) . '/ext/view/'; $extViewFile = $extPath . basename($viewFile); if(file_exists($extViewFile)) { @@ -439,8 +440,8 @@ class baseControl * 获取适用于当前方法的css:该模块公用的css + 当前方法的css + 扩展的css。 * Get css codes applied to current method: module common css + method css + extension css. * - * @param string $moduleName - * @param string $methodName + * @param string $moduleName + * @param string $methodName * @access public * @return string */ @@ -450,7 +451,7 @@ class baseControl $methodName = strtolower(trim($methodName)); $modulePath = $this->app->getModulePath($this->appName, $moduleName); - $cssExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'css') ; + $cssExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'css'); $clientLang = $this->app->getClientLang(); $notCNLang = strpos('|zh-cn|zh-tw|', "|{$clientLang}|") === false; @@ -492,7 +493,7 @@ class baseControl { $cssMethodExt = $cssExtPath['site'] . $methodName . DS; $cssCommonExt = $cssExtPath['site'] . 'common' . DS; - $cssExtFiles = glob($cssCommonExt . $devicePrefix . '*.css'); + $cssExtFiles = glob($cssCommonExt . $devicePrefix . '*.css'); if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); $cssExtFiles = glob($cssMethodExt . $devicePrefix . '*.css'); @@ -506,7 +507,7 @@ class baseControl /** * Get extension css and extension css with lang. * - * @param array $files + * @param array $files * @access public * @return string */ @@ -518,7 +519,7 @@ class baseControl $filePairs = array(); foreach($files as $cssFile) { - $fileName = basename($cssFile); + $fileName = basename($cssFile); $filePairs[$fileName] = $cssFile; } @@ -558,24 +559,24 @@ class baseControl * 获取适用于当前方法的js:该模块公用的js + 当前方法的js + 扩展的js。 * Get js codes applied to current method: module common js + method js + extension js. * - * @param string $moduleName - * @param string $methodName + * @param string $moduleName + * @param string $methodName * @access public * @return string */ public function getJS($moduleName, $methodName) { - $moduleName = strtolower(trim($moduleName)); - $methodName = strtolower(trim($methodName)); + $moduleName = strtolower(trim($moduleName)); + $methodName = strtolower(trim($methodName)); - $modulePath = $this->app->getModulePath($this->appName, $moduleName); - $jsExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'js'); + $modulePath = $this->app->getModulePath($this->appName, $moduleName); + $jsExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'js'); - $js = ''; + $js = ''; $mainJsFile = $modulePath . 'js' . DS . $this->devicePrefix . 'common.js'; $methodJsFile = $modulePath . 'js' . DS . $this->devicePrefix . $methodName . '.js'; - if(file_exists($mainJsFile)) $js .= file_get_contents($mainJsFile); - if(is_file($methodJsFile)) $js .= file_get_contents($methodJsFile); + if(file_exists($mainJsFile)) $js .= file_get_contents($mainJsFile); + if(is_file($methodJsFile)) $js .= file_get_contents($methodJsFile); if(!empty($jsExtPath)) { @@ -608,8 +609,8 @@ class baseControl * 向$view传递一个变量。 * Assign one var to the view vars. * - * @param string $name the name. - * @param mixed $value the value. + * @param string $name the name. + * @param mixed $value the value. * @access public * @return void */ @@ -634,8 +635,8 @@ class baseControl * 渲染视图文件。 * Parse view file. * - * @param string $moduleName module name, if empty, use current module. - * @param string $methodName method name, if empty, use current method. + * @param string $moduleName module name, if empty, use current module. + * @param string $methodName method name, if empty, use current method. * @access public * @return string the parsed result. */ @@ -654,8 +655,8 @@ class baseControl * 渲染json格式。 * Parse json format. * - * @param string $moduleName module name - * @param string $methodName method name + * @param string $moduleName module name + * @param string $methodName method name * @access public * @return void */ @@ -682,8 +683,8 @@ class baseControl * 默认渲染方法,适用于viewType = html的时候。 * Default parse method when viewType != json, like html. * - * @param string $moduleName module name - * @param string $methodName method name + * @param string $moduleName module name + * @param string $methodName method name * @access public * @return void */ @@ -704,7 +705,7 @@ class baseControl $css = $this->getCSS($moduleName, $methodName); $js = $this->getJS($moduleName, $methodName); if($css) $this->view->pageCSS = $css; - if($js) $this->view->pageJS = $js; + if($js) $this->view->pageJS = $js; /** * 切换到视图文件所在的目录,以保证视图文件里面的include语句能够正常运行。 @@ -738,9 +739,9 @@ class baseControl * Get the output of one module's one method as a string, thus in one module's method, can fetch other module's content. * If the module name is empty, then use the current module and method. If set, use the user defined module and method. * - * @param string $moduleName module name. - * @param string $methodName method name. - * @param array $params params. + * @param string $moduleName module name. + * @param string $methodName method name. + * @param array $params params. * @access public * @return string the parsed html. */ @@ -752,7 +753,7 @@ class baseControl */ if($moduleName == '') $moduleName = $this->moduleName; if($methodName == '') $methodName = $this->methodName; - if($appName == '') $appName = $this->appName; + if($appName == '') $appName = $this->appName; if($moduleName == $this->moduleName and $methodName == $this->methodName) { $this->parse($moduleName, $methodName); @@ -831,7 +832,7 @@ class baseControl * 解析参数,创建模块control对象。 * Parse the params, create the $module control object. */ - $module = new $className($moduleName, $methodName, $appName); + $module = new $className($moduleName, $methodName, $appName); $module->viewType = $this->viewType; /** @@ -866,8 +867,8 @@ class baseControl * 向浏览器输出内容。 * Print the content of the view. * - * @param string $moduleName module name - * @param string $methodName method name + * @param string $moduleName module name + * @param string $methodName method name * @access public * @return void */ @@ -881,8 +882,8 @@ class baseControl * 直接输出data数据,通常用于ajax请求中。 * Send data directly, for ajax requests. * - * @param misc $data - * @param string $type + * @param mixed $data + * @param string $type * @access public * @return void */ @@ -890,7 +891,7 @@ class baseControl { if($type != 'json') die(); - $data = (array) $data; + $data = (array)$data; if(helper::isAjaxRequest() or $this->viewType == 'json') { /* Process for zh-cn in json. */ @@ -928,21 +929,47 @@ class baseControl { $message = json_decode(json_encode((array)$data['message'])); foreach((array)$message as $item => $errors) $message->$item = implode(',', $errors); - die(js::alert(strip_tags(implode('\n', (array) $message)))); + die(js::alert(strip_tags(implode('\n', (array)$message)))); } die('fail'); } } + /** + * return error json + * @param mixed $error + * @author thanatos thanatos915@163.com + */ + public function sendError($error) + { + $this->send([ + 'result' => 'fail', + 'message' => $error, + ]); + } + + /** + * send success json + * + * @param array $data + * @author thanatos thanatos915@163.com + */ + public function sendSuccess($data) + { + $data['result'] = 'success'; + if(empty($data['message'])) $data['message'] = $this->lang->saveSuccess; + $this->send($data); + } + /** * 创建一个模块方法的链接。 * Create a link to one method of one module. * - * @param string $moduleName module name - * @param string $methodName method name - * @param string|array $vars the params passed, can be array(key=>value) or key1=value1&key2=value2 - * @param string $viewType the view type - * @param string $onlybody remove header and footer or not in iframe + * @param string $moduleName module name + * @param string $methodName method name + * @param string|array $vars the params passed, can be array(key=>value) or key1=value1&key2=value2 + * @param string $viewType the view type + * @param string $onlybody remove header and footer or not in iframe * @access public * @return string the link string. */ @@ -956,9 +983,9 @@ class baseControl * 创建当前模块的一个方法链接。 * Create a link to the inner method of current module. * - * @param string $methodName method name - * @param string|array $vars the params passed, can be array(key=>value) or key1=value1&key2=value2 - * @param string $viewType the view type + * @param string $methodName method name + * @param string|array $vars the params passed, can be array(key=>value) or key1=value1&key2=value2 + * @param string $viewType the view type * @access public * @return string the link string. */ @@ -971,7 +998,7 @@ class baseControl * 重定向到另一个页面。 * Location to another page. * - * @param string $url the target url. + * @param string $url the target url. * @access public * @return void */ diff --git a/lib/base/dao/dao.class.php b/lib/base/dao/dao.class.php index 58ef1d5c5d..d6bb835790 100644 --- a/lib/base/dao/dao.class.php +++ b/lib/base/dao/dao.class.php @@ -322,7 +322,7 @@ class baseDAO * * @param string $fields * @access public - * @return static the dao object self. + * @return static|sql|baseDAO the dao object self. */ public function select($fields = '*') { @@ -388,7 +388,7 @@ class baseDAO * * @param string $table * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function update($table) { @@ -404,7 +404,7 @@ class baseDAO * The delete method, call sql::delete(). * * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function delete() { @@ -420,7 +420,7 @@ class baseDAO * * @param string $table * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function insert($table) { @@ -437,7 +437,7 @@ class baseDAO * * @param string $table * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function replace($table) { @@ -454,7 +454,7 @@ class baseDAO * * @param string $table * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function from($table) { @@ -469,7 +469,7 @@ class baseDAO * * @param string $fields * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function fields($fields) { @@ -483,7 +483,7 @@ class baseDAO * * @param string $alias * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function alias($alias) { @@ -498,7 +498,7 @@ class baseDAO * * @param object $data the data object or array * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function data($data, $skipFields = '') { @@ -646,7 +646,7 @@ class baseDAO * * @param object $dbh * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function dbh($dbh) { @@ -659,7 +659,7 @@ class baseDAO * Query the sql, return the statement object. * * @access public - * @return object the PDOStatement object. + * @return static|sql the PDOStatement object. */ public function query($sql = '') { @@ -707,7 +707,7 @@ class baseDAO * @param object $pager * @param string $distinctField * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function page($pager, $distinctField = '') { @@ -957,7 +957,7 @@ class baseDAO * @param string $funcName the function name to be called * @param array $funcArgs the params * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function __call($funcName, $funcArgs) { @@ -1034,7 +1034,7 @@ class baseDAO * @param string $funcName the check rule * @param string $condition the condition * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function check($fieldName, $funcName, $condition = '') { @@ -1115,7 +1115,7 @@ class baseDAO * @param string $fieldName * @param string $funcName * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function checkIF($condition, $fieldName, $funcName) { @@ -1136,7 +1136,7 @@ class baseDAO * @param string $fields the fields to check, join with , * @param string $funcName * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function batchCheck($fields, $funcName) { @@ -1158,7 +1158,7 @@ class baseDAO * @param string $fields * @param string $funcName * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function batchCheckIF($condition, $fields, $funcName) { @@ -1179,7 +1179,7 @@ class baseDAO * * @param string $skipFields fields to skip checking * @access public - * @return static the dao object self. + * @return static|sql the dao object self. */ public function autoCheck($skipFields = '') { @@ -1607,7 +1607,7 @@ class baseSQL * * @param int $count * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function markLeft($count = 1) { @@ -1623,7 +1623,7 @@ class baseSQL * * @param int $count * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function markRight($count = 1) { @@ -1639,7 +1639,7 @@ class baseSQL * * @param string $set * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function set($set) { @@ -1663,7 +1663,7 @@ class baseSQL * * @param string $table * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function from($table) { @@ -1677,10 +1677,11 @@ class baseSQL * * @param string $alias * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function alias($alias) { + if($this->inCondition and !$this->conditionIsTrue) return $this; $this->sql .= " AS $alias "; return $this; } @@ -1691,10 +1692,11 @@ class baseSQL * * @param string $table * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function leftJoin($table) { + if($this->inCondition and !$this->conditionIsTrue) return $this; $this->sql .= " LEFT JOIN $table"; return $this; } @@ -1705,10 +1707,11 @@ class baseSQL * * @param string $condition * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function on($condition) { + if($this->inCondition and !$this->conditionIsTrue) return $this; $this->sql .= " ON $condition "; return $this; } @@ -1719,7 +1722,7 @@ class baseSQL * * @param bool $condition * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function beginIF($condition) { @@ -1733,7 +1736,7 @@ class baseSQL * End the condition judge. * * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function fi() { @@ -1750,7 +1753,7 @@ class baseSQL * @param string $arg2 the operator * @param string $arg3 the value * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function where($arg1, $arg2 = null, $arg3 = null) { @@ -1776,7 +1779,7 @@ class baseSQL * * @param string $condition * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function andWhere($condition, $addMark = false) { @@ -1792,7 +1795,7 @@ class baseSQL * * @param bool $condition * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function orWhere($condition) { @@ -1807,7 +1810,7 @@ class baseSQL * * @param string $value * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function eq($value) { @@ -1822,7 +1825,7 @@ class baseSQL * * @param string $value * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function ne($value) { @@ -1837,7 +1840,7 @@ class baseSQL * * @param string $value * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function gt($value) { @@ -1852,7 +1855,7 @@ class baseSQL * * @param string $value * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function ge($value) { @@ -1867,7 +1870,7 @@ class baseSQL * * @param mixed $value * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function lt($value) { @@ -1882,7 +1885,7 @@ class baseSQL * * @param mixed $value * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function le($value) { @@ -1898,7 +1901,7 @@ class baseSQL * @param string $min * @param string $max * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function between($min, $max) { @@ -1915,7 +1918,7 @@ class baseSQL * * @param string|array $ids ','分割的字符串或者数组 list string by ',' or an array * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function in($ids) { @@ -1930,7 +1933,7 @@ class baseSQL * * @param string|array $ids list string by ',' or an array * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function notin($ids) { @@ -1945,7 +1948,7 @@ class baseSQL * * @param string $string * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function like($string) { @@ -1960,7 +1963,7 @@ class baseSQL * * @param string $string * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function notLike($string) { @@ -1975,7 +1978,7 @@ class baseSQL * * @param string $order * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function orderBy($order) { @@ -2030,7 +2033,7 @@ class baseSQL * * @param string $limit * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function limit($limit) { @@ -2054,7 +2057,7 @@ class baseSQL * * @param string $groupBy * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function groupBy($groupBy) { @@ -2074,7 +2077,7 @@ class baseSQL * * @param string $having * @access public - * @return static the sql object. + * @return static|sql the sql object. */ public function having($having) { @@ -2088,7 +2091,7 @@ class baseSQL * Get the sql string. * * @access public - * @return static + * @return static|sql */ public function get() { diff --git a/lib/base/filter/filter.class.php b/lib/base/filter/filter.class.php index 5b4c324851..189297c2c3 100644 --- a/lib/base/filter/filter.class.php +++ b/lib/base/filter/filter.class.php @@ -5,7 +5,7 @@ * * The author disclaims copyright to this source code. In place of * a legal notice, here is a blessing: - * + * * May you do good and not evil. * May you find forgiveness for yourself and forgive others. * May you share freely, never taking more than you give. @@ -14,7 +14,7 @@ /** * validater类,检查数据是否符合规则。 * The validater class, checking data by rules. - * + * * @package framework */ class baseValidater @@ -28,8 +28,8 @@ class baseValidater /** * 是否是Bool类型。 * Bool checking. - * - * @param bool $var + * + * @param bool $var * @static * @access public * @return bool @@ -42,8 +42,8 @@ class baseValidater /** * 是否是Int类型。 * Int checking. - * - * @param int $var + * + * @param int $var * @static * @access public * @return bool @@ -77,9 +77,9 @@ class baseValidater /** * 检查不是Int类型。 - * Not int checking. - * - * @param int $var + * Not int checking. + * + * @param int $var * @static * @access public * @return bool @@ -92,9 +92,9 @@ class baseValidater /** * 检查Float类型。 * Float checking. - * - * @param float $var - * @param string $decimal + * + * @param float $var + * @param string $decimal * @static * @access public * @return bool @@ -107,8 +107,8 @@ class baseValidater /** * 检查Email。 * Email checking. - * - * @param string $var + * + * @param string $var * @static * @access public * @return bool @@ -121,8 +121,8 @@ class baseValidater /** * 检查电话或手机号码 * Check phone number. - * - * @param string $var + * + * @param string $var * @static * @access public * @return void @@ -135,8 +135,8 @@ class baseValidater /** * 检查电话号码 * Check tel number. - * - * @param int $var + * + * @param int $var * @static * @access public * @return void @@ -149,8 +149,8 @@ class baseValidater /** * 检查手机号码 * Check mobile number. - * - * @param string $var + * + * @param string $var * @static * @access public * @return void @@ -164,10 +164,10 @@ class baseValidater * 检查网址。 * 该规则不支持中文字符的网址。 * - * URL checking. + * URL checking. * The check rule of filter don't support chinese. - * - * @param string $var + * + * @param string $var * @static * @access public * @return bool @@ -179,11 +179,11 @@ class baseValidater /** * 检查域名,不支持中文。 - * Domain checking. + * Domain checking. * * The check rule of filter don't support chinese. - * - * @param string $var + * + * @param string $var * @static * @access public * @return bool @@ -196,9 +196,9 @@ class baseValidater /** * 检查IP地址。 * IP checking. - * - * @param ip $var - * @param string $range all|public|static|private + * + * @param ip $var + * @param string $range all|public|static|private * @static * @access public * @return bool @@ -217,25 +217,25 @@ class baseValidater /** * 身份证号检查。 * Idcard checking. - * + * * @access public * @return void */ public static function checkIdcard($idcard) { - if(strlen($idcard)!=18) return false; - $idcard = strtoupper($idcard); + if(strlen($idcard) != 18) return false; + $idcard = strtoupper($idcard); $cityList = array( - '11','12','13','14','15','21','22', - '23','31','32','33','34','35','36', - '37','41','42','43','44','45','46', - '50','51','52','53','54','61','62', - '63','64','65','71','81','82','91' + '11', '12', '13', '14', '15', '21', '22', + '23', '31', '32', '33', '34', '35', '36', + '37', '41', '42', '43', '44', '45', '46', + '50', '51', '52', '53', '54', '61', '62', + '63', '64', '65', '71', '81', '82', '91' ); - if (!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $idcard)) return false; + if(!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $idcard)) return false; - if (!in_array(substr($idcard, 0, 2), $cityList)) return false; + if(!in_array(substr($idcard, 0, 2), $cityList)) return false; $baseCode = substr($idcard, 0, 17); $verifyCode = substr($idcard, 17, 1); @@ -244,7 +244,7 @@ class baseValidater $verifyConfig = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'); $total = 0; - for($i=0; $i<17; $i++) $total += substr($baseCode, $i, 1) * $interference[$i]; + for($i = 0; $i < 17; $i++) $total += substr($baseCode, $i, 1) * $interference[$i]; $mod = $total % 11; @@ -254,8 +254,8 @@ class baseValidater /** * 日期检查。注意,2009-09-31是一个合法日期,系统会将它转换为2009-10-01。 * Date checking. Note: 2009-09-31 will be an valid date, because strtotime auto fixed it to 10-01. - * - * @param date $date + * + * @param date $date * @static * @access public * @return bool @@ -264,14 +264,14 @@ class baseValidater { if(empty($date)) return true; if($date == '0000-00-00') return true; - if(preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $parts)) return checkdate($parts[2], $parts[3], $parts[1]); + if(preg_match("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $parts)) return checkdate($parts[2], $parts[3], $parts[1]); return false; } /** * Check datetime. - * - * @param string $datetime + * + * @param string $datetime * @static * @access public * @return bool @@ -282,16 +282,16 @@ class baseValidater if($datetime == '0000-00-00') return true; if($datetime == '0000-00-00 00:00:00') return true; $date = substr($datetime, 0, 10); - if(preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $parts)) return checkdate($parts[2], $parts[3], $parts[1]); + if(preg_match("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $parts)) return checkdate($parts[2], $parts[3], $parts[1]); return false; } /** * 检查正则表达式。 * REG checking. - * - * @param string $var - * @param string $reg + * + * @param string $var + * @param string $reg * @static * @access public * @return bool @@ -304,10 +304,10 @@ class baseValidater /** * 检查长度。 * Length checking. - * - * @param string $var - * @param string $max - * @param int $min + * + * @param string $var + * @param string $max + * @param int $min * @static * @access public * @return bool @@ -321,8 +321,8 @@ class baseValidater /** * 检查不为空。 * Not empty checking. - * - * @param mixed $var + * + * @param mixed $var * @static * @access public * @return bool @@ -335,8 +335,8 @@ class baseValidater /** * 检查为空。 * Empty checking. - * - * @param mixed $var + * + * @param mixed $var * @static * @access public * @return bool @@ -349,8 +349,8 @@ class baseValidater /** * 检查用户名。 * Account checking. - * - * @param string $var + * + * @param string $var * @static * @access public * @return bool @@ -365,8 +365,8 @@ class baseValidater /** * 检查Code。 * Check code. - * - * @param string $var + * + * @param string $var * @static * @access public * @return bool @@ -379,8 +379,8 @@ class baseValidater /** * 检查验证码。 * Check captcha. - * - * @param mixed $var + * + * @param mixed $var * @static * @access public * @return bool @@ -394,9 +394,9 @@ class baseValidater /** * 是否等于给定的值。 * Must equal a value. - * - * @param mixed $var - * @param mixed $value + * + * @param mixed $var + * @param mixed $value * @static * @access public * @return bool @@ -409,9 +409,9 @@ class baseValidater /** * 检查不等于给定的值 * Must not equal a value. - * - * @param mixed $var - * @param mixed $value + * + * @param mixed $var + * @param mixed $value * @static * @access public * @return bool @@ -424,9 +424,9 @@ class baseValidater /** * 检查大于给定的值。 * Must greater than a value. - * - * @param mixed $var - * @param mixed $value + * + * @param mixed $var + * @param mixed $value * @static * @access public * @return bool @@ -439,9 +439,9 @@ class baseValidater /** * 检查小于给定的值 * Must less than a value. - * - * @param mixed $var - * @param mixed $value + * + * @param mixed $var + * @param mixed $value * @static * @access public * @return bool @@ -454,9 +454,9 @@ class baseValidater /** * 检查大于等于给定的值 * Must greater than a value or equal a value. - * - * @param mixed $var - * @param mixed $value + * + * @param mixed $var + * @param mixed $value * @static * @access public * @return bool @@ -469,9 +469,9 @@ class baseValidater /** * 检查小于等于给定的值 * Must less than a value or equal a value. - * - * @param mixed $var - * @param mixed $value + * + * @param mixed $var + * @param mixed $value * @static * @access public * @return bool @@ -484,9 +484,9 @@ class baseValidater /** * 检查是否在给定的列表里面。 * Must in value list. - * - * @param mixed $var - * @param mixed $value + * + * @param mixed $var + * @param mixed $value * @static * @access public * @return bool @@ -500,8 +500,8 @@ class baseValidater /** * 检查文件名。 * Check file name. - * - * @param string $var + * + * @param string $var * @static * @access public * @return bool @@ -514,9 +514,9 @@ class baseValidater /** * 检查敏感词。 * Check sensitive words. - * - * @param object $vars - * @param array $dicts + * + * @param object $vars + * @param array $dicts * @static * @access public * @return void @@ -537,8 +537,8 @@ class baseValidater /** * 过滤附件。 - * Filter files. - * + * Filter files. + * * @access public * @return array */ @@ -578,8 +578,8 @@ class baseValidater /** * 过滤超级变量。 * Filter super vars. - * - * @param array $super + * + * @param array $super * @access public * @return array */ @@ -596,13 +596,13 @@ class baseValidater foreach($item as $subkey => $subItem) { if(is_array($subItem)) continue; - $subItem = self::filterTrojan($subItem); + $subItem = self::filterTrojan($subItem); $super[$key][$subkey] = self::filterXSS($subItem); } } else { - $item = self::filterTrojan($item); + $item = self::filterTrojan($item); $super[$key] = self::filterXSS($item); } } @@ -613,8 +613,8 @@ class baseValidater /** * 过滤不符合规则的键值。 * Filter bad keys. - * - * @param mix $var + * + * @param mix $var * @access public * @return mix */ @@ -629,8 +629,8 @@ class baseValidater /** * 过滤木马代码。 * Filter trojan codes. - * - * @param string $var + * + * @param string $var * @access public * @return string */ @@ -640,7 +640,7 @@ class baseValidater if(empty($config->framework->filterTrojan)) return $var; if(strpos(htmlspecialchars_decode($var), 'getModuleName(); - $methodName = $app->getMethodName(); - $params = $app->getParams(); + $moduleName = $app->getModuleName(); + $methodName = $app->getMethodName(); + $params = $app->getParams(); if($type == 'cookie') { - $pagerCookie = 'pager' . ucfirst($moduleName) . ucfirst($methodName); + $pagerCookie = 'pager' . ucfirst($moduleName) . ucfirst($methodName); $filter->default->cookie[$pagerCookie] = 'int'; } foreach($var as $key => $value) @@ -722,8 +722,8 @@ class baseValidater /** * Replace space to i tag. - * - * @param string $var + * + * @param string $var * @static * @access public * @return string @@ -743,9 +743,9 @@ class baseValidater /** * Check by rule. - * - * @param string $var - * @param string $rule like: int account reg::md5 reg::/^[a-zA-Z0-9]+$/. + * + * @param string $var + * @param string $rule like: int account reg::md5 reg::/^[a-zA-Z0-9]+$/. * @static * @access public * @return bool @@ -761,7 +761,7 @@ class baseValidater $checkMethod = 'check' . $operator; if(method_exists('baseValidater', $checkMethod)) { - if(empty($param) and self::$checkMethod($var) === false) return false; + if(empty($param) and self::$checkMethod($var) === false) return false; if(!empty($param) and self::$checkMethod($var, $param) === false) return false; } elseif(function_exists('is_' . $operator)) @@ -779,8 +779,8 @@ class baseValidater /** * Parse rule string. - * - * @param string $rule like: int account reg::md5 reg::/^[a-zA-Z0-9]+$/. + * + * @param string $rule like: int account reg::md5 reg::/^[a-zA-Z0-9]+$/. * @static * @access public * @return array @@ -799,9 +799,9 @@ class baseValidater /** * 调用一个方法进行检查。 * Call a function to check it. - * - * @param mixed $var - * @param string $func + * + * @param mixed $var + * @param string $func * @static * @access public * @return bool @@ -815,7 +815,7 @@ class baseValidater /** * fixer类,处理数据。 * fixer class, to fix data types. - * + * * @package framework */ class baseFixer @@ -823,7 +823,7 @@ class baseFixer /** * 处理的数据。 * The data to be fixed. - * + * * @var object * @access public */ @@ -832,8 +832,8 @@ class baseFixer /** * 跳过处理的字段。 * The fields to striped. - * - * @var array + * + * @var array * @access public */ public $stripedFields = array(); @@ -841,47 +841,47 @@ class baseFixer /** * 构造方法,将超级全局变量转换为对象。 * The construction function, according the scope, convert it to object. - * - * @param string $scope the scope of the var, should be post|get|server|session|cookie|env + * + * @param string $scope the scope of the var, should be post|get|server|session|cookie|env * @access public * @return void */ public function __construct($scope) { - switch($scope) + switch ($scope) { - case 'post': - $this->data = (object)$_POST; - break; - case 'server': - $this->data = (object)$_SERVER; - break; - case 'get': - $this->data = (object)$_GET; - break; - case 'session': - $this->data = (object)$_SESSION; - break; - case 'cookie': - $this->data = (object)$_COOKIE; - break; - case 'env': - $this->data = (object)$_ENV; - break; - case 'file': - $this->data = (object)$_FILES; - break; + case 'post': + $this->data = (object)$_POST; + break; + case 'server': + $this->data = (object)$_SERVER; + break; + case 'get': + $this->data = (object)$_GET; + break; + case 'session': + $this->data = (object)$_SESSION; + break; + case 'cookie': + $this->data = (object)$_COOKIE; + break; + case 'env': + $this->data = (object)$_ENV; + break; + case 'file': + $this->data = (object)$_FILES; + break; - default: - die('scope not supported, should be post|get|server|session|cookie|env'); + default: + die('scope not supported, should be post|get|server|session|cookie|env'); } } /** * 工厂方法。 * The factory function. - * - * @param string $scope + * + * @param string $scope * @access public * @return object fixer object. */ @@ -893,8 +893,8 @@ class baseFixer /** * 处理Email。 * Email fix. - * - * @param string $fieldName + * + * @param string $fieldName * @access public * @return object fixer object. */ @@ -908,8 +908,8 @@ class baseFixer /** * url编码。 * urlencode. - * - * @param string $fieldName + * + * @param string $fieldName * @access public * @return object fixer object. */ @@ -919,7 +919,7 @@ class baseFixer $args = func_get_args(); foreach($fields as $fieldName) { - $this->data->$fieldName = isset($args[1]) ? filter_var($this->data->$fieldName, FILTER_SANITIZE_ENCODED, $args[1]) : filter_var($this->data->$fieldName, FILTER_SANITIZE_ENCODED); + $this->data->$fieldName = isset($args[1]) ? filter_var($this->data->$fieldName, FILTER_SANITIZE_ENCODED, $args[1]) : filter_var($this->data->$fieldName, FILTER_SANITIZE_ENCODED); } return $this; } @@ -927,8 +927,8 @@ class baseFixer /** * 清理网址。 * Clean the url. - * - * @param string $fieldName + * + * @param string $fieldName * @access public * @return object fixer object. */ @@ -942,23 +942,23 @@ class baseFixer /** * 处理Float类型。 * Float fixer. - * - * @param string $fieldName + * + * @param string $fieldName * @access public * @return object fixer object. */ public function cleanFloat($fieldName) { $fields = $this->processFields($fieldName); - foreach($fields as $fieldName) $this->data->$fieldName = (float)filter_var($this->data->$fieldName, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION|FILTER_FLAG_ALLOW_THOUSAND); + foreach($fields as $fieldName) $this->data->$fieldName = (float)filter_var($this->data->$fieldName, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND); return $this; } /** * 处理Int类型。 - * Int fixer. - * - * @param string $fieldName + * Int fixer. + * + * @param string $fieldName * @access public * @return object fixer object. */ @@ -978,8 +978,8 @@ class baseFixer /** * 将字符串转换为可以在浏览器查看的编码。 * Special chars. - * - * @param string $fieldName + * + * @param string $fieldName * @access public * @return object fixer object */ @@ -990,7 +990,7 @@ class baseFixer { if(empty($this->stripedFields) or !isset($this->stripedFields[$fieldName])) { - $this->data->$fieldName = $this->specialArray($this->data->$fieldName); + $this->data->$fieldName = $this->specialArray($this->data->$fieldName); $this->stripedFields[$fieldName] = $fieldName; } } @@ -998,9 +998,9 @@ class baseFixer } /** - * Special array - * - * @param mix $data + * Special array + * + * @param mix $data * @access public * @return mix */ @@ -1015,11 +1015,11 @@ class baseFixer /** * 忽略该标签。 - * Strip tags - * - * @param string $fieldName - * @param string $allowableTags - * @param array $attributes + * Strip tags + * + * @param string $fieldName + * @param string $allowableTags + * @param array $attributes * @access public * @return object fixer object */ @@ -1042,10 +1042,10 @@ class baseFixer /** * Strip tags for data - * - * @param string $data - * @param string $allowedTags - * @param array $attributes + * + * @param string $data + * @param string $allowedTags + * @param array $attributes * @static * @access public * @return string @@ -1073,7 +1073,7 @@ class baseFixer $purifierConfig->set('HTML.Attr.Name.UseCDATA', true); $purifier = new HTMLPurifier($purifierConfig); - $def = $purifierConfig->getHTMLDefinition(true); + $def = $purifierConfig->getHTMLDefinition(true); $def->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top'); if(!empty($attributes)) @@ -1118,8 +1118,8 @@ class baseFixer /** * 忽略处理给定的字段。 * Skip special chars check. - * - * @param string $filename + * + * @param string $filename * @access public * @return object fixer object */ @@ -1132,9 +1132,9 @@ class baseFixer /** * 给字段添加引用,防止字符与关键字冲突。 - * Quote - * - * @param string $fieldName + * Quote + * + * @param string $fieldName * @access public * @return object fixer object */ @@ -1148,26 +1148,54 @@ class baseFixer /** * 设置字段的默认值。 * Set default value of some fileds. - * - * @param string $fields - * @param mixed $value + * + * @param string $fields + * @param mixed $value * @access public * @return object fixer object */ public function setDefault($fields, $value) { $fields = strpos($fields, ',') ? explode(',', str_replace(' ', '', $fields)) : array($fields); - foreach($fields as $fieldName)if(!isset($this->data->$fieldName) or empty($this->data->$fieldName)) $this->data->$fieldName = $value; + foreach($fields as $fieldName) if(!isset($this->data->$fieldName) or empty($this->data->$fieldName)) $this->data->$fieldName = $value; + return $this; + } + + /** + * 将字段的值进行json编码 + * @param string $filed + * @return static + * @author thanatos thanatos915@163.com + */ + public function json($fields) + { + $fields = strpos($fields, ',') ? explode(',', str_replace(' ', '', $fields)) : array($fields); + foreach($fields as $field) + if(isset($this->data->$field)) $this->data->$field = json_encode($this->data->$field); + return $this; + } + + /** + * 将字段的值进行HTML标签解码 + * @param string $filed + * @return static + * @author thanatos thanatos915@163.com + */ + public function unHtml($fields) + { + $fields = strpos($fields, ',') ? explode(',', str_replace(' ', '', $fields)) : array($fields); + foreach($fields as $field) + if(isset($this->data->$field)) $this->data->$field = htmlspecialchars_decode($this->data->$field); return $this; } /** * 如果条件为真,则为字段赋值。 * Set value of a filed on the condition is true. - * - * @param bool $condition - * @param string $fieldName - * @param string $value + * + * @param bool $condition + * @param string $fieldName + * @param string $value * @access public * @return object fixer object */ @@ -1180,9 +1208,9 @@ class baseFixer /** * 强制给字段赋值。 * Set the value of a filed in force. - * - * @param string $fieldName - * @param mixed $value + * + * @param string $fieldName + * @param mixed $value * @access public * @return object fixer object */ @@ -1195,8 +1223,8 @@ class baseFixer /** * 移除一个字段。 * Remove a field. - * - * @param string $fieldName + * + * @param string $fieldName * @access public * @return object fixer object */ @@ -1210,9 +1238,9 @@ class baseFixer /** * 如果条件为真,移除该字段。 * Remove a filed on the condition is true. - * - * @param bool $condition - * @param string $fields + * + * @param bool $condition + * @param string $fields * @access public * @return object fixer object */ @@ -1226,9 +1254,9 @@ class baseFixer /** * 为数据添加新的项。 * Add an item to the data. - * - * @param string $fieldName - * @param mixed $value + * + * @param string $fieldName + * @param mixed $value * @access public * @return object fixer object */ @@ -1241,10 +1269,10 @@ class baseFixer /** * 如果条件为真,则为数据添加新的项。 * Add an item to the data on the condition if true. - * - * @param bool $condition - * @param string $fieldName - * @param mixed $value + * + * @param bool $condition + * @param string $fieldName + * @param mixed $value * @access public * @return object fixer object */ @@ -1255,11 +1283,11 @@ class baseFixer } /** - * 为指定字段增加值。 + * 为指定字段增加值。 * Join the field. - * - * @param string $fieldName - * @param string $value + * + * @param string $fieldName + * @param string $value * @access public * @return object fixer object */ @@ -1273,9 +1301,9 @@ class baseFixer /** * 调用一个方法来处理数据。 * Call a function to fix it. - * - * @param string $fieldName - * @param string $func + * + * @param string $fieldName + * @param string $func * @access public * @return object fixer object */ @@ -1289,8 +1317,8 @@ class baseFixer /** * 处理完成后返回数据。 * Get the data after fixing. - * - * @param string $fieldName + * + * @param string $fieldName * @access public * @return object */ @@ -1315,8 +1343,8 @@ class baseFixer /** * 处理字段,如果字段中含有',',拆分成数组。如果字段不在$data中,删除掉。 * Process fields, if contains ',', split it to array. If not in $data, remove it. - * - * @param string $fields + * + * @param string $fields * @access public * @return array */ diff --git a/module/api/config.php b/module/api/config.php new file mode 100644 index 0000000000..d7d3d41ca4 --- /dev/null +++ b/module/api/config.php @@ -0,0 +1,17 @@ +api = new stdClass(); +$config->api->createlib = new stdclass(); +$config->api->createlib->requiredFields = 'name'; + +$config->api->create = new stdclass(); +$config->api->create->requiredFields = 'lib,module,title,path,method,protocol'; + +$config->api->edit = new stdclass(); +$config->api->edit->requiredFields = 'lib,module,title,path,method,protocol'; + +$config->api->editor = new stdclass(); +$config->api->editor->createlib = ['id' => 'desc', 'tools' => 'simpleTools']; +$config->api->editor->create = ['id' => 'desc', 'tools' => 'simpleTools']; +$config->api->editor->edit = ['id' => 'desc', 'tools' => 'simpleTools']; diff --git a/module/api/control.php b/module/api/control.php index b93aacdca4..d284ce6337 100644 --- a/module/api/control.php +++ b/module/api/control.php @@ -1,4 +1,5 @@ group = $this->loadModel('group'); + $this->user = $this->loadModel('user'); + $this->doc = $this->loadModel('doc'); + $this->action = $this->loadModel('action'); + $this->tree = $this->loadModel('tree'); + $this->api = $this->loadModel('api'); + } + + /** + * Api doc index page. + * @return void + * @author thanatos thanatos915@163.com + */ + public function index() + { + $params = $_GET; + $libID = $params['libID']; + $module = $params['module']; + $apiID = $params['apiID']; + $version = $params['version']; + + /* Get all api doc libraries */ + $libs = $this->doc->getApiLibs(); + + /* generate bread crumbs dropMenu */ + if($libs) + { + if($libID == 0) $libID = key($libs); + $this->lang->modulePageNav = $this->generateLibsDropMenu($libs, $libID); + $this->view->libID = $libID; + } + $this->setMenu($libID); + + + /* Get an api doc */ + if($apiID > 0) + { + $api = $this->api->getLibById($apiID, $version); + if($api) + { + $module = $api->module; + $_GET['module'] = $module; + $libID = $api->lib; + $this->view->api = $api; + $this->view->apiID = $apiID; + $this->view->version = $version; + $this->view->actions = $apiID ? $this->action->getList('api', $apiID) : array(); + } + } + else + { + /* Get module api list */ + $apiList = $this->api->getListByModuleId($libID, $module); + $this->view->apiList = $apiList; + $this->view->moudle = $module; + } + + /* Get module tree */ + $moduleTree = $this->doc->getApiModuleTree($libID, $apiID); + + $this->view->title = $this->lang->api->title; + $this->view->libs = $libs; + $this->view->moduleTree = $moduleTree; + $this->view->users = $this->user->getPairs('noclosed,noletter'); + + $this->display(); + } + + /** + * Show an Api doc + * @param $id + * @author thanatos thanatos915@163.com + */ + public function detail($id) + { + + } + + /** + * Create a api doc library. + * @author thanatos thanatos915@163.com + */ + public function createLib() + { + if(!empty($_POST)) + { + $lib = fixer::input('post') + ->join('groups', ',') + ->join('users', ',') + ->get(); + + if($lib->acl == 'private') $lib->users = $this->app->user->account; + + /* save api doc library */ + $libID = $this->doc->createApiLib($lib); + if(dao::isError()) + { + $this->sendError(dao::getError()); + exit; + } + $this->action->create('docLib', $libID, 'Created'); + + /* save doc library success */ + $this->sendSuccess([ + 'locate' => $this->createLink('api', 'index', "libID=$libID"), + ]); + exit; + } + $this->view->groups = $this->group->getPairs(); + $this->view->users = $this->user->getPairs('nocode'); + + $this->display(); + } + + public function edit() + { + $apiID = $_GET['apiID']; + if(helper::isAjaxRequest() && !empty($_POST)) + { + $this->loadModel('api'); + + $now = helper::now(); + $userId = $this->app->user->account; + $params = fixer::input('post') + ->add('addedBy', $userId) + ->add('addedDate', $now) + ->add('editedBy', $userId) + ->add('editedDate', $now) + ->setDefault('product,module', 0) + ->json('params,response') + ->get(); + + + $this->api->update($apiID, $params); + if(dao::isError()) + { + $this->sendError(dao::getError()); + exit; + } + + $this->action->create('api', $apiID, 'Edited'); + $this->sendSuccess([ + 'locate' => helper::createLink('api', 'index', "apiID=$apiID"), + ]); + exit; + } + + $api = $this->api->getLibById($apiID); + if($api) + { + $this->view->api = $api; + $this->view->edit = true; + } + + $example = [ + 'example' => 'type,description' + ]; + $this->view->example = json_encode($example, JSON_PRETTY_PRINT); + + $allUsers = $this->loadModel('user')->getPairs('devfirst|noclosed'); + $this->view->user = $this->app->user->account; + $this->view->allUsers = $allUsers; + $this->view->moduleOptionMenu = $this->tree->getOptionMenu($api->lib, 'api', $startModuleID = 0); + $this->view->moduleID = $api->module ? (int)$api->module : (int)$this->cookie->lastDocModule; + $this->view->title = $api->title . $this->lang->api->edit; + + $this->display(); + + } + + /** + * Create an api doc. + * @author thanatos thanatos915@163.com + */ + public function create() + { + $libID = $_GET['libID']; + $moduleID = $_GET['moduleID']; + if(helper::isAjaxRequest() && !empty($_POST)) + { + $this->loadModel('api'); + + $now = helper::now(); + $userId = $this->app->user->account; + $params = fixer::input('post') + ->add('addedBy', $userId) + ->add('addedDate', $now) + ->add('editedBy', $userId) + ->add('editedDate', $now) + ->add('version', 1) + ->setDefault('product,module', 0) + ->unHtml('params,response') + ->json('params,response') + ->get(); + + $apiID = $this->api->create($params); + if(empty($apiID)) + { + $this->sendError(dao::getError()); + exit; + } + + $this->action->create('api', $apiID, 'Created'); + $this->sendSuccess([ + 'locate' => helper::createLink('api', 'index', "apiID=$apiID"), + ]); + exit; + } + + $libs = $this->doc->getLibs('api', '', $libID); + if(!$libID and !empty($libs)) $libID = key($libs); + + $lib = $this->doc->getLibByID($libID); + $libName = isset($lib->name) ? $lib->name . $this->lang->colon : ''; + + $example = [ + 'example' => 'type,description' + ]; + $this->view->example = json_encode($example, JSON_PRETTY_PRINT); + + $allUsers = $this->loadModel('user')->getPairs('devfirst|noclosed'); + $this->view->user = $this->app->user->account; + $this->view->allUsers = $allUsers; + $this->view->libID = $libID; + $this->view->libName = $lib->name; + $this->view->moduleOptionMenu = $this->tree->getOptionMenu($libID, 'api', $startModuleID = 0); + $this->view->moduleID = $moduleID ? (int)$moduleID : (int)$this->cookie->lastDocModule; + $this->view->libs = $libs; + $this->view->title = $libName . $this->lang->api->create; + $this->view->users = $this->user->getPairs('nocode'); + + $this->display('api', 'create'); + } + + /** + * @param $apiID + * @param string $confirm + * @author thanatos thanatos915@163.com + */ + public function delete($apiID, $confirm = 'no') + { + if($confirm == 'no') + { + $tips = $this->lang->api->confirmDelete; + die(js::confirm($tips, inlink('delete', "apiID=$apiID&confirm=yes"))); + } + else + { + $api = $this->api->getLibById($apiID); + $this->api->delete(TABLE_API, $apiID); + + if(dao::isError()) + { + $this->sendError(dao::getError()); + } + else + { + $this->sendSuccess([ + 'locate' => $this->createLink('api', 'index', "libID=$api->lib&module=$api->module"), + ]); + } + } + } + + /** + * Get params type options by scope + * + * @param string $scope the params position + * @author thanatos thanatos915@163.com + */ + public function ajaxGetParamsTypeOptions($scope) + { + if(empty($scope)) die(); + $options = []; + if($scope == apiModel::SCOPE_BODY) + { + $options = $this->lang->api->allParamsTypeOptions; + } + else + { + $options = $this->lang->api->paramsTypeOptions; + } + + echo html::select('paramsTypeOptions', $options, '', "class='form-control' onchange='changeType(this);'"); + exit; + } + + /** + * Set doc menu by method name. + * + * @author thanatos thanatos915@163.com + */ + private function setMenu($libID = 0) + { + $menu = ''; + // page of index menu + if(intval($libID) > 0) + { + $menu = ""; + } + else + { + /* generate create api doc lib button */ + if(common::hasPriv('api', 'createDoc')) + { + $menu = html::a(helper::createLink('api', 'createLib'), ' ' . $this->lang->api->createLib, '', 'class="btn btn-secondary iframe"'); + } + } + + $this->lang->TRActions = $menu; + } + + /** + * Generate api doc index page dropMenu + * + * @author thanatos thanatos915@163.com + */ + private function generateLibsDropMenu($libs, $libID) + { + if(empty($libs)) return ''; + + $libName = $libs[$libID]->name; + $output = << +
+ +
"; + + return $output; + } + + /** + * Show doc of api doc library + * @author thanatos thanatos915@163.com + */ + public function showLibs($libID = 0) + { + $lib = $this->doc->getLibById($libID); + if(!empty($lib) and $lib->deleted == '1') $appendLib = $libID; + + + } + /** * Return session to the client. * * @access public * @return void */ - public function getSessionID() + public + function getSessionID() { $this->session->set('rand', mt_rand(0, 10000)); $this->view->sessionName = session_name(); @@ -29,13 +411,14 @@ class api extends control /** * Execute a module's model's method, return the result. * - * @param string $moduleName - * @param string $methodName - * @param string $params param1=value1,param2=value2, don't use & to join them. + * @param string $moduleName + * @param string $methodName + * @param string $params param1=value1,param2=value2, don't use & to join them. * @access public * @return string */ - public function getModel($moduleName, $methodName, $params = '') + public + function getModel($moduleName, $methodName, $params = '') { if(!$this->config->features->apiGetModel) die(sprintf($this->lang->api->error->disabled, '$config->features->apiGetModel')); @@ -43,7 +426,7 @@ class api extends control $newParams = array_shift($params); foreach($params as $param) { - $sign = strpos($param, '=') !== false ? '&' : ','; + $sign = strpos($param, '=') !== false ? '&' : ','; $newParams .= $sign . $param; } @@ -61,12 +444,13 @@ class api extends control /** * The interface of api. * - * @param int $filePath - * @param int $action + * @param int $filePath + * @param int $action * @access public * @return void */ - public function debug($filePath, $action) + public + function debug($filePath, $action) { $filePath = helper::safe64Decode($filePath); if($action == 'extendModel') @@ -101,7 +485,7 @@ class api extends control /** * Query sql. * - * @param string $keyField + * @param string $keyField * @access public * @return void */ @@ -116,4 +500,35 @@ class api extends control $this->output = json_encode($output); die($this->output); } + + + /** + * @var groupModel + */ + public $group; + + /** + * @var userModel + */ + public $user; + + /** + * @var docModel + */ + public $doc; + + /** + * @var actionModel + */ + public $action; + + /** + * @var treeModel; + */ + public $tree; + + /** + * @var apiModel + */ + public $api; } diff --git a/module/api/css/common.css b/module/api/css/common.css new file mode 100644 index 0000000000..f16f4e659b --- /dev/null +++ b/module/api/css/common.css @@ -0,0 +1,98 @@ +.split-row > .side-col, +.split-row > .main-col {padding: 0;} +.col-spliter {width: 20px; position: relative; z-index: 10; cursor: ew-resize;} +.col-spliter:before, +.col-spliter:after {content: ''; display: block; position: absolute; left: 50%; width: 10px; margin-left: -5px; top: 0; bottom: 0; background: rgba(0,0,0,.075); opacity: 0; transition: opacity .2s;} +.col-spliter:before {border-radius: 5px;} +.col-spliter:after {background: transparent; top: 50%; bottom: auto; height: 20px; opacity: 1; width: 4px; border-left: 1px solid rgba(0,0,0,.2); border-right: rgba(0,0,0,.2) 1px solid; margin-left: -2px; margin-top: -10px;} +/* .col-spliter:hover:after {width: 2px; background: rgba(0,0,0,.15); margin-left: -1px; top: 0; bottom: 20px; height: auto; margin-top: auto; border: none;} */ +.row-spliting .col-spliter:after, +.col-spliter:hover:after {border-color: rgba(0,0,0,.3);} +.col-spliter:hover:before, +.col-spliter:hover:after, +.row-spliting .col-spliter:before, +.row-spliting .col-spliter:after {opacity: 1;} + +@media (max-width: 720px) +{ + .split-row > .side-col, + .split-row > .main-col {width: 100% !important;} +} + +.side-col .tab-content {margin-right: -5px;} +.side-col .cell .nav a.setting {padding: 8px;} +.side-footer {padding: 8px; margin: 0 5px; border-top: 1px solid #ddd;} +.col-sm-size .col-sm-5, +.col-sm-size .col-sm-7 {width: 100%;} +.col-sm-size .table .c-user, +.col-sm-size .table .c-num, +.col-md-size .table .c-datetime {display: none;} + +.table-files .btn {padding: 0 6px;} + +#docsTree li > a > .icon {opacity: .65;} + +.files-grid {padding: 0 10px;} +.files-grid .col {width: 20%; text-align: center; padding: 0; margin-bottom: 10px;} +.files-grid .actions {background: #E9F2FB; z-index: 10; opacity: 0; transition: opacity .2s; padding-bottom: 8px; border-radius: 0 0 3px 3px; padding-top: 8px;} +.files-grid .col:hover .actions {opacity: 1;} +.files-grid .file {padding: 10px; cursor: pointer; display: block; border-radius: 2px; transition: background-color .2s; border-radius: 3px 3px 0 0;} +.files-grid .col:hover .file {background-color: #E9F2FB;} +.files-grid .file-icon {font-size: 54px; width: 64px; height: 64px; display: block; margin: 0 auto 8px; line-height: 64px; color: #8E939A;} +.files-grid .file-name, +.files-grid .file-info {text-overflow: ellipsis; white-space: nowrap; overflow: hidden; line-height: 20px;} +.files-grid .file-info {font-size: 12px; margin-top: 3px;} +.files-grid .icon-folder {background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI1MnB4IiBoZWlnaHQ9IjQ2cHgiIHZpZXdCb3g9IjAgMCA1MiA0NiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5pY29uLWJpZy1mb2xkZXJpY29uLWJpZy1mb2xkZXI8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4gICAgICAgIDxnIGlkPSJ3ZWItbWF4IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTA5NS4wMDAwMDAsIC02OTUuMDAwMDAwKSI+ICAgICAgICAgICAgPGcgaWQ9Ijgt5paH5qGjIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDkwLjAwMDAwMCwgNTgzLjAwMDAwMCkiPiAgICAgICAgICAgICAgICA8ZyBpZD0iaWNvbi1iaWctZm9sZGVyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1LjAwMDAwMCwgMTEyLjAwMDAwMCkiPiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIxLjA0NTY4OTEsNC4yNzAyMzU0MiBDMjEuOTYxODA1OSw1LjEwNzIwMzY1IDIzLjAyMjcwMDQsNS41NTc5NjY1OSAyNC4zNjg4OTQ0LDUuNTI1MDEyMTggTDI2LjE2MDIzOCw1LjUyNTAxMjE4IEwzMC44MTIxMDExLDUuNTI1MDEyMTggQzI5LjYwMDkxMDksNS41MjUwMTIxOCAyOC40Mzg1MTg2LDUuMDM1NzUxMTMgMjcuNTc3MDQ3LDQuMTg1ODk1OTMgTDI0LjY3ODE1NjYsMS4zMjY0MDI3MSBDMjMuODE2NTgwOCwwLjQ3NjU0NzUxMSAyMi42NTQyOTI3LDAgMjEuNDQzMTAyNSwwIEwxNS4xMTQ5MDQ2LDAgTDE1LDAgQzE2LjIyNjg2NzksMC4wMzk0MzcwODA1IDE3LjMwMjA1NTcsMC41NTY4NjUwODcgMTguMTYzNTI3MywxLjQwNjYxNjIyIEwyMS4wNDU2ODkxLDQuMjcwMjM1NDIgWiIgaWQ9IlNoYXBlLUNvcHktNyIgZmlsbD0iI0ZGQzg1QSI+PC9wYXRoPiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTQ5LjMxMDMyMDMsNS41MjAwMjkxOCBMMzguNTUxNzAzMSw1LjUyMDAyOTE4IEwzNi44MDY4NTk0LDUuNTIwMDI5MTggTDMyLjI3NTc1LDUuNTIwMDI5MTggTDMwLjUzMDkwNjMsNS41MjAwMjkxOCBMMjYsNS41MjAwMjkxOCBMMjQuMjU1MTU2Miw1LjUyMDAyOTE4IEMyMy4wNzU0MDYzLDUuNTIwMDI5MTggMjEuOTQzMTg3NSw1LjA0MjgxMzM1IDIxLjEwNDA3ODEsNC4xOTE3NjYzIEwxOC4yODA0Mzc1LDEuMzI4MjYyODggQzE3LjQ0MTIyNjYsMC40NzcyMTU4MjkgMTYuMzA5MTA5NCwwIDE1LjEyOTM1OTQsMCBMOC45NjU1MzEyNSwwIEwyLjY4OTY3OTY5LDAgQzEuMjA0MjI2NTYsNy40MDUxNTkyM2UtMTYgMCwxLjIzNTcxNjk5IDAsMi43NjAwMTQ1OSBMMCw4LjI4MDA0Mzc3IEwwLDkuMjAwMDgzMzcgTDAsNDMuMjM5OTg1NCBDMCw0NC43NjQyODMgMS4yMDQyMjY1Niw0NiAyLjY4OTY3OTY5LDQ2IEw0OS4zMTAzMjAzLDQ2IEM1MC43OTU3NzM0LDQ2IDUyLDQ0Ljc2NDI4MyA1Miw0My4yMzk5ODU0IEw1Miw4LjI4MDA0Mzc3IEM1Miw2Ljc1NTY0MTk1IDUwLjc5NTc3MzQsNS41MjAwMjkxOCA0OS4zMTAzMjAzLDUuNTIwMDI5MTggTDQ5LjMxMDMyMDMsNS41MjAwMjkxOCBaIiBpZD0iU2hhcGUtQ29weS04IiBmaWxsPSIjRkZFMDY2Ij48L3BhdGg+ICAgICAgICAgICAgICAgIDwvZz4gICAgICAgICAgICA8L2c+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=) no-repeat center;} +.files-grid .icon-paper-clip {background:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTJweCIgaGVpZ2h0PSI0NnB4IiB2aWV3Qm94PSIwIDAgNTIgNDYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQ5LjEgKDUxMTQ3KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5pY29uLWJpZy1lbmNsb3NlaWNvbi1iaWctZW5jbG9zZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSLmiYDmnIlJQ09OIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTQwNC4wMDAwMDAsIC02OTUuMDAwMDAwKSI+CiAgICAgICAgICAgIDxnIGlkPSI4LeaWh+ahoyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTA5MC4wMDAwMDAsIDU4My4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJHcm91cC03LUNvcHkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxNC4wMDAwMDAsIDExMi4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICA8ZyBpZD0iaWNvbi1iaWctZm9sZGVyIj4KICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIxLjA0NTY4OTEsNC4yNzAyMzU0MiBDMjEuOTYxODA1OSw1LjEwNzIwMzY1IDIzLjAyMjcwMDQsNS41NTc5NjY1OSAyNC4zNjg4OTQ0LDUuNTI1MDEyMTggTDI2LjE2MDIzOCw1LjUyNTAxMjE4IEwzMC44MTIxMDExLDUuNTI1MDEyMTggQzI5LjYwMDkxMDksNS41MjUwMTIxOCAyOC40Mzg1MTg2LDUuMDM1NzUxMTMgMjcuNTc3MDQ3LDQuMTg1ODk1OTMgTDI0LjY3ODE1NjYsMS4zMjY0MDI3MSBDMjMuODE2NTgwOCwwLjQ3NjU0NzUxMSAyMi42NTQyOTI3LDAgMjEuNDQzMTAyNSwwIEwxNS4xMTQ5MDQ2LDAgTDE1LDAgQzE2LjIyNjg2NzksMC4wMzk0MzcwODA1IDE3LjMwMjA1NTcsMC41NTY4NjUwODcgMTguMTYzNTI3MywxLjQwNjYxNjIyIEwyMS4wNDU2ODkxLDQuMjcwMjM1NDIgWiIgaWQ9IlNoYXBlLUNvcHktNyIgZmlsbD0iI0ZGQzg1QSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNDkuMzEwMzIwMyw1LjUyMDAyOTE4IEwzOC41NTE3MDMxLDUuNTIwMDI5MTggTDM2LjgwNjg1OTQsNS41MjAwMjkxOCBMMzIuMjc1NzUsNS41MjAwMjkxOCBMMzAuNTMwOTA2Myw1LjUyMDAyOTE4IEwyNiw1LjUyMDAyOTE4IEwyNC4yNTUxNTYyLDUuNTIwMDI5MTggQzIzLjA3NTQwNjMsNS41MjAwMjkxOCAyMS45NDMxODc1LDUuMDQyODEzMzUgMjEuMTA0MDc4MSw0LjE5MTc2NjMgTDE4LjI4MDQzNzUsMS4zMjgyNjI4OCBDMTcuNDQxMjI2NiwwLjQ3NzIxNTgyOSAxNi4zMDkxMDk0LDAgMTUuMTI5MzU5NCwwIEw4Ljk2NTUzMTI1LDAgTDIuNjg5Njc5NjksMCBDMS4yMDQyMjY1Niw3LjQwNTE1OTIzZS0xNiAwLDEuMjM1NzE2OTkgMCwyLjc2MDAxNDU5IEwwLDguMjgwMDQzNzcgTDAsOS4yMDAwODMzNyBMMCw0My4yMzk5ODU0IEMwLDQ0Ljc2NDI4MyAxLjIwNDIyNjU2LDQ2IDIuNjg5Njc5NjksNDYgTDQ5LjMxMDMyMDMsNDYgQzUwLjc5NTc3MzQsNDYgNTIsNDQuNzY0MjgzIDUyLDQzLjIzOTk4NTQgTDUyLDguMjgwMDQzNzcgQzUyLDYuNzU1NjQxOTUgNTAuNzk1NzczNCw1LjUyMDAyOTE4IDQ5LjMxMDMyMDMsNS41MjAwMjkxOCBMNDkuMzEwMzIwMyw1LjUyMDAyOTE4IFoiIGlkPSJTaGFwZS1Db3B5LTgiIGZpbGw9IiNGRkUwNjYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNi41MDAwMDAsIDI2LjUwMDAwMCkgcm90YXRlKDQ1LjAwMDAwMCkgdHJhbnNsYXRlKC0yNi41MDAwMDAsIC0yNi41MDAwMDApIHRyYW5zbGF0ZSgyMC4wMDAwMDAsIDE0LjAwMDAwMCkiIGZpbGw9IiNGRkE5MjkiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yLjUsMTguMjUgQzIuNSwxOC45NDAzNTU5IDEuOTQwMzU1OTQsMTkuNSAxLjI1LDE5LjUgQzAuNTU5NjQ0MDYzLDE5LjUgMCwxOC45NDAzNTU5IDAsMTguMjUgTDAsNi4yNSBDMCwyLjc5ODIyMDMxIDIuNzk4MjIwMzEsMCA2LjI1LDAgQzkuNzAxNzc5NjksMCAxMi41LDIuNzk4MjIwMzEgMTIuNSw2LjI1IEwxMi41LDIwLjI1IEMxMi41LDIwLjk0MDM1NTkgMTEuOTQwMzU1OSwyMS41IDExLjI1LDIxLjUgQzEwLjU1OTY0NDEsMjEuNSAxMCwyMC45NDAzNTU5IDEwLDIwLjI1IEwxMCw2LjI1IEMxMCw0LjE3ODkzMjE5IDguMzIxMDY3ODEsMi41IDYuMjUsMi41IEM0LjE3ODkzMjE5LDIuNSAyLjUsNC4xNzg5MzIxOSAyLjUsNi4yNSBMMi41LDE4LjI1IFoiIGlkPSJSZWN0YW5nbGUtMzciPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYsNS43NSBDNiw1LjA1OTY0NDA2IDYuNTU5NjQ0MDYsNC41IDcuMjUsNC41IEM3Ljk0MDM1NTk0LDQuNSA4LjUsNS4wNTk2NDQwNiA4LjUsNS43NSBMOC41LDIwLjI1IEM4LjUsMjIuNTk3MjEwMiA2LjU5NzIxMDE5LDI0LjUgNC4yNSwyNC41IEMxLjkwMjc4OTgxLDI0LjUgMCwyMi41OTcyMTAyIDAsMjAuMjUgTDAsOC4yNSBDMCw3LjU1OTY0NDA2IDAuNTU5NjQ0MDYzLDcgMS4yNSw3IEMxLjk0MDM1NTk0LDcgMi41LDcuNTU5NjQ0MDYgMi41LDguMjUgTDIuNSwyMC4yNSBDMi41LDIxLjIxNjQ5ODMgMy4yODM1MDE2OSwyMiA0LjI1LDIyIEM1LjIxNjQ5ODMxLDIyIDYsMjEuMjE2NDk4MyA2LDIwLjI1IEw2LDUuNzUgWiIgaWQ9IlJlY3RhbmdsZS0zNy1Db3B5Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=') no-repeat center;} +.files-grid .icon-product {background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI1MnB4IiBoZWlnaHQ9IjQ2cHgiIHZpZXdCb3g9IjAgMCA1MiA0NiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5Hcm91cCA4PC90aXRsZT4gICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+ICAgIDxkZWZzPjwvZGVmcz4gICAgPGcgaWQ9IlBhZ2UtMiIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgICAgICA8ZyBpZD0iR3JvdXAtOCI+ICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLUNvcHktMiI+ICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMS4wNDU2ODkxLDQuMjcwMjM1NDIgQzIxLjk2MTgwNTksNS4xMDcyMDM2NSAyMy4wMjI3MDA0LDUuNTU3OTY2NTkgMjQuMzY4ODk0NCw1LjUyNTAxMjE4IEwyNi4xNjAyMzgsNS41MjUwMTIxOCBMMzAuODEyMTAxMSw1LjUyNTAxMjE4IEMyOS42MDA5MTA5LDUuNTI1MDEyMTggMjguNDM4NTE4Niw1LjAzNTc1MTEzIDI3LjU3NzA0Nyw0LjE4NTg5NTkzIEwyNC42NzgxNTY2LDEuMzI2NDAyNzEgQzIzLjgxNjU4MDgsMC40NzY1NDc1MTEgMjIuNjU0MjkyNywwIDIxLjQ0MzEwMjUsMCBMMTUuMTE0OTA0NiwwIEwxNSwwIEMxNi4yMjY4Njc5LDAuMDM5NDM3MDgwNSAxNy4zMDIwNTU3LDAuNTU2ODY1MDg3IDE4LjE2MzUyNzMsMS40MDY2MTYyMiBMMjEuMDQ1Njg5MSw0LjI3MDIzNTQyIFoiIGlkPSJTaGFwZSIgZmlsbD0iI0ZGQzg1QSI+PC9wYXRoPiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNDkuMzEwMzIwMyw1LjUyMDAyOTE4IEwzOC41NTE3MDMxLDUuNTIwMDI5MTggTDM2LjgwNjg1OTQsNS41MjAwMjkxOCBMMzIuMjc1NzUsNS41MjAwMjkxOCBMMzAuNTMwOTA2Myw1LjUyMDAyOTE4IEwyNiw1LjUyMDAyOTE4IEwyNC4yNTUxNTYyLDUuNTIwMDI5MTggQzIzLjA3NTQwNjMsNS41MjAwMjkxOCAyMS45NDMxODc1LDUuMDQyODEzMzUgMjEuMTA0MDc4MSw0LjE5MTc2NjMgTDE4LjI4MDQzNzUsMS4zMjgyNjI4OCBDMTcuNDQxMjI2NiwwLjQ3NzIxNTgyOSAxNi4zMDkxMDk0LDAgMTUuMTI5MzU5NCwwIEw4Ljk2NTUzMTI1LDAgTDIuNjg5Njc5NjksMCBDMS4yMDQyMjY1Niw3LjQwNTE1OTIzZS0xNiAwLDEuMjM1NzE2OTkgMCwyLjc2MDAxNDU5IEwwLDguMjgwMDQzNzcgTDAsOS4yMDAwODMzNyBMMCw0My4yMzk5ODU0IEMwLDQ0Ljc2NDI4MyAxLjIwNDIyNjU2LDQ2IDIuNjg5Njc5NjksNDYgTDQ5LjMxMDMyMDMsNDYgQzUwLjc5NTc3MzQsNDYgNTIsNDQuNzY0MjgzIDUyLDQzLjIzOTk4NTQgTDUyLDguMjgwMDQzNzcgQzUyLDYuNzU1NjQxOTUgNTAuNzk1NzczNCw1LjUyMDAyOTE4IDQ5LjMxMDMyMDMsNS41MjAwMjkxOCBMNDkuMzEwMzIwMyw1LjUyMDAyOTE4IFoiIGlkPSJTaGFwZSIgZmlsbD0iI0ZGRTA2NiI+PC9wYXRoPiAgICAgICAgICAgIDwvZz4gICAgICAgICAgICA8ZyBpZD0iR3JvdXAtNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTYuMDAwMDAwLCAxNS4wMDAwMDApIiBmaWxsPSIjRjc5MTJBIj4gICAgICAgICAgICAgICAgPHBhdGggZD0iTTEwLDIuNzc3MDUzNjEgTDIuNjQ1NDU5NTgsNi40NzI0OTI4NyBMMy4wOTU2OTA0OSwxNC4zMTU5ODk5IEwxMCwxOS4wNzAyNDUzIEwxNi45MDQzMDk1LDE0LjMxNTk4OTkgTDE3LjM1NDU0MDQsNi40NzI0OTI4NyBMMTAsMi43NzcwNTM2MSBaIE0xMC40NDg5Nzg3LDAuMTA2MDUxOTIzIEwxOS40NDg5Mzk4LDQuNjI4MjY2NDcgQzE5LjgwNTI4MTIsNC44MDczMTc0NyAyMC4wMjExNzE3LDUuMTgwOTc1NTggMTkuOTk4MzE3Nyw1LjU3OTExNjQxIEwxOS40NDM3Mzc4LDE1LjI0MDQ4MjQgQzE5LjQyNjAzOTcsMTUuNTQ4ODAyNiAxOS4yNjY4NzgxLDE1LjgzMTY0ODIgMTkuMDEyNTIwOSwxNi4wMDY3OTY2IEwxMC41NjcxMzk3LDIxLjgyMjIyMjQgQzEwLjIyNTYxNTIsMjIuMDU3MzkzNiA5Ljc3NDM4NDc3LDIyLjA1NzM5MzYgOS40MzI4NjAzNSwyMS44MjIyMjI0IEwwLjk4NzQ3OTA5OCwxNi4wMDY3OTY2IEMwLjczMzEyMTk0NywxNS44MzE2NDgyIDAuNTczOTYwMzA2LDE1LjU0ODgwMjYgMC41NTYyNjIxNzMsMTUuMjQwNDgyNCBMMC4wMDE2ODIyOTQ2OSw1LjU3OTExNjQxIEMtMC4wMjExNzE3MDg3LDUuMTgwOTc1NTggMC4xOTQ3MTg4MjcsNC44MDczMTc0NyAwLjU1MTA2MDE4Myw0LjYyODI2NjQ3IEw5LjU1MTAyMTMxLDAuMTA2MDUxOTIzIEM5LjgzMzUxMjMxLC0wLjAzNTg5MTQ1NTcgMTAuMTY2NDg3NywtMC4wMzU4OTE0NTU3IDEwLjQ0ODk3ODcsMC4xMDYwNTE5MjMgWiIgaWQ9IlBvbHlnb24iIGZpbGwtcnVsZT0ibm9uemVybyI+PC9wYXRoPiAgICAgICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLTMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgeD0iOC41IiB5PSIxMSIgd2lkdGg9IjMiIGhlaWdodD0iOSI+PC9yZWN0PiAgICAgICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLTMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNi4wODAxMjcsIDguNzk5MDM4KSByb3RhdGUoMTIwLjAwMDAwMCkgdHJhbnNsYXRlKC02LjA4MDEyNywgLTguNzk5MDM4KSAiIHg9IjQuNTgwMTI3MDIiIHk9IjMuNzk5MDM4MTEiIHdpZHRoPSIzIiBoZWlnaHQ9IjEwIj48L3JlY3Q+ICAgICAgICAgICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUtMyIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNC4wODAxMjcsIDguNzk5MDM4KSBzY2FsZSgtMSwgMSkgcm90YXRlKDEyMC4wMDAwMDApIHRyYW5zbGF0ZSgtMTQuMDgwMTI3LCAtOC43OTkwMzgpICIgeD0iMTIuNTgwMTI3IiB5PSIzLjc5OTAzODExIiB3aWR0aD0iMyIgaGVpZ2h0PSIxMCI+PC9yZWN0PiAgICAgICAgICAgIDwvZz4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==) no-repeat center;} +.files-grid .icon-execution {background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI1MnB4IiBoZWlnaHQ9IjQ2cHgiIHZpZXdCb3g9IjAgMCA1MiA0NiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5Hcm91cCA5PC90aXRsZT4gICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+ICAgIDxkZWZzPjwvZGVmcz4gICAgPGcgaWQ9IlBhZ2UtMiIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgICAgICA8ZyBpZD0iR3JvdXAtOSI+ICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLUNvcHkiPiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjEuMDQ1Njg5MSw0LjI3MDIzNTQyIEMyMS45NjE4MDU5LDUuMTA3MjAzNjUgMjMuMDIyNzAwNCw1LjU1Nzk2NjU5IDI0LjM2ODg5NDQsNS41MjUwMTIxOCBMMjYuMTYwMjM4LDUuNTI1MDEyMTggTDMwLjgxMjEwMTEsNS41MjUwMTIxOCBDMjkuNjAwOTEwOSw1LjUyNTAxMjE4IDI4LjQzODUxODYsNS4wMzU3NTExMyAyNy41NzcwNDcsNC4xODU4OTU5MyBMMjQuNjc4MTU2NiwxLjMyNjQwMjcxIEMyMy44MTY1ODA4LDAuNDc2NTQ3NTExIDIyLjY1NDI5MjcsMCAyMS40NDMxMDI1LDAgTDE1LjExNDkwNDYsMCBMMTUsMCBDMTYuMjI2ODY3OSwwLjAzOTQzNzA4MDUgMTcuMzAyMDU1NywwLjU1Njg2NTA4NyAxOC4xNjM1MjczLDEuNDA2NjE2MjIgTDIxLjA0NTY4OTEsNC4yNzAyMzU0MiBaIiBpZD0iU2hhcGUiIGZpbGw9IiNGRkM4NUEiPjwvcGF0aD4gICAgICAgICAgICAgICAgPHBhdGggZD0iTTQ5LjMxMDMyMDMsNS41MjAwMjkxOCBMMzguNTUxNzAzMSw1LjUyMDAyOTE4IEwzNi44MDY4NTk0LDUuNTIwMDI5MTggTDMyLjI3NTc1LDUuNTIwMDI5MTggTDMwLjUzMDkwNjMsNS41MjAwMjkxOCBMMjYsNS41MjAwMjkxOCBMMjQuMjU1MTU2Miw1LjUyMDAyOTE4IEMyMy4wNzU0MDYzLDUuNTIwMDI5MTggMjEuOTQzMTg3NSw1LjA0MjgxMzM1IDIxLjEwNDA3ODEsNC4xOTE3NjYzIEwxOC4yODA0Mzc1LDEuMzI4MjYyODggQzE3LjQ0MTIyNjYsMC40NzcyMTU4MjkgMTYuMzA5MTA5NCwwIDE1LjEyOTM1OTQsMCBMOC45NjU1MzEyNSwwIEwyLjY4OTY3OTY5LDAgQzEuMjA0MjI2NTYsNy40MDUxNTkyM2UtMTYgMCwxLjIzNTcxNjk5IDAsMi43NjAwMTQ1OSBMMCw4LjI4MDA0Mzc3IEwwLDkuMjAwMDgzMzcgTDAsNDMuMjM5OTg1NCBDMCw0NC43NjQyODMgMS4yMDQyMjY1Niw0NiAyLjY4OTY3OTY5LDQ2IEw0OS4zMTAzMjAzLDQ2IEM1MC43OTU3NzM0LDQ2IDUyLDQ0Ljc2NDI4MyA1Miw0My4yMzk5ODU0IEw1Miw4LjI4MDA0Mzc3IEM1Miw2Ljc1NTY0MTk1IDUwLjc5NTc3MzQsNS41MjAwMjkxOCA0OS4zMTAzMjAzLDUuNTIwMDI5MTggTDQ5LjMxMDMyMDMsNS41MjAwMjkxOCBaIiBpZD0iU2hhcGUiIGZpbGw9IiNGRkUwNjYiPjwvcGF0aD4gICAgICAgICAgICA8L2c+ICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLTUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE2LjAwMDAwMCwgMTQuMDAwMDAwKSIgZmlsbD0iI0Y3OTEyQSI+ICAgICAgICAgICAgICAgIDxnPiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIuMzAyMjI4ODIsOCBMMi44ODU4ODIzNSw4IEwyLjg4NTg4MjM1LDcuNzAxMjY5NDIgTDIuMzAyMjI4ODIsOCBaIE0yLjg4NTg4MjM1LDcuNzAxMjY5NDIgTDEwLDQuMDYwMDYwNDcgTDE3LjExNDExNzYsNy43MDEyNjk0MiBMMTcuMTE0MTE3Niw2LjcyNzgzMzQ5IEMxNy4xMTQxMTc2LDcuMjMzMTgzNTMgMTcuMzUzNDc1OCw3LjcwMjUzNDMzIDE3Ljc0OTA5MTcsOCBMMjAsOCBMMjAsNi43Mjc4MzM0OSBDMjAsNi4yNDIwNDU1MSAxOS43Mjc5NDE1LDUuNzk3MTc0ODUgMTkuMjk1NTA0OSw1LjU3NTg0MTQgTDEwLjU4OTYyMjUsMS4xMTk5MjE3MyBDMTAuMjE5Mzc5OSwwLjkzMDQyMDk5MyA5Ljc4MDYyMDA2LDAuOTMwNDIwOTkzIDkuNDEwMzc3NDksMS4xMTk5MjE3MyBMMC43MDQ0OTUxMzYsNS41NzU4NDE0IEMwLjI3MjA1ODQ3NSw1Ljc5NzE3NDg1IDcuMDg5NzYzNzJlLTE0LDYuMjQyMDQ1NTEgNy4wOTU3MTI5MWUtMTQsNi43Mjc4MzM0OSBMNy4wOTU3MTI5MWUtMTQsOCBMMi4yNTA5MDgyNyw4IEMyLjY0NjUyNDIsNy43MDI1MzQzMyAyLjg4NTg4MjM1LDcuMjMzMTgzNTMgMi44ODU4ODIzNSw2LjcyNzgzMzQ5IEwyLjg4NTg4MjM1LDcuNzAxMjY5NDIgWiBNMTAuNzI1MjM1NywzLjY4ODg2NDEgQzEwLjI2OTgzNzMsMy45MjE5NTAwMSA5LjczMDE2MjY3LDMuOTIxOTUwMDEgOS4yNzQ3NjQzMSwzLjY4ODg2NDEgTDEwLDQuMDYwMDYwNDcgTDEwLjcyNTIzNTcsMy42ODg4NjQxIFogTTE3LjY5Nzc3MTIsOCBMMTcuMTE0MTE3Niw4IEwxNy4xMTQxMTc2LDcuNzAxMjY5NDIgTDE3LjY5Nzc3MTIsOCBaIE0xNy42OTc3NzEyLDggTDE3LjExNDExNzYsOCBMMTcuMTE0MTE3Niw3LjcwMTI2OTQyIEwxNy42OTc3NzEyLDggWiBNMTcuMTE0MTE3Niw2LjcyNzgzMzQ5IEMxNy4xMTQxMTc2LDcuMjMzMTgzNTMgMTcuMzUzNDc1OCw3LjcwMjUzNDMzIDE3Ljc0OTA5MTcsOCBMMjAsOCBMMjAsNi43Mjc4MzM0OSBDMjAsNi4yNDIwNDU1MSAxOS43Mjc5NDE1LDUuNzk3MTc0ODUgMTkuMjk1NTA0OSw1LjU3NTg0MTQgTDEwLjU4OTYyMjUsMS4xMTk5MjE3MyBDMTAuMjE5Mzc5OSwwLjkzMDQyMDk5MyA5Ljc4MDYyMDA2LDAuOTMwNDIwOTkzIDkuNDEwMzc3NDksMS4xMTk5MjE3MyBMMC43MDQ0OTUxMzYsNS41NzU4NDE0IEMwLjI3MjA1ODQ3NSw1Ljc5NzE3NDg1IDcuMDg5NzYzNzJlLTE0LDYuMjQyMDQ1NTEgNy4wOTU3MTI5MWUtMTQsNi43Mjc4MzM0OSBMNy4wOTU3MTI5MWUtMTQsOCBMMi4yNTA5MDgyNyw4IEMyLjY0NjUyNDIsNy43MDI1MzQzMyAyLjg4NTg4MjM1LDcuMjMzMTgzNTMgMi44ODU4ODIzNSw2LjcyNzgzMzQ5IEwyLjg4NTg4MjM1LDcuNzAxMjY5NDIgTDEwLDQuMDYwMDYwNDcgTDE3LjExNDExNzYsNy43MDEyNjk0MiBMMTcuMTE0MTE3Niw2LjcyNzgzMzQ5IFogTTEwLjcyNTIzNTcsMy42ODg4NjQxIEMxMC4yNjk4MzczLDMuOTIxOTUwMDEgOS43MzAxNjI2NywzLjkyMTk1MDAxIDkuMjc0NzY0MzEsMy42ODg4NjQxIEwxMCw0LjA2MDA2MDQ3IEwxMC43MjUyMzU3LDMuNjg4ODY0MSBaIE0yLjg4NTg4MjM1LDggTDIuMzAyMjI4ODIsOCBMMi44ODU4ODIzNSw3LjcwMTI2OTQyIEwyLjg4NTg4MjM1LDggWiIgaWQ9IlBvbHlnb24iIGZpbGwtcnVsZT0ibm9uemVybyI+PC9wYXRoPiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLjAwMDAwMCwgNS4yMzUyOTQpIj4gICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOS40NTU1ODQ1OSw3LjczNTcwNDIgTDAsMi43NjQ3MDU4OCBMMS41NDIyMjMxNywwLjM0MDc0OTg1NSBMMi4yNDk5MTAzNCwwLjY4MjUzOTMzNyBMMTAuMDYzNDk0Niw0Ljg3MDgyMzIxIEwxOC40NjEwOTQ5LDAuMzMzNDQ4ODE5IEwyMCwyLjc2NDcwNTg4IEwxMC42NjU3OTQ1LDcuNzMyNjI3NzggQzEwLjI4Nzc0OTcsNy45MzM4MzM2MyA5LjgzNDY0NzQxLDcuOTM0OTg1NDUgOS40NTU1ODQ1OSw3LjczNTcwNDIgWiIgaWQ9IkNvbWJpbmVkLVNoYXBlIj48L3BhdGg+ICAgICAgICAgICAgICAgICAgICA8L2c+ICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOS40NjgwMDk5MywyMi44MzM4ODE0IEwwLjEwNTQ1MjQ3NCwxNy43NTcxMDAxIEwxLjY0MDY4NDI3LDE1LjMzMzE0NCBMMi4zNDUxNjMyNywxNS42NzQ5MzM1IEwxMC4xMjMzMjYyLDIwLjAwNDcyMiBMMTguNDgyODU3NiwxNS40NjczNDc2IEwyMC4wMTQ3ODYzLDE3Ljg5ODYwNDcgTDEwLjc3Njg3MTIsMjIuODM3NjY4NSBDMTAuNTcxNjk3NSwyMi45NDczNjQ4IDEwLjM0NDIwMzUsMjMuMDAxNDUzNSAxMC4xMTcwNDQ3LDIzIEM5Ljg5MzE0MjMzLDIyLjk5ODU2NzMgOS42Njk1NjU2NCwyMi45NDMxNzM1IDkuNDY4MDA5OTMsMjIuODMzODgxNCBaIiBpZD0iQ29tYmluZWQtU2hhcGUiPjwvcGF0aD4gICAgICAgICAgICAgICAgICAgIDxnIGlkPSJHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsIDkuNDExNzY1KSI+ICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTkuMzk3MTI0OSw4LjQ2OTc0MjA4IEwwLjExMDQ5OTM5NSwzLjM3NzQ4OTg4IEwxLjYyODY1MzgsMC45NTM1MzM4NDggTDIuMzI1Mjk2NDIsMS4yOTUzMjMzMyBMMTAuMDE2OTM3Nyw1LjYyNTExMTgzIEwxOC4yODM0ODA1LDEuMDg3NzM3NDQgTDE5Ljc5ODM2ODYsMy41MTg5OTQ1IEwxMC42MzQ4MjUxLDguNDczNDA2NTcgQzEwLjI0ODM3OTcsOC42ODIzNDQyOCA5Ljc4MjMyNjMzLDguNjgwOTY0NDIgOS4zOTcxMjQ5LDguNDY5NzQyMDggWiIgaWQ9IkNvbWJpbmVkLVNoYXBlIj48L3BhdGg+ICAgICAgICAgICAgICAgICAgICA8L2c+ICAgICAgICAgICAgICAgIDwvZz4gICAgICAgICAgICA8L2c+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=) no-repeat center;} +.files-grid .icon-product:before, +.files-grid .icon-execution:before, +.files-grid .icon-paper-clip:before, +.files-grid .icon-folder:before {display: none;} +.files-grid .img-holder {height: 64px; line-height: 64px; margin: 0 auto 8px; width: 100%; background-size: contain; background-repeat: no-repeat; background-position: center;} +.files-grid .img-holder > img {max-height: 64px; opacity: 0; width: 100%;} +.files-grid + .table-footer {margin-top: 20px;} + +@keyframes flash-icon +{ + 0% {color: #666;} + 100% {color: #fff;} +} + +.main-col > .panel > .panel-body {padding: 5px 10px;} +.main-col .panel-title a.active {color: #0c64eb;} + +.side-col > .cell {overflow: hidden auto; position: relative;} +.side-col > .cell > header {position: absolute; top: 10px; right: 10px; left: 10px;} +.side-col > .cell > header > .c-sm {padding-right: 20px; width: 60px;} +.side-col .docsTree {position: absolute; top: 53px; left: 0; right: 0; bottom: 0; overflow: auto; padding: 0 10px 10px;} + +td.c-name a {color: #0c60e1;} +td.c-name a:visited {color: #082999;} + +.panel-title.font-normal .btn-group {margin-left: 20px;} + +.querybox-opened {color: #0c64eb; background: rgba(0,0,0,.075);} + +#queryBox #groupAndOr {min-width: 65px;} +#noticeAcl {margin-left: 10px;} + +#pageNav .dropdown-menu {max-height: 350px; overflow-y: auto;} + +ol, ul {margin-bottom: 0} +#subHeader #dropMenu .table-col .list-group {padding-top: 5px;} +#createDropdown ul.dropdown-menu {text-align: left;} +#collection-menu {max-width: 300px;} +#collection-menu li a {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} +#project, #product, #custom, #book, #execution {min-height: 160px;} +#title .menu-title {font-size: 15px; font-weight: 600; position: relative; padding: 2px 0 2px 15px; list-style: none;} +#title .dropdown-menu {top: 38px;} +.tree li > a {white-space: nowrap; text-overflow: ellipsis; overflow: hidden;} +.side-col .menu-actions {position: absolute; top: 0; right: 0; padding: 7px 8px;} +.menu-actions i {font-size: 15px; color: #8c8c8c;} +#whiteListBox .chosen-container .chosen-results {max-height: 180px;} + +.c-product, .c-execution, .c-lib {width: 80px !important;} + +.header-btn .btn > .text {text-overflow: unset !important;} diff --git a/module/api/css/create.css b/module/api/css/create.css new file mode 100644 index 0000000000..1128dfc974 --- /dev/null +++ b/module/api/css/create.css @@ -0,0 +1,17 @@ +#paramDiv .input-group { + padding: 3px; +} +#paramDiv .form-control { + display: table-cell; + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.table-row { + margin-bottom: 10px; +} +.col-custom { + margin-bottom: 10px; +} \ No newline at end of file diff --git a/module/api/css/createlib.css b/module/api/css/createlib.css new file mode 100644 index 0000000000..afd4e4895c --- /dev/null +++ b/module/api/css/createlib.css @@ -0,0 +1,5 @@ +.modal-dialog {width: 75%;} +form {margin-bottom: 100px; padding-left: 65px;} +table {width: 90% !important;} +#whiteListBox div.input-group {margin-bottom: 2px;} +#whiteListBox .input-group:last-child {margin-top: 10px;} diff --git a/module/api/css/edit.css b/module/api/css/edit.css new file mode 100644 index 0000000000..1128dfc974 --- /dev/null +++ b/module/api/css/edit.css @@ -0,0 +1,17 @@ +#paramDiv .input-group { + padding: 3px; +} +#paramDiv .form-control { + display: table-cell; + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.table-row { + margin-bottom: 10px; +} +.col-custom { + margin-bottom: 10px; +} \ No newline at end of file diff --git a/module/api/css/index.css b/module/api/css/index.css new file mode 100644 index 0000000000..f33fb65e1d --- /dev/null +++ b/module/api/css/index.css @@ -0,0 +1,124 @@ +.lib {width: 130px; margin-bottom: 10px;} +.addbtn {padding-top: 22px; height: 63px; border: 1px dashed #ddd; width: 60px;} +.addbtn .icon-plus {font-size: 18px; display: block; opacity: 0.5; transition: opacity .2s; text-shadow: 1px 1px 3px rgba(0,0,0,.2);} +.addbtn:hover .icon-plus {opacity: .9; animation: flash-icon 1s linear alternate infinite;} +#subHeader #dropMenu {min-width: 250px; box-sizing: inhert; max-height: inherit;} +#subHeader #dropMenu .table-col .list-group {padding-top: 10px;} +.main-col .block-files .panel-heading {padding-right: 20px;} +.main-col .block-files .panel-heading .panel-title {height: 35px; line-height: 30px;} +.side-col .action a {margin: 0 auto 3px; display: block; max-width: 200px;} +.side-col .tips {padding: 0 10px;} +.main-col .doc-title {display: flex; font-size: 16px; margin-bottom: 15px;} +.main-col .doc-title .title {margin-right: 10px; line-height: 30px; font-size: 25px;} +.main-col .doc-title .http-method { line-height: 30px; font-size: 16px;margin-right: 10px; padding: 0 8px } +.main-col .doc-title .path { line-height: 30px; font-size: 16px;margin-right: 10px; } +.main-col .doc-title .info {flex: 1 1 0;} +.main-col .doc-title .version a {font-size: 13px; color: #8c8c8c;} +.main-col .doc-title .version .dropdown-menu a:hover {color: #ffffff;} +.main-col .doc-title .actions a + a {margin-left: 8px;} +.main-col .doc-title .actions i {font-size: 15px; color: #8c8c8c;} +#content .title {max-width: 54%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} +#content .detail-content {padding-left: 10px;} +#mainContent .scrollbar-hover {max-height: 2000px; overflow: scroll;} +#sidebar {width: 275px;} +#sidebar>.cell {width: 100%;} +#sidebar>.sidebar-toggle {left: 3px; right: auto;} +.hide-sidebar #sidebar>.cell {display: none;} +.hide-sidebar #sidebar>.sidebar-toggle>.icon:before {content: "\e314";} +.detail.empty {line-height: 200px;} +.main-col+.side-col {padding-left: 16px;} +.main-col iframe {min-height: 380px;} +.article-content .keywords {margin-bottom: 15px;} + +.article-content {width: 100%; display: inline-block;} +.outline {position: relative;} +.outline .outline-toggle i.icon-angle-right, i.icon-angle-left {width: 18px; height: 18px; background: #efefef; border-radius: 50%; position: absolute; padding-left: 2px; padding-top: 1px;} +.outline .outline-toggle i.icon-angle-right:before {content: "\e314"; cursor: pointer;} +.outline .outline-toggle i.icon-angle-left:before {content: "\e315"; cursor: pointer;} +.outline ul li {list-style: none;} +.outline-content {display: none; padding-top: 18px;} +.outline-content a {color: #838A9D;} +.outline-content li.text-ellipsis.active>a {font-weight: 700; color: #0c64eb;} +#outline li.has-list.open:before {content: unset;} + +.title {font-size: 20px !important;} +.article-content.comment {width: 100% !important;} + +.cell .detail .detail-title {padding-left: 5px; list-style: none;} +.menu-actions {position: absolute; top: 7px; right: 45px; padding: 7px 8px;} +.no-content {width: 100px; height: 100px; margin: 0 auto;} +.notice {text-align: center; padding-left: 15px; padding-top: 20px;} +.no-content-button {text-align: center; padding-top: 20px;} +.no-content-button a:nth-child(2) {margin-left: 20px;} + +.detail .list-group-item .heading.GET { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.detail .list-group-item .heading.GET a { + color: #0f6ab4; +} + +.detail .list-group-item .heading.OPTIONS { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.detail .list-group-item .heading.OPTIONS a { + color: #0f6ab4; +} + +.detail .list-group-item .heading.POST { + background-color: #e7f6ec; + border: 1px solid #c3e8d1; +} +.detail .list-group-item .heading.POST a { + color: #10a54a; +} + +.detail .list-group-item .heading.PUT { + background-color: #f9f2e9; + border: 1px solid #f0e0ca; +} +.detail .list-group-item .heading.PUT a { + color: #c5862b; +} +.detail .list-group-item .heading.PATCH { + background-color: #f9f2e9; + border: 1px solid #f0e0ca; +} +.detail .list-group-item .heading.PATCH a { + color: #c5862b; +} + +.detail .list-group-item .heading.DELETE { + background-color: #f5e8e8; + border: 1px solid #e8c6c7; +} +.detail .list-group-item .heading.DELETE a { + color: #a41e22; +} + +.detail .list-group-item .path { + padding-left: 10px; + font-size: 14px; + color: black +} +.detail .list-group-item .desc { + width: auto; + font-size: 14px; + line-height: 30px; + float: right; + padding-right: 10px; +} +.detail .list-group-item {list-style: none; font-size: 14px; margin-bottom: 10px; line-height: 30px} +.detail .list-group-item span { + line-height: 30px; + width: 50px; +} + +.paramsTable th { + text-align: center!important; +} +.paramsTable td { + text-align: center; +} \ No newline at end of file diff --git a/module/api/js/common.js b/module/api/js/common.js new file mode 100644 index 0000000000..d863d4a641 --- /dev/null +++ b/module/api/js/common.js @@ -0,0 +1,163 @@ +/** + * Toggle acl. + * + * @param string $acl + * @param string $type + * @access public + * @return void + */ +function toggleAcl(acl, type) +{ + console.log(noticeAcl, acl); + if(acl == 'custom') + { + $('#whiteListBox').removeClass('hidden'); + } + else + { + $('#whiteListBox').addClass('hidden'); + } + if(type == 'lib') + { + var notice = typeof(noticeAcl[acl]) != 'undefined' ? noticeAcl[acl] : ''; + $('#noticeAcl').html(notice); + } + else + { + var notice = typeof(noticeAcl[acl]) != 'undefined' ? noticeAcl[acl] : ''; + $('#noticeAcl').html(notice); + } +} + + +$(document).ready(function() +{ + var NAME = 'zui.splitRow'; // model name. + + /* The SplitRow model class. */ + var SplitRow = function(element, options) + { + var that = this; + that.name = NAME; + var $element = that.$ = $(element); + + options = that.options = $.extend({}, SplitRow.DEFAULTS, this.$.data(), options); + var id = options.id || $element.attr('id') || $.zui.uuid(); + var $cols = $element.children('.side-col,.main-col'); + var $firstCol = $cols.first(); + var $secondCol = $cols.eq(1); + var $spliter = $firstCol.next('.col-spliter'); + if (!$spliter.length) + { + $spliter = $(options.spliter); + if (!$spliter.parent().length) + { + $spliter.insertAfter($firstCol); + } + } + var spliterWidth = $spliter.width(); + var minFirstColWidth = $firstCol.data('minWidth'); + var minSecondColWidth = $secondCol.data('minWidth'); + var setFirstColWidth = function(width) + { + var rowWidth = $element.width(); + var maxFirstWidth = rowWidth - minSecondColWidth - spliterWidth; + width = Math.max(minFirstColWidth, Math.min(width, maxFirstWidth)); + $firstCol.width(width); + $.zui.store.set('splitRowFirstSize:' + id, width); + }; + + var defaultWidth = $.zui.store.get('splitRowFirstSize:' + id); + if(typeof(defaultWidth) == 'undefined') + { + defaultWidth = 0; + $firstCol.find('.tabs ul.nav-tabs li').each(function(){defaultWidth += $(this).outerWidth()}); + defaultWidth += ($firstCol.find('.tabs ul.nav-tabs li').length - 1) * 10; + defaultWidth += 30; + } + setFirstColWidth(defaultWidth); + + var documentEventName = '.' + id; + + var mouseDownX, isMouseDown, startFirstWidth; + $spliter.on('mousedown', function(e) + { + startFirstWidth = $firstCol.width(); + mouseDownX = e.pageX; + isMouseDown = true; + $element.addClass('row-spliting'); + e.preventDefault(); + $(document).on('mousemove' + documentEventName, function(e) + { + if (isMouseDown) + { + var deltaX = e.pageX - mouseDownX; + setFirstColWidth(startFirstWidth + deltaX); + e.preventDefault(); + } + else + { + $(document).off(documentEventName); + $element.removeClass('row-spliting'); + } + }).on('mouseup' + documentEventName + ' mouseleave' + documentEventName, function(e) + { + isMouseDown = false; + $(document).off(documentEventName); + $element.removeClass('row-spliting'); + }); + }); + + var fixColClass = function($col) + { + if (options.smallSize) $col.toggleClass('col-sm-size', $col.width() < options.smallSize); + if (options.middleSize) $col.toggleClass('col-md-size', $col.width() < options.middleSize); + }; + + var resizeCols = function() + { + var cellHeight = $(window).height() - $('#footer').outerHeight() - $('#header').outerHeight() - 42; + $cols.children('.panel').height(cellHeight).css('maxHeight', cellHeight).find('.panel-body').css('position', 'absolute'); + var sideHeight = cellHeight - $cols.find('.nav-tabs').height() - $cols.find('.side-footer').height() - 35; + $cols.find('.tab-content').height(sideHeight).css('maxHeight', sideHeight).css('overflow-y', 'auto'); + }; + + $(window).on('resize', resizeCols); + $firstCol.on('resize', function(e) {fixColClass($firstCol);}); + $secondCol.on('resize', function(e) {fixColClass($secondCol);}); + fixColClass($firstCol); + fixColClass($secondCol); + resizeCols(); + }; + + /* default options. */ + SplitRow.DEFAULTS = + { + spliter: '
', + smallSize: 700, + middleSize: 850 + }; + + /* Extense jquery element. */ + $.fn.splitRow = function(option) + { + return this.each(function() + { + var $this = $(this); + var data = $this.data(NAME); + var options = typeof option == 'object' && option; + if(!data) $this.data(NAME, (data = new SplitRow(this, options))); + }); + }; + + SplitRow.NAME = NAME; + + $.fn.splitRow.Constructor = SplitRow; + + /* Auto call splitRow after document load complete. */ + $(function() + { + $('.split-row').splitRow(); + }); + +}); \ No newline at end of file diff --git a/module/api/js/create.js b/module/api/js/create.js new file mode 100644 index 0000000000..5a0a440f0e --- /dev/null +++ b/module/api/js/create.js @@ -0,0 +1,80 @@ +var currentParam = null +var paramsLen = 0 +$(document).ready(function() +{ + $('.col-custom').html() + + $('.customType').click(function () { + currentParam = $(this).parents('.col-custom') + }) + + $('.submit-custom').click(function () { + var val = $(this).parent().prev().find('.customTypeTextarea').val() + currentParam.find('.custom').val(val) + $('#customType').modal('hide') + }) + + $('#customType').on('shown.zui.modal', () => { + var val = currentParam.find('.custom').val() + var newVal = val ? val : example; + $('.customTypeTextarea').val(newVal); + }) + $('.formatCustom').click(function () { + var text = $(this).parent().prev().find('.customTypeTextarea') + var val = text.val() + console.log(val); + try { + var format = JSON.stringify(JSON.parse(val), null, ' '); + text.val(format); + } catch (e) { + } + }); +}); + +function addItem(t) +{ + var html = $(t).parents('#paramDiv').find('.col-custom:first').html() + paramsLen += 1 + html = html.replace(/params\[\d\]/g, 'params['+ paramsLen +']') + $('#paramDiv').append('
' + html + '
') + changeType($('#paramDiv .col-custom').last().find('#paramsTypeOptions')); +} + +function deleteItem(t) +{ + if ($('.col-custom').length < 2) { + return false + } + $(t).parents('.col-custom').remove() +} + +/** + * Load params type options by scope + */ +function loadParamsTypeOptions(t) +{ + var field = $(t).attr('name'); + var scope = $(t).val(); + field = field.replace('scope', 'paramsType') + + var url = createLink('api', 'ajaxGetParamsTypeOptions', 'scope='+ scope) + $.get(url, function(data) + { + data = data.replace('paramsTypeOptions', field) + $(t).parents('.col-custom').find('select[name="'+ field +'"]').replaceWith(data) + }); +} + +function changeType(t) +{ + var val = $(t).val() + + console.log(val) + var customRef = $(t).parents('.col-custom').find('.typeCustom') + if (val == 'custom') { + customRef.removeClass('hidden') + } else { + customRef.addClass('hidden') + } + +} \ No newline at end of file diff --git a/module/api/js/createlib.js b/module/api/js/createlib.js new file mode 100644 index 0000000000..4215cd9cf4 --- /dev/null +++ b/module/api/js/createlib.js @@ -0,0 +1,13 @@ +$(document).ready(function() +{ + $('#apiForm').ajaxForm({ + success: (data) => { + if (data.result == 'success') { + if (data.locate) { + window.parent.location.href = data.locate + } + $.zui.closeModal() + } + } + }) +}); \ No newline at end of file diff --git a/module/api/js/edit.js b/module/api/js/edit.js new file mode 100644 index 0000000000..787e721d25 --- /dev/null +++ b/module/api/js/edit.js @@ -0,0 +1,87 @@ +var currentParam = null +var paramsLen = 0 +$(document).ready(function() +{ + + $('#top-submit').click(function() + { + $(this).addClass('disabled'); + $('form').submit(); + }) + + $('.col-custom').html() + + $('.customType').click(function () { + currentParam = $(this).parents('.col-custom') + }) + + $('.submit-custom').click(function () { + var val = $(this).parent().prev().find('.customTypeTextarea').val() + currentParam.find('.custom').val(val) + $('#customType').modal('hide') + }) + + $('#customType').on('shown.zui.modal', () => { + var val = currentParam.find('.custom').val() + var newVal = val ? val : example; + $('.customTypeTextarea').val(newVal); + }) + $('.formatCustom').click(function () { + var text = $(this).parent().prev().find('.customTypeTextarea') + var val = text.val() + console.log(val); + try { + var format = JSON.stringify(JSON.parse(val), null, ' '); + text.val(format); + } catch (e) { + } + }); +}); + +function addItem(t) +{ + var html = $(t).parents('#paramDiv').find('.col-custom:first').html() + paramsLen += 1 + html = html.replace(/params\[\d\]/g, 'params['+ paramsLen +']') + $('#paramDiv').append('
' + html + '
') + changeType($('#paramDiv .col-custom').last().find('#paramsTypeOptions')); +} + +function deleteItem(t) +{ + if ($('.col-custom').length < 2) { + return false + } + $(t).parents('.col-custom').remove() +} + +/** + * Load params type options by scope + */ +function loadParamsTypeOptions(t) +{ + var field = $(t).attr('name'); + var scope = $(t).val(); + field = field.replace('scope', 'paramsType') + + var url = createLink('api', 'ajaxGetParamsTypeOptions', 'scope='+ scope) + $.get(url, function(data) + { + data = data.replace('paramsTypeOptions', field) + $(t).parents('.col-custom').find('select[name="'+ field +'"]').replaceWith(data) + }); +} + +function changeType(t) +{ + var val = $(t).val() + + console.log(val) + var customRef = $(t).parents('.col-custom').find('.typeCustom') + if (val == 'custom') { + customRef.removeClass('hidden') + } else { + customRef.addClass('hidden') + } + +} \ No newline at end of file diff --git a/module/api/js/index.js b/module/api/js/index.js new file mode 100644 index 0000000000..6dd023c9c9 --- /dev/null +++ b/module/api/js/index.js @@ -0,0 +1,116 @@ +$(document).ready(function() +{ + + /* Update doc content silently on switch doc version, story #40503 */ + $(document).on('click', '.api-version-menu a, #mainActions .container a', function(event) + { + var $tmpDiv = $('
'); + $tmpDiv.load($(this).data('url') + ' #mainContent', function() + { + $('#content').html($tmpDiv.find('#content').html()); + $('#sidebarContent').html($tmpDiv.find('#sidebarContent').html()); + $('#actionbox .histories-list').html($tmpDiv.find('#actionbox .histories-list').html()); + if($.cookie('isFullScreen') == 1) fullScreen(); + $('#content [data-ride="tree"]').tree(); + $('#outline li.has-list').addClass('open in'); + $('#outline li.has-list>i+ul').prev('i').remove(); + }); + }); +}); + +/** + * Ajax delete api doc. + * + * @param string $link + * @param int $replaceID + * @param stirng $notice + * @access public + * @return void + */ +function ajaxDeleteApi(link, replaceID) +{ + if(confirm(confirmDelete)) + { + $.get(link, function(data) + { + location.href = JSON.parse(data).locate; + }); + } +} + +/** + * Display the document in full screen. + * + * @access public + * @return void + */ +function fullScreen() +{ + var element = document.getElementById('content'); + var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen; + if(requestMethod) + { + var afterEnterFullscreen = function() + { + $('#mainActions').removeClass('hidden'); + $('#content').addClass('scrollbar-hover'); + $('#content .actions').addClass('hidden'); + $.cookie('isFullScreen', 1); + }; + + var whenFailEnterFullscreen = function(error) + { + $.cookie('isFullScreen', 0); + }; + + try + { + var result = requestMethod.call(element); + if(result && (typeof result.then === 'function' || result instanceof window.Promise)) + { + result.then(afterEnterFullscreen).catch(whenFailEnterFullscreen); + } + else + { + afterEnterFullscreen(); + } + } + catch (error) + { + whenFailEnterFullscreen(error); + } + } +} + +/** + * Exit full screen. + * + * @access public + * @return void + */ +function exitFullScreen() +{ + $('#mainActions').addClass('hidden'); + $('#content').removeClass('scrollbar-hover'); + $('#content .actions').removeClass('hidden'); + $.cookie('isFullScreen', 0); +} +document.addEventListener('fullscreenchange', function (e) +{ + if(!document.fullscreenElement) exitFullScreen(); +}); + +document.addEventListener('webkitfullscreenchange', function (e) +{ + if(!document.webkitFullscreenElement) exitFullScreen(); +}); + +document.addEventListener('mozfullscreenchange', function (e) +{ + if(!document.mozFullScreenElement) exitFullScreen(); +}); + +document.addEventListener('msfullscreenChange', function (e) +{ + if(!document.msfullscreenElement) exitFullScreen(); +}); \ No newline at end of file diff --git a/module/api/lang/zh-cn.php b/module/api/lang/zh-cn.php index 2ea834808c..85c1696b63 100644 --- a/module/api/lang/zh-cn.php +++ b/module/api/lang/zh-cn.php @@ -9,23 +9,129 @@ * @version $Id: zh-cn.php 5129 2013-07-15 00:16:07Z zhujinyonging@gmail.com $ * @link http://www.zentao.net */ -$lang->api = new stdclass(); +$lang->api = new stdclass(); $lang->api->common = 'API接口'; $lang->api->getModel = '超级model调用接口'; $lang->api->sql = 'SQL查询接口'; -$lang->api->position = '位置'; -$lang->api->startLine = "%s,%s行"; -$lang->api->desc = '描述'; -$lang->api->debug = '调试'; -$lang->api->submit = '提交'; -$lang->api->url = '请求地址'; -$lang->api->result = '返回结果'; -$lang->api->status = '状态'; -$lang->api->data = '内容'; -$lang->api->noParam = 'GET方式调试不需要输入参数,'; -$lang->api->post = 'POST方式调试请参照页面表单'; +$lang->api->edit = '编辑'; +$lang->api->delete = '删除'; +$lang->api->position = '位置'; +$lang->api->startLine = "%s,%s行"; +$lang->api->desc = '描述'; +$lang->api->debug = '调试'; +$lang->api->submit = '提交'; +$lang->api->url = '请求地址'; +$lang->api->result = '返回结果'; +$lang->api->status = '状态'; +$lang->api->data = '内容'; +$lang->api->noParam = 'GET方式调试不需要输入参数,'; +$lang->api->noModule = '接口库下没有目录,请先维护目录'; +$lang->api->post = 'POST方式调试请参照页面表单'; +$lang->api->noUniqueName = '接口库名已存在。'; +$lang->api->createLib = '创建接口库'; +$lang->api->editLib = '编辑接口库'; +$lang->api->deleteLib = '删除接口库'; +$lang->api->create = '创建文档'; +$lang->api->createApi = '创建接口'; +$lang->api->title = '接口库'; +$lang->api->module = '模块'; +$lang->api->apiDoc = '接口'; +$lang->api->manageType = '维护模块'; +$lang->api->doing = '开发中'; +$lang->api->basicInfo = '基本信息'; +$lang->api->principal = '负责人'; +$lang->api->apiDesc = '接口说明'; +$lang->api->confirmDelete = "您确定删除该接口吗?"; +$lang->api->confirmDeleteLib = "您确定删除该接口库吗?"; -$lang->api->error = new stdclass(); +/* fields of form */ +$lang->api->name = '接口库名称'; +$lang->api->desc = '描述'; +$lang->api->control = '访问控制'; +$lang->api->noLib = '暂时没有接口库。'; +$lang->api->noApi = '暂时没有接口。'; +$lang->api->lib = '所属接口库'; +$lang->api->module = '所属模块'; +$lang->api->formTitle = '接口名称'; +$lang->api->path = '请求路径'; +$lang->api->protocol = '请求协议'; +$lang->api->method = '请求方式'; +$lang->api->requestType = '请求格式'; +$lang->api->status = '开发状态'; +$lang->api->owner = '负责人'; +$lang->api->params = '请求参数'; +$lang->api->response = '请求响应'; +$lang->api->res = new stdClass(); +$lang->api->res->name = '名称'; +$lang->api->res->desc = '描述'; +$lang->api->res->type = '类型'; +$lang->api->field = '字段'; +$lang->api->scope = '位置'; +$lang->api->paramsType = '类型'; +$lang->api->required = '是否必填'; +$lang->api->default = '默认值'; +$lang->api->desc = '描述'; +$lang->api->customType = '自定义结构'; +$lang->api->format = '格式化'; +$lang->api->methodOptions = [ + 'GET' => 'GET', + 'POST' => 'POST', + 'PUT' => 'PUT', + 'DELETE' => 'DELETE', + 'PATCH' => 'PATCH', + 'OPTIONS' => 'OPTIONS', + 'HEAD' => 'HEAD' +]; +$lang->api->protocalOptions = [ + 'HTTP' => 'HTTP', + 'HTTPS' => 'HTTPS', +]; +$lang->api->requestTypeOptions = [ + 'application/json' => 'application/json', + 'application/x-www-form-urlencoded' => 'application/x-www-form-urlencoded', + 'multipart/form-data' => 'multipart/form-data' +]; +$lang->api->statusOptions = [ + 'doing' => '开发中', + 'done' => '开发完成', + 'hidden' => '不显示' +]; +$lang->api->paramsScopeOptions = [ + 'formData' => 'formData', + 'path' => 'path', + 'query' => 'query', + 'body' => 'body', + 'header' => 'header', + 'cookie' => 'cookie', +]; +/* Api global common params */ +$lang->api->paramsTypeOptions = [ + 'string' => 'string', + 'date' => 'date', + 'datetime' => 'datetime', + 'boolean' => 'boolean', + 'int' => 'int', + 'long' => 'long', + 'float' => 'float', + 'double' => 'double', + 'decimal' => 'decimal' +]; +/* Api params */ +$lang->api->paramsTypeCustomOptions = [ + 'file' => 'file', + 'ref' => 'ref', + 'custom' => '自定义' +]; +$lang->api->allParamsTypeOptions = array_merge($lang->api->paramsTypeOptions, $lang->api->paramsTypeCustomOptions); +$lang->api->requiredOptions = [ + 0 => '否', + 1 => '是', +]; + +$lang->doclib = new stdclass(); +$lang->doclib->name = '接口库名称'; + +$lang->api->error = new stdclass(); $lang->api->error->onlySelect = 'SQL查询接口只允许SELECT查询'; $lang->api->error->disabled = '因为安全原因,该功能被禁用。可以到config目录,修改配置项 %s,打开此功能。'; diff --git a/module/api/model.php b/module/api/model.php index 4f5431735e..df5d2c1b7b 100644 --- a/module/api/model.php +++ b/module/api/model.php @@ -1,4 +1,5 @@ dao->insert(TABLE_API)->data($params) + ->autoCheck() + ->batchCheck($this->config->api->create->requiredFields, 'notempty') + ->exec(); + + if(dao::isError()) return false; + + return $this->dao->lastInsertID(); + } + + /** + * Update an api doc. + * @param $id + * @param $data + * @author thanatos thanatos915@163.com + */ + public function update($id, $data) + { + $oldApi = $this->dao->findByID($id)->from(TABLE_API)->fetch(); + + $data->id = $oldApi->id; + $data->version = $oldApi->version + 1; + $apiSpec = $this->getApiSpecByData($data); + + $this->dao->replace(TABLE_API_SPEC)->data($apiSpec)->exec(); + + unset($data->id); + $this->dao + ->update(TABLE_API) + ->data($data) + ->autoCheck() + ->batchCheck($this->config->api->edit->requiredFields, 'notempty') + ->where('id')->eq($id) + ->exec(); + return; + } + + /** + * Get api doc by id. + * + * @param int $id + * @access public + * @return object + */ + public function getLibById($id, $version = 0) + { + + if($version) + { + $fields = 'spec.*,api.id,api.product,api.lib,api.version,doc.name as libName,module.name as moduleName'; + } + else + { + $fields = 'api.*,doc.name as libName,module.name as moduleName'; + } + + $model = $this->dao + ->select($fields) + ->from(TABLE_API)->alias('api') + ->beginIF($version)->leftJoin(TABLE_API_SPEC)->alias('spec')->on('api.id = spec.doc')->fi() + ->leftJoin(TABLE_DOCLIB)->alias('doc')->on('api.lib = doc.id') + ->leftJoin(TABLE_MODULE)->alias('module')->on('api.module = module.id') + ->where('api.id')->eq($id) + ->beginIF($version)->andWhere('spec.version')->eq($version)->fi() + ->fetch(); + + if($model) + { + $model->params = json_decode(htmlspecialchars_decode($model->params), true); + $model->response = json_decode(htmlspecialchars_decode($model->response), true); + } + return $model; + } + + /** + * Get api doc list by module id + * @param int $libID + * @param int $moduleID + * @return array $list + * @author thanatos thanatos915@163.com + */ + public function getListByModuleId($libID = 0, $moduleID = 0) + { + if($moduleID > 0) + { + $sub = $this->dao->select('id')->from(TABLE_MODULE)->where('FIND_IN_SET(' . $moduleID . ', path)')->processSQL(); + $where = 'module in (' . $sub . ')'; + } + else + { + $where = 'lib = ' . $libID; + } + $list = $this->dao->select('*') + ->from(TABLE_API) + ->where($where) + ->andWhere('deleted')->eq(0) + ->fetchAll(); + array_map(function ($item) { + $item->params = json_decode(htmlspecialchars_decode($item->params), true); + return $item; + }, $list); + return $list; + } + + /** + * Get status text by status. + * @param $status + * @return string + * @author thanatos thanatos915@163.com + */ + public static function getApiStatusText($status) + { + global $lang; + switch($status) + { + case static::STATUS_DOING: + return $lang->api->doing; + case static::STATUS_DONE: + return $lang->api->done; + } + } + /** * Get the details of the method by file path. * - * @param string $filePath - * @param string $ext + * @param string $filePath + * @param string $ext * @access public * @return object */ @@ -26,8 +171,8 @@ class apiModel extends model if(!class_exists($className)) helper::import($fileName); $methodName = basename($filePath); - $method = new ReflectionMethod($className . $ext, $methodName); - $data = new stdClass(); + $method = new ReflectionMethod($className . $ext, $methodName); + $data = new stdClass(); $data->startLine = $method->getStartLine(); $data->endLine = $method->getEndLine(); $data->comment = $method->getDocComment(); @@ -51,9 +196,9 @@ class apiModel extends model /** * Request the api. * - * @param string $moduleName - * @param string $methodName - * @param string $action + * @param string $moduleName + * @param string $methodName + * @param string $action * @access public * @return array */ @@ -68,7 +213,7 @@ class apiModel extends model foreach($_POST as $key => $value) $param .= ',' . $key . '=' . $value; $param = ltrim($param, ','); } - $url = rtrim($host, '/') . inlink('getModel', "moduleName=$moduleName&methodName=$methodName¶ms=$param", 'json'); + $url = rtrim($host, '/') . inlink('getModel', "moduleName=$moduleName&methodName=$methodName¶ms=$param", 'json'); $url .= $this->config->requestType == "PATH_INFO" ? '?' : '&'; $url .= $this->config->sessionVar . '=' . session_id(); } @@ -79,7 +224,7 @@ class apiModel extends model foreach($_POST as $key => $value) $param .= '&' . $key . '=' . $value; $param = ltrim($param, '&'); } - $url = rtrim($host, '/') . helper::createLink($moduleName, $methodName, $param, 'json'); + $url = rtrim($host, '/') . helper::createLink($moduleName, $methodName, $param, 'json'); $url .= $this->config->requestType == "PATH_INFO" ? '?' : '&'; $url .= $this->config->sessionVar . '=' . session_id(); } @@ -95,8 +240,8 @@ class apiModel extends model /** * Query sql. * - * @param string $sql - * @param string $keyField + * @param string $sql + * @param string $keyField * @access public * @return array */ @@ -107,7 +252,7 @@ class apiModel extends model $sql = trim($sql); if(strpos($sql, ';') !== false) $sql = substr($sql, 0, strpos($sql, ';')); - $result = array(); + $result = array(); $result['status'] = 'fail'; $result['message'] = ''; @@ -136,8 +281,7 @@ class apiModel extends model $result['status'] = 'success'; $result['data'] = $rows; - } - catch(PDOException $e) + } catch(PDOException $e) { $result['status'] = 'fail'; $result['message'] = $e->getMessage(); @@ -146,4 +290,31 @@ class apiModel extends model return $result; } } + + /** + * @author thanatos thanatos915@163.com + */ + private function getApiSpecByData($data) + { + + $now = helper::now(); + return [ + 'doc' => $data->id, + 'module' => $data->module, + 'title' => $data->title, + 'path' => $data->path, + 'protocol' => $data->protocol, + 'method' => $data->method, + 'requestType' => $data->requestType, + 'responseType' => $data->responseType, + 'status' => $data->status, + 'owner' => $data->owner, + 'desc' => $data->desc, + 'version' => $data->version, + 'params' => $data->params, + 'response' => $data->response, + 'addedBy' => $this->app->user->account, + 'addedDate' => $now, + ]; + } } diff --git a/module/api/view/content.html.php b/module/api/view/content.html.php new file mode 100644 index 0000000000..2f325a40b2 --- /dev/null +++ b/module/api/view/content.html.php @@ -0,0 +1,145 @@ +
+
+
+
+
+
+
method ?>
+
path; ?>
+
title; ?>
+
+
+
+ + #version; ?> + + + +
+
+
+
+ ', '', "title='{$lang->fullscreen}' class='btn btn-link fullscreen-btn'"); + if(common::hasPriv('api', 'edit')) echo html::a(inlink('edit', "apiID=$api->id"), '', '', "title='{$lang->api->edit}' class='btn btn-link' data-app='{$this->app->tab}'"); + if(common::hasPriv('doc', 'delete')) + { + $deleteURL = $this->createLink('api', 'delete', "apiID=$api->id&confirm=yes"); + echo html::a("javascript:ajaxDeleteApi(\"$deleteURL\", confirmDelete)", '', '', "title='{$lang->api->delete}' class='btn btn-link'"); + } + ?> +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
api->principal; ?>owner; ?>
api->apiDesc; ?>desc; ?>
api->response; ?> + response['type'] == apiModel::PARAMS_TYPE_CUSTOM) { + echo '
'. $api->response['custom'] .'
'; + } else { + echo $api->response['type']; + } + ?> +
api->params; ?>
+ + + + + + + + + params as $param):?> + + + + + + + + +
参数参数位置类型说明
+ '. $param['custom'] .''; + } else { + echo $param['paramsType']; + } + ?> +
+
+
+
+ +
+ createLink('action', 'comment', "objectType=doc&objectID=$api->id"); + ?> + +
+
+ +
+
\ No newline at end of file diff --git a/module/api/view/create.html.php b/module/api/view/create.html.php new file mode 100644 index 0000000000..2e64fbd56a --- /dev/null +++ b/module/api/view/create.html.php @@ -0,0 +1,220 @@ + + * @package doc + * @version $Id: create.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ + * @link http://www.zentao.net + */ +?> + + + + +
+
+
+ +

+ id;?> + createLink('api', 'index', "apiID=$api->id"), $api->title, '', "title='$api->title'");?> + arrow . ' ' . $lang->api->edit;?> +

+
save, '', 'id="top-submit" class="btn btn-primary"');?>
+ +

api->create; ?>

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
api->lib; ?> lib ? $api->lib : $libID, "class='form-control chosen' onchange=loadDocModule(this.value)"); ?>
api->module; ?> + +
api->formTitle; ?>title, "class='form-control' required"); ?>
api->path; ?>path, "class='form-control'"); ?>
api->protocol; ?>api->protocalOptions, $api->protocol ? $api->protocol : 'HTTP'); ?>
api->method; ?> + api->methodOptions, $api->method ? $api->method : 'GET', "class='form-control chosen'"); ?> +
api->requestType; ?> + api->requestTypeOptions, $api->requestType ? $api->requestType : 'application/json', "class='form-control chosen'"); ?> +
api->status; ?>api->statusOptions, $api->status ? $api->status : apiModel::STATUS_DOING); ?>
+ api->owner; ?> + +
+ owner ? $api->owner : $user, "class='form-control chosen'"); ?> +
+
api->params; ?> + params ? $api->params : [''] + ?> + +
+
+
+ api->field; ?> + +
+
+
+
+ api->required; ?> + api->requiredOptions, $param['required'] ? $param['required'] : 0, "class='form-control'"); ?> +
+
+
+
+ api->scope; ?> + api->paramsScopeOptions, $param['scope'], "class='form-control' onchange='loadParamsTypeOptions(this);'"); ?> +
+
+
+
+ api->paramsType; ?> + api->paramsTypeOptions, $param['paramsType'], "class='form-control' onchange='changeType(this);'"); ?> +
+
+
'> +
+ + +
+
+
+
+ api->default; ?> + default, "class='form-control'"); ?> +
+
+
+
+ api->desc; ?> + desc, "class='form-control' style='height:32px'"); ?> +
+
+
+ + +
+
+ +
api->response; ?> +
+
+
+ api->res->name; ?> + response['name'], "class='form-control'"); ?> +
+
+
+
+ api->res->desc; ?> + response['desc'], "class='form-control'"); ?> +
+
+
+
+ api->res->type; ?> + api->allParamsTypeOptions, $api->response['type'], "class='form-control' onchange='changeType(this);'"); ?> +
+
+
'> +
+ + +
+
+
+
api->desc; ?> +
desc, "style='width:100%;height:200px'"); ?>
+
+ + goback, "data-app='{$app->tab}'"); ?> + goback, '', "class='btn btn-back btn-wide'"); ?> +
+
+
+
+noticeAcl); ?> + \ No newline at end of file diff --git a/module/api/view/createlib.html.php b/module/api/view/createlib.html.php new file mode 100644 index 0000000000..67e7e82c88 --- /dev/null +++ b/module/api/view/createlib.html.php @@ -0,0 +1,81 @@ + + * @package doc + * @version $Id: createlib.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ + * @link http://www.zentao.net + */ +?> + + + +
+
+
+
+
+

api->createLib;?>

+
+
+ + + + + + + + + + + + + + + + + + + + +
api->name?>
api->control;?> + acl->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")'")?> + noticeAcl['open'];?> +
api->desc;?> + +
+
+
+
+
+
+ +noticeAcl);?> + diff --git a/module/api/view/edit.html.php b/module/api/view/edit.html.php new file mode 100644 index 0000000000..9c0a60109d --- /dev/null +++ b/module/api/view/edit.html.php @@ -0,0 +1,216 @@ + + * @package doc + * @version $Id: create.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $ + * @link http://www.zentao.net + */ +?> + + + + +
+
+
+ +

+ id; ?> + createLink('api', 'index', "apiID=$api->id"), $api->title, '', "title='$api->title'"); ?> + arrow . ' ' . $lang->api->edit; ?> +

+
save, '', 'id="top-submit" class="btn btn-primary"'); ?>
+ +

api->create; ?>

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
api->module; ?> + +
api->formTitle; ?>title, "class='form-control' required"); ?>
api->path; ?>path, "class='form-control'"); ?>
api->protocol; ?>api->protocalOptions, $api->protocol ? $api->protocol : 'HTTP'); ?>
api->method; ?> + api->methodOptions, $api->method ? $api->method : 'GET', "class='form-control chosen'"); ?> +
api->requestType; ?> + api->requestTypeOptions, $api->requestType ? $api->requestType : 'application/json', "class='form-control chosen'"); ?> +
api->status; ?>api->statusOptions, $api->status ? $api->status : apiModel::STATUS_DOING); ?>
+ api->owner; ?> + +
+ owner ? $api->owner : $user, "class='form-control chosen'"); ?> +
+
api->params; ?> + params ? $api->params : [''] + ?> + +
+
+
+ api->field; ?> + +
+
+
+
+ api->required; ?> + api->requiredOptions, $param['required'] ? $param['required'] : 0, "class='form-control'"); ?> +
+
+
+
+ api->scope; ?> + api->paramsScopeOptions, $param['scope'], "class='form-control' onchange='loadParamsTypeOptions(this);'"); ?> +
+
+
+
+ api->paramsType; ?> + api->allParamsTypeOptions : $lang->api->paramsTypeOptions ?> + +
+
+
'> +
+ + +
+
+
+
+ api->default; ?> + default, "class='form-control'"); ?> +
+
+
+
+ api->desc; ?> + desc, "class='form-control' style='height:32px'"); ?> +
+
+
+ + +
+
+ +
api->response; ?> +
+
+
+ api->res->name; ?> + response['name'], "class='form-control'"); ?> +
+
+
+
+ api->res->desc; ?> + response['desc'], "class='form-control'"); ?> +
+
+
+
+ api->res->type; ?> + api->allParamsTypeOptions, $api->response['type'], "class='form-control' onchange='changeType(this);'"); ?> +
+
+
'> +
+ + +
+
+
+
api->desc; ?> +
desc, "style='width:100%;height:200px'"); ?>
+
+ + goback, "data-app='{$app->tab}'"); ?> + goback, '', "class='btn btn-back btn-wide'"); ?> +
+
+
+
+noticeAcl); ?> + \ No newline at end of file diff --git a/module/api/view/index.html.php b/module/api/view/index.html.php new file mode 100644 index 0000000000..deb2b9d749 --- /dev/null +++ b/module/api/view/index.html.php @@ -0,0 +1,95 @@ + + * @package doc + * @version $Id$ + * @link http://www.zentao.net + */ +?> + +api->confirmDelete);?> +
+ +
+
+
+ + "; + echo html::a('javascript:;', "", '', "data-toggle='dropdown' class='btn btn-link'"); + echo "
'; + ?> +
+ +
+
+ api->noModule; ?> +
+ + +
+
+ + + + + +
+
+
  • 0 ? $lang->api->module : $lang->api->title; ?>
  • +
    +
    +
    +
    api->noLib : $lang->api->noApi; ?>
    +
    + ' . $lang->api->createApi, '', 'class="btn btn-info btn-wide"'); + } + else + { + $html = html::a(helper::createLink('api', 'createLib'), ' ' . $lang->api->createLib, '', 'class="btn btn-info btn-wide iframe"'); + } + echo $html; + ?> +
    +
    +
    + + + + + +
    + diff --git a/module/common/lang/common.php b/module/common/lang/common.php index d74e9b3b3c..eb9b866705 100644 --- a/module/common/lang/common.php +++ b/module/common/lang/common.php @@ -164,6 +164,7 @@ $lang->createIcons['project'] = 'project'; $lang->createIcons['product'] = 'product'; $lang->createIcons['program'] = 'program'; + $lang->noMenuModule = array('report', 'my', 'todo', 'effort', 'program', 'product', 'execution', 'task', 'build', 'productplan', 'project', 'projectrelease', 'projectstory', 'story', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'pssp', 'sms', 'message', 'webhook', 'search', 'score', 'stage', 'entry', 'jenkins', 'gitlab'); if(isset($_SESSION['tutorialMode']) and $_SESSION['tutorialMode'] and !defined('TUTORIAL')) define('TUTORIAL', true); diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index c48cbed074..68ab60f215 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -1,5 +1,5 @@ navIcons = array(); +$lang->navIcons = array(); $lang->navIcons['my'] = ""; $lang->navIcons['program'] = ""; $lang->navIcons['product'] = ""; @@ -13,9 +13,9 @@ $lang->navIcons['system'] = ""; $lang->navIcons['admin'] = ""; global $config; -list($programModule, $programMethod) = explode('-', $config->programLink); -list($productModule, $productMethod) = explode('-', $config->productLink); -list($projectModule, $projectMethod) = explode('-', $config->projectLink); +list($programModule, $programMethod) = explode('-', $config->programLink); +list($productModule, $productMethod) = explode('-', $config->productLink); +list($projectModule, $projectMethod) = explode('-', $config->projectLink); list($executionModule, $executionMethod) = explode('-', $config->executionLink); if(defined('TUTORIAL')) @@ -31,7 +31,7 @@ if(defined('TUTORIAL')) } /* Main Navigation. */ -$lang->mainNav = new stdclass(); +$lang->mainNav = new stdclass(); $lang->mainNav->my = "{$lang->navIcons['my']} {$lang->my->shortCommon}|my|index|"; if($config->systemMode == 'new') $lang->mainNav->program = "{$lang->navIcons['program']} {$lang->program->common}|$programModule|$programMethod|"; $lang->mainNav->product = "{$lang->navIcons['product']} {$lang->product->common}|$productModule|$productMethod|"; @@ -45,15 +45,15 @@ else { $lang->mainNav->execution = "{$lang->navIcons['project']} {$lang->execution->common}|$executionModule|$executionMethod|"; } -$lang->mainNav->qa = "{$lang->navIcons['qa']} {$lang->qa->common}|qa|index|"; -$lang->mainNav->devops = "{$lang->navIcons['devops']} DevOps|repo|browse|"; -$lang->mainNav->doc = "{$lang->navIcons['doc']} {$lang->doc->common}|doc|index|"; -$lang->mainNav->report = "{$lang->navIcons['report']} {$lang->report->common}|report|productSummary|"; -$lang->mainNav->system = "{$lang->navIcons['system']} {$lang->system->common}|my|team|"; -$lang->mainNav->admin = "{$lang->navIcons['admin']} {$lang->admin->common}|admin|index|"; +$lang->mainNav->qa = "{$lang->navIcons['qa']} {$lang->qa->common}|qa|index|"; +$lang->mainNav->devops = "{$lang->navIcons['devops']} DevOps|repo|browse|"; +$lang->mainNav->doc = "{$lang->navIcons['doc']} {$lang->doc->common}|doc|index|"; +$lang->mainNav->report = "{$lang->navIcons['report']} {$lang->report->common}|report|productSummary|"; +$lang->mainNav->system = "{$lang->navIcons['system']} {$lang->system->common}|my|team|"; +$lang->mainNav->admin = "{$lang->navIcons['admin']} {$lang->admin->common}|admin|index|"; -$lang->dividerMenu = ',doc,oa,admin,'; -$lang->mainNav->menuOrder[5] = 'my'; +$lang->dividerMenu = ',doc,oa,admin,'; +$lang->mainNav->menuOrder[5] = 'my'; if($config->systemMode == 'new') $lang->mainNav->menuOrder[10] = 'program'; $lang->mainNav->menuOrder[15] = 'product'; if($config->systemMode == 'new') $lang->mainNav->menuOrder[20] = 'project'; @@ -66,16 +66,16 @@ $lang->mainNav->menuOrder[40] = 'system'; $lang->mainNav->menuOrder[55] = 'admin'; /* My menu. */ -$lang->my->menu = new stdclass(); -$lang->my->menu->index = array('link' => "$lang->dashboard|my|index"); -$lang->my->menu->calendar = array('link' => "$lang->calendar|my|calendar|", 'subModule' => 'todo', 'alias' => 'todo'); -$lang->my->menu->work = array('link' => "{$lang->my->work}|my|work|mode=task", 'subModule' => 'task'); +$lang->my->menu = new stdclass(); +$lang->my->menu->index = array('link' => "$lang->dashboard|my|index"); +$lang->my->menu->calendar = array('link' => "$lang->calendar|my|calendar|", 'subModule' => 'todo', 'alias' => 'todo'); +$lang->my->menu->work = array('link' => "{$lang->my->work}|my|work|mode=task", 'subModule' => 'task'); if($config->systemMode == 'new') $lang->my->menu->project = array('link' => "{$lang->project->common}|my|project|"); $lang->my->menu->execution = array('link' => "{$lang->execution->common}|my|execution|type=undone"); $lang->my->menu->contribute = array('link' => "$lang->contribute|my|contribute|mode=task"); $lang->my->menu->dynamic = array('link' => "$lang->dynamic|my|dynamic|"); if($config->systemScore) $lang->my->menu->score = array('link' => "{$lang->score->shortCommon}|my|score|", 'subModule' => 'score'); -$lang->my->menu->contacts = array('link' => "$lang->contact|my|managecontacts|"); +$lang->my->menu->contacts = array('link' => "$lang->contact|my|managecontacts|"); /* My menu order. */ $lang->my->menuOrder[5] = 'index'; @@ -89,8 +89,8 @@ $lang->my->menuOrder[40] = 'dynamic'; $lang->my->menuOrder[45] = 'score'; $lang->my->menuOrder[50] = 'contacts'; -$lang->my->menu->work['subMenu'] = new stdclass(); -$lang->my->menu->work['subMenu']->task = array('link' => "{$lang->task->common}|my|work|mode=task", 'subModule' => 'task'); +$lang->my->menu->work['subMenu'] = new stdclass(); +$lang->my->menu->work['subMenu']->task = array('link' => "{$lang->task->common}|my|work|mode=task", 'subModule' => 'task'); if($config->URAndSR) $lang->my->menu->work['subMenu']->requirement = "$lang->URCommon|my|work|mode=requirement"; $lang->my->menu->work['subMenu']->story = "$lang->SRCommon|my|work|mode=story"; $lang->my->menu->work['subMenu']->bug = "{$lang->bug->common}|my|work|mode=bug"; @@ -104,8 +104,8 @@ $lang->my->menu->work['menuOrder'][20] = 'bug'; $lang->my->menu->work['menuOrder'][25] = 'testcase'; $lang->my->menu->work['menuOrder'][30] = 'testtask'; -$lang->my->menu->contribute['subMenu'] = new stdclass(); -$lang->my->menu->contribute['subMenu']->task = "{$lang->task->common}|my|contribute|mode=task"; +$lang->my->menu->contribute['subMenu'] = new stdclass(); +$lang->my->menu->contribute['subMenu']->task = "{$lang->task->common}|my|contribute|mode=task"; if($config->URAndSR) $lang->my->menu->contribute['subMenu']->requirement = "$lang->URCommon|my|contribute|mode=requirement"; $lang->my->menu->contribute['subMenu']->story = "$lang->SRCommon|my|contribute|mode=story"; $lang->my->menu->contribute['subMenu']->bug = "{$lang->bug->common}|my|contribute|mode=bug"; @@ -124,11 +124,11 @@ $lang->my->menu->contribute['menuOrder'][35] = 'doc'; $lang->my->dividerMenu = ',work,dynamic,'; /* Program menu. */ -$lang->program->homeMenu = new stdclass(); +$lang->program->homeMenu = new stdclass(); $lang->program->homeMenu->browse = array('link' => "{$lang->program->list}|program|browse|", 'alias' => 'create,edit'); $lang->program->homeMenu->kanban = array('link' => "{$lang->program->kanban}|program|kanban|"); -$lang->program->menu = new stdclass(); +$lang->program->menu = new stdclass(); $lang->program->menu->product = array('link' => "{$lang->product->common}|program|product|programID=%s", 'alias' => 'view'); $lang->program->menu->project = array('link' => "{$lang->project->common}|program|project|programID=%s"); $lang->program->menu->personnel = array('link' => "{$lang->personnel->common}|personnel|invest|programID=%s"); @@ -140,29 +140,29 @@ $lang->program->menuOrder[10] = 'project'; $lang->program->menuOrder[15] = 'personnel'; $lang->program->menuOrder[20] = 'stakeholder'; -$lang->program->menu->personnel['subMenu'] = new stdClass(); +$lang->program->menu->personnel['subMenu'] = new stdClass(); $lang->program->menu->personnel['subMenu']->invest = array('link' => "{$lang->personnel->invest}|personnel|invest|programID=%s"); $lang->program->menu->personnel['subMenu']->accessible = array('link' => "{$lang->personnel->accessible}|personnel|accessible|programID=%s"); $lang->program->menu->personnel['subMenu']->whitelist = array('link' => "{$lang->whitelist}|personnel|whitelist|objectID=%s", 'alias' => 'addwhitelist'); /* Product menu. */ -$lang->product->homeMenu = new stdclass(); +$lang->product->homeMenu = new stdclass(); $lang->product->homeMenu->home = array('link' => "{$lang->dashboard}|product|index|"); $lang->product->homeMenu->list = array('link' => $lang->product->list . '|product|all|', 'alias' => 'create,batchedit,manageline'); $lang->product->homeMenu->kanban = array('link' => "{$lang->product->kanban}|product|kanban|"); -$lang->product->menu = new stdclass(); -$lang->product->menu->dashboard = array('link' => "{$lang->dashboard}|product|dashboard|productID=%s"); +$lang->product->menu = new stdclass(); +$lang->product->menu->dashboard = array('link' => "{$lang->dashboard}|product|dashboard|productID=%s"); if($config->URAndSR) $lang->product->menu->requirement = array('link' => "$lang->URCommon|product|browse|productID=%s&branch=&browseType=unclosed¶m=0&storyType=requirement", 'alias' => 'batchedit', 'subModule' => 'story'); -$lang->product->menu->story = array('link' => "$lang->SRCommon|product|browse|productID=%s", 'alias' => 'batchedit', 'subModule' => 'story'); -$lang->product->menu->plan = array('link' => "{$lang->productplan->shortCommon}|productplan|browse|productID=%s", 'subModule' => 'productplan'); -$lang->product->menu->release = array('link' => "{$lang->release->common}|release|browse|productID=%s", 'subModule' => 'release'); -$lang->product->menu->roadmap = array('link' => "{$lang->roadmap}|product|roadmap|productID=%s"); -$lang->product->menu->project = array('link' => "{$lang->project->common}|product|project|status=all&productID=%s"); -$lang->product->menu->track = array('link' => "{$lang->track}|story|track|productID=%s"); -$lang->product->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=product&objectID=%s", 'subModule' => 'doc'); -$lang->product->menu->dynamic = array('link' => "{$lang->dynamic}|product|dynamic|productID=%s"); -$lang->product->menu->settings = array('link' => "{$lang->settings}|product|view|productID=%s", 'subModule' => 'tree,branch', 'alias' => 'edit,whitelist,addwhitelist'); +$lang->product->menu->story = array('link' => "$lang->SRCommon|product|browse|productID=%s", 'alias' => 'batchedit', 'subModule' => 'story'); +$lang->product->menu->plan = array('link' => "{$lang->productplan->shortCommon}|productplan|browse|productID=%s", 'subModule' => 'productplan'); +$lang->product->menu->release = array('link' => "{$lang->release->common}|release|browse|productID=%s", 'subModule' => 'release'); +$lang->product->menu->roadmap = array('link' => "{$lang->roadmap}|product|roadmap|productID=%s"); +$lang->product->menu->project = array('link' => "{$lang->project->common}|product|project|status=all&productID=%s"); +$lang->product->menu->track = array('link' => "{$lang->track}|story|track|productID=%s"); +$lang->product->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=product&objectID=%s", 'subModule' => 'doc'); +$lang->product->menu->dynamic = array('link' => "{$lang->dynamic}|product|dynamic|productID=%s"); +$lang->product->menu->settings = array('link' => "{$lang->settings}|product|view|productID=%s", 'subModule' => 'tree,branch', 'alias' => 'edit,whitelist,addwhitelist'); /* Product menu order. */ $lang->product->menuOrder[5] = 'dashboard'; @@ -181,7 +181,7 @@ $lang->product->menuOrder[65] = 'all'; $lang->product->menu->doc['subMenu'] = new stdclass(); -$lang->product->menu->settings['subMenu'] = new stdclass(); +$lang->product->menu->settings['subMenu'] = new stdclass(); $lang->product->menu->settings['subMenu']->view = array('link' => "{$lang->overview}|product|view|productID=%s", 'alias' => 'edit'); $lang->product->menu->settings['subMenu']->module = array('link' => "{$lang->module}|tree|browse|product=%s&view=story", 'subModule' => 'tree'); $lang->product->menu->settings['subMenu']->branch = array('link' => "@branch@|branch|manage|product=%s", 'subModule' => 'branch'); @@ -190,12 +190,12 @@ $lang->product->menu->settings['subMenu']->whitelist = array('link' => "{$lang-> $lang->product->dividerMenu = $config->URAndSR ? ',story,requirement,settings,' : ',story,track,settings,'; /* Project menu. */ -$lang->project->homeMenu = new stdclass(); +$lang->project->homeMenu = new stdclass(); $lang->project->homeMenu->browse = array('link' => ($config->systemMode == 'new' ? $lang->project->list : $lang->executionCommon) . '|project|browse|', 'alias' => 'batchedit,create'); if($config->systemMode == 'new') $lang->project->homeMenu->kanban = array('link' => "{$lang->project->kanban}|project|kanban|"); /* Scrum menu. */ -$lang->scrum->menu = new stdclass(); +$lang->scrum->menu = new stdclass(); $lang->scrum->menu->index = array('link' => "{$lang->dashboard}|project|index|project=%s"); $lang->scrum->menu->execution = array('link' => "$lang->executionCommon|project|execution|status=all&projectID=%s", 'exclude' => 'execution-testreport'); $lang->scrum->menu->story = array('link' => "$lang->SRCommon|projectstory|story|projectID=%s", 'subModule' => 'projectstory,tree', 'alias' => 'story,track'); @@ -230,7 +230,7 @@ $lang->scrum->menu->qa['subMenu']->testcase = array('link' => "{$lang->testcas $lang->scrum->menu->qa['subMenu']->testtask = array('link' => "{$lang->testtask->common}|project|testtask|projectID=%s", 'subModule' => 'testtask', 'class' => 'dropdown dropdown-hover'); $lang->scrum->menu->qa['subMenu']->testreport = array('link' => "{$lang->testreport->common}|project|testreport|projectID=%s", 'subModule' => 'testreport'); -$lang->scrum->menu->settings['subMenu'] = new stdclass(); +$lang->scrum->menu->settings['subMenu'] = new stdclass(); $lang->scrum->menu->settings['subMenu']->view = array('link' => "$lang->overview|project|view|project=%s", 'alias' => 'edit'); $lang->scrum->menu->settings['subMenu']->products = array('link' => "{$lang->product->common}|project|manageProducts|project=%s", 'alias' => 'manageproducts'); $lang->scrum->menu->settings['subMenu']->members = array('link' => "{$lang->team->common}|project|team|project=%s", 'alias' => 'managemembers,team'); @@ -240,11 +240,11 @@ $lang->scrum->menu->settings['subMenu']->group = array('link' => "{$lang-> /* Execution menu. */ -$lang->execution->homeMenu = new stdclass(); +$lang->execution->homeMenu = new stdclass(); $lang->execution->homeMenu->all = array('link' => "{$lang->execution->all}|execution|all|", 'alias' => 'batchedit'); if($config->systemMode == 'new') $lang->execution->homeMenu->executionkanban = array('link' => "{$lang->execution->executionKanban}|execution|executionkanban|"); -$lang->execution->menu = new stdclass(); +$lang->execution->menu = new stdclass(); $lang->execution->menu->task = array('link' => "{$lang->task->common}|execution|task|executionID=%s", 'subModule' => 'task,tree', 'alias' => 'importtask,importbug'); $lang->execution->menu->kanban = array('link' => "$lang->kanban|execution|kanban|executionID=%s"); $lang->execution->menu->burn = array('link' => "$lang->burn|execution|burn|executionID=%s"); @@ -275,7 +275,7 @@ $lang->execution->menuOrder[65] = 'settings'; $lang->execution->menu->doc['subMenu'] = new stdclass(); -$lang->execution->menu->view['subMenu'] = new stdclass(); +$lang->execution->menu->view['subMenu'] = new stdclass(); $lang->execution->menu->view['subMenu']->groupTask = "$lang->groupView|execution|grouptask|executionID=%s"; $lang->execution->menu->view['subMenu']->tree = "$lang->treeView|execution|tree|executionID=%s"; @@ -291,7 +291,7 @@ $lang->execution->menu->qa['menuOrder'][10] = 'bug'; $lang->execution->menu->qa['menuOrder'][15] = 'testcase'; $lang->execution->menu->qa['menuOrder'][20] = 'testtask'; -$lang->execution->menu->settings['subMenu'] = new stdclass(); +$lang->execution->menu->settings['subMenu'] = new stdclass(); $lang->execution->menu->settings['subMenu']->view = array('link' => "$lang->overview|execution|view|executionID=%s", 'subModule' => 'view', 'alias' => 'edit,start,suspend,putoff,close'); $lang->execution->menu->settings['subMenu']->products = array('link' => "$lang->productCommon|execution|manageproducts|executionID=%s"); $lang->execution->menu->settings['subMenu']->team = array('link' => "{$lang->team->common}|execution|team|executionID=%s", 'alias' => 'managemembers'); @@ -300,7 +300,7 @@ $lang->execution->menu->settings['subMenu']->whitelist = array('link' => "$lang- $lang->execution->dividerMenu = ',story,build,'; /* QA menu.*/ -$lang->qa->menu = new stdclass(); +$lang->qa->menu = new stdclass(); $lang->qa->menu->index = array('link' => "$lang->dashboard|qa|index"); $lang->qa->menu->bug = array('link' => "{$lang->bug->common}|bug|browse|productID=%s", 'subModule' => 'bug'); $lang->qa->menu->testcase = array('link' => "{$lang->testcase->shortCommon}|testcase|browse|productID=%s", 'subModule' => 'testcase,story'); @@ -331,7 +331,7 @@ $lang->qa->menuOrder[45] = 'automation'; $lang->qa->dividerMenu = ',bug,testtask,caselib,'; /* DevOps menu. */ -$lang->devops->menu = new stdclass(); +$lang->devops->menu = new stdclass(); $lang->devops->menu->code = array('link' => "{$lang->repo->common}|repo|browse|repoID=%s", 'alias' => 'diff,view,revision,log,blame,showsynccommit'); $lang->devops->menu->compile = array('link' => "{$lang->devops->compile}|job|browse", 'subModule' => 'compile,job'); $lang->devops->menu->mr = array('link' => "{$lang->devops->mr}|mr|browse"); @@ -348,12 +348,13 @@ $lang->devops->menuOrder[25] = 'jenkins'; $lang->devops->menuOrder[30] = 'maintain'; $lang->devops->menuOrder[35] = 'rules'; /* Doc menu. */ -$lang->doc->menu = new stdclass(); +$lang->doc->menu = new stdclass(); $lang->doc->menu->dashboard = array('link' => "{$lang->dashboard}|doc|index"); $lang->doc->menu->recent = array('link' => "{$lang->doc->recent}|doc|browse|browseTyp=byediteddate", 'alias' => 'recent'); $lang->doc->menu->my = array('link' => "{$lang->doc->my}|doc|browse|browseTyp=openedbyme", 'alias' => 'my'); $lang->doc->menu->collect = array('link' => "{$lang->doc->favorite}|doc|browse|browseTyp=collectedbyme", 'alias' => 'collect'); $lang->doc->menu->product = array('link' => "{$lang->doc->product}|doc|tableContents|type=product", 'alias' => 'showfiles,product'); +$lang->doc->menu->api = array('link' => "{$lang->doc->api}|api|index", 'alias' => 'api'); if($config->systemMode == 'new') $lang->doc->menu->project = array('link' => "{$lang->doc->project}|doc|tableContents|type=project", 'alias' => 'showfiles,project'); $lang->doc->menu->execution = array('link' => "{$lang->doc->execution}|doc|tableContents|type=execution", 'alias' => 'showfiles,execution'); $lang->doc->menu->custom = array('link' => "{$lang->doc->custom}|doc|tableContents|type=custom", 'alias' => 'custom'); @@ -368,15 +369,18 @@ $lang->doc->menuOrder[20] = 'collect'; $lang->doc->menuOrder[25] = 'product'; if($config->systemMode == 'new') $lang->doc->menuOrder[30] = 'project'; $lang->doc->menuOrder[35] = 'execution'; +$lang->doc->menuOrder[36] = 'api'; $lang->doc->menuOrder[40] = 'custom'; $lang->doc->menu->product['subMenu'] = new stdclass(); if($config->systemMode == 'new') $lang->doc->menu->project['subMenu'] = new stdclass(); $lang->doc->menu->execution['subMenu'] = new stdclass(); -$lang->doc->menu->custom['subMenu'] = new stdclass(); +$lang->doc->menu->custom['subMenu'] = new stdclass(); +$lang->doc->menu->api['subMenu'] = new stdclass(); + /* Report menu.*/ -$lang->report->menu = new stdclass(); +$lang->report->menu = new stdclass(); $lang->report->menu->annual = array('link' => "{$lang->report->annual}|report|annualData|year=&dept=&userID=" . (isset($_SESSION['user']) ? zget($_SESSION['user'], 'id', 0) : 0), 'target' => '_blank'); $lang->report->menu->product = array('link' => "{$lang->product->common}|report|productsummary"); $lang->report->menu->project = array('link' => "{$lang->project->common}|report|projectdeviation"); @@ -391,7 +395,7 @@ $lang->report->menuOrder[20] = 'test'; $lang->report->menuOrder[25] = 'staff'; /* Company menu.*/ -$lang->company->menu = new stdclass(); +$lang->company->menu = new stdclass(); $lang->company->menu->browseUser = array('link' => "{$lang->user->common}|company|browse", 'subModule' => ',user,'); $lang->company->menu->dept = array('link' => "{$lang->dept->common}|dept|browse", 'subModule' => 'dept'); $lang->company->menu->browseGroup = array('link' => "$lang->priv|group|browse", 'subModule' => 'group'); @@ -405,7 +409,7 @@ $lang->company->menuOrder[25] = 'batchAddUser'; $lang->company->menuOrder[30] = 'addUser'; /* Admin menu. */ -$lang->admin->menu = new stdclass(); +$lang->admin->menu = new stdclass(); $lang->admin->menu->index = array('link' => "$lang->indexPage|admin|index", 'alias' => 'register,certifytemail,certifyztmobile,ztcompany'); $lang->admin->menu->company = array('link' => "{$lang->personnel->common}|company|browse|", 'subModule' => ',user,dept,group,'); $lang->admin->menu->model = array('link' => "$lang->model|custom|browsestoryconcept|", 'subModule' => 'holiday'); @@ -425,12 +429,12 @@ $lang->admin->menuOrder[30] = 'extension'; $lang->admin->menuOrder[35] = 'dev'; $lang->admin->menuOrder[40] = 'system'; -$lang->admin->menu->model['subMenu'] = new stdclass(); +$lang->admin->menu->model['subMenu'] = new stdclass(); $lang->admin->menu->model['subMenu']->storyConcept = array('link' => "{$lang->storyConcept}|custom|browsestoryconcept|"); $lang->admin->menu->model['menuOrder'][5] = 'storyConcept'; -$lang->admin->menu->message['subMenu'] = new stdclass(); +$lang->admin->menu->message['subMenu'] = new stdclass(); $lang->admin->menu->message['subMenu']->message = new stdclass(); $lang->admin->menu->message['subMenu']->mail = array('link' => "{$lang->mail->common}|mail|index", 'subModule' => 'mail'); $lang->admin->menu->message['subMenu']->webhook = array('link' => "Webhook|webhook|browse", 'subModule' => 'webhook'); @@ -442,12 +446,12 @@ $lang->admin->menu->message['menuOrder'][10] = 'webhook'; $lang->admin->menu->message['menuOrder'][15] = 'browser'; $lang->admin->menu->message['menuOrder'][20] = 'setting'; -$lang->admin->menu->company['subMenu'] = new stdclass(); +$lang->admin->menu->company['subMenu'] = new stdclass(); $lang->admin->menu->company['subMenu']->browseUser = array('link' => "{$lang->user->common}|company|browse", 'subModule' => 'user'); $lang->admin->menu->company['subMenu']->dept = array('link' => "{$lang->dept->common}|dept|browse", 'subModule' => 'dept'); $lang->admin->menu->company['subMenu']->browseGroup = array('link' => "{$lang->priv}|group|browse", 'subModule' => 'group'); -$lang->admin->menu->dev['subMenu'] = new stdclass(); +$lang->admin->menu->dev['subMenu'] = new stdclass(); $lang->admin->menu->dev['subMenu']->api = array('link' => "API|dev|api"); $lang->admin->menu->dev['subMenu']->db = array('link' => "$lang->db|dev|db"); $lang->admin->menu->dev['subMenu']->editor = array('link' => "$lang->editor|dev|editor"); @@ -458,7 +462,7 @@ $lang->admin->menu->dev['menuOrder'][10] = 'db'; $lang->admin->menu->dev['menuOrder'][15] = 'editor'; $lang->admin->menu->dev['menuOrder'][20] = 'entry'; -$lang->admin->menu->system['subMenu'] = new stdclass(); +$lang->admin->menu->system['subMenu'] = new stdclass(); $lang->admin->menu->system['subMenu']->data = array('link' => "{$lang->admin->data}|backup|index", 'subModule' => 'action'); $lang->admin->menu->system['subMenu']->safe = array('link' => "$lang->security|admin|safe", 'alias' => 'checkweak'); $lang->admin->menu->system['subMenu']->cron = array('link' => "{$lang->admin->cron}|cron|index", 'subModule' => 'cron'); @@ -467,14 +471,14 @@ $lang->admin->menu->system['subMenu']->buildIndex = array('link' => "{$lang->adm $lang->admin->dividerMenu = ',company,message,system,'; -$lang->subject->menu = new stdclass(); +$lang->subject->menu = new stdclass(); $lang->subject->menu->storyConcept = array('link' => "{$lang->storyConcept}|custom|browsestoryconcept|"); /* System menu. */ -$lang->system->menu = new stdclass(); -$lang->system->menu->team = array('link' => "{$lang->team->common}|my|team|", 'subModule' => 'user'); -$lang->system->menu->dynamic = array('link' => "$lang->dynamic|company|dynamic|"); -$lang->system->menu->view = array('link' => "{$lang->company->common}|company|view"); +$lang->system->menu = new stdclass(); +$lang->system->menu->team = array('link' => "{$lang->team->common}|my|team|", 'subModule' => 'user'); +$lang->system->menu->dynamic = array('link' => "$lang->dynamic|company|dynamic|"); +$lang->system->menu->view = array('link' => "{$lang->company->common}|company|view"); /* System menu order. */ $lang->system->menuOrder[5] = 'team'; @@ -483,7 +487,7 @@ $lang->system->menuOrder[15] = 'dynamic'; $lang->system->menuOrder[20] = 'view'; /* Nav group.*/ -$lang->navGroup = new stdclass(); +$lang->navGroup = new stdclass(); $lang->navGroup->my = 'my'; $lang->navGroup->effort = 'my'; $lang->navGroup->score = 'my'; @@ -522,6 +526,8 @@ $lang->navGroup->team = 'execution'; $lang->navGroup->doc = 'doc'; $lang->navGroup->doclib = 'doc'; +$lang->navGroup->api = 'doc'; + $lang->navGroup->report = 'report'; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index e96e03cf19..f41e5e0aa2 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -10,7 +10,7 @@ * @link http://www.zentao.net */ -include (dirname(__FILE__) . '/common.php'); +include(dirname(__FILE__) . '/common.php'); global $config; @@ -113,7 +113,7 @@ $lang->selectAll = '全选'; $lang->selectReverse = '反选'; $lang->loading = '稍候...'; $lang->notFound = '抱歉,您访问的对象不存在!'; -$lang->notPage = '抱歉,您访问的功能正在开发中!'; +$lang->notPage = '抱歉,您访问的功能正在开发中!'; $lang->showAll = '[[全部显示]]'; $lang->selectedItems = '已选择 {0} 项'; @@ -223,6 +223,7 @@ $lang->doc->my = '我的文档'; $lang->doc->favorite = '我的收藏'; $lang->doc->product = '产品库'; $lang->doc->project = '项目库'; +$lang->doc->api = '接口库'; $lang->doc->execution = "{$lang->execution->common}库"; $lang->doc->custom = '自定义库'; $lang->doc->wiki = 'WIKI'; @@ -232,9 +233,9 @@ $lang->product->kanban = $lang->productCommon . '看板'; $lang->project->report = '报告'; -$lang->report->weekly = '周报'; -$lang->report->annual = '年度总结'; -$lang->report->notice = new stdclass(); +$lang->report->weekly = '周报'; +$lang->report->annual = '年度总结'; +$lang->report->notice = new stdclass(); $lang->report->notice->help = '注:统计报表的数据来源于列表页面的检索结果,生成统计报表前请先在列表页面进行检索。比如列表页面我们检索的是%tab%,那么报表就是基于之前检索的%tab%的结果集进行统计。'; $lang->testcase->case = '用例'; @@ -317,8 +318,27 @@ $lang->themes['pink'] = '芙蕖粉'; $lang->themes['blackberry'] = '露莓黑'; $lang->themes['classic'] = '经典蓝'; +/* global access control lang */ +/* common access control lang */ +$lang->acl->whiteList = '白名单'; +$lang->acl->aclList['open'] = '公开'; +$lang->acl->aclList['private'] = '私有'; +$lang->acl->aclList['custom'] = '自定义'; +$lang->acl->group = '分组'; +$lang->acl->user = '用户'; + +$lang->noticeAcl = [ + 'open' => '所有人都可以访问', + 'custom' => '白名单的用户可以访问', + 'private' => '只有创建者自己可以访问', +]; + +/* 全局公众配置 */ +$lang->curd->create = '创建'; + + /* 错误提示信息。*/ -$lang->error = new stdclass(); +$lang->error = new stdclass(); $lang->error->companyNotFound = "您访问的域名 %s 没有对应的公司。"; $lang->error->length = array("『%s』长度错误,应当为『%s』", "『%s』长度应当不超过『%s』,且大于『%s』。"); $lang->error->reg = "『%s』不符合格式,应当为:『%s』。"; @@ -348,7 +368,7 @@ $lang->error->tutorialData = '新手模式下不会插入数据,请退出 $lang->error->noCurlExt = '服务器未安装Curl模块。'; /* 分页信息。*/ -$lang->pager = new stdclass(); +$lang->pager = new stdclass(); $lang->pager->noRecord = "暂时没有记录"; $lang->pager->digest = "共 %s 条记录,%s %s/%s   "; $lang->pager->recPerPage = "每页 %s 条"; @@ -371,7 +391,7 @@ $lang->pager->pageSize = '每页 {recPerPage} 项'; $lang->pager->itemsRange = '第 {start} ~ {end} 项'; $lang->pager->pageOfTotal = '第 {page}/{totalPage} 页'; -$lang->colorPicker = new stdclass(); +$lang->colorPicker = new stdclass(); $lang->colorPicker->errorTip = '不是有效的颜色值'; $lang->downNotify = "下载桌面提醒"; @@ -397,23 +417,23 @@ $lang->pasteImgFail = "贴图失败,请稍后重试。"; $lang->pasteImgUploading = "正在上传图片,请稍后..."; /* 时间格式设置。*/ -if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s'); -if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i'); +if(!defined('DT_DATETIME1')) define('DT_DATETIME1', 'Y-m-d H:i:s'); +if(!defined('DT_DATETIME2')) define('DT_DATETIME2', 'y-m-d H:i'); if(!defined('DT_MONTHTIME1')) define('DT_MONTHTIME1', 'n/d H:i'); if(!defined('DT_MONTHTIME2')) define('DT_MONTHTIME2', 'n月d日 H:i'); -if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d'); -if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd'); -if(!defined('DT_DATE3')) define('DT_DATE3', 'Y年m月d日'); -if(!defined('DT_DATE4')) define('DT_DATE4', 'n月j日'); -if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n'); -if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s'); -if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i'); -if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31'); +if(!defined('DT_DATE1')) define('DT_DATE1', 'Y-m-d'); +if(!defined('DT_DATE2')) define('DT_DATE2', 'Ymd'); +if(!defined('DT_DATE3')) define('DT_DATE3', 'Y年m月d日'); +if(!defined('DT_DATE4')) define('DT_DATE4', 'n月j日'); +if(!defined('DT_DATE5')) define('DT_DATE5', 'j/n'); +if(!defined('DT_TIME1')) define('DT_TIME1', 'H:i:s'); +if(!defined('DT_TIME2')) define('DT_TIME2', 'H:i'); +if(!defined('LONG_TIME')) define('LONG_TIME', '2059-12-31'); /* datepicker 时间*/ $lang->datepicker = new stdclass(); -$lang->datepicker->dpText = new stdclass(); +$lang->datepicker->dpText = new stdclass(); $lang->datepicker->dpText->TEXT_OR = '或 '; $lang->datepicker->dpText->TEXT_PREV_YEAR = '去年'; $lang->datepicker->dpText->TEXT_PREV_MONTH = '上月'; @@ -432,4 +452,4 @@ $lang->datepicker->dayNames = array('星期日', '星期一', '星期二', ' $lang->datepicker->abbrDayNames = array('日', '一', '二', '三', '四', '五', '六'); $lang->datepicker->monthNames = array('一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'); -include (dirname(__FILE__) . '/menu.php'); +include(dirname(__FILE__) . '/menu.php'); diff --git a/module/common/lang/zh-tw.php b/module/common/lang/zh-tw.php index 0f1061abcb..09e188ae89 100644 --- a/module/common/lang/zh-tw.php +++ b/module/common/lang/zh-tw.php @@ -223,6 +223,7 @@ $lang->doc->my = '我的文檔'; $lang->doc->favorite = '我的收藏'; $lang->doc->product = '產品庫'; $lang->doc->project = '項目庫'; +$lang->doc->interface = '項目庫'; $lang->doc->execution = "{$lang->execution->common}庫"; $lang->doc->custom = '自定義庫'; $lang->doc->wiki = 'WIKI'; diff --git a/module/doc/control.php b/module/doc/control.php index 7f72f78c8e..1f64f40f6b 100644 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -1,4 +1,5 @@ app->getURI(true); - $this->session->set('docList', $uri, 'doc'); - $this->session->set('productList', $uri, 'product'); + $this->session->set('docList', $uri, 'doc'); + $this->session->set('productList', $uri, 'product'); $this->session->set('executionList', $uri, 'execution'); - $this->session->set('projectList', $uri, 'project'); + $this->session->set('projectList', $uri, 'project'); $this->loadModel('search'); /* Set browseType.*/ @@ -84,7 +85,7 @@ class doc extends control $moduleID = ($browseType == 'bymodule') ? (int)$param : 0; /* Set header and position. */ - $this->view->title = $this->lang->doc->common; + $this->view->title = $this->lang->doc->common; /* Load pager. */ $this->app->loadClass('pager', $static = true); @@ -120,8 +121,8 @@ class doc extends control /** * Create a library. * - * @param string $type - * @param int $objectID + * @param string $type + * @param int $objectID * @access public * @return void */ @@ -133,10 +134,10 @@ class doc extends control if(!dao::isError()) { $objectType = $this->post->type; - if($objectType == 'project' and $this->post->project) $objectID = $this->post->project; - if($objectType == 'product' and $this->post->product) $objectID = $this->post->product; + if($objectType == 'project' and $this->post->project) $objectID = $this->post->project; + if($objectType == 'product' and $this->post->product) $objectID = $this->post->product; if($objectType == 'execution' and $this->post->execution) $objectID = $this->post->execution; - if($objectType == 'custom' or $objectType == 'book') $objectID = 0; + if($objectType == 'custom' or $objectType == 'book') $objectID = 0; $this->action->create('docLib', $libID, 'Created'); @@ -161,8 +162,8 @@ class doc extends control } $libTypeList = $this->lang->doc->libTypeList; - if(empty($products)) unset($libTypeList['product']); - if(empty($projects)) unset($libTypeList['project']); + if(empty($products)) unset($libTypeList['product']); + if(empty($projects)) unset($libTypeList['project']); if(empty($executions)) unset($libTypeList['execution']); $this->view->groups = $this->loadModel('group')->getPairs(); @@ -179,7 +180,7 @@ class doc extends control /** * Edit a library. * - * @param int $libID + * @param int $libID * @access public * @return void */ @@ -205,7 +206,7 @@ class doc extends control } $lib = $this->doc->getLibByID($libID); - if(!empty($lib->product)) $this->view->product = $this->dao->select('id,name')->from(TABLE_PRODUCT)->where('id')->eq($lib->product)->fetch(); + if(!empty($lib->product)) $this->view->product = $this->dao->select('id,name')->from(TABLE_PRODUCT)->where('id')->eq($lib->product)->fetch(); if(!empty($lib->execution)) { $execution = $this->execution->getByID($lib->execution); @@ -213,10 +214,10 @@ class doc extends control $this->view->execution = $execution; } - $this->view->lib = $lib; - $this->view->groups = $this->loadModel('group')->getPairs(); - $this->view->users = $this->user->getPairs('noletter|noclosed', $lib->users); - $this->view->libID = $libID; + $this->view->lib = $lib; + $this->view->groups = $this->loadModel('group')->getPairs(); + $this->view->users = $this->user->getPairs('noletter|noclosed', $lib->users); + $this->view->libID = $libID; die($this->display()); } @@ -224,9 +225,9 @@ class doc extends control /** * Delete a library. * - * @param int $libID - * @param string $confirm yes|no - * @param string $from lib|book + * @param int $libID + * @param string $confirm yes|no + * @param string $from lib|book * @access public * @return void */ @@ -265,11 +266,11 @@ class doc extends control /** * Create a doc. * - * @param string $objectType - * @param int $objectID - * @param int|string $libID - * @param int $moduleID - * @param string $docType + * @param string $objectType + * @param int $objectID + * @param int|string $libID + * @param int $moduleID + * @param string $docType * @access public * @return void */ @@ -290,7 +291,7 @@ class doc extends control } $fileAction = ''; - if(!empty($files)) $fileAction = $this->lang->addFiles . join(',', $files) . "\n" ; + if(!empty($files)) $fileAction = $this->lang->addFiles . join(',', $files) . "\n"; $this->action->create('doc', $docID, 'Created', $fileAction); if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $docID)); @@ -354,11 +355,11 @@ class doc extends control /** * Edit a doc. * - * @param int $docID - * @param bool $comment - * @param string $objectType - * @param int $objectID - * @param int $libID + * @param int $docID + * @param bool $comment + * @param string $objectType + * @param int $objectID + * @param int $libID * @access public * @return void */ @@ -375,9 +376,9 @@ class doc extends control } if($this->post->comment != '' or !empty($changes) or !empty($files)) { - $action = !empty($changes) ? 'Edited' : 'Commented'; + $action = !empty($changes) ? 'Edited' : 'Commented'; $fileAction = ''; - if(!empty($files)) $fileAction = $this->lang->addFiles . join(',', $files) . "\n" ; + if(!empty($files)) $fileAction = $this->lang->addFiles . join(',', $files) . "\n"; $actionID = $this->action->create('doc', $docID, $action, $fileAction . $this->post->comment); if(!empty($changes)) $this->action->logHistory($actionID, $changes); } @@ -420,9 +421,9 @@ class doc extends control } else if($this->app->tab == 'my') { - $this->lang->doc->menu = $this->lang->my->menu->contribute; - $this->lang->modulePageNav = ''; - $this->lang->TRActions = ''; + $this->lang->doc->menu = $this->lang->my->menu->contribute; + $this->lang->modulePageNav = ''; + $this->lang->TRActions = ''; $this->lang->my->menu->contribute['subModule'] = 'doc'; } else @@ -437,15 +438,15 @@ class doc extends control /* High light menu. */ if(strpos(',product,project,execution,custom,book,', ",$objectType,") !== false) { - $menu = $this->lang->doc->menu->$objectType; - $menu['alias'] .= ',edit'; - $menu['subModule'] = 'doc'; + $menu = $this->lang->doc->menu->$objectType; + $menu['alias'] .= ',edit'; + $menu['subModule'] = 'doc'; $this->lang->doc->menu->$objectType = $menu; } } - $objects = $this->doc->getOrderedObjects($objectType); - $libs = $this->doc->getLibsByObject($objectType, $objectID); + $objects = $this->doc->getOrderedObjects($objectType); + $libs = $this->doc->getLibsByObject($objectType, $objectID); $this->lang->modulePageNav = $this->doc->select($objectType, $objects, $objectID, $libs, $libID); $this->lang->TRActions = common::hasPriv('doc', 'create') ? $this->doc->buildCreateButton4Doc($objectType, $objectID, $libID) : ''; @@ -465,8 +466,8 @@ class doc extends control /** * View a doc. * - * @param int $docID - * @param int $version + * @param int $docID + * @param int $version * @access public * @return void */ @@ -527,9 +528,9 @@ class doc extends control /** * Delete a doc. * - * @param int $docID - * @param string $confirm yes|no - * @param string $from + * @param int $docID + * @param string $confirm yes|no + * @param string $from * @access public * @return void */ @@ -563,7 +564,7 @@ class doc extends control if($from == 'lib') { - $response['locate'] = $this->createLink('doc', 'objectLibs', "type=$objectType"); + $response['locate'] = $this->createLink('doc', 'objectLibs', "type=$objectType"); } } return $this->send($response); @@ -576,9 +577,9 @@ class doc extends control /** * Delete file for doc. * - * @param int $docID - * @param int $fileID - * @param string $confirm + * @param int $docID + * @param int $fileID + * @param string $confirm * @access public * @return void */ @@ -592,17 +593,17 @@ class doc extends control else { $docContent = $this->dao->select('t1.*')->from(TABLE_DOCCONTENT)->alias('t1') - ->leftJoin(TABLE_DOC)->alias('t2')->on('t1.doc=t2.id and t1.version=t2.version') - ->where('t2.id')->eq($docID) - ->fetch(); + ->leftJoin(TABLE_DOC)->alias('t2')->on('t1.doc=t2.id and t1.version=t2.version') + ->where('t2.id')->eq($docID) + ->fetch(); unset($docContent->id); - $docContent->files = trim(str_replace(",{$fileID},", ',', ",{$docContent->files},"), ','); + $docContent->files = trim(str_replace(",{$fileID},", ',', ",{$docContent->files},"), ','); $docContent->version += 1; $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec(); $this->dao->update(TABLE_DOC)->set('version')->eq($docContent->version)->where('id')->eq($docID)->exec(); $file = $this->file->getById($fileID); - $this->action->create($file->objectType, $file->objectID, 'deletedFile', '', $extra=$file->title); + $this->action->create($file->objectType, $file->objectID, 'deletedFile', '', $extra = $file->title); die(js::locate($this->createLink('doc', 'view', "docID=$docID"), 'parent')); } } @@ -610,14 +611,14 @@ class doc extends control /** * Collect doc, doclib or module of doclib. * - * @param int $objectID - * @param int $objectType + * @param int $objectID + * @param int $objectType * @access public * @return void */ public function collect($objectID, $objectType) { - if($objectType == 'doc') $table = TABLE_DOC; + if($objectType == 'doc') $table = TABLE_DOC; if($objectType == 'doclib') $table = TABLE_DOCLIB; if($objectType == 'module') $table = TABLE_MODULE; $collectors = $this->dao->select('collector')->from($table)->where('id')->eq($objectID)->fetch('collector'); @@ -629,9 +630,9 @@ class doc extends control } else { - $collectors = explode(',', $collectors); + $collectors = explode(',', $collectors); $collectors[] = $this->app->user->account; - $collectors = implode(',', $collectors); + $collectors = implode(',', $collectors); } $collectors = trim($collectors, ',') ? ',' . trim($collectors, ',') . ',' : ''; @@ -644,7 +645,7 @@ class doc extends control /** * Sort doc lib. * - * @param string $type + * @param string $type * @access public * @return void */ @@ -669,7 +670,7 @@ class doc extends control /** * Ajax get modules by libID. * - * @param int $libID + * @param int $libID * @access public * @return void */ @@ -682,28 +683,28 @@ class doc extends control /** * Ajax fixed menu. * - * @param int $libID - * @param string $type + * @param int $libID + * @param string $type * @access public * @return void */ public function ajaxFixedMenu($libID, $type = 'fixed') { $customMenuKey = $this->config->global->flow . '_doc'; - $customMenus = $this->loadModel('setting')->getItem("owner={$this->app->user->account}&module=common§ion=customMenu&key={$customMenuKey}"); + $customMenus = $this->loadModel('setting')->getItem("owner={$this->app->user->account}&module=common§ion=customMenu&key={$customMenuKey}"); if($customMenus) $customMenus = json_decode($customMenus); if(empty($customMenus)) { if($type == 'remove') die(js::reload('parent')); $customMenus = array(); - $i = 0; + $i = 0; foreach($this->lang->doc->menu as $name => $item) { if($name == 'list') continue; - $customMenu = new stdclass(); - $customMenu->name = $name; + $customMenu = new stdclass(); + $customMenu->name = $name; $customMenu->order = $i; - $customMenus[] = $customMenu; + $customMenus[] = $customMenu; $i++; } } @@ -714,11 +715,11 @@ class doc extends control if(isset($customMenu->name) and $customMenu->name == "custom{$libID}") unset($customMenus[$i]); } - $lib = $this->doc->getLibByID($libID); - $customMenu = new stdclass(); - $customMenu->name = "custom{$libID}"; - $customMenu->order = count($customMenus); - $customMenu->float = 'right'; + $lib = $this->doc->getLibByID($libID); + $customMenu = new stdclass(); + $customMenu->name = "custom{$libID}"; + $customMenu->order = count($customMenus); + $customMenu->float = 'right'; if($type == 'fixed') $customMenus[] = $customMenu; $this->setting->setItem("{$this->app->user->account}.common.customMenu.{$customMenuKey}", json_encode($customMenus)); die(js::reload('parent')); @@ -744,14 +745,14 @@ class doc extends control public function ajaxGetChild($libID, $type = 'module') { $childModules = $this->tree->getOptionMenu($libID, 'doc'); - $select = ($type == 'module') ? html::select('module', $childModules, '', "class='form-control chosen'") : html::select('parent', $childModules, '', "class='form-control chosen'"); + $select = ($type == 'module') ? html::select('module', $childModules, '', "class='form-control chosen'") : html::select('parent', $childModules, '', "class='form-control chosen'"); die($select); } /** * Ajax save draft. * - * @param int $docID + * @param int $docID * @access public * @return void */ @@ -763,13 +764,13 @@ class doc extends control /** * Show files. * - * @param string $type - * @param int $objectID - * @param string $viewType - * @param string $orderBy - * @param int $recTotal - * @param int $recPerPage - * @param int $pageID + * @param string $type + * @param int $objectID + * @param string $viewType + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID * @access public * @return void */ @@ -778,9 +779,9 @@ class doc extends control if(empty($viewType)) $viewType = !empty($_COOKIE['docFilesViewType']) ? $this->cookie->docFilesViewType : 'card'; setcookie('docFilesViewType', $viewType, $this->config->cookieLife, $this->config->webRoot, '', false, true); - $objects = $this->doc->getOrderedObjects($type); - $objectID = $this->{$type}->saveState($objectID, $objects); - $libs = $this->doc->getLibsByObject($type, $objectID); + $objects = $this->doc->getOrderedObjects($type); + $objectID = $this->{$type}->saveState($objectID, $objects); + $libs = $this->doc->getLibsByObject($type, $objectID); $this->lang->modulePageNav = $this->doc->select($type, $objects, $objectID, $libs); $tab = strpos('doc,product,project,execution', $this->app->tab) !== false ? $this->app->tab : 'doc'; @@ -789,7 +790,7 @@ class doc extends control $table = $this->config->objectTables[$type]; $object = $this->dao->select('id,name,status')->from($table)->where('id')->eq($objectID)->fetch(); - $this->lang->TRActions = $this->doc->buildCollectButton4Doc(); + $this->lang->TRActions = $this->doc->buildCollectButton4Doc(); $this->lang->TRActions .= $this->doc->buildBrowseSwitch($type, $objectID, $viewType); /* Load pager. */ @@ -820,11 +821,11 @@ class doc extends control /** * Show all libs by type. * - * @param string $type - * @param string $product - * @param int $recTotal - * @param int $recPerPage - * @param int $pageID + * @param string $type + * @param string $product + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID * @access public * @return void */ @@ -885,12 +886,12 @@ class doc extends control /** * Show libs for product or project. * - * @param string $type - * @param int $objectID projectID|productID - * @param int $libID - * @param int $docID - * @param int $version - * @param int $appendLib + * @param string $type + * @param int $objectID projectID|productID + * @param int $libID + * @param int $docID + * @param int $version + * @param int $appendLib * @access public * @return void */ @@ -967,7 +968,7 @@ class doc extends control /* Add the anchor to the element. */ $content[$index] = str_replace('<' . $includeHeadElement[0] . $headElement[2] . '>', '<' . $includeHeadElement[0] . $headElement[2] . " id='anchor{$index}'" . '>', $content[$index]); - $outline .= '
  • ' . html::a('#anchor' . $index, strip_tags($headElement[3]), '', "title='" . strip_tags($headElement[3]) . "'"); + $outline .= '
  • ' . html::a('#anchor' . $index, strip_tags($headElement[3]), '', "title='" . strip_tags($headElement[3]) . "'"); $preElement = $headElement[1]; } @@ -978,12 +979,12 @@ class doc extends control /* Add the anchor to the element. */ $content[$index] = str_replace('<' . $includeHeadElement[1] . $headElement[2] . '>', '<' . $includeHeadElement[1] . $headElement[2] . " id='anchor{$index}'" . '>', $content[$index]); - $outline .= '
  • ' . html::a('#anchor' . $index, strip_tags($headElement[3]), '', "title='" . strip_tags($headElement[3]) . "'") . '
  • '; + $outline .= '
  • ' . html::a('#anchor' . $index, strip_tags($headElement[3]), '', "title='" . strip_tags($headElement[3]) . "'") . '
  • '; $preElement = $includeHeadElement[1]; } } - if(isset($includeHeadElement[1]) and $preElement == $includeHeadElement[1] and !isset($content[$index+1])) $outline .= ''; + if(isset($includeHeadElement[1]) and $preElement == $includeHeadElement[1] and !isset($content[$index + 1])) $outline .= ''; } $outline .= ''; @@ -1020,9 +1021,9 @@ class doc extends control /** * Show the catalog of the doc library. * - * @param string $type - * @param int $objectID - * @param int $libID + * @param string $type + * @param int $objectID + * @param int $libID * @access public * @return void */ diff --git a/module/doc/model.php b/module/doc/model.php index ba6bee9694..f37902441d 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -11,12 +11,17 @@ */ ?> dao->findByID($libID)->from(TABLE_DOCLIB)->fetch(); } + /** + * Get api Libraries. + * + * @return array + * @author thanatos thanatos915@163.com + */ + public function getApiLibs() + { + $libs = $this->dao->select('*')->from(TABLE_DOCLIB) + ->where('deleted')->eq(0) + ->andWhere('type')->eq('api') + ->orderBy('id_desc') + ->fetchAll('id'); + $libs = array_filter($libs, function ($value) { + return $this->checkPrivLib($value); + }); + return $libs; + } + /** * Get libraries. * - * @param string $type - * @param string $extra - * @param string $appendLibs - * @param int $projectID + * @param string $type + * @param string $extra + * @param string $appendLibs + * @param int $projectID * @access public * @return array */ @@ -59,17 +83,17 @@ class docModel extends model $libPairs = array(); while($lib = $stmt->fetch()) { - if($lib->product != 0 and !isset($products[$lib->product])) continue; + if($lib->product != 0 and !isset($products[$lib->product])) continue; if($lib->execution != 0 and !isset($executions[$lib->execution])) continue; - if($lib->project != 0 and !isset($projects[$lib->project]) and $lib->type == 'project') continue; + if($lib->project != 0 and !isset($projects[$lib->project]) and $lib->type == 'project') continue; if($this->checkPrivLib($lib, $extra)) { if(strpos($extra, 'withObject') !== false) { - if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name; + if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name; if($lib->execution != 0) $lib->name = zget($executions, $lib->execution, '') . ' / ' . $lib->name; - if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name; + if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name; } $libPairs[$lib->id] = $lib->name; @@ -143,7 +167,7 @@ class docModel extends model if($lib->type == 'execution' and $lib->execution) { - $execution = $this->loadModel('execution')->getByID($lib->execution); + $execution = $this->loadModel('execution')->getByID($lib->execution); $lib->project = $execution->project; } @@ -155,10 +179,29 @@ class docModel extends model return $this->dao->lastInsertID(); } + /** + * creat a api doc library. + * @param stdClass $data form data. + * @return int + * @author thanatos thanatos915@163.com + */ + public function createApiLib($data) + { + /* replace doc library name */ + $this->lang->doclib->name = '接口库名称'; + + $data->type = static::DOC_TYPE_API; + $this->dao->insert(TABLE_DOCLIB)->data($data)->autoCheck() + ->batchCheck($this->config->api->createlib->requiredFields, 'notempty') + ->check('name', 'unique', "`type` = '" . static::DOC_TYPE_API . "'") + ->exec(); + return $this->dao->lastInsertID(); + } + /** * Update a library. * - * @param int $libID + * @param int $libID * @access public * @return void */ @@ -166,7 +209,7 @@ class docModel extends model { $libID = (int)$libID; $oldLib = $this->getLibById($libID); - $lib = fixer::input('post') + $lib = fixer::input('post') ->setDefault('users', '') ->setDefault('groups', '') ->join('groups', ',') @@ -187,11 +230,11 @@ class docModel extends model /** * Get docs by browse type. * - * @param string $browseType - * @param int $queryID - * @param int $moduleID - * @param string $sort - * @param object $pager + * @param string $browseType + * @param int $queryID + * @param int $moduleID + * @param string $sort + * @param object $pager * @access public * @return array */ @@ -227,7 +270,7 @@ class docModel extends model ->andWhere('actor')->eq($this->app->user->account) ->andWhere('action')->eq('edited') ->fetchAll('objectID'); - $docs = $this->dao->select('*')->from(TABLE_DOC) + $docs = $this->dao->select('*')->from(TABLE_DOC) ->where('deleted')->eq(0) ->andWhere('id')->in(array_keys($docIDList)) ->andWhere('lib')->in($allLibs) @@ -305,7 +348,7 @@ class docModel extends model } else { - $fileSize = round($fileSize / 1024 / 1024 /1024, 2) . 'G'; + $fileSize = round($fileSize / 1024 / 1024 / 1024, 2) . 'G'; } $docs[$index]->fileSize = $fileSize; @@ -318,7 +361,7 @@ class docModel extends model /** * Get projects, executions and products by docIdList. * - * @param array $docIdList + * @param array $docIdList * @access public * @return array */ @@ -348,10 +391,10 @@ class docModel extends model /** * Get docs. * - * @param int|string $libID - * @param int $module - * @param string $orderBy - * @param object $pager + * @param int|string $libID + * @param int $module + * @param string $orderBy + * @param object $pager * @access public * @return void */ @@ -369,9 +412,9 @@ class docModel extends model /** * Get priv docs. * - * @param int $libID - * @param int $module - * @param string $mode normal|all + * @param int $libID + * @param int $module + * @param string $mode normal|all * @access public * @return void */ @@ -397,9 +440,9 @@ class docModel extends model /** * Get doc info by id. * - * @param int $docID - * @param int $version - * @param bool $setImgSize + * @param int $docID + * @param int $version + * @param bool $setImgSize * @access public * @return void */ @@ -414,46 +457,46 @@ class docModel extends model if(strpos($this->server->http_referer, $loginLink) !== false) die(js::locate(inlink('index'))); die(js::locate('back')); } - $version = $version ? $version : $doc->version; + $version = $version ? $version : $doc->version; $docContent = $this->dao->select('*')->from(TABLE_DOCCONTENT)->where('doc')->eq($doc->id)->andWhere('version')->eq($version)->fetch(); /* When file change then version add one. */ - $files = $this->loadModel('file')->getByObject('doc', $docID); + $files = $this->loadModel('file')->getByObject('doc', $docID); $docFiles = array(); foreach($files as $file) { - $pathName = $this->file->getRealPathName($file->pathname); + $pathName = $this->file->getRealPathName($file->pathname); $file->webPath = $this->file->webPath . $pathName; $file->realPath = $this->file->savePath . $pathName; if(strpos(",{$docContent->files},", ",{$file->id},") !== false) $docFiles[$file->id] = $file; } /* Check file change. */ - if($version == $doc->version and ((empty($docContent->files) and $docFiles) OR ($docContent->files and count(explode(',', trim($docContent->files, ','))) != count($docFiles)))) + if($version == $doc->version and ((empty($docContent->files) and $docFiles) or ($docContent->files and count(explode(',', trim($docContent->files, ','))) != count($docFiles)))) { unset($docContent->id); $doc->version += 1; - $docContent->version = $doc->version; - $docContent->files = join(',', array_keys($docFiles)); + $docContent->version = $doc->version; + $docContent->files = join(',', array_keys($docFiles)); $this->dao->insert(TABLE_DOCCONTENT)->data($docContent)->exec(); $this->dao->update(TABLE_DOC)->set('version')->eq($doc->version)->where('id')->eq($doc->id)->exec(); } - $doc->title = isset($docContent->title) ? $docContent->title : ''; - $doc->digest = isset($docContent->digest) ? $docContent->digest : ''; + $doc->title = isset($docContent->title) ? $docContent->title : ''; + $doc->digest = isset($docContent->digest) ? $docContent->digest : ''; $doc->content = isset($docContent->content) ? $docContent->content : ''; - $doc->contentType = isset($docContent->type) ? $docContent->type : ''; + $doc->contentType = isset($docContent->type) ? $docContent->type : ''; - if($doc->type != 'url' and $doc->contentType != 'markdown') $doc = $this->loadModel('file')->replaceImgURL($doc, 'content,draft'); + if($doc->type != 'url' and $doc->contentType != 'markdown') $doc = $this->loadModel('file')->replaceImgURL($doc, 'content,draft'); if($setImgSize) $doc->content = $this->file->setImgSize($doc->content); $doc->files = $docFiles; $doc->productName = ''; $doc->executionName = ''; $doc->moduleName = ''; - if($doc->product) $doc->productName = $this->dao->findByID($doc->product)->from(TABLE_PRODUCT)->fetch('name'); + if($doc->product) $doc->productName = $this->dao->findByID($doc->product)->from(TABLE_PRODUCT)->fetch('name'); if($doc->execution) $doc->executionName = $this->dao->findByID($doc->execution)->from(TABLE_EXECUTION)->fetch('name'); - if($doc->module) $doc->moduleName = $this->dao->findByID($doc->module)->from(TABLE_MODULE)->fetch('name'); + if($doc->module) $doc->moduleName = $this->dao->findByID($doc->module)->from(TABLE_MODULE)->fetch('name'); if(!$doc->module and $doc->type == 'article' and $doc->parent) $doc->moduleName = $this->dao->findByID($doc->parent)->from(TABLE_DOC)->fetch('title'); return $doc; } @@ -461,7 +504,7 @@ class docModel extends model /** * Get docs info by id list. * - * @param array $docIdList + * @param array $docIdList * @access public * @return array */ @@ -506,18 +549,18 @@ class docModel extends model } /* Fix bug #2929. strip_tags($this->post->contentMarkdown, $this->config->allowedTags)*/ - $doc = $this->loadModel('file')->processImgURL($doc, $this->config->doc->editor->create['id'], $this->post->uid); + $doc = $this->loadModel('file')->processImgURL($doc, $this->config->doc->editor->create['id'], $this->post->uid); $doc->contentMarkdown = $this->post->contentMarkdown; if($doc->acl == 'private') $doc->users = $this->app->user->account; if($doc->title) { $condition = "lib = '$doc->lib' AND module = $doc->module"; - $result = $this->loadModel('common')->removeDuplicate('doc', $doc, $condition); + $result = $this->loadModel('common')->removeDuplicate('doc', $doc, $condition); if($result['stop']) return array('status' => 'exists', 'id' => $result['duplicate']); } - $lib = $this->getLibByID($doc->lib); + $lib = $this->getLibByID($doc->lib); $doc->product = $lib->product; $doc->project = $lib->project; $doc->execution = $lib->execution; @@ -527,7 +570,7 @@ class docModel extends model $doc->contentType = 'html'; } - $docContent = new stdclass(); + $docContent = new stdclass(); $docContent->title = $doc->title; $docContent->content = $doc->contentType == 'html' ? $doc->content : $doc->contentMarkdown; $docContent->type = $doc->contentType; @@ -566,7 +609,7 @@ class docModel extends model /** * Update a doc. * - * @param int $docID + * @param int $docID * @access public * @return void */ @@ -586,7 +629,7 @@ class docModel extends model ->setDefault('groups', '') ->setDefault('product', 0) ->setDefault('execution', 0) - ->add('editedBy', $this->app->user->account) + ->add('editedBy', $this->app->user->account) ->add('editedDate', $now) ->cleanInt('module') ->join('groups', ',') @@ -638,17 +681,17 @@ class docModel extends model if($changed) { - $doc->version = $oldDoc->version + 1; - $docContent = new stdclass(); + $doc->version = $oldDoc->version + 1; + $docContent = new stdclass(); $docContent->doc = $docID; $docContent->title = $doc->title; $docContent->content = isset($doc->content) ? $doc->content : ''; $docContent->version = $doc->version; $docContent->type = $oldDocContent->type; $docContent->files = $oldDocContent->files; - if(isset($doc->digest)) $docContent->digest = $doc->digest; + if(isset($doc->digest)) $docContent->digest = $doc->digest; if($files) $docContent->files .= ',' . join(',', array_keys($files)); - $docContent->files = trim($docContent->files, ','); + $docContent->files = trim($docContent->files, ','); $this->dao->replace(TABLE_DOCCONTENT)->data($docContent)->exec(); } unset($doc->contentType); @@ -670,16 +713,16 @@ class docModel extends model /** * Save draft. * - * @param int $docID + * @param int $docID * @access public * @return void */ public function saveDraft($docID) { - $data = fixer::input('post') + $data = fixer::input('post') ->stripTags($this->config->doc->editor->edit['id'], $this->config->allowedTags) ->get(); - $doc = new stdclass(); + $doc = new stdclass(); $doc->draft = $data->content; $docType = $this->dao->select('type')->from(TABLE_DOCCONTENT)->where('doc')->eq((int)$docID)->orderBy('version_desc')->fetch(); @@ -691,23 +734,23 @@ class docModel extends model /** * Build search form. * - * @param string $libID - * @param array $libs - * @param int $queryID - * @param string $actionURL + * @param string $libID + * @param array $libs + * @param int $queryID + * @param string $actionURL * @access public * @return void */ public function buildSearchForm($libID, $libs, $queryID, $actionURL, $type) { - $this->config->doc->search['actionURL'] = $actionURL; - $this->config->doc->search['queryID'] = $queryID; - $this->config->doc->search['params']['product']['values'] = array(''=>'') + $this->loadModel('product')->getPairs('nocode', $this->session->project) + array('all'=>$this->lang->doc->allProduct); - $this->config->doc->search['params']['execution']['values'] = array(''=>'') + $this->loadModel('execution')->getPairs($this->session->project, 'all', 'noclosed') + array('all'=>$this->lang->doc->allExecutions); - $this->config->doc->search['params']['lib']['values'] = array(''=>'', $libID => ($libID ? $libs[$libID] : 0), 'all' => $this->lang->doclib->all); + $this->config->doc->search['actionURL'] = $actionURL; + $this->config->doc->search['queryID'] = $queryID; + $this->config->doc->search['params']['product']['values'] = array('' => '') + $this->loadModel('product')->getPairs('nocode', $this->session->project) + array('all' => $this->lang->doc->allProduct); + $this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'all', 'noclosed') + array('all' => $this->lang->doc->allExecutions); + $this->config->doc->search['params']['lib']['values'] = array('' => '', $libID => ($libID ? $libs[$libID] : 0), 'all' => $this->lang->doclib->all); /* Get the modules. */ - $moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'doc', $startModuleID = 0); + $moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, 'doc', $startModuleID = 0); $this->config->doc->search['params']['module']['values'] = $moduleOptionMenu; if($type == 'index' || $type == 'objectLibs' || $libID == 0) @@ -737,8 +780,8 @@ class docModel extends model /** * Get doc menu. * - * @param int $libID - * @param int $parent + * @param int $libID + * @param int $parent * @access public * @return array */ @@ -772,13 +815,13 @@ class docModel extends model * * Like this: * - * @param string $content + * @param string $content * @access public * @return void */ public function extractKETableCSS($content) { - $css = ''; + $css = ''; $rule = '/
    product) or !empty($object->execution)) { $acls = $this->app->user->rights['acls']; - if(!empty($object->product) and !empty($acls['products']) and !in_array($object->product, $acls['products'])) return false; + if(!empty($object->product) and !empty($acls['products']) and !in_array($object->product, $acls['products'])) return false; if(!empty($object->execution) and !empty($acls['sprints']) and !in_array($object->execution, $acls['sprints'])) return false; if(!empty($object->execution)) return $this->loadModel('execution')->checkPriv($object->execution); if(!empty($object->product)) return $this->loadModel('product')->checkPriv($object->product); @@ -852,7 +895,7 @@ class docModel extends model /** * Check priv for doc. * - * @param object $object + * @param object $object * @access public * @return bool */ @@ -888,9 +931,9 @@ class docModel extends model /** * Get all libs by type. * - * @param string $type - * @param int $pager - * @param string $extra + * @param string $type + * @param int $pager + * @param string $extra * @access public * @return array */ @@ -946,7 +989,7 @@ class docModel extends model /** * Get all lib groups. * - * @param string $appendLibs + * @param string $appendLibs * @access public * @return array */ @@ -988,8 +1031,8 @@ class docModel extends model ->andWhere('t2.deleted')->eq(0) ->fetchPairs('product', 'product'); - $hasLibsPriv = common::hasPriv('doc', 'allLibs'); - $hasFilesPriv = common::hasPriv('doc', 'showFiles'); + $hasLibsPriv = common::hasPriv('doc', 'allLibs'); + $hasFilesPriv = common::hasPriv('doc', 'showFiles'); $productOrderLibs = array(); foreach($products as $product) { @@ -1006,7 +1049,7 @@ class docModel extends model } } - $executions = $this->dao->select('id,name,status')->from(TABLE_EXECUTION) + $executions = $this->dao->select('id,name,status')->from(TABLE_EXECUTION) ->where('id')->in(array_keys($executionLibs)) ->andWhere('deleted')->eq('0') ->beginIF(strpos($this->config->doc->custom->showLibs, 'unclosed') !== false)->andWhere('status')->notin('done,closed')->fi() @@ -1033,8 +1076,8 @@ class docModel extends model /** * Get limit libs. * - * @param string $type - * @param int $limit + * @param string $type + * @param int $limit * @access public * @return array */ @@ -1093,7 +1136,7 @@ class docModel extends model } $libs[$docLib->id] = $docLib->name; - $i ++; + $i++; } } @@ -1103,8 +1146,8 @@ class docModel extends model /** * Get execution or product libs groups. * - * @param string $type - * @param array $idList + * @param string $type + * @param array $idList * @access public * @return array */ @@ -1130,10 +1173,10 @@ class docModel extends model /** * Get libs by object. * - * @param string $type - * @param int $objectID - * @param string $mode - * @param int $appendLib + * @param string $type + * @param int $objectID + * @param string $mode + * @param int $appendLib * @access public * @return array */ @@ -1190,7 +1233,7 @@ class docModel extends model /** * Get ordered objects for dic. * - * @param string $objectType + * @param string $objectType * @access public * @return array */ @@ -1233,7 +1276,7 @@ class docModel extends model foreach($objects as $objectID => $object) { - $object->parent = $this->program->getTopByID($object->parent); + $object->parent = $this->program->getTopByID($object->parent); $orderedProjects[$objectID] = $object; unset($objects[$object->id]); } @@ -1291,7 +1334,7 @@ class docModel extends model /** * Stat module and document counts of lib. * - * @param array $idList + * @param array $idList * @access public * @return array */ @@ -1315,14 +1358,14 @@ class docModel extends model { if(!$this->checkPrivDoc($doc)) continue; if(!isset($docCounts[$doc->lib])) $docCounts[$doc->lib] = 0; - $docCounts[$doc->lib] ++; + $docCounts[$doc->lib]++; } $itemCounts = array(); foreach($idList as $libID) { - $docCount = isset($docCounts[$libID]) ? $docCounts[$libID] : 0; - $moduleCount = isset($moduleCounts[$libID]) ? $moduleCounts[$libID] : 0; + $docCount = isset($docCounts[$libID]) ? $docCounts[$libID] : 0; + $moduleCount = isset($moduleCounts[$libID]) ? $moduleCounts[$libID] : 0; $itemCounts[$libID] = $docCount + $moduleCount; } @@ -1332,10 +1375,10 @@ class docModel extends model /** * Get lib files. * - * @param string $type - * @param int $objectID - * @param string $orderBy - * @param object $pager + * @param string $type + * @param int $objectID + * @param string $orderBy + * @param object $pager * @access public * @return array */ @@ -1353,7 +1396,7 @@ class docModel extends model $bugIdList = $testReportIdList = $caseIdList = $storyIdList = $planIdList = $releaseIdList = $executionIdList = $taskIdList = $buildIdList = $issueIdList = $meetingIdList = $designIdList = 0; $userView = $this->app->user->view->products; - if($type == 'project') $userView = $this->app->user->view->projects; + if($type == 'project') $userView = $this->app->user->view->projects; if($type == 'execution') $userView = $this->app->user->view->sprints; $bugPairs = $this->dao->select('id')->from(TABLE_BUG)->where($type)->eq($objectID)->andWhere('deleted')->eq('0')->andWhere($type)->in($userView)->fetchPairs('id'); @@ -1393,7 +1436,7 @@ class docModel extends model $taskPairs = $this->dao->select('id')->from(TABLE_TASK)->where('execution')->in($executionIdList)->andWhere('deleted')->eq('0')->andWhere('execution')->in($this->app->user->view->sprints)->fetchPairs('id'); if(!empty($taskPairs)) $taskIdList = implode(',', $taskPairs); - $buildPairs = $this->dao->select('id')->from(TABLE_BUILD)->where('execution')->in($executionIdList)->andWhere('deleted')->eq('0')->andWhere('execution')->in($this->app->user->view->sprints)->fetchPairs('id'); + $buildPairs = $this->dao->select('id')->from(TABLE_BUILD)->where('execution')->in($executionIdList)->andWhere('deleted')->eq('0')->andWhere('execution')->in($this->app->user->view->sprints)->fetchPairs('id'); if(!empty($buildPairs)) $buildIdList = implode(',', $buildPairs); $executionIdList = join(',', $executionIdList); @@ -1414,24 +1457,20 @@ class docModel extends model ->orWhere("(objectType = 'bug' and objectID in ($bugIdList))") ->orWhere("(objectType = 'testreport' and objectID in ($testReportIdList))") ->orWhere("(objectType = 'testcase' and objectID in ($caseIdList))") - ->beginIF($type == 'product') ->orWhere("(objectType in ('story','requirement') and objectID in ($storyIdList))") ->orWhere("(objectType = 'release' and objectID in ($releaseIdList))") ->fi() - ->beginIF($type == 'project') ->orWhere("(objectType = 'execution' and objectID in ('$executionIdList'))") ->orWhere("(objectType = 'issue' and objectID in ($issueIdList))") ->orWhere("(objectType = 'meeting' and objectID in ($meetingIdList))") ->orWhere("(objectType = 'design' and objectID in ($designIdList))") ->fi() - ->beginIF($type == 'project' or $type == 'execution') ->orWhere("(objectType = 'task' and objectID in ($taskIdList))") ->orWhere("(objectType = 'build' and objectID in ($buildIdList))") ->fi() - ->markRight(1) ->beginIF($searchTitle)->andWhere('title')->like("%{$searchTitle}%")->fi() ->orderBy($orderBy) @@ -1442,7 +1481,7 @@ class docModel extends model { $pathName = $this->file->getRealPathName($file->pathname); $file->realPath = $this->file->savePath . $pathName; - $file->webPath = $this->file->webPath . $pathName; + $file->webPath = $this->file->webPath . $pathName; } return $files; @@ -1451,7 +1490,7 @@ class docModel extends model /** * Get file source pairs. * - * @param array $files + * @param array $files * @access public * @return array */ @@ -1468,9 +1507,9 @@ class docModel extends model foreach($sourceList as $type => $idList) { - $table = $this->config->objectTables[$type]; - $title = in_array($type, array('story', 'bug', 'issue', 'case', 'testcase', 'testreport', 'doc', 'requirement')) ? 'title' : 'name'; - $name = $this->dao->select('id,' . $title)->from($table)->where('id')->in($idList)->fetchPairs('id'); + $table = $this->config->objectTables[$type]; + $title = in_array($type, array('story', 'bug', 'issue', 'case', 'testcase', 'testreport', 'doc', 'requirement')) ? 'title' : 'name'; + $name = $this->dao->select('id,' . $title)->from($table)->where('id')->in($idList)->fetchPairs('id'); $sourcePairs[$type] = $name; } @@ -1480,7 +1519,7 @@ class docModel extends model /** * Get file icon. * - * @param array $files + * @param array $files * @access public * @return array */ @@ -1511,7 +1550,7 @@ class docModel extends model /** * Get doc tree. * - * @param int $libID + * @param int $libID * @access public * @return array */ @@ -1521,7 +1560,7 @@ class docModel extends model array_unshift($fullTrees, array('id' => 0, 'name' => '/', 'type' => 'doc', 'actions' => false, 'root' => $libID)); foreach($fullTrees as $i => $tree) { - $tree = (object)$tree; + $tree = (object)$tree; $fullTrees[$i] = $this->fillDocsInTree($tree, $libID); } if(empty($fullTrees[0]->children)) array_shift($fullTrees); @@ -1531,8 +1570,8 @@ class docModel extends model /** * Fill docs in tree. * - * @param object $node - * @param int $libID + * @param object $node + * @param int $libID * @access public * @return array */ @@ -1542,7 +1581,7 @@ class docModel extends model static $docGroups; if(empty($docGroups)) { - $docs = $this->dao->select('*')->from(TABLE_DOC) + $docs = $this->dao->select('*')->from(TABLE_DOC) ->where('lib')->eq((int)$libID) ->andWhere('deleted')->eq(0) ->fetchAll(); @@ -1554,25 +1593,25 @@ class docModel extends model } if(!empty($node->children)) foreach($node->children as $i => $child) $node->children[$i] = $this->fillDocsInTree($child, $libID); - if(!isset($node->id))$node->id = 0; + if(!isset($node->id)) $node->id = 0; $node->type = 'module'; - $docs = isset($docGroups[$node->id]) ? $docGroups[$node->id] : array(); - $menu = !empty($node->children) ? $node->children : array(); + $docs = isset($docGroups[$node->id]) ? $docGroups[$node->id] : array(); + $menu = !empty($node->children) ? $node->children : array(); if(!empty($docs)) { $docItems = array(); foreach($docs as $doc) { - $docItem = new stdclass(); - $docItem->type = 'doc'; - $docItem->id = $doc->id; - $docItem->title = $doc->title; - $docItem->url = helper::createLink('doc', 'view', "doc=$doc->id"); + $docItem = new stdclass(); + $docItem->type = 'doc'; + $docItem->id = $doc->id; + $docItem->title = $doc->title; + $docItem->url = helper::createLink('doc', 'view', "doc=$doc->id"); - $buttons = ''; - $buttons .= common::buildIconButton('doc', 'edit', "docID=$doc->id", '', 'list'); - if(common::hasPriv('doc', 'delete'))$buttons .= html::a(helper::createLink('doc', 'delete', "docID=$doc->id"), "", 'hiddenwin', "class='btn-icon' title='{$this->lang->doc->delete}'"); + $buttons = ''; + $buttons .= common::buildIconButton('doc', 'edit', "docID=$doc->id", '', 'list'); + if(common::hasPriv('doc', 'delete')) $buttons .= html::a(helper::createLink('doc', 'delete', "docID=$doc->id"), "", 'hiddenwin', "class='btn-icon' title='{$this->lang->doc->delete}'"); $docItem->buttons = $buttons; $docItem->actions = false; $docItems[] = $docItem; @@ -1592,8 +1631,8 @@ class docModel extends model /** * Get product crumb. * - * @param int $productID - * @param int $executionID + * @param int $productID + * @param int $executionID * @access public * @return string */ @@ -1612,7 +1651,7 @@ class docModel extends model $object = $this->dao->select('id,name')->from(TABLE_PRODUCT)->where('id')->eq($productID)->fetch(); if(empty($object)) return ''; - $crumb = ''; + $crumb = ''; $crumb .= html::a(helper::createLink('doc', 'allLibs', "type=product"), $this->lang->productCommon) . $this->lang->doc->separator; $crumb .= html::a(helper::createLink('doc', 'objectLibs', "type=product&objectID=$productID"), $object->name) . $this->lang->doc->separator; $crumb .= html::a(helper::createLink('doc', 'allLibs', "type=execution&product=$productID"), $this->lang->doclib->execution); @@ -1623,8 +1662,8 @@ class docModel extends model /** * Set lib users. * - * @param string $type - * @param int $objectID + * @param string $type + * @param int $objectID * @access public * @return bool */ @@ -1665,7 +1704,7 @@ class docModel extends model $executionLibs = array(); $productLibs = array(); if($executions) $executionLibs = $this->dao->select('id')->from(TABLE_DOCLIB)->where('execution')->in(array_keys($executions))->fetchPairs(); - if($products) $productLibs = $this->dao->select('id')->from(TABLE_DOCLIB)->where('product')->in($products)->fetchPairs(); + if($products) $productLibs = $this->dao->select('id')->from(TABLE_DOCLIB)->where('product')->in($products)->fetchPairs(); $customLibs = $this->dao->select('id')->from(TABLE_DOCLIB)->where('type')->eq('custom')->fetchPairs(); $libIdList = array_merge($customLibs, $executionLibs, $productLibs); @@ -1684,8 +1723,8 @@ class docModel extends model $libIdList = $this->getLibIdListByProject($this->session->project); $docIdList = $this->getPrivDocs($libIdList); - $today = date('Y-m-d'); - $lately = date('Y-m-d', strtotime('-3 day')); + $today = date('Y-m-d'); + $lately = date('Y-m-d', strtotime('-3 day')); $statisticInfo = $this->dao->select("count(id) as totalDocs, count(editedDate like '{$today}%' or null) as todayEditedDocs, count(editedDate > '{$lately}' or null) as lastEditedDocs, count(addedDate > '{$lately}' or null) as lastAddedDocs, count(collector like '%,{$this->app->user->account},%' or null) as myCollection, count(addedBy = '{$this->app->user->account}' or null) as myDocs")->from(TABLE_DOC) @@ -1705,8 +1744,8 @@ class docModel extends model /** * Get the previous and next doc. * - * @param int $docID - * @param int $libID + * @param int $docID + * @param int $libID * @access public * @return object */ @@ -1728,8 +1767,8 @@ class docModel extends model ->beginIF($this->config->doc->notArticleType)->andWhere('t1.type')->notIN($this->config->doc->notArticleType)->fi() ->get(); $query .= " order by field(module, $sortedModules)"; - $stmt = $this->dbh->query($query); - $docs = $stmt->fetchAll(); + $stmt = $this->dbh->query($query); + $docs = $stmt->fetchAll(); $preAndNextDoc = new stdClass(); $preAndNextDoc->pre = ''; @@ -1800,7 +1839,7 @@ class docModel extends model foreach($parantMoudles as $parentID => $moduleName) { - $title .= html::a(helper::createLink('doc', 'browse', "libID=$libID&browseType=byModule¶m={$parentID}"), " " . $moduleName->name , ''); + $title .= html::a(helper::createLink('doc', 'browse', "libID=$libID&browseType=byModule¶m={$parentID}"), " " . $moduleName->name, ''); } return $title; @@ -1809,9 +1848,9 @@ class docModel extends model /** * Build document module index page create document button. * - * @param string $objectType - * @param int $objectID - * @param int $libID + * @param string $objectType + * @param int $objectID + * @param int $libID * @access public * @return string */ @@ -1823,16 +1862,16 @@ class docModel extends model } elseif($libID) { - $html = "";t'+this.lang.daysMin[t++%7]+"";e+="",this.picker.find(".datetimepicker-days thead").append(e)},fillMonths:function(){for(var t="",e=0;e<12;)t+=''+this.lang.monthsShort[e++]+"";this.picker.find(".datetimepicker-months td").html(t)},fill:function(){if(null!=this.date&&null!=this.viewDate){var i=new Date(this.viewDate),n=i.getUTCFullYear(),o=i.getUTCMonth(),s=i.getUTCDate(),r=i.getUTCHours(),l=i.getUTCMinutes(),h=this.startDate!==-(1/0)?this.startDate.getUTCFullYear():-(1/0),c=this.startDate!==-(1/0)?this.startDate.getUTCMonth():-(1/0),d=this.endDate!==1/0?this.endDate.getUTCFullYear():1/0,u=this.endDate!==1/0?this.endDate.getUTCMonth():1/0,f=new e(this.date.getUTCFullYear(),this.date.getUTCMonth(),this.date.getUTCDate()).valueOf(),p=new Date;if(this.picker.find(".datetimepicker-days thead th:eq(1)").text(this.lang.months[o]+" "+n),"time"==this.formatViewType){var g=r%12?r%12:12,m=(g<10?"0":"")+g,v=(l<10?"0":"")+l,y=this.lang.meridiem[r<12?0:1];this.picker.find(".datetimepicker-hours thead th:eq(1)").text(m+":"+v+" "+y.toUpperCase()),this.picker.find(".datetimepicker-minutes thead th:eq(1)").text(m+":"+v+" "+y.toUpperCase())}else this.picker.find(".datetimepicker-hours thead th:eq(1)").text(s+" "+this.lang.months[o]+" "+n),this.picker.find(".datetimepicker-minutes thead th:eq(1)").text(s+" "+this.lang.months[o]+" "+n);this.picker.find("tfoot th.today").text(this.lang.today).toggle(this.todayBtn!==!1),this.updateNavArrows(),this.fillMonths();var b=e(n,o-1,28,0,0,0,0),w=a.getDaysInMonth(b.getUTCFullYear(),b.getUTCMonth());b.setUTCDate(w),b.setUTCDate(w-(b.getUTCDay()-this.weekStart+7)%7);var x=new Date(b);x.setUTCDate(x.getUTCDate()+42),x=x.valueOf();for(var C,_=[];b.valueOf()"),C="",b.getUTCFullYear()n||b.getUTCFullYear()==n&&b.getUTCMonth()>o)&&(C+=" new"),this.todayHighlight&&b.getUTCFullYear()==p.getFullYear()&&b.getUTCMonth()==p.getMonth()&&b.getUTCDate()==p.getDate()&&(C+=" today"),b.valueOf()==f&&(C+=" active"),(b.valueOf()+864e5<=this.startDate||b.valueOf()>this.endDate||t.inArray(b.getUTCDay(),this.daysOfWeekDisabled)!==-1)&&(C+=" disabled"),_.push('"),b.getUTCDay()==this.weekEnd&&_.push(""),b.setUTCDate(b.getUTCDate()+1);this.picker.find(".datetimepicker-days tbody").empty().append(_.join("")),_=[];for(var k="",T="",S="",D=0;D<24;D++){var M=e(n,o,s,D);C="",M.valueOf()+36e5<=this.startDate||M.valueOf()>this.endDate?C+=" disabled":r==D&&(C+=" active"),this.showMeridian&&2==this.lang.meridiem.length?(T=D<12?this.lang.meridiem[0]:this.lang.meridiem[1],T!=S&&(""!=S&&_.push(""),_.push('
    '+T.toUpperCase()+"")),S=T,k=D%12?D%12:12,_.push(''+k+""),23==D&&_.push("
    ")):(k=D+":00",_.push(''+k+""))}this.picker.find(".datetimepicker-hours td").html(_.join("")),_=[],k="",T="",S="";for(var D=0;D<60;D+=this.minuteStep){var M=e(n,o,s,r,D,0);C="",M.valueOf()this.endDate?C+=" disabled":Math.floor(l/this.minuteStep)==Math.floor(D/this.minuteStep)&&(C+=" active"),this.showMeridian&&2==this.lang.meridiem.length?(T=r<12?this.lang.meridiem[0]:this.lang.meridiem[1],T!=S&&(""!=S&&_.push(""),_.push('
    '+T.toUpperCase()+"")),S=T,k=r%12?r%12:12,_.push(''+k+":"+(D<10?"0"+D:D)+""),59==D&&_.push("
    ")):(k=D+":00",_.push(''+r+":"+(D<10?"0"+D:D)+""))}this.picker.find(".datetimepicker-minutes td").html(_.join(""));var P=this.date.getUTCFullYear(),z=this.picker.find(".datetimepicker-months").find("th:eq(1)").text(n).end().find("span").removeClass("active");P==n&&z.eq(this.date.getUTCMonth()).addClass("active"),(nd)&&z.addClass("disabled"),n==h&&z.slice(0,c).addClass("disabled"),n==d&&z.slice(u+1).addClass("disabled"),_="",n=10*parseInt(n/10,10);var L=this.picker.find(".datetimepicker-years").find("th:eq(1)").text(n+"-"+(n+9)).end().find("td");n-=1;for(var D=-1;D<11;D++)_+='d?" disabled":"")+'">'+n+"",n+=1;L.html(_),this.place()}},updateNavArrows:function(){var t=new Date(this.viewDate),e=t.getUTCFullYear(),i=t.getUTCMonth(),n=t.getUTCDate(),o=t.getUTCHours();switch(this.viewMode){case 0:this.startDate!==-(1/0)&&e<=this.startDate.getUTCFullYear()&&i<=this.startDate.getUTCMonth()&&n<=this.startDate.getUTCDate()&&o<=this.startDate.getUTCHours()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==1/0&&e>=this.endDate.getUTCFullYear()&&i>=this.endDate.getUTCMonth()&&n>=this.endDate.getUTCDate()&&o>=this.endDate.getUTCHours()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 1:this.startDate!==-(1/0)&&e<=this.startDate.getUTCFullYear()&&i<=this.startDate.getUTCMonth()&&n<=this.startDate.getUTCDate()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==1/0&&e>=this.endDate.getUTCFullYear()&&i>=this.endDate.getUTCMonth()&&n>=this.endDate.getUTCDate()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 2:this.startDate!==-(1/0)&&e<=this.startDate.getUTCFullYear()&&i<=this.startDate.getUTCMonth()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==1/0&&e>=this.endDate.getUTCFullYear()&&i>=this.endDate.getUTCMonth()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 3:case 4:this.startDate!==-(1/0)&&e<=this.startDate.getUTCFullYear()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==1/0&&e>=this.endDate.getUTCFullYear()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"})}},mousewheel:function(t){if(t.preventDefault(),t.stopPropagation(),!this.wheelPause){this.wheelPause=!0;var e=t.originalEvent,i=e.wheelDelta,n=i>0?1:0===i?0:-1;this.wheelViewModeNavigationInverseDirection&&(n=-n),this.showMode(n),setTimeout(function(){this.wheelPause=!1}.bind(this),this.wheelViewModeNavigationDelay)}},click:function(i){i.stopPropagation(),i.preventDefault();var n=t(i.target).closest("span, td, th, legend");if(1==n.length){if(n.is(".disabled"))return void this.element.trigger({type:"outOfRange",date:this.viewDate,startDate:this.startDate,endDate:this.endDate});switch(n[0].nodeName.toLowerCase()){case"th":switch(n[0].className){case"switch":this.showMode(1);break;case"prev":case"next":var o=a.modes[this.viewMode].navStep*("prev"==n[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveHour(this.viewDate,o);break;case 1:this.viewDate=this.moveDate(this.viewDate,o);break;case 2:this.viewDate=this.moveMonth(this.viewDate,o);break;case 3:case 4:this.viewDate=this.moveYear(this.viewDate,o)}this.fill();break;case"today":var s=new Date;s=e(s.getFullYear(),s.getMonth(),s.getDate(),s.getHours(),s.getMinutes(),s.getSeconds(),0),sthis.endDate&&(s=this.endDate),this.viewMode=this.startViewMode,this.showMode(0),this._setDate(s),this.fill(),this.autoclose&&this.hide()}break;case"span":if(!n.is(".disabled")){var r=this.viewDate.getUTCFullYear(),l=this.viewDate.getUTCMonth(),h=this.viewDate.getUTCDate(),c=this.viewDate.getUTCHours(),d=this.viewDate.getUTCMinutes(),u=this.viewDate.getUTCSeconds();if(n.is(".month")?(this.viewDate.setUTCDate(1),l=n.parent().find("span").index(n),h=this.viewDate.getUTCDate(),this.viewDate.setUTCMonth(l),this.element.trigger({type:"changeMonth",date:this.viewDate}),this.viewSelect>=3&&this._setDate(e(r,l,h,c,d,u,0))):n.is(".year")?(this.viewDate.setUTCDate(1),r=parseInt(n.text(),10)||0,this.viewDate.setUTCFullYear(r),this.element.trigger({type:"changeYear",date:this.viewDate}),this.viewSelect>=4&&this._setDate(e(r,l,h,c,d,u,0))):n.is(".hour")?(c=parseInt(n.text(),10)||0,(n.hasClass("hour_am")||n.hasClass("hour_pm"))&&(12==c&&n.hasClass("hour_am")?c=0:12!=c&&n.hasClass("hour_pm")&&(c+=12)),this.viewDate.setUTCHours(c),this.element.trigger({type:"changeHour",date:this.viewDate}),this.viewSelect>=1&&this._setDate(e(r,l,h,c,d,u,0))):n.is(".minute")&&(d=parseInt(n.text().substr(n.text().indexOf(":")+1),10)||0,this.viewDate.setUTCMinutes(d),this.element.trigger({type:"changeMinute",date:this.viewDate}),this.viewSelect>=0&&this._setDate(e(r,l,h,c,d,u,0))),0!=this.viewMode){var f=this.viewMode;this.showMode(-1),this.fill(),f==this.viewMode&&this.autoclose&&this.hide()}else this.fill(),this.autoclose&&this.hide()}break;case"td":if(n.is(".day")&&!n.is(".disabled")){var h=parseInt(n.text(),10)||1,r=this.viewDate.getUTCFullYear(),l=this.viewDate.getUTCMonth(),c=this.viewDate.getUTCHours(),d=this.viewDate.getUTCMinutes(),u=this.viewDate.getUTCSeconds();n.is(".old")?0===l?(l=11,r-=1):l-=1:n.is(".new")&&(11==l?(l=0,r+=1):l+=1),this.viewDate.setUTCFullYear(r),this.viewDate.setUTCMonth(l,h),this.element.trigger({type:"changeDay",date:this.viewDate}),this.viewSelect>=2&&this._setDate(e(r,l,h,c,d,u,0));var f=this.viewMode;this.showMode(-1),this.fill(),f==this.viewMode&&this.autoclose&&this.hide()}}}},_setDate:function(t,e){e&&"date"!=e||(this.date=t),e&&"view"!=e||(this.viewDate=t),this.fill(),this.setValue();var i;this.isInput?i=this.element:this.component&&(i=this.element.find("input")),i&&(i.change(),this.autoclose&&(!e||"date"==e)),this.element.trigger({type:"changeDate",date:this.date}),null===t&&(this.date=this.viewDate)},moveMinute:function(t,e){if(!e)return t;var i=new Date(t.valueOf());return i.setUTCMinutes(i.getUTCMinutes()+e*this.minuteStep),i},moveHour:function(t,e){if(!e)return t;var i=new Date(t.valueOf());return i.setUTCHours(i.getUTCHours()+e),i},moveDate:function(t,e){if(!e)return t;var i=new Date(t.valueOf());return i.setUTCDate(i.getUTCDate()+e),i},moveMonth:function(t,e){if(!e)return t;var i,n,o=new Date(t.valueOf()),a=o.getUTCDate(),s=o.getUTCMonth(),r=Math.abs(e);if(e=e>0?1:-1,1==r)n=e==-1?function(){return o.getUTCMonth()==s}:function(){return o.getUTCMonth()!=i},i=s+e,o.setUTCMonth(i),(i<0||i>11)&&(i=(i+12)%12);else{for(var l=0;l=this.startDate&&t<=this.endDate},keydown:function(t){if(this.picker.is(":not(:visible)"))return void(27==t.keyCode&&this.show());var e,i,n,o=!1;switch(t.keyCode){case 27:this.hide(),t.preventDefault();break;case 37:case 39:if(!this.keyboardNavigation)break;e=37==t.keyCode?-1:1,viewMode=this.viewMode,t.ctrlKey?viewMode+=2:t.shiftKey&&(viewMode+=1),4==viewMode?(i=this.moveYear(this.date,e),n=this.moveYear(this.viewDate,e)):3==viewMode?(i=this.moveMonth(this.date,e),n=this.moveMonth(this.viewDate,e)):2==viewMode?(i=this.moveDate(this.date,e),n=this.moveDate(this.viewDate,e)):1==viewMode?(i=this.moveHour(this.date,e),n=this.moveHour(this.viewDate,e)):0==viewMode&&(i=this.moveMinute(this.date,e),n=this.moveMinute(this.viewDate,e)),this.dateWithinRange(i)&&(this.date=i,this.viewDate=n,this.setValue(),this.update(),t.preventDefault(),o=!0);break;case 38:case 40:if(!this.keyboardNavigation)break;e=38==t.keyCode?-1:1,viewMode=this.viewMode,t.ctrlKey?viewMode+=2:t.shiftKey&&(viewMode+=1),4==viewMode?(i=this.moveYear(this.date,e),n=this.moveYear(this.viewDate,e)):3==viewMode?(i=this.moveMonth(this.date,e),n=this.moveMonth(this.viewDate,e)):2==viewMode?(i=this.moveDate(this.date,7*e),n=this.moveDate(this.viewDate,7*e)):1==viewMode?this.showMeridian?(i=this.moveHour(this.date,6*e),n=this.moveHour(this.viewDate,6*e)):(i=this.moveHour(this.date,4*e),n=this.moveHour(this.viewDate,4*e)):0==viewMode&&(i=this.moveMinute(this.date,4*e),n=this.moveMinute(this.viewDate,4*e)),this.dateWithinRange(i)&&(this.date=i,this.viewDate=n,this.setValue(),this.update(),t.preventDefault(),o=!0);break;case 13:if(0!=this.viewMode){var a=this.viewMode;this.showMode(-1),this.fill(),a==this.viewMode&&this.autoclose&&this.hide()}else this.fill(),this.autoclose&&this.hide();t.preventDefault();break;case 9:this.hide()}if(o){var s;this.isInput?s=this.element:this.component&&(s=this.element.find("input")),s&&s.change(),this.element.trigger({type:"changeDate",date:this.date})}},showMode:function(t){if(t){var e=Math.max(0,Math.min(a.modes.length-1,this.viewMode+t));e>=this.minView&&e<=this.maxView&&(this.element.trigger({type:"changeMode",date:this.viewDate,oldViewMode:this.viewMode,newViewMode:e}),this.viewMode=e)}this.picker.find(">div").hide().filter(".datetimepicker-"+a.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()},reset:function(t){this._setDate(null,"date")}},t.fn.datetimepicker=function(e){var n=Array.apply(null,arguments);return n.shift(),this.each(function(){var o=t(this),a=o.data("datetimepicker"),s="object"==typeof e&&e;a||o.data("datetimepicker",a=new i(this,t.extend({},t.fn.datetimepicker.defaults,o.data(),s))),"string"==typeof e&&"function"==typeof a[e]&&a[e].apply(a,n)})},t.fn.datetimepicker.defaults={pickerPosition:"auto-right"},t.fn.datetimepicker.Constructor=i;var n=t.fn.datetimepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],meridiem:["am","pm"],suffix:["st","nd","rd","th"],today:"Today"},"zh-cn":{days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六","星期日"],daysShort:["周日","周一","周二","周三","周四","周五","周六","周日"],daysMin:["日","一","二","三","四","五","六","日"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],today:"今日",suffix:[],meridiem:[]},"zh-tw":{days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六","星期日"],daysShort:["周日","周一","周二","周三","周四","周五","周六","周日"],daysMin:["日","一","二","三","四","五","六","日"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],today:"今天",suffix:[],meridiem:["上午","下午"]}},o=function(e){var i=n[e];return i||(i=t.zui&&t.zui.getLangData?n[e]=t.zui.getLangData("datetimepicker",this.language,n):n.en),i},a={modes:[{clsName:"minutes",navFnc:"Hours",navStep:1},{clsName:"hours",navFnc:"Date",navStep:1},{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(t){return t%4===0&&t%100!==0||t%400===0},getDaysInMonth:function(t,e){return[31,a.isLeapYear(t)?29:28,31,30,31,30,31,31,30,31,30,31][e]},getDefaultFormat:function(t,e){if("standard"==t)return"input"==e?"yyyy-mm-dd hh:ii":"yyyy-mm-dd hh:ii:ss";if("php"==t)return"input"==e?"Y-m-d H:i":"Y-m-d H:i:s";throw new Error("Invalid format type.")},validParts:function(t){if("standard"==t)return/hh?|HH?|p|P|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g;if("php"==t)return/[dDjlNwzFmMnStyYaABgGhHis]/g;throw new Error("Invalid format type.")},nonpunctuation:/[^ -\/:-@\[-`{-~\t\n\rTZ]+/g,parseFormat:function(t,e){var i=t.replace(this.validParts(e),"\0").split("\0"),n=t.match(this.validParts(e));if(!i||!i.length||!n||0==n.length)throw new Error("Invalid date format.");return{separators:i,parts:n}},parseDate:function(n,a,s,r){if(n instanceof Date){var l=new Date(n.valueOf()-6e4*n.getTimezoneOffset());return l.setMilliseconds(0),l}if(/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(n)&&(a=this.parseFormat("yyyy-mm-dd",r)),/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(n)&&(a=this.parseFormat("yyyy-mm-dd hh:ii",r)),/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(n)&&(a=this.parseFormat("yyyy-mm-dd hh:ii:ss",r)),/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(n)){var h,c,d=/([-+]\d+)([dmwy])/,u=n.match(/([-+]\d+)([dmwy])/g);n=new Date;for(var f=0;f
    ',contTemplate:'',footTemplate:''};a.template='
    '+b.getUTCDate()+"
    '+a.headTemplate+a.contTemplate+a.footTemplate+'
    '+a.headTemplate+a.contTemplate+a.footTemplate+'
    '+a.headTemplate+""+a.footTemplate+'
    '+a.headTemplate+a.contTemplate+a.footTemplate+'
    '+a.headTemplate+a.contTemplate+a.footTemplate+"
    ",t.fn.datetimepicker.DPGlobal=a,t.fn.datetimepicker.noConflict=function(){return t.fn.datetimepicker=old,this},t(document).on("focus.datetimepicker.data-api click.datetimepicker.data-api",'[data-provide="datetimepicker"]',function(e){ -var i=t(this);i.data("datetimepicker")||(e.preventDefault(),i.datetimepicker("show"))}),t(function(){t('[data-provide="datetimepicker-inline"]').datetimepicker()})}(window.jQuery),/*! bootbox.js v4.4.0 http://bootboxjs.com/license.txt */ -function(t,e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e(require("jquery")):t.bootbox=e(t.jQuery)}(this,function t(e,i){"use strict";function n(t){var i=e.zui&&e.zui.getLangData?e.zui.getLangData("bootbox",p.locale,m):m[p.locale];return i?i[t]:m.en[t]}function o(t,e,i){t.stopPropagation(),t.preventDefault();var n="function"==typeof i&&i.call(e,t)===!1;n||e.modal("hide")}function a(t){var e,i=0;for(e in t)i++;return i}function s(t,i){var n=0;e.each(t,function(t,e){i(t,e,n++)})}function r(t){var i,n;if("object"!=typeof t)throw new Error("Please supply an object of options");if(!t.message)throw new Error("Please specify a message");return t=e.extend({},p,t),t.buttons||(t.buttons={}),i=t.buttons,n=a(i),s(i,function(t,o,a){if("function"==typeof o&&(o=i[t]={callback:o}),"object"!==e.type(o))throw new Error("button with key "+t+" must be an object");o.label||(o.label=t),o.className||(2===n&&("ok"===t||"confirm"===t)||1===n?o.className="btn-primary":o.className="btn-default")}),t}function l(t,e){var i=t.length,n={};if(i<1||i>2)throw new Error("Invalid argument length");return 2===i||"string"==typeof t[0]?(n[e[0]]=t[0],n[e[1]]=t[1]):n=t[0],n}function h(t,i,n){return e.extend(!0,{},t,l(i,n))}function c(t,e,i,n){var o={className:"bootbox-"+t,buttons:d.apply(null,e)};return u(h(o,n,i),e)}function d(){for(var t={},e=0,i=arguments.length;e",header:"",footer:"",closeButton:"",form:"
    ",inputs:{text:"",textarea:"",email:"",select:"",checkbox:"
    ",date:"",time:"",number:"",password:""}},p={locale:e.zui&&e.zui.clientLang?e.zui.clientLang():"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},g={};g.alert=function(){var t;if(t=c("alert",["ok"],["message","callback"],arguments),t.callback&&"function"!=typeof t.callback)throw new Error("alert requires callback property to be a function when provided");return t.buttons.ok.callback=t.onEscape=function(){return"function"!=typeof t.callback||t.callback.call(this)},g.dialog(t)},g.confirm=function(){var t;if(t=c("confirm",["confirm","cancel"],["message","callback"],arguments),t.buttons.cancel.callback=t.onEscape=function(){return t.callback.call(this,!1)},t.buttons.confirm.callback=function(){return t.callback.call(this,!0)},"function"!=typeof t.callback)throw new Error("confirm requires a callback");return g.dialog(t)},g.prompt=function(){var t,n,o,a,r,l,c;if(a=e(f.form),n={className:"bootbox-prompt",buttons:d("cancel","confirm"),value:"",inputType:"text"},t=u(h(n,arguments,["title","callback"]),["confirm","cancel"]),l=t.show===i||t.show,t.message=a,t.buttons.cancel.callback=t.onEscape=function(){return t.callback.call(this,null)},t.buttons.confirm.callback=function(){var i;switch(t.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":i=r.val();break;case"checkbox":var n=r.find("input:checked");i=[],s(n,function(t,n){i.push(e(n).val())})}return t.callback.call(this,i)},t.show=!1,!t.title)throw new Error("prompt requires a title");if("function"!=typeof t.callback)throw new Error("prompt requires a callback");if(!f.inputs[t.inputType])throw new Error("invalid prompt type");switch(r=e(f.inputs[t.inputType]),t.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":r.val(t.value);break;case"select":var p={};if(c=t.inputOptions||[],!Array.isArray(c))throw new Error("Please pass an array of input options");if(!c.length)throw new Error("prompt with select requires options");s(c,function(t,n){var o=r;if(n.value===i||n.text===i)throw new Error("given options in wrong format");n.group&&(p[n.group]||(p[n.group]=e("").attr("label",n.group)),o=p[n.group]),o.append("")}),s(p,function(t,e){r.append(e)}),r.val(t.value);break;case"checkbox":var m=Array.isArray(t.value)?t.value:[t.value];if(c=t.inputOptions||[],!c.length)throw new Error("prompt with checkbox requires options");if(!c[0].value||!c[0].text)throw new Error("given options in wrong format");r=e("
    "),s(c,function(i,n){var o=e(f.inputs[t.inputType]);o.find("input").attr("value",n.value),o.find("label").append(n.text),s(m,function(t,e){e===n.value&&o.find("input").prop("checked",!0)}),r.append(o)})}return t.placeholder&&r.attr("placeholder",t.placeholder),t.pattern&&r.attr("pattern",t.pattern),t.maxlength&&r.attr("maxlength",t.maxlength),a.append(r),a.on("submit",function(t){t.preventDefault(),t.stopPropagation(),o.find(".btn-primary").click()}),o=g.dialog(t),o.off("shown.zui.modal"),o.on("shown.zui.modal",function(){r.focus()}),l===!0&&o.modal("show"),o},g.dialog=function(t){t=r(t);var n=e(f.dialog),a=n.find(".modal-dialog"),l=n.find(".modal-body"),h=t.buttons,c="",d={onEscape:t.onEscape};if(e.fn.modal===i)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(s(h,function(t,e){c+="",d[t]=e.callback}),l.find(".bootbox-body").html(t.message),t.animate===!0&&n.addClass("fade"),t.className&&n.addClass(t.className),"large"===t.size?a.addClass("modal-lg"):"small"===t.size&&a.addClass("modal-sm"),t.title&&l.before(f.header),t.closeButton){var u=e(f.closeButton);t.title?n.find(".modal-header").prepend(u):u.css("margin-top","-10px").prependTo(l)}return t.title&&n.find(".modal-title").html(t.title),c.length&&(l.after(f.footer),n.find(".modal-footer").html(c)),n.on("hidden.zui.modal",function(t){t.target===this&&n.remove()}),n.on("shown.zui.modal",function(){n.find(".btn-primary:first").focus()}),"static"!==t.backdrop&&n.on("click.dismiss.zui.modal",function(t){n.children(".modal-backdrop").length&&(t.currentTarget=n.children(".modal-backdrop").get(0)),t.target===t.currentTarget&&n.trigger("escape.close.bb")}),n.on("escape.close.bb",function(t){d.onEscape&&o(t,n,d.onEscape)}),n.on("click",".modal-footer button",function(t){var i=e(this).data("bb-handler");o(t,n,d[i])}),n.on("click",".bootbox-close-button",function(t){o(t,n,d.onEscape)}),n.on("keyup",function(t){27===t.which&&n.trigger("escape.close.bb")}),e(t.container).append(n),n.modal({backdrop:!!t.backdrop&&"static",keyboard:!1,show:!1}),t.show&&n.modal("show"),n},g.setDefaults=function(){var t={};2===arguments.length?t[arguments[0]]=arguments[1]:t=arguments[0],e.extend(p,t)},g.hideAll=function(){return e(".bootbox").modal("hide"),g};var m={en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"Confirm"},zh_cn:{OK:"确认",CANCEL:"取消",CONFIRM:"确认"},zh_tw:{OK:"確認",CANCEL:"取消",CONFIRM:"確認"}};return g.addLocale=function(t,i){return e.each(["OK","CANCEL","CONFIRM"],function(t,e){if(!i[e])throw new Error("Please supply a translation for '"+e+"'")}),m[t]={OK:i.OK,CANCEL:i.CANCEL,CONFIRM:i.CONFIRM},g},g.removeLocale=function(t){return delete m[t],g},g.setLocale=function(t){return g.setDefaults("locale",t)},g.init=function(i){return t(i||e)},g}),/*! + !function (t) { + function e() { + return new Date(Date.UTC.apply(Date, arguments)) + } + + var i = function (e, i) { + var o = this; + this.element = t(e), this.language = (i.language || this.element.data("date-language") || (t.zui && t.zui.clientLang ? t.zui.clientLang().replace("_", "-") : "zh-cn")).toLowerCase(), this.lang = t.zui && t.zui.getLangData ? t.zui.getLangData("datetimepicker", this.language, n) : n[this.language], this.isRTL = this.lang.rtl || !1, this.formatType = i.formatType || this.element.data("format-type") || "standard", this.format = a.parseFormat(i.format || this.element.data("date-format") || this.lang.format || a.getDefaultFormat(this.formatType, "input"), this.formatType), this.isInline = !1, this.isVisible = !1, this.isInput = this.element.is("input"), this.component = !!this.element.is(".date") && this.element.find(".input-group-addon .icon-th, .input-group-addon .icon-time, .input-group-addon .icon-calendar").parent(), this.componentReset = !!this.element.is(".date") && this.element.find(".input-group-addon .icon-remove").parent(), this.hasInput = this.component && this.element.find("input").length, this.component && 0 === this.component.length && (this.component = !1), this.linkField = i.linkField || this.element.data("link-field") || !1, this.linkFormat = a.parseFormat(i.linkFormat || this.element.data("link-format") || a.getDefaultFormat(this.formatType, "link"), this.formatType), this.minuteStep = i.minuteStep || this.element.data("minute-step") || 5, this.pickerPosition = i.pickerPosition || this.element.data("picker-position") || "bottom-right", this.showMeridian = i.showMeridian || this.element.data("show-meridian") || !1, this.initialDate = i.initialDate || new Date, this.pickerClass = i.eleClass, this.onlyPickTime = i.maxView <= 1, this.pickerId = i.eleId, this._attachEvents(), this.formatViewType = "datetime", "formatViewType" in i ? this.formatViewType = i.formatViewType : "formatViewType" in this.element.data() && (this.formatViewType = this.element.data("formatViewType")), this.minView = 0, "minView" in i ? this.minView = i.minView : "minView" in this.element.data() && (this.minView = this.element.data("min-view")), this.minView = a.convertViewMode(this.minView), this.maxView = a.modes.length - 1, "maxView" in i ? this.maxView = i.maxView : "maxView" in this.element.data() && (this.maxView = this.element.data("max-view")), this.maxView = a.convertViewMode(this.maxView), this.wheelViewModeNavigation = !1, "wheelViewModeNavigation" in i ? this.wheelViewModeNavigation = i.wheelViewModeNavigation : "wheelViewModeNavigation" in this.element.data() && (this.wheelViewModeNavigation = this.element.data("view-mode-wheel-navigation")), this.wheelViewModeNavigationInverseDirection = !1, "wheelViewModeNavigationInverseDirection" in i ? this.wheelViewModeNavigationInverseDirection = i.wheelViewModeNavigationInverseDirection : "wheelViewModeNavigationInverseDirection" in this.element.data() && (this.wheelViewModeNavigationInverseDirection = this.element.data("view-mode-wheel-navigation-inverse-dir")), this.wheelViewModeNavigationDelay = 100, "wheelViewModeNavigationDelay" in i ? this.wheelViewModeNavigationDelay = i.wheelViewModeNavigationDelay : "wheelViewModeNavigationDelay" in this.element.data() && (this.wheelViewModeNavigationDelay = this.element.data("view-mode-wheel-navigation-delay")), this.startViewMode = 2, "startView" in i ? this.startViewMode = i.startView : "startView" in this.element.data() && (this.startViewMode = this.element.data("start-view")), this.startViewMode = a.convertViewMode(this.startViewMode), this.viewMode = this.startViewMode, this.viewSelect = this.minView, "viewSelect" in i ? this.viewSelect = i.viewSelect : "viewSelect" in this.element.data() && (this.viewSelect = this.element.data("view-select")), this.viewSelect = a.convertViewMode(this.viewSelect), this.forceParse = !0, "forceParse" in i ? this.forceParse = i.forceParse : "dateForceParse" in this.element.data() && (this.forceParse = this.element.data("date-force-parse")), this.picker = t(a.template).appendTo(this.isInline ? this.element : "body").on({click: this.click.bind(this)}), this.wheelViewModeNavigation && (t.fn.mousewheel ? this.picker.on({mousewheel: this.mousewheel.bind(this)}) : console.log("Mouse Wheel event is not supported. Please include the jQuery Mouse Wheel plugin before enabling this option")), this.isInline ? this.picker.addClass("datetimepicker-inline") : this.picker.addClass("datetimepicker-dropdown-" + this.pickerPosition + " dropdown-menu"), this.isRTL && (this.picker.addClass("datetimepicker-rtl"), this.picker.find(".prev span, .next span").toggleClass("icon-arrow-left icon-arrow-right")), t(document).on("mousedown", function (e) { + 0 === t(e.target).closest(".datetimepicker").length && o.hide() + }), this.autoclose = !1, "autoclose" in i ? this.autoclose = i.autoclose : "dateAutoclose" in this.element.data() && (this.autoclose = this.element.data("date-autoclose")), this.keyboardNavigation = !0, "keyboardNavigation" in i ? this.keyboardNavigation = i.keyboardNavigation : "dateKeyboardNavigation" in this.element.data() && (this.keyboardNavigation = this.element.data("date-keyboard-navigation")), this.todayBtn = i.todayBtn || this.element.data("date-today-btn") || !1, this.todayHighlight = i.todayHighlight || this.element.data("date-today-highlight") || !1, this.weekStart = (i.weekStart || this.element.data("date-weekstart") || this.lang.weekStart || 0) % 7, this.weekEnd = (this.weekStart + 6) % 7, this.startDate = -(1 / 0), this.endDate = 1 / 0, this.daysOfWeekDisabled = [], this.setStartDate(i.startDate || this.element.data("date-startdate")), this.setEndDate(i.endDate || this.element.data("date-enddate")), this.setDaysOfWeekDisabled(i.daysOfWeekDisabled || this.element.data("date-days-of-week-disabled")), this.fillDow(), this.fillMonths(), this.update(), this.showMode(), this.isInline && this.show() + }; + i.prototype = { + constructor: i, _events: [], _attachEvents: function () { + this._detachEvents(), this.isInput ? this._events = [[this.element, { + focus: this.show.bind(this), + keyup: this.update.bind(this), + keydown: this.keydown.bind(this) + }]] : this.component && this.hasInput ? (this._events = [[this.element.find("input"), { + focus: this.show.bind(this), + keyup: this.update.bind(this), + keydown: this.keydown.bind(this) + }], [this.component, {click: this.show.bind(this)}]], this.componentReset && this._events.push([this.componentReset, {click: this.reset.bind(this)}])) : this.element.is("div") ? this.isInline = !0 : this._events = [[this.element, {click: this.show.bind(this)}]]; + for (var t, e, i = 0; i < this._events.length; i++) t = this._events[i][0], e = this._events[i][1], t.on(e) + }, _detachEvents: function () { + for (var t, e, i = 0; i < this._events.length; i++) t = this._events[i][0], e = this._events[i][1], t.off(e); + this._events = [] + }, show: function (e) { + this.picker.show(), this.height = this.component ? this.component.outerHeight() : this.element.outerHeight(), this.forceParse && this.update(), this.place(), t(window).on("resize", this.place.bind(this)), e && (e.stopPropagation(), e.preventDefault()), this.isVisible = !0, this.element.trigger({ + type: "show", + date: this.date + }) + }, hide: function (e) { + this.isVisible && (this.isInline || (this.picker.hide(), t(window).off("resize", this.place), this.viewMode = this.startViewMode, this.showMode(), this.isInput || t(document).off("mousedown", this.hide), this.forceParse && (this.isInput && this.element.val() || this.hasInput && this.element.find("input").val()) && this.setValue(), this.isVisible = !1, this.element.trigger({ + type: "hide", + date: this.date + }))) + }, remove: function () { + this._detachEvents(), this.picker.remove(), delete this.picker, delete this.element.data().datetimepicker + }, getDate: function () { + var t = this.getUTCDate(); + return new Date(t.getTime() + 6e4 * t.getTimezoneOffset()) + }, getUTCDate: function () { + return this.date + }, setDate: function (t) { + this.setUTCDate(new Date(t.getTime() - 6e4 * t.getTimezoneOffset())) + }, setUTCDate: function (t) { + t >= this.startDate && t <= this.endDate ? (this.date = t, this.setValue(), this.viewDate = this.date, this.fill()) : this.element.trigger({ + type: "outOfRange", + date: t, + startDate: this.startDate, + endDate: this.endDate + }) + }, setFormat: function (t) { + this.format = a.parseFormat(t, this.formatType); + var e; + this.isInput ? e = this.element : this.component && (e = this.element.find("input")), e && e.val() && this.setValue() + }, setValue: function () { + var e = this.getFormattedDate(); + this.isInput ? this.element.val(e) : (this.component && this.element.find("input").val(e), this.element.data("date", e)), this.linkField && t("#" + this.linkField).val(this.getFormattedDate(this.linkFormat)) + }, getFormattedDate: function (t) { + return void 0 == t && (t = this.format), a.formatDate(this.date, t, this.language, this.formatType) + }, setStartDate: function (t) { + this.startDate = t || -(1 / 0), this.startDate !== -(1 / 0) && (this.startDate = a.parseDate(this.startDate, this.format, this.language, this.formatType)), this.update(), this.updateNavArrows() + }, setEndDate: function (t) { + this.endDate = t || 1 / 0, this.endDate !== 1 / 0 && (this.endDate = a.parseDate(this.endDate, this.format, this.language, this.formatType)), this.update(), this.updateNavArrows() + }, setDaysOfWeekDisabled: function (e) { + this.daysOfWeekDisabled = e || [], Array.isArray(this.daysOfWeekDisabled) || (this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/)), this.daysOfWeekDisabled = t.map(this.daysOfWeekDisabled, function (t) { + return parseInt(t, 10) + }), this.update(), this.updateNavArrows() + }, place: function () { + if (!this.isInline) { + var e = 0; + t("div").each(function () { + var i = parseInt(t(this).css("zIndex"), 10); + i > e && (e = i) + }); + var i, n, o, a = e + 10; + this.component ? (i = this.component.offset(), o = i.left, "bottom-left" !== this.pickerPosition && "top-left" !== this.pickerPosition && "auto-left" !== this.pickerPosition || (o += this.component.outerWidth() - this.picker.outerWidth())) : (i = this.element.offset(), o = i.left); + var s = 0 === this.pickerPosition.indexOf("auto-"), + r = s ? (i.top + this.picker.outerHeight() > t(window).height() + t(window).scrollTop() ? "top" : "bottom") + (0 === this.pickerPosition.lastIndexOf("-left") ? "-left" : "-right") : this.pickerPosition; + n = "top-left" === r || "top-right" === r ? i.top - this.picker.outerHeight() : i.top + this.height, this.picker.css({ + top: n, + left: o, + zIndex: a + }).attr("class", "datetimepicker dropdown-menu datetimepicker-dropdown-" + r), this.pickerClass && this.picker.addClass(this.pickerClass), this.pickerId && this.picker.attr("id", this.pickerId), this.onlyPickTime && this.picker.addClass("datetimepicker-only-time") + } + }, update: function () { + var t, e = !1; + arguments && arguments.length && ("string" == typeof arguments[0] || arguments[0] instanceof Date) ? (t = arguments[0], e = !0) : (t = this.element.data("date") || (this.isInput ? this.element.val() : this.element.find("input").val()) || this.initialDate, ("string" == typeof t || t instanceof String) && (t = t.replace(/^\s+|\s+$/g, ""))), t || (t = new Date, e = !1), this.date = a.parseDate(t, this.format, this.language, this.formatType), e && this.setValue(), this.date < this.startDate ? this.viewDate = new Date(this.startDate) : this.date > this.endDate ? this.viewDate = new Date(this.endDate) : this.viewDate = new Date(this.date), this.fill() + }, fillDow: function () { + for (var t = this.weekStart, e = ""; t < this.weekStart + 7;) e += '' + this.lang.daysMin[t++ % 7] + ""; + e += "", this.picker.find(".datetimepicker-days thead").append(e) + }, fillMonths: function () { + for (var t = "", e = 0; e < 12;) t += '' + this.lang.monthsShort[e++] + ""; + this.picker.find(".datetimepicker-months td").html(t) + }, fill: function () { + if (null != this.date && null != this.viewDate) { + var i = new Date(this.viewDate), n = i.getUTCFullYear(), o = i.getUTCMonth(), s = i.getUTCDate(), + r = i.getUTCHours(), l = i.getUTCMinutes(), + h = this.startDate !== -(1 / 0) ? this.startDate.getUTCFullYear() : -(1 / 0), + c = this.startDate !== -(1 / 0) ? this.startDate.getUTCMonth() : -(1 / 0), + d = this.endDate !== 1 / 0 ? this.endDate.getUTCFullYear() : 1 / 0, + u = this.endDate !== 1 / 0 ? this.endDate.getUTCMonth() : 1 / 0, + f = new e(this.date.getUTCFullYear(), this.date.getUTCMonth(), this.date.getUTCDate()).valueOf(), + p = new Date; + if (this.picker.find(".datetimepicker-days thead th:eq(1)").text(this.lang.months[o] + " " + n), "time" == this.formatViewType) { + var g = r % 12 ? r % 12 : 12, m = (g < 10 ? "0" : "") + g, v = (l < 10 ? "0" : "") + l, + y = this.lang.meridiem[r < 12 ? 0 : 1]; + this.picker.find(".datetimepicker-hours thead th:eq(1)").text(m + ":" + v + " " + y.toUpperCase()), this.picker.find(".datetimepicker-minutes thead th:eq(1)").text(m + ":" + v + " " + y.toUpperCase()) + } else this.picker.find(".datetimepicker-hours thead th:eq(1)").text(s + " " + this.lang.months[o] + " " + n), this.picker.find(".datetimepicker-minutes thead th:eq(1)").text(s + " " + this.lang.months[o] + " " + n); + this.picker.find("tfoot th.today").text(this.lang.today).toggle(this.todayBtn !== !1), this.updateNavArrows(), this.fillMonths(); + var b = e(n, o - 1, 28, 0, 0, 0, 0), w = a.getDaysInMonth(b.getUTCFullYear(), b.getUTCMonth()); + b.setUTCDate(w), b.setUTCDate(w - (b.getUTCDay() - this.weekStart + 7) % 7); + var x = new Date(b); + x.setUTCDate(x.getUTCDate() + 42), x = x.valueOf(); + for (var C, _ = []; b.valueOf() < x;) b.getUTCDay() == this.weekStart && _.push(""), C = "", b.getUTCFullYear() < n || b.getUTCFullYear() == n && b.getUTCMonth() < o ? C += " old" : (b.getUTCFullYear() > n || b.getUTCFullYear() == n && b.getUTCMonth() > o) && (C += " new"), this.todayHighlight && b.getUTCFullYear() == p.getFullYear() && b.getUTCMonth() == p.getMonth() && b.getUTCDate() == p.getDate() && (C += " today"), b.valueOf() == f && (C += " active"), (b.valueOf() + 864e5 <= this.startDate || b.valueOf() > this.endDate || t.inArray(b.getUTCDay(), this.daysOfWeekDisabled) !== -1) && (C += " disabled"), _.push('' + b.getUTCDate() + ""), b.getUTCDay() == this.weekEnd && _.push(""), b.setUTCDate(b.getUTCDate() + 1); + this.picker.find(".datetimepicker-days tbody").empty().append(_.join("")), _ = []; + for (var k = "", T = "", S = "", D = 0; D < 24; D++) { + var M = e(n, o, s, D); + C = "", M.valueOf() + 36e5 <= this.startDate || M.valueOf() > this.endDate ? C += " disabled" : r == D && (C += " active"), this.showMeridian && 2 == this.lang.meridiem.length ? (T = D < 12 ? this.lang.meridiem[0] : this.lang.meridiem[1], T != S && ("" != S && _.push(""), _.push('
    ' + T.toUpperCase() + "")), S = T, k = D % 12 ? D % 12 : 12, _.push('' + k + ""), 23 == D && _.push("
    ")) : (k = D + ":00", _.push('' + k + "")) + } + this.picker.find(".datetimepicker-hours td").html(_.join("")), _ = [], k = "", T = "", S = ""; + for (var D = 0; D < 60; D += this.minuteStep) { + var M = e(n, o, s, r, D, 0); + C = "", M.valueOf() < this.startDate || M.valueOf() > this.endDate ? C += " disabled" : Math.floor(l / this.minuteStep) == Math.floor(D / this.minuteStep) && (C += " active"), this.showMeridian && 2 == this.lang.meridiem.length ? (T = r < 12 ? this.lang.meridiem[0] : this.lang.meridiem[1], T != S && ("" != S && _.push(""), _.push('
    ' + T.toUpperCase() + "")), S = T, k = r % 12 ? r % 12 : 12, _.push('' + k + ":" + (D < 10 ? "0" + D : D) + ""), 59 == D && _.push("
    ")) : (k = D + ":00", _.push('' + r + ":" + (D < 10 ? "0" + D : D) + "")) + } + this.picker.find(".datetimepicker-minutes td").html(_.join("")); + var P = this.date.getUTCFullYear(), + z = this.picker.find(".datetimepicker-months").find("th:eq(1)").text(n).end().find("span").removeClass("active"); + P == n && z.eq(this.date.getUTCMonth()).addClass("active"), (n < h || n > d) && z.addClass("disabled"), n == h && z.slice(0, c).addClass("disabled"), n == d && z.slice(u + 1).addClass("disabled"), _ = "", n = 10 * parseInt(n / 10, 10); + var L = this.picker.find(".datetimepicker-years").find("th:eq(1)").text(n + "-" + (n + 9)).end().find("td"); + n -= 1; + for (var D = -1; D < 11; D++) _ += ' d ? " disabled" : "") + '">' + n + "", n += 1; + L.html(_), this.place() + } + }, updateNavArrows: function () { + var t = new Date(this.viewDate), e = t.getUTCFullYear(), i = t.getUTCMonth(), n = t.getUTCDate(), + o = t.getUTCHours(); + switch (this.viewMode) { + case 0: + this.startDate !== -(1 / 0) && e <= this.startDate.getUTCFullYear() && i <= this.startDate.getUTCMonth() && n <= this.startDate.getUTCDate() && o <= this.startDate.getUTCHours() ? this.picker.find(".prev").css({visibility: "hidden"}) : this.picker.find(".prev").css({visibility: "visible"}), this.endDate !== 1 / 0 && e >= this.endDate.getUTCFullYear() && i >= this.endDate.getUTCMonth() && n >= this.endDate.getUTCDate() && o >= this.endDate.getUTCHours() ? this.picker.find(".next").css({visibility: "hidden"}) : this.picker.find(".next").css({visibility: "visible"}); + break; + case 1: + this.startDate !== -(1 / 0) && e <= this.startDate.getUTCFullYear() && i <= this.startDate.getUTCMonth() && n <= this.startDate.getUTCDate() ? this.picker.find(".prev").css({visibility: "hidden"}) : this.picker.find(".prev").css({visibility: "visible"}), this.endDate !== 1 / 0 && e >= this.endDate.getUTCFullYear() && i >= this.endDate.getUTCMonth() && n >= this.endDate.getUTCDate() ? this.picker.find(".next").css({visibility: "hidden"}) : this.picker.find(".next").css({visibility: "visible"}); + break; + case 2: + this.startDate !== -(1 / 0) && e <= this.startDate.getUTCFullYear() && i <= this.startDate.getUTCMonth() ? this.picker.find(".prev").css({visibility: "hidden"}) : this.picker.find(".prev").css({visibility: "visible"}), this.endDate !== 1 / 0 && e >= this.endDate.getUTCFullYear() && i >= this.endDate.getUTCMonth() ? this.picker.find(".next").css({visibility: "hidden"}) : this.picker.find(".next").css({visibility: "visible"}); + break; + case 3: + case 4: + this.startDate !== -(1 / 0) && e <= this.startDate.getUTCFullYear() ? this.picker.find(".prev").css({visibility: "hidden"}) : this.picker.find(".prev").css({visibility: "visible"}), this.endDate !== 1 / 0 && e >= this.endDate.getUTCFullYear() ? this.picker.find(".next").css({visibility: "hidden"}) : this.picker.find(".next").css({visibility: "visible"}) + } + }, mousewheel: function (t) { + if (t.preventDefault(), t.stopPropagation(), !this.wheelPause) { + this.wheelPause = !0; + var e = t.originalEvent, i = e.wheelDelta, n = i > 0 ? 1 : 0 === i ? 0 : -1; + this.wheelViewModeNavigationInverseDirection && (n = -n), this.showMode(n), setTimeout(function () { + this.wheelPause = !1 + }.bind(this), this.wheelViewModeNavigationDelay) + } + }, click: function (i) { + i.stopPropagation(), i.preventDefault(); + var n = t(i.target).closest("span, td, th, legend"); + if (1 == n.length) { + if (n.is(".disabled")) return void this.element.trigger({ + type: "outOfRange", + date: this.viewDate, + startDate: this.startDate, + endDate: this.endDate + }); + switch (n[0].nodeName.toLowerCase()) { + case"th": + switch (n[0].className) { + case"switch": + this.showMode(1); + break; + case"prev": + case"next": + var o = a.modes[this.viewMode].navStep * ("prev" == n[0].className ? -1 : 1); + switch (this.viewMode) { + case 0: + this.viewDate = this.moveHour(this.viewDate, o); + break; + case 1: + this.viewDate = this.moveDate(this.viewDate, o); + break; + case 2: + this.viewDate = this.moveMonth(this.viewDate, o); + break; + case 3: + case 4: + this.viewDate = this.moveYear(this.viewDate, o) + } + this.fill(); + break; + case"today": + var s = new Date; + s = e(s.getFullYear(), s.getMonth(), s.getDate(), s.getHours(), s.getMinutes(), s.getSeconds(), 0), s < this.startDate ? s = this.startDate : s > this.endDate && (s = this.endDate), this.viewMode = this.startViewMode, this.showMode(0), this._setDate(s), this.fill(), this.autoclose && this.hide() + } + break; + case"span": + if (!n.is(".disabled")) { + var r = this.viewDate.getUTCFullYear(), l = this.viewDate.getUTCMonth(), + h = this.viewDate.getUTCDate(), c = this.viewDate.getUTCHours(), + d = this.viewDate.getUTCMinutes(), u = this.viewDate.getUTCSeconds(); + if (n.is(".month") ? (this.viewDate.setUTCDate(1), l = n.parent().find("span").index(n), h = this.viewDate.getUTCDate(), this.viewDate.setUTCMonth(l), this.element.trigger({ + type: "changeMonth", + date: this.viewDate + }), this.viewSelect >= 3 && this._setDate(e(r, l, h, c, d, u, 0))) : n.is(".year") ? (this.viewDate.setUTCDate(1), r = parseInt(n.text(), 10) || 0, this.viewDate.setUTCFullYear(r), this.element.trigger({ + type: "changeYear", + date: this.viewDate + }), this.viewSelect >= 4 && this._setDate(e(r, l, h, c, d, u, 0))) : n.is(".hour") ? (c = parseInt(n.text(), 10) || 0, (n.hasClass("hour_am") || n.hasClass("hour_pm")) && (12 == c && n.hasClass("hour_am") ? c = 0 : 12 != c && n.hasClass("hour_pm") && (c += 12)), this.viewDate.setUTCHours(c), this.element.trigger({ + type: "changeHour", + date: this.viewDate + }), this.viewSelect >= 1 && this._setDate(e(r, l, h, c, d, u, 0))) : n.is(".minute") && (d = parseInt(n.text().substr(n.text().indexOf(":") + 1), 10) || 0, this.viewDate.setUTCMinutes(d), this.element.trigger({ + type: "changeMinute", + date: this.viewDate + }), this.viewSelect >= 0 && this._setDate(e(r, l, h, c, d, u, 0))), 0 != this.viewMode) { + var f = this.viewMode; + this.showMode(-1), this.fill(), f == this.viewMode && this.autoclose && this.hide() + } else this.fill(), this.autoclose && this.hide() + } + break; + case"td": + if (n.is(".day") && !n.is(".disabled")) { + var h = parseInt(n.text(), 10) || 1, r = this.viewDate.getUTCFullYear(), + l = this.viewDate.getUTCMonth(), c = this.viewDate.getUTCHours(), + d = this.viewDate.getUTCMinutes(), u = this.viewDate.getUTCSeconds(); + n.is(".old") ? 0 === l ? (l = 11, r -= 1) : l -= 1 : n.is(".new") && (11 == l ? (l = 0, r += 1) : l += 1), this.viewDate.setUTCFullYear(r), this.viewDate.setUTCMonth(l, h), this.element.trigger({ + type: "changeDay", + date: this.viewDate + }), this.viewSelect >= 2 && this._setDate(e(r, l, h, c, d, u, 0)); + var f = this.viewMode; + this.showMode(-1), this.fill(), f == this.viewMode && this.autoclose && this.hide() + } + } + } + }, _setDate: function (t, e) { + e && "date" != e || (this.date = t), e && "view" != e || (this.viewDate = t), this.fill(), this.setValue(); + var i; + this.isInput ? i = this.element : this.component && (i = this.element.find("input")), i && (i.change(), this.autoclose && (!e || "date" == e)), this.element.trigger({ + type: "changeDate", + date: this.date + }), null === t && (this.date = this.viewDate) + }, moveMinute: function (t, e) { + if (!e) return t; + var i = new Date(t.valueOf()); + return i.setUTCMinutes(i.getUTCMinutes() + e * this.minuteStep), i + }, moveHour: function (t, e) { + if (!e) return t; + var i = new Date(t.valueOf()); + return i.setUTCHours(i.getUTCHours() + e), i + }, moveDate: function (t, e) { + if (!e) return t; + var i = new Date(t.valueOf()); + return i.setUTCDate(i.getUTCDate() + e), i + }, moveMonth: function (t, e) { + if (!e) return t; + var i, n, o = new Date(t.valueOf()), a = o.getUTCDate(), s = o.getUTCMonth(), r = Math.abs(e); + if (e = e > 0 ? 1 : -1, 1 == r) n = e == -1 ? function () { + return o.getUTCMonth() == s + } : function () { + return o.getUTCMonth() != i + }, i = s + e, o.setUTCMonth(i), (i < 0 || i > 11) && (i = (i + 12) % 12); else { + for (var l = 0; l < r; l++) o = this.moveMonth(o, e); + i = o.getUTCMonth(), o.setUTCDate(a), n = function () { + return i != o.getUTCMonth() + } + } + for (; n();) o.setUTCDate(--a), o.setUTCMonth(i); + return o + }, moveYear: function (t, e) { + return this.moveMonth(t, 12 * e) + }, dateWithinRange: function (t) { + return t >= this.startDate && t <= this.endDate + }, keydown: function (t) { + if (this.picker.is(":not(:visible)")) return void (27 == t.keyCode && this.show()); + var e, i, n, o = !1; + switch (t.keyCode) { + case 27: + this.hide(), t.preventDefault(); + break; + case 37: + case 39: + if (!this.keyboardNavigation) break; + e = 37 == t.keyCode ? -1 : 1, viewMode = this.viewMode, t.ctrlKey ? viewMode += 2 : t.shiftKey && (viewMode += 1), 4 == viewMode ? (i = this.moveYear(this.date, e), n = this.moveYear(this.viewDate, e)) : 3 == viewMode ? (i = this.moveMonth(this.date, e), n = this.moveMonth(this.viewDate, e)) : 2 == viewMode ? (i = this.moveDate(this.date, e), n = this.moveDate(this.viewDate, e)) : 1 == viewMode ? (i = this.moveHour(this.date, e), n = this.moveHour(this.viewDate, e)) : 0 == viewMode && (i = this.moveMinute(this.date, e), n = this.moveMinute(this.viewDate, e)), this.dateWithinRange(i) && (this.date = i, this.viewDate = n, this.setValue(), this.update(), t.preventDefault(), o = !0); + break; + case 38: + case 40: + if (!this.keyboardNavigation) break; + e = 38 == t.keyCode ? -1 : 1, viewMode = this.viewMode, t.ctrlKey ? viewMode += 2 : t.shiftKey && (viewMode += 1), 4 == viewMode ? (i = this.moveYear(this.date, e), n = this.moveYear(this.viewDate, e)) : 3 == viewMode ? (i = this.moveMonth(this.date, e), n = this.moveMonth(this.viewDate, e)) : 2 == viewMode ? (i = this.moveDate(this.date, 7 * e), n = this.moveDate(this.viewDate, 7 * e)) : 1 == viewMode ? this.showMeridian ? (i = this.moveHour(this.date, 6 * e), n = this.moveHour(this.viewDate, 6 * e)) : (i = this.moveHour(this.date, 4 * e), n = this.moveHour(this.viewDate, 4 * e)) : 0 == viewMode && (i = this.moveMinute(this.date, 4 * e), n = this.moveMinute(this.viewDate, 4 * e)), this.dateWithinRange(i) && (this.date = i, this.viewDate = n, this.setValue(), this.update(), t.preventDefault(), o = !0); + break; + case 13: + if (0 != this.viewMode) { + var a = this.viewMode; + this.showMode(-1), this.fill(), a == this.viewMode && this.autoclose && this.hide() + } else this.fill(), this.autoclose && this.hide(); + t.preventDefault(); + break; + case 9: + this.hide() + } + if (o) { + var s; + this.isInput ? s = this.element : this.component && (s = this.element.find("input")), s && s.change(), this.element.trigger({ + type: "changeDate", + date: this.date + }) + } + }, showMode: function (t) { + if (t) { + var e = Math.max(0, Math.min(a.modes.length - 1, this.viewMode + t)); + e >= this.minView && e <= this.maxView && (this.element.trigger({ + type: "changeMode", + date: this.viewDate, + oldViewMode: this.viewMode, + newViewMode: e + }), this.viewMode = e) + } + this.picker.find(">div").hide().filter(".datetimepicker-" + a.modes[this.viewMode].clsName).css("display", "block"), this.updateNavArrows() + }, reset: function (t) { + this._setDate(null, "date") + } + }, t.fn.datetimepicker = function (e) { + var n = Array.apply(null, arguments); + return n.shift(), this.each(function () { + var o = t(this), a = o.data("datetimepicker"), s = "object" == typeof e && e; + a || o.data("datetimepicker", a = new i(this, t.extend({}, t.fn.datetimepicker.defaults, o.data(), s))), "string" == typeof e && "function" == typeof a[e] && a[e].apply(a, n) + }) + }, t.fn.datetimepicker.defaults = {pickerPosition: "auto-right"}, t.fn.datetimepicker.Constructor = i; + var n = t.fn.datetimepicker.dates = { + en: { + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], + daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], + daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + meridiem: ["am", "pm"], + suffix: ["st", "nd", "rd", "th"], + today: "Today" + }, + "zh-cn": { + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], + daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], + daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + today: "今日", + suffix: [], + meridiem: [] + }, + "zh-tw": { + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], + daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], + daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + today: "今天", + suffix: [], + meridiem: ["上午", "下午"] + } + }, o = function (e) { + var i = n[e]; + return i || (i = t.zui && t.zui.getLangData ? n[e] = t.zui.getLangData("datetimepicker", this.language, n) : n.en), i + }, a = { + modes: [{clsName: "minutes", navFnc: "Hours", navStep: 1}, { + clsName: "hours", + navFnc: "Date", + navStep: 1 + }, {clsName: "days", navFnc: "Month", navStep: 1}, { + clsName: "months", + navFnc: "FullYear", + navStep: 1 + }, {clsName: "years", navFnc: "FullYear", navStep: 10}], + isLeapYear: function (t) { + return t % 4 === 0 && t % 100 !== 0 || t % 400 === 0 + }, + getDaysInMonth: function (t, e) { + return [31, a.isLeapYear(t) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][e] + }, + getDefaultFormat: function (t, e) { + if ("standard" == t) return "input" == e ? "yyyy-mm-dd hh:ii" : "yyyy-mm-dd hh:ii:ss"; + if ("php" == t) return "input" == e ? "Y-m-d H:i" : "Y-m-d H:i:s"; + throw new Error("Invalid format type.") + }, + validParts: function (t) { + if ("standard" == t) return /hh?|HH?|p|P|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g; + if ("php" == t) return /[dDjlNwzFmMnStyYaABgGhHis]/g; + throw new Error("Invalid format type.") + }, + nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\rTZ]+/g, + parseFormat: function (t, e) { + var i = t.replace(this.validParts(e), "\0").split("\0"), n = t.match(this.validParts(e)); + if (!i || !i.length || !n || 0 == n.length) throw new Error("Invalid date format."); + return {separators: i, parts: n} + }, + parseDate: function (n, a, s, r) { + if (n instanceof Date) { + var l = new Date(n.valueOf() - 6e4 * n.getTimezoneOffset()); + return l.setMilliseconds(0), l + } + if (/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(n) && (a = this.parseFormat("yyyy-mm-dd", r)), /^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(n) && (a = this.parseFormat("yyyy-mm-dd hh:ii", r)), /^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(n) && (a = this.parseFormat("yyyy-mm-dd hh:ii:ss", r)), /^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(n)) { + var h, c, d = /([-+]\d+)([dmwy])/, u = n.match(/([-+]\d+)([dmwy])/g); + n = new Date; + for (var f = 0; f < u.length; f++) switch (h = d.exec(u[f]), c = parseInt(h[1]), h[2]) { + case"d": + n.setUTCDate(n.getUTCDate() + c); + break; + case"m": + n = i.prototype.moveMonth.call(i.prototype, n, c); + break; + case"w": + n.setUTCDate(n.getUTCDate() + 7 * c); + break; + case"y": + n = i.prototype.moveYear.call(i.prototype, n, c) + } + return e(n.getUTCFullYear(), n.getUTCMonth(), n.getUTCDate(), n.getUTCHours(), n.getUTCMinutes(), n.getUTCSeconds(), 0) + } + var p, g, h, u = n && n.match(this.nonpunctuation) || [], n = new Date(0, 0, 0, 0, 0, 0, 0), m = {}, + v = ["hh", "h", "ii", "i", "ss", "s", "yyyy", "yy", "M", "MM", "m", "mm", "D", "DD", "d", "dd", "H", "HH", "p", "P"], + y = { + hh: function (t, e) { + return t.setUTCHours(e) + }, h: function (t, e) { + return t.setUTCHours(e) + }, HH: function (t, e) { + return t.setUTCHours(12 == e ? 0 : e) + }, H: function (t, e) { + return t.setUTCHours(12 == e ? 0 : e) + }, ii: function (t, e) { + return t.setUTCMinutes(e) + }, i: function (t, e) { + return t.setUTCMinutes(e) + }, ss: function (t, e) { + return t.setUTCSeconds(e) + }, s: function (t, e) { + return t.setUTCSeconds(e) + }, yyyy: function (t, e) { + return t.setUTCFullYear(e) + }, yy: function (t, e) { + return t.setUTCFullYear(2e3 + e) + }, m: function (t, e) { + for (e -= 1; e < 0;) e += 12; + for (e %= 12, t.setUTCMonth(e); t.getUTCMonth() != e;) t.setUTCDate(t.getUTCDate() - 1); + return t + }, d: function (t, e) { + return t.setUTCDate(e) + }, p: function (t, e) { + return t.setUTCHours(1 == e ? t.getUTCHours() + 12 : t.getUTCHours()) + } + }; + if (y.M = y.MM = y.mm = y.m, y.dd = y.d, y.P = y.p, n = e(n.getFullYear(), n.getMonth(), n.getDate(), n.getHours(), n.getMinutes(), n.getSeconds()), u.length == a.parts.length) { + for (var f = 0, b = a.parts.length; f < b; f++) { + if (p = parseInt(u[f], 10), h = a.parts[f], isNaN(p)) switch (h) { + case"MM": + g = t(o(s).months).filter(function () { + var t = this.slice(0, u[f].length), e = u[f].slice(0, t.length); + return t == e + }), p = t.inArray(g[0], o(s).months) + 1; + break; + case"M": + g = t(o(s).monthsShort).filter(function () { + var t = this.slice(0, u[f].length), e = u[f].slice(0, t.length); + return t == e + }), p = t.inArray(g[0], o(s).monthsShort) + 1; + break; + case"p": + case"P": + p = t.inArray(u[f].toLowerCase(), o(s).meridiem) + } + m[h] = p + } + for (var w, f = 0; f < v.length; f++) w = v[f], w in m && !isNaN(m[w]) && y[w](n, m[w]) + } + return n + }, + formatDate: function (e, i, n, s) { + if (null == e) return ""; + var r; + if ("standard" == s) r = { + yy: e.getUTCFullYear().toString().substring(2), + yyyy: e.getUTCFullYear(), + m: e.getUTCMonth() + 1, + M: o(n).monthsShort[e.getUTCMonth()], + MM: o(n).months[e.getUTCMonth()], + d: e.getUTCDate(), + D: o(n).daysShort[e.getUTCDay()], + DD: o(n).days[e.getUTCDay()], + p: 2 == o(n).meridiem.length ? o(n).meridiem[e.getUTCHours() < 12 ? 0 : 1] : "", + h: e.getUTCHours(), + i: e.getUTCMinutes(), + s: e.getUTCSeconds() + }, 2 == o(n).meridiem.length ? r.H = r.h % 12 == 0 ? 12 : r.h % 12 : r.H = r.h, r.HH = (r.H < 10 ? "0" : "") + r.H, r.P = r.p.toUpperCase(), r.hh = (r.h < 10 ? "0" : "") + r.h, r.ii = (r.i < 10 ? "0" : "") + r.i, r.ss = (r.s < 10 ? "0" : "") + r.s, r.dd = (r.d < 10 ? "0" : "") + r.d, r.mm = (r.m < 10 ? "0" : "") + r.m; else { + if ("php" != s) throw new Error("Invalid format type."); + r = { + y: e.getUTCFullYear().toString().substring(2), + Y: e.getUTCFullYear(), + F: o(n).months[e.getUTCMonth()], + M: o(n).monthsShort[e.getUTCMonth()], + n: e.getUTCMonth() + 1, + t: a.getDaysInMonth(e.getUTCFullYear(), e.getUTCMonth()), + j: e.getUTCDate(), + l: o(n).days[e.getUTCDay()], + D: o(n).daysShort[e.getUTCDay()], + w: e.getUTCDay(), + N: 0 == e.getUTCDay() ? 7 : e.getUTCDay(), + S: e.getUTCDate() % 10 <= o(n).suffix.length ? o(n).suffix[e.getUTCDate() % 10 - 1] : "", + a: 2 == o(n).meridiem.length ? o(n).meridiem[e.getUTCHours() < 12 ? 0 : 1] : "", + g: e.getUTCHours() % 12 == 0 ? 12 : e.getUTCHours() % 12, + G: e.getUTCHours(), + i: e.getUTCMinutes(), + s: e.getUTCSeconds() + }, r.m = (r.n < 10 ? "0" : "") + r.n, r.d = (r.j < 10 ? "0" : "") + r.j, r.A = r.a.toString().toUpperCase(), r.h = (r.g < 10 ? "0" : "") + r.g, r.H = (r.G < 10 ? "0" : "") + r.G, r.i = (r.i < 10 ? "0" : "") + r.i, r.s = (r.s < 10 ? "0" : "") + r.s + } + for (var e = [], l = t.extend([], i.separators), h = 0, c = i.parts.length; h < c; h++) l.length && e.push(l.shift()), e.push(r[i.parts[h]]); + return l.length && e.push(l.shift()), e.join("") + }, + convertViewMode: function (t) { + switch (t) { + case 4: + case"decade": + t = 4; + break; + case 3: + case"year": + t = 3; + break; + case 2: + case"month": + t = 2; + break; + case 1: + case"day": + t = 1; + break; + case 0: + case"hour": + t = 0 + } + return t + }, + headTemplate: '', + contTemplate: '', + footTemplate: '' + }; + a.template = '
    ' + a.headTemplate + a.contTemplate + a.footTemplate + '
    ' + a.headTemplate + a.contTemplate + a.footTemplate + '
    ' + a.headTemplate + "" + a.footTemplate + '
    ' + a.headTemplate + a.contTemplate + a.footTemplate + '
    ' + a.headTemplate + a.contTemplate + a.footTemplate + "
    ", t.fn.datetimepicker.DPGlobal = a, t.fn.datetimepicker.noConflict = function () { + return t.fn.datetimepicker = old, this + }, t(document).on("focus.datetimepicker.data-api click.datetimepicker.data-api", '[data-provide="datetimepicker"]', function (e) { + var i = t(this); + i.data("datetimepicker") || (e.preventDefault(), i.datetimepicker("show")) + }), t(function () { + t('[data-provide="datetimepicker-inline"]').datetimepicker() + }) + }(window.jQuery),/*! bootbox.js v4.4.0 http://bootboxjs.com/license.txt */ + function (t, e) { + "use strict"; + "function" == typeof define && define.amd ? define(["jquery"], e) : "object" == typeof exports ? module.exports = e(require("jquery")) : t.bootbox = e(t.jQuery) + }(this, function t(e, i) { + "use strict"; + + function n(t) { + var i = e.zui && e.zui.getLangData ? e.zui.getLangData("bootbox", p.locale, m) : m[p.locale]; + return i ? i[t] : m.en[t] + } + + function o(t, e, i) { + t.stopPropagation(), t.preventDefault(); + var n = "function" == typeof i && i.call(e, t) === !1; + n || e.modal("hide") + } + + function a(t) { + var e, i = 0; + for (e in t) i++; + return i + } + + function s(t, i) { + var n = 0; + e.each(t, function (t, e) { + i(t, e, n++) + }) + } + + function r(t) { + var i, n; + if ("object" != typeof t) throw new Error("Please supply an object of options"); + if (!t.message) throw new Error("Please specify a message"); + return t = e.extend({}, p, t), t.buttons || (t.buttons = {}), i = t.buttons, n = a(i), s(i, function (t, o, a) { + if ("function" == typeof o && (o = i[t] = {callback: o}), "object" !== e.type(o)) throw new Error("button with key " + t + " must be an object"); + o.label || (o.label = t), o.className || (2 === n && ("ok" === t || "confirm" === t) || 1 === n ? o.className = "btn-primary" : o.className = "btn-default") + }), t + } + + function l(t, e) { + var i = t.length, n = {}; + if (i < 1 || i > 2) throw new Error("Invalid argument length"); + return 2 === i || "string" == typeof t[0] ? (n[e[0]] = t[0], n[e[1]] = t[1]) : n = t[0], n + } + + function h(t, i, n) { + return e.extend(!0, {}, t, l(i, n)) + } + + function c(t, e, i, n) { + var o = {className: "bootbox-" + t, buttons: d.apply(null, e)}; + return u(h(o, n, i), e) + } + + function d() { + for (var t = {}, e = 0, i = arguments.length; e < i; e++) { + var o = arguments[e], a = o.toLowerCase(), s = o.toUpperCase(); + t[a] = {label: n(s)} + } + return t + } + + function u(t, e) { + var n = {}; + return s(e, function (t, e) { + n[e] = !0 + }), s(t.buttons, function (t) { + if (n[t] === i) throw new Error("button key " + t + " is not allowed (options are " + e.join("\n") + ")") + }), t + } + + var f = { + dialog: "", + header: "", + footer: "", + closeButton: "", + form: "
    ", + inputs: { + text: "", + textarea: "", + email: "", + select: "", + checkbox: "
    ", + date: "", + time: "", + number: "", + password: "" + } + }, p = { + locale: e.zui && e.zui.clientLang ? e.zui.clientLang() : "en", + backdrop: "static", + animate: !0, + className: null, + closeButton: !0, + show: !0, + container: "body" + }, g = {}; + g.alert = function () { + var t; + if (t = c("alert", ["ok"], ["message", "callback"], arguments), t.callback && "function" != typeof t.callback) throw new Error("alert requires callback property to be a function when provided"); + return t.buttons.ok.callback = t.onEscape = function () { + return "function" != typeof t.callback || t.callback.call(this) + }, g.dialog(t) + }, g.confirm = function () { + var t; + if (t = c("confirm", ["confirm", "cancel"], ["message", "callback"], arguments), t.buttons.cancel.callback = t.onEscape = function () { + return t.callback.call(this, !1) + }, t.buttons.confirm.callback = function () { + return t.callback.call(this, !0) + }, "function" != typeof t.callback) throw new Error("confirm requires a callback"); + return g.dialog(t) + }, g.prompt = function () { + var t, n, o, a, r, l, c; + if (a = e(f.form), n = { + className: "bootbox-prompt", + buttons: d("cancel", "confirm"), + value: "", + inputType: "text" + }, t = u(h(n, arguments, ["title", "callback"]), ["confirm", "cancel"]), l = t.show === i || t.show, t.message = a, t.buttons.cancel.callback = t.onEscape = function () { + return t.callback.call(this, null) + }, t.buttons.confirm.callback = function () { + var i; + switch (t.inputType) { + case"text": + case"textarea": + case"email": + case"select": + case"date": + case"time": + case"number": + case"password": + i = r.val(); + break; + case"checkbox": + var n = r.find("input:checked"); + i = [], s(n, function (t, n) { + i.push(e(n).val()) + }) + } + return t.callback.call(this, i) + }, t.show = !1, !t.title) throw new Error("prompt requires a title"); + if ("function" != typeof t.callback) throw new Error("prompt requires a callback"); + if (!f.inputs[t.inputType]) throw new Error("invalid prompt type"); + switch (r = e(f.inputs[t.inputType]), t.inputType) { + case"text": + case"textarea": + case"email": + case"date": + case"time": + case"number": + case"password": + r.val(t.value); + break; + case"select": + var p = {}; + if (c = t.inputOptions || [], !Array.isArray(c)) throw new Error("Please pass an array of input options"); + if (!c.length) throw new Error("prompt with select requires options"); + s(c, function (t, n) { + var o = r; + if (n.value === i || n.text === i) throw new Error("given options in wrong format"); + n.group && (p[n.group] || (p[n.group] = e("").attr("label", n.group)), o = p[n.group]), o.append("") + }), s(p, function (t, e) { + r.append(e) + }), r.val(t.value); + break; + case"checkbox": + var m = Array.isArray(t.value) ? t.value : [t.value]; + if (c = t.inputOptions || [], !c.length) throw new Error("prompt with checkbox requires options"); + if (!c[0].value || !c[0].text) throw new Error("given options in wrong format"); + r = e("
    "), s(c, function (i, n) { + var o = e(f.inputs[t.inputType]); + o.find("input").attr("value", n.value), o.find("label").append(n.text), s(m, function (t, e) { + e === n.value && o.find("input").prop("checked", !0) + }), r.append(o) + }) + } + return t.placeholder && r.attr("placeholder", t.placeholder), t.pattern && r.attr("pattern", t.pattern), t.maxlength && r.attr("maxlength", t.maxlength), a.append(r), a.on("submit", function (t) { + t.preventDefault(), t.stopPropagation(), o.find(".btn-primary").click() + }), o = g.dialog(t), o.off("shown.zui.modal"), o.on("shown.zui.modal", function () { + r.focus() + }), l === !0 && o.modal("show"), o + }, g.dialog = function (t) { + t = r(t); + var n = e(f.dialog), a = n.find(".modal-dialog"), l = n.find(".modal-body"), h = t.buttons, c = "", + d = {onEscape: t.onEscape}; + if (e.fn.modal === i) throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details."); + if (s(h, function (t, e) { + c += "", d[t] = e.callback + }), l.find(".bootbox-body").html(t.message), t.animate === !0 && n.addClass("fade"), t.className && n.addClass(t.className), "large" === t.size ? a.addClass("modal-lg") : "small" === t.size && a.addClass("modal-sm"), t.title && l.before(f.header), t.closeButton) { + var u = e(f.closeButton); + t.title ? n.find(".modal-header").prepend(u) : u.css("margin-top", "-10px").prependTo(l) + } + return t.title && n.find(".modal-title").html(t.title), c.length && (l.after(f.footer), n.find(".modal-footer").html(c)), n.on("hidden.zui.modal", function (t) { + t.target === this && n.remove() + }), n.on("shown.zui.modal", function () { + n.find(".btn-primary:first").focus() + }), "static" !== t.backdrop && n.on("click.dismiss.zui.modal", function (t) { + n.children(".modal-backdrop").length && (t.currentTarget = n.children(".modal-backdrop").get(0)), t.target === t.currentTarget && n.trigger("escape.close.bb") + }), n.on("escape.close.bb", function (t) { + d.onEscape && o(t, n, d.onEscape) + }), n.on("click", ".modal-footer button", function (t) { + var i = e(this).data("bb-handler"); + o(t, n, d[i]) + }), n.on("click", ".bootbox-close-button", function (t) { + o(t, n, d.onEscape) + }), n.on("keyup", function (t) { + 27 === t.which && n.trigger("escape.close.bb") + }), e(t.container).append(n), n.modal({ + backdrop: !!t.backdrop && "static", + keyboard: !1, + show: !1 + }), t.show && n.modal("show"), n + }, g.setDefaults = function () { + var t = {}; + 2 === arguments.length ? t[arguments[0]] = arguments[1] : t = arguments[0], e.extend(p, t) + }, g.hideAll = function () { + return e(".bootbox").modal("hide"), g + }; + var m = { + en: {OK: "OK", CANCEL: "Cancel", CONFIRM: "Confirm"}, + zh_cn: {OK: "确认", CANCEL: "取消", CONFIRM: "确认"}, + zh_tw: {OK: "確認", CANCEL: "取消", CONFIRM: "確認"} + }; + return g.addLocale = function (t, i) { + return e.each(["OK", "CANCEL", "CONFIRM"], function (t, e) { + if (!i[e]) throw new Error("Please supply a translation for '" + e + "'") + }), m[t] = {OK: i.OK, CANCEL: i.CANCEL, CONFIRM: i.CONFIRM}, g + }, g.removeLocale = function (t) { + return delete m[t], g + }, g.setLocale = function (t) { + return g.setDefaults("locale", t) + }, g.init = function (i) { + return t(i || e) + }, g + }),/*! Chosen, a Select Box Enhancer for jQuery and Prototype by Patrick Filler for Harvest, http://getharvest.com @@ -41,8 +3933,804 @@ Copyright (c) 2011 Harvest http://getharvest.com MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */ -function(){var t,e,i,n,o,a={}.hasOwnProperty,s=function(t,e){function i(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return i.prototype=e.prototype,t.prototype=new i,t.__super__=e.prototype,t},r={zh_cn:{no_results_text:"没有找到"},zh_tw:{no_results_text:"沒有找到"},en:{no_results_text:"No results match"}},l={};n=function(){function e(){this.options_index=0,this.parsed=[]}return e.prototype.add_node=function(t){return"OPTGROUP"===t.nodeName.toUpperCase()?this.add_group(t):this.add_option(t)},e.prototype.add_group=function(e){var i,n,o,a,s,r;for(i=this.parsed.length,this.parsed.push({array_index:i,group:!0,label:this.escapeExpression(e.label),children:0,disabled:e.disabled,title:e.title,search_keys:t.trim(e.getAttribute("data-keys")||"").replace(/,/g," ")}),s=e.childNodes,r=[],o=0,a=s.length;o\"\'\`]/.test(t)?(e={"<":"<",">":">",'"':""","'":"'","`":"`"},i=/&(?!\w+;)|[\<\>\"\'\`]/g,t.replace(i,function(t){return e[t]||"&"})):t},e}(),n.select_to_array=function(t){var e,i,o,a,s;for(i=new n,s=t.childNodes,o=0,a=s.length;o0?(e=document.createElement("li"),e.className="group-result",e.title=t.title,e.innerHTML=t.search_text,this.outerHTML(e)):""},e.prototype.results_update_field=function(){this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing&&(this.winnow_results(),this.autoResizeDrop())},e.prototype.reset_single_select_options=function(){var t,e,i,n,o;for(n=this.results_data,o=[],e=0,i=n.length;e"+i.search_text.substr(l+r.length),i.search_text=h.substr(0,l)+""+h.substr(l)):i.search_keys_match&&i.search_keys.length&&(l=i.search_keys.search(c),h=i.search_keys.substr(0,l+r.length)+""+i.search_keys.substr(l+r.length),i.search_text+='  '+h.substr(0,l)+""+h.substr(l)+""),null!=s&&(s.group_match=!0)):null!=i.group_array_index&&this.results_data[i.group_array_index].search_match&&(i.search_match=!0)));return this.result_clear_highlight(),a<1&&r.length?(this.update_results_content(""),this.no_results(r)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight(t))},e.prototype.search_string_match=function(t,e){var i,n,o,a;if(e.test(t))return!0;if(this.enable_split_word_search&&(t.indexOf(" ")>=0||0===t.indexOf("["))&&(n=t.replace(/\[|\]/g,"").split(" "),n.length))for(o=0,a=n.length;o0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(t.preventDefault(),this.results_showing)return this.result_select(t);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},e.prototype.clipboard_event_checker=function(t){var e=this;return setTimeout(function(){return e.results_search()},50)},e.prototype.container_width=function(){return null!=this.options.width?this.options.width:this.form_field&&this.form_field.classList&&this.form_field.classList.contains("form-control")?"100%":""+this.form_field.offsetWidth+"px"},e.prototype.include_option_in_results=function(t){return!(this.is_multiple&&!this.display_selected_options&&t.selected)&&(!(!this.display_disabled_options&&t.disabled)&&!t.empty)},e.prototype.search_results_touchstart=function(t){return this.touch_started=!0,this.search_results_mouseover(t)},e.prototype.search_results_touchmove=function(t){return this.touch_started=!1,this.search_results_mouseout(t)},e.prototype.search_results_touchend=function(t){if(this.touch_started)return this.search_results_mouseup(t)},e.prototype.outerHTML=function(t){var e;return t.outerHTML?t.outerHTML:(e=document.createElement("div"),e.appendChild(t),e.innerHTML)},e.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:!/iP(od|hone)/i.test(window.navigator.userAgent)&&(!/Android/i.test(window.navigator.userAgent)||!/Mobile/i.test(window.navigator.userAgent))},e.default_multiple_text="",e.default_single_text="",e.default_no_result_text="No results match",e}(),t=jQuery,t.fn.extend({chosen:function(n){return e.browser_is_supported()?this.each(function(e){var o=t(this),a=o.data("chosen");"destroy"===n&&a?a.destroy():a||o.data("chosen",new i(this,t.extend({},o.data(),n)))}):this}}),i=function(e){function i(){return o=i.__super__.constructor.apply(this,arguments)}return s(i,e),i.prototype.setup=function(){return this.form_field_jq=t(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},i.prototype.set_up_html=function(){var e,i;e=["chosen-container"],e.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&e.push(this.form_field.className),this.is_rtl&&e.push("chosen-rtl");var n=this.form_field.getAttribute("data-css-class");return n&&e.push(n),i={"class":e.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(i.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=t("
    ",i),this.is_multiple?this.container.html('
      '):(this.container.html(''+this.default_text+'
        '),this.compact_search?this.container.addClass("chosen-compact").find(".chosen-search").appendTo(this.container.find(".chosen-single")):this.container.find(".chosen-search").prependTo(this.container.find(".chosen-drop")),this.options.highlight_selected!==!1&&this.container.addClass("chosen-highlight-selected")),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.options.drop_width&&this.dropdown.css("width",this.options.drop_width).addClass("chosen-drop-size-limited"),this.max_drop_width&&this.dropdown.addClass("chosen-auto-max-width"),this.options.no_wrap&&this.dropdown.addClass("chosen-no-wrap"),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},i.prototype.register_observers=function(){var t=this;return this.container.bind("mousedown.chosen",function(e){t.container_mousedown(e)}),this.container.bind("mouseup.chosen",function(e){t.container_mouseup(e)}),this.container.bind("mouseenter.chosen",function(e){t.mouse_enter(e)}),this.container.bind("mouseleave.chosen",function(e){t.mouse_leave(e)}),this.search_results.bind("mouseup.chosen",function(e){t.search_results_mouseup(e)}),this.search_results.bind("mouseover.chosen",function(e){t.search_results_mouseover(e)}),this.search_results.bind("mouseout.chosen",function(e){t.search_results_mouseout(e)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(e){t.search_results_mousewheel(e)}),this.search_results.bind("touchstart.chosen",function(e){t.search_results_touchstart(e)}),this.search_results.bind("touchmove.chosen",function(e){t.search_results_touchmove(e)}),this.search_results.bind("touchend.chosen",function(e){t.search_results_touchend(e)}),this.form_field_jq.bind("chosen:updated.chosen",function(e){t.results_update_field(e)}),this.form_field_jq.bind("chosen:activate.chosen",function(e){t.activate_field(e)}),this.form_field_jq.bind("chosen:open.chosen",function(e){t.container_mousedown(e)}),this.form_field_jq.bind("chosen:close.chosen",function(e){t.input_blur(e)}),this.search_field.bind("blur.chosen",function(e){t.input_blur(e)}),this.search_field.bind("keyup.chosen",function(e){t.keyup_checker(e)}),this.search_field.bind("keydown.chosen",function(e){t.keydown_checker(e)}),this.search_field.bind("focus.chosen",function(e){t.input_focus(e)}),this.search_field.bind("cut.chosen",function(e){t.clipboard_event_checker(e)}),this.search_field.bind("paste.chosen",function(e){t.clipboard_event_checker(e)}),this.is_multiple?this.search_choices.bind("click.chosen",function(e){t.choices_click(e)}):this.container.bind("click.chosen",function(t){t.preventDefault()})},i.prototype.destroy=function(){return t(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},i.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},i.prototype.container_mousedown=function(e){if(!this.is_disabled&&(e&&"mousedown"===e.type&&!this.results_showing&&e.preventDefault(),null==e||!t(e.target).hasClass("search-choice-close")))return this.active_field?this.is_multiple||!e||t(e.target)[0]!==this.selected_item[0]&&!t(e.target).parents("a.chosen-single").length||(e.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),t(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field()},i.prototype.container_mouseup=function(t){if("ABBR"===t.target.nodeName&&!this.is_disabled)return this.results_reset(t)},i.prototype.search_results_mousewheel=function(t){var e;if(t.originalEvent&&(e=-t.originalEvent.wheelDelta||t.originalEvent.detail),null!=e)return t.preventDefault(),"DOMMouseScroll"===t.type&&(e=40*e),this.search_results.scrollTop(e+this.search_results.scrollTop())},i.prototype.blur_test=function(t){if(!this.active_field&&this.container.hasClass("chosen-container-active"))return this.close_field()},i.prototype.close_field=function(){return t(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},i.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},i.prototype.test_active_click=function(e){var i;return i=t(e.target).closest(".chosen-container"),i.length&&this.container[0]===i[0]?this.active_field=!0:this.close_field()},i.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=n.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch"),this.container.removeClass("chosen-with-search")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"),this.container.addClass("chosen-with-search"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},i.prototype.result_do_highlight=function(t,e){if(t.length){var i,n,o,a,s,r,l=-1;this.result_clear_highlight(),this.result_highlight=t,this.result_highlight.addClass("highlighted"),o=parseInt(this.search_results.css("maxHeight"),10),r=this.result_highlight.outerHeight(),s=this.search_results.scrollTop(),a=o+s,n=this.result_highlight.position().top+this.search_results.scrollTop(),i=n+r,this.middle_highlight&&(e||"always"===this.middle_highlight)?l=Math.min(n-r,Math.max(0,n-(o-r)/2)):i>=a?l=i-o>0?i-o:0:n-1?this.search_results.scrollTop(l):this.result_highlight.scrollIntoView&&this.result_highlight.scrollIntoView()}},i.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},i.prototype.results_show=function(){var e=this;if(e.is_multiple&&e.max_selected_options<=e.choices_count())return e.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1;e.results_showing=!0,e.search_field.focus(),e.search_field.val(e.search_field.val()),e.container.addClass("chosen-with-drop"),e.winnow_results(1);var i=e.drop_direction;if("function"==typeof i&&(i=i.call(this)),"auto"===i)if(e.drop_directionFixed)i=e.drop_directionFixed;else{var n=e.container.find(".chosen-drop"),o=n.outerHeight();e.drop_item_height&&o.active-result").length*e.drop_item_height));var a=e.container.offset();a.top+o+30>t(window).height()+t(window).scrollTop()&&(i="up"),e.drop_directionFixed=i}return e.container.toggleClass("chosen-up","up"===i),e.autoResizeDrop(),e.form_field_jq.trigger("chosen:showing_dropdown",{chosen:e})},i.prototype.autoResizeDrop=function(){var e=this,i=e.max_drop_width;if(i){var n=e.container.find(".chosen-drop");n.removeClass("in");var o=0,a=n.find(".chosen-results"),s=a.children("li"),r=parseFloat(a.css("padding-left").replace("px","")),l=parseFloat(a.css("padding-right").replace("px","")),h=(isNaN(r)?0:r)+(isNaN(l)?0:l);s.each(function(){o=Math.max(o,t(this).outerWidth())}),n.css("width",Math.min(o+h+20,i)),e.fixDropWidthTimer=setTimeout(function(){e.fixDropWidthTimer=null,n.addClass("in"),e.winnow_results_set_highlight(1)},50)}},i.prototype.update_results_content=function(t){return this.search_results.html(t)},i.prototype.results_hide=function(){var t=this;return t.fixDropWidthTimer&&(clearTimeout(t.fixDropWidthTimer),t.fixDropWidthTimer=null),t.results_showing&&(t.result_clear_highlight(),t.container.removeClass("chosen-with-drop"),t.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:t}),t.drop_directionFixed=0),t.results_showing=!1},i.prototype.set_tab_index=function(t){var e;if(this.form_field.tabIndex)return e=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=e},i.prototype.set_label_behavior=function(){var e=this;if(this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=t("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0)return this.form_field_label.bind("click.chosen",function(t){return e.is_multiple?e.container_mousedown(t):e.activate_field()})},i.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},i.prototype.search_results_mouseup=function(e){var i;if(i=t(e.target).hasClass("active-result")?t(e.target):t(e.target).parents(".active-result").first(),i.length)return this.result_highlight=i,this.result_select(e),this.search_field.focus()},i.prototype.search_results_mouseover=function(e){var i;if(i=t(e.target).hasClass("active-result")?t(e.target):t(e.target).parents(".active-result").first())return this.result_do_highlight(i)},i.prototype.search_results_mouseout=function(e){if(t(e.target).hasClass("active-result"))return this.result_clear_highlight()},i.prototype.choice_build=function(e){var i,n,o=this;return i=t("
      • ",{"class":"search-choice"}).html(""+e.html+""),e.disabled?i.addClass("search-choice-disabled"):(n=t("",{"class":"search-choice-close","data-option-array-index":e.array_index}),n.bind("click.chosen",function(t){return o.choice_destroy_link_click(t)}),i.append(n)),this.search_container.before(i)},i.prototype.choice_destroy_link_click=function(e){if(e.preventDefault(),e.stopPropagation(),!this.is_disabled)return this.choice_destroy(t(e.target))},i.prototype.choice_destroy=function(t){if(this.result_deselect(t[0].getAttribute("data-option-array-index")))return this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),t.parents("li").first().remove(),this.search_field_scale()},i.prototype.results_reset=function(){var t=this.form_field_jq.val();this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup();var e=this.form_field_jq.val(),i={selected:e};if(t===e||e.length||(i.deselected=t),this.form_field_jq.trigger("change",i),this.sync_sort_field(),this.active_field)return this.results_hide()},i.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},i.prototype.result_select=function(t){var e,i;if(this.result_highlight)return e=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?e.removeClass("active-result"):this.reset_single_select_options(),i=this.results_data[e[0].getAttribute("data-option-array-index")],i.selected=!0,this.form_field.options[i.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(i):this.single_set_selected_text(i.text),(t.metaKey||t.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&(this.form_field_jq.trigger("change",{selected:this.form_field.options[i.options_index].value}),this.sync_sort_field()),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())},i.prototype.single_set_selected_text=function(t){return null==t&&(t=this.default_text),t===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.compact_search&&this.search_field.attr("placeholder",t),this.selected_item.find("span").attr("title",t).text(t)},i.prototype.sync_sort_field=function(){var e=this;if(e.is_multiple&&e.sort_field){var i=t(e.sort_field);if(!i.length)return;var n=[];e.search_choices.find("li.search-choice").each(function(){var i=t(this),o=i.children(".search-choice-close").first().data("optionArrayIndex"),a=e.results_data[o];a&&a.selected&&n.push(a.value)}),i.val(n.join(e.sort_value_splitter)).trigger("change")}},i.prototype.result_deselect=function(t){var e;return e=this.results_data[t],!this.form_field.options[e.options_index].disabled&&(e.selected=!1,this.form_field.options[e.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[e.options_index].value}),this.sync_sort_field(),this.search_field_scale(),!0)},i.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect)return this.selected_item.find("abbr").length||this.selected_item.find("span").first().after(''),this.selected_item.addClass("chosen-single-with-deselect")},i.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":t("
        ").text(t.trim(this.search_field.val())).html()},i.prototype.winnow_results_set_highlight=function(t){var e,i;if(i=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),e=i.length?i.first():this.search_results.find(".active-result").first(),null!=e)return this.result_do_highlight(e,t)},i.prototype.no_results=function(e){var i;return i=t('
      • '+this.results_none_found+' ""
      • '),i.find("span").first().html(e),this.search_results.append(i),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},i.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},i.prototype.keydown_arrow=function(){var t;return this.results_showing&&this.result_highlight?(t=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(t):void 0:this.results_show()},i.prototype.keyup_arrow=function(){var t;return this.results_showing||this.is_multiple?this.result_highlight?(t=this.result_highlight.prevAll("li.active-result"),t.length?this.result_do_highlight(t.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},i.prototype.keydown_backstroke=function(){var t;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(t=this.search_container.siblings("li.search-choice").last(),t.length&&!t.hasClass("search-choice-disabled")?(this.pending_backstroke=t,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},i.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},i.prototype.keydown_checker=function(t){var e,i;switch(e=null!=(i=t.which)?i:t.keyCode,this.search_field_scale(),8!==e&&this.pending_backstroke&&this.clear_backstroke(),e){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(t),this.mouse_on_container=!1;break;case 13:t.preventDefault();break;case 38:t.preventDefault(),this.keyup_arrow();break;case 40:t.preventDefault(),this.keydown_arrow()}},i.prototype.search_field_scale=function(){var e,i,n,o,a,s,r,l,h;if(this.is_multiple){for(n=0,r=0,a="position:absolute; left: -1000px; top: -1000px; display:none;",s=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],l=0,h=s.length;l",{style:a}),e.text(this.search_field.val()),t("body").append(e),r=e.width()+25,e.remove(),i=this.container.outerWidth(),r>i-10&&(r=i-10),this.search_field.css({width:r+"px"})}},i}(e),i.DEFAULTS=l,i.LANGUAGES=r,t.fn.chosen.Constructor=i}.call(this),function(t){"use strict";var e="zui.selectable",i=function(i,n){this.name=e,this.$=t(i),this.id=t.zui.uuid(),this.selectOrder=1,this.selections={},this.getOptions(n),this._init()},n=function(t,e,i){return t>=i.left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height},o=function(t,e){var i=Math.max(t.left,e.left),o=Math.max(t.top,e.top),a=Math.min(t.left+t.width,e.left+e.width),s=Math.min(t.top+t.height,e.top+e.height);return n(i,o,t)&&n(a,s,t)&&n(i,o,e)&&n(a,s,e)};i.DEFAULTS={selector:"li,tr,div",trigger:"",selectClass:"active",rangeStyle:{border:"1px solid "+(t.zui.colorset?t.zui.colorset.primary:"#3280fc"),backgroundColor:t.zui.colorset?new t.zui.Color(t.zui.colorset.primary).fade(20).toCssStr():"rgba(50, 128, 252, 0.2)"},clickBehavior:"toggle",ignoreVal:3,listenClick:!0},i.prototype.getOptions=function(e){this.options=t.extend({},i.DEFAULTS,this.$.data(),e)},i.prototype.select=function(t){this.toggle(t,!0)},i.prototype.unselect=function(t){this.toggle(t,!1)},i.prototype.toggle=function(e,i,n){var o,a,s=this.options.selector,r=this;if(void 0===e)return void this.$.find(s).each(function(){r.toggle(this,i)});if("object"==typeof e?(o=t(e).closest(s),a=o.data("id")):(a=e,o=r.$.find('.slectable-item[data-id="'+a+'"]')),o&&o.length){if(a||(a=t.zui.uuid(),o.attr("data-id",a)),void 0!==i&&null!==i||(i=!r.selections[a]),!!i!=!!r.selections[a]){var l;"function"==typeof n&&(l=n(i)),l!==!0&&(r.selections[a]=!!i&&r.selectOrder++,r.callEvent(i?"select":"unselect",{id:a,selections:r.selections,target:o, -selected:r.getSelectedArray()},r))}r.options.selectClass&&o.toggleClass(r.options.selectClass,i)}},i.prototype.getSelectedArray=function(){var e=[];return t.each(this.selections,function(t,i){i&&e.push(t)}),e},i.prototype.syncSelectionsFromClass=function(){var e=this,i=e.$children=e.$.find(e.options.selector);e.selections={},i.each(function(){var i=t(this);e.selections[i.data("id")]=i.hasClass(e.options.selectClass)})},i.prototype._init=function(){var e,i,n,a,s,r,l,h=this.options,c=this,d=h.ignoreVal,u=!0,f="."+this.name+"."+this.id,p="function"==typeof h.checkFunc?h.checkFunc:null,g="function"==typeof h.rangeFunc?h.rangeFunc:null,m=!1,v=null,y="mousedown"+f,b=function(){a&&c.$children.each(function(){var e=t(this),i=e.offset();i.width=e.outerWidth(),i.height=e.outerHeight();var n=g?g.call(this,a,i):o(a,i);if(p){var s=p.call(c,{intersect:n,target:e,range:a,targetRange:i});s===!0?c.select(e):s===!1&&c.unselect(e)}else n?c.select(e):c.multiKey||c.unselect(e)})},w=function(o){m&&(s=o.pageX,r=o.pageY,a={width:Math.abs(s-e),height:Math.abs(r-i),left:s>e?e:s,top:r>i?i:r},u&&a.width
        ').css(t.extend({zIndex:1060,position:"absolute",top:e,left:i,pointerEvents:"none"},c.options.rangeStyle)).appendTo(t("body")))),n.css(a),clearTimeout(l),l=setTimeout(b,10),u=!1))},x=function(e){t(document).off(f),clearTimeout(v),m&&(m=!1,n&&n.remove(),u||a&&(clearTimeout(l),b(),a=null),c.callEvent("finish",{selections:c.selections,selected:c.getSelectedArray()}),e.preventDefault())},C=function(o){if(m)return x(o);var a=t.zui.getMouseButtonCode(h.mouseButton);if(!(a>-1&&o.button!==a||c.altKey||3===o.which||c.callEvent("start",o)===!1)){var s=c.$children=c.$.find(h.selector);s.addClass("slectable-item");var r=c.multiKey?"multi":h.clickBehavior;if("single"===r&&c.unselect(),h.listenClick&&("multi"===r?c.toggle(o.target):"single"===r?c.select(o.target):"toggle"===r&&c.toggle(o.target,null,function(t){c.unselect()})),c.callEvent("startDrag",o)===!1)return void c.callEvent("finish",{selections:c.selections,selected:c.getSelectedArray()});e=o.pageX,i=o.pageY,n=null,u=!0,m=!0,t(document).on("mousemove"+f,w).on("mouseup"+f,x),v=setTimeout(function(){t(document).on(y,x)},10),o.preventDefault()}},_=h.container&&"default"!==h.container?t(h.container):this.$;h.trigger?_.on(y,h.trigger,C):_.on(y,C),t(document).on("keydown",function(t){var e=t.keyCode;17===e||91==e?c.multiKey=e:18===e&&(c.altKey=!0)}).on("keyup",function(t){c.multiKey=!1,c.altKey=!1})},i.prototype.callEvent=function(e,i){var n=t.Event(e+"."+this.name);this.$.trigger(n,i);var o=n.result,a=this.options[e];return"function"==typeof a&&(o=a.apply(this,Array.isArray(i)?i:[i])),o},t.fn.selectable=function(n){return this.each(function(){var o=t(this),a=o.data(e),s="object"==typeof n&&n;a||o.data(e,a=new i(this,s)),"string"==typeof n&&a[n]()})},t.fn.selectable.Constructor=i,t(function(){t('[data-ride="selectable"]').selectable()})}(jQuery),+function(t,e,i){"use strict";if(!t.fn.droppable)return void console.error("Sortable requires droppable.js");var n="zui.sortable",o={selector:"li,div",dragCssClass:"invisible",sortingClass:"sortable-sorting"},a="order",s=function(e,i){var n=this;n.$=t(e),n.options=t.extend({},o,n.$.data(),i),n.init()};s.DEFAULTS=o,s.NAME=n,s.prototype.init=function(){var e,i=this,n=i.$,o=i.options,s=o.selector,r=o.containerSelector,l=o.sortingClass,h=o.dragCssClass,c=o.targetSelector,d=o.reverse,u=function(e){e=e||i.getItems(1);var n=e.length;n&&e.each(function(e){var i=d?n-e:e;t(this).attr("data-"+a,i).data(a,i)})};u(),n.droppable({handle:o.trigger,target:c?c:r?s+","+r:s,selector:s,container:n,always:o.always,flex:!0,lazy:o.lazy,canMoveHere:o.canMoveHere,dropToClass:o.dropToClass,before:o.before,nested:!!r,mouseButton:o.mouseButton,stopPropagation:o.stopPropagation,start:function(t){h&&t.element.addClass(h),e=!1,i.trigger("start",t)},drag:function(t){if(n.addClass(l),t.isIn){var o=t.element,h=t.target,c=r&&h.is(r);if(c){if(!h.children(s).filter(".dragging").length){h.append(o);var f=i.getItems(1);u(f),i.trigger(a,{list:f,element:o})}return}var p=o.data(a),g=h.data(a);if(p===g)return u(f);p>g?h[d?"after":"before"](o):h[d?"before":"after"](o),e=!0;var f=i.getItems(1);u(f),i.trigger(a,{list:f,element:o})}},finish:function(t){h&&t.element&&t.element.removeClass(h),n.removeClass(l),i.trigger("finish",{list:i.getItems(),element:t.element,changed:e})}})},s.prototype.destroy=function(){this.$.droppable("destroy"),this.$.data(n,null)},s.prototype.reset=function(){this.destroy(),this.init()},s.prototype.getItems=function(e){var i=this.$.find(this.options.selector).not(".drag-shadow");return e?i:i.map(function(){var e=t(this);return{item:e,order:e.data("order")}})},s.prototype.trigger=function(e,i){return t.zui.callEvent(this.options[e],i,this)},t.fn.sortable=function(e){return this.each(function(){var i=t(this),o=i.data(n),a="object"==typeof e&&e;o?"object"==typeof e&&o.reset():i.data(n,o=new s(this,a)),"string"==typeof e&&o[e]()})},t.fn.sortable.Constructor=s}(jQuery,window,document),function(t,e){"use strict";var i="zui.contextmenu",n={animation:"fade",menuTemplate:'',toggleTrigger:!1,duration:200,limitInsideWindow:!0},o=!1,a={},s="zui-contextmenu-"+t.zui.uuid(),r=0,l=0,h=function(){return t(document).off("mousemove."+i).on("mousemove."+i,function(t){r=t.clientX,l=t.clientY}),a},c=function(e,i){if("string"==typeof e&&(e="seperator"===e||"divider"===e||"-"===e||"|"===e?{type:"seperator"}:{label:e,id:i}),"seperator"===e.type||"divider"===e.type)return t('
      • ');var n=t("
        ").attr({href:e.url||"###","class":e.className,style:e.style}).data("item",e);return e.html?e.html===!0?n.html(e.label||e.text):n=t(e.html):n.text(e.label||e.text),e.onClick&&n.on("click",e.onClick),t("
      • ").toggleClass("disabled",e.disabled===!0).append(n)},d=function(e){var i=t("#"+s);return i.length&&i.hasClass("contextmenu-show")&&(!e||(i.data("options")||{}).id===e)},u=null,f=function(e,i){"function"==typeof e&&(i=e,e=null),u&&(clearTimeout(u),u=null);var n=t("#"+s);if(n.length){var o=n.removeClass("contextmenu-show").data("options");if(!e||o.id===e){var r=function(){n.find(".contextmenu-menu").removeClass("open"),o.onHidden&&o.onHidden(),i&&i()};o.onHide&&o.onHide();var l=o.animation;n.find(".contextmenu-menu").removeClass("in"),l?u=setTimeout(r,o.duration):r()}}return a},p=function(h,d,p){t.isPlainObject(h)&&(p=d,d=h,h=d.items),o=!0,d=t.extend({},n,d);var g=t("#"+s);g.length||(g=t('
        ').appendTo("body"));var m=g.find(".contextmenu-menu").off("click."+i).on("click."+i,"a,.contextmenu-item",function(e){var i=t(this),n=d.onClickItem&&d.onClickItem(i.data("item"),i,e,d);n!==!1&&f()}).empty();m.attr("class","contextmenu-menu"+(d.className?" "+d.className:"")),g.attr("class","contextmenu contextmenu-show");var v=d.menuCreator;if(v)m.append(v(h,d));else{m.append(d.menuTemplate);var y=m.children().first(),b=d.itemCreator||c,w=typeof h;if("string"===w?h=h.split(","):"function"===w&&(h=h(d)),!h)return!1;t.each(h,function(t,e){y.append(b(e,t,d))})}var x=d.animation,C=d.duration;x===!0&&(d.animation=x="fade"),u&&(clearTimeout(u),u=null);var _=function(){m.addClass("in"),d.onShown&&d.onShown(),p&&p()};d.onShow&&d.onShow(),g.data("options",{animation:x,onHide:d.onHide,onHidden:d.onHidden,id:d.id,duration:C});var k=d.x,T=d.y;k===e&&(k=(d.event||d).clientX),k===e&&(k=r),T===e&&(T=(d.event||d).clientY),T===e&&(T=l);var y=m.children().first(),S=y.outerWidth(),D=y.outerHeight();if(d.position){var M=d.position({x:k,y:T,width:S,height:D},d,m);M&&(k=M.x,T=M.y)}if(d.limitInsideWindow){var P=t(window);k=Math.max(0,Math.min(k,P.width()-S)),T=Math.max(0,Math.min(T,P.height()-D))}return g.css({left:k,top:T}).show(),m.addClass("open"),x?(m.addClass(x),u=setTimeout(function(){_(),o=!1},10)):(_(),o=!1),a};t.extend(a,{NAME:i,DEFAULTS:n,show:p,hide:f,listenMouse:h,isShow:d}),t.zui({ContextMenu:a});var g=function(e,n){var o=this;o.name=i,o.$=t(e),o.id=t.zui.uuid(),n=o.options=t.extend({trigger:"contextmenu"},a.DEFAULTS,this.$.data(),n);var s=function(t){if("mousedown"!==t.type||2===t.button){if(n.toggleTrigger&&o.isShow())o.hide();else{var e={x:t.clientX,y:t.clientY,event:t};if(o.show(e)===!1)return}return t.preventDefault(),t.returnValue=!1,!1}},r=n.trigger,l=r+"."+i;n.selector?o.$.on(l,n.selector,s):o.$.on(l,s),n.show&&o.show("object"==typeof n.show?n.show:null)};g.prototype.destory=function(){that.$.off("."+i)},g.prototype.hide=function(t){return a.hide(this.id,t)},g.prototype.show=function(e,i){return e=t.extend({id:this.id,$toggle:this.$},this.options,e),a.show(e,i)},g.prototype.isShow=function(){return d(this.id)},t.fn.contextmenu=function(e){return this.each(function(){var n=t(this),o=n.data(i),a="object"==typeof e&&e;o||n.data(i,o=new g(this,a)),"string"==typeof e&&o[e]()})},t.fn.contextmenu.Constructor=g,t.fn.contextDropdown=function(e){t(this).contextmenu(t.extend({trigger:"click",animation:"fade",toggleTrigger:!0,menuCreator:function(e,i){var n=i.$toggle,o=n.attr("data-target");o||(o=n.attr("href"),o=o&&/#/.test(o)&&o.replace(/.*(?=#[^\s]*$)/,""));var a=o?t(o):n.next(".dropdown-menu"),s=i.transferEvent;if(s!==!1){var r="data-contextmenu-index";a.find("a,.contextmenu-item").each(function(e){t(this).attr(r,e)});var l=a.clone();return l.on("string"==typeof s?s:"click","a,.contextmenu-item",function(e){var i=a.find("["+r+'="'+t(this).attr(r)+'"]'),n=i[0];if(n)return n[e.type]?n[e.type]():i.trigger(e.type),e.preventDefault(),e.stopPropagation(),!1}),l}return a.clone()},position:function(t,e,i){var n=e.placement,o=e.$toggle;if(!n){var a=i.find(".dropdown-menu"),s=a.hasClass("pull-right"),r=o.parent().hasClass("dropup");n=s?r?"top-right":"bottom-right":r?"top-left":"bottom-left",s&&a.removeClass("pull-right")}var l=o[0].getBoundingClientRect();switch(n){case"top-left":return{x:l.left,y:Math.floor(l.top-t.height)};case"top-right":return{x:Math.floor(l.right-t.width),y:Math.floor(l.top-t.height)};case"bottom-left":return{x:l.left,y:l.bottom};case"bottom-right":return{x:Math.floor(l.right-t.width),y:l.bottom}}return t}},e))},t(document).on("click",function(e){var n=t(e.target),a=n.closest('[data-toggle="context-dropdown"]');if(a.length){var s=a.data(i);s||a.contextDropdown({show:!0})}else o||n.closest(".contextmenu").length||f()})}(jQuery,void 0),/*! + function () { + var t, e, i, n, o, a = {}.hasOwnProperty, s = function (t, e) { + function i() { + this.constructor = t + } + + for (var n in e) a.call(e, n) && (t[n] = e[n]); + return i.prototype = e.prototype, t.prototype = new i, t.__super__ = e.prototype, t + }, r = { + zh_cn: {no_results_text: "没有找到"}, + zh_tw: {no_results_text: "沒有找到"}, + en: {no_results_text: "No results match"} + }, l = {}; + n = function () { + function e() { + this.options_index = 0, this.parsed = [] + } + + return e.prototype.add_node = function (t) { + return "OPTGROUP" === t.nodeName.toUpperCase() ? this.add_group(t) : this.add_option(t) + }, e.prototype.add_group = function (e) { + var i, n, o, a, s, r; + for (i = this.parsed.length, this.parsed.push({ + array_index: i, + group: !0, + label: this.escapeExpression(e.label), + children: 0, + disabled: e.disabled, + title: e.title, + search_keys: t.trim(e.getAttribute("data-keys") || "").replace(/,/g, " ") + }), s = e.childNodes, r = [], o = 0, a = s.length; o < a; o++) n = s[o], r.push(this.add_option(n, i, e.disabled)); + return r + }, e.prototype.add_option = function (e, i, n) { + if ("OPTION" === e.nodeName.toUpperCase()) return "" !== e.text ? (null != i && (this.parsed[i].children += 1), this.parsed.push({ + array_index: this.parsed.length, + options_index: this.options_index, + value: e.value, + text: e.text, + title: e.title, + html: e.innerHTML, + selected: e.selected, + disabled: n === !0 ? n : e.disabled, + group_array_index: i, + classes: e.className, + style: e.style.cssText, + data: e.getAttribute("data-data"), + search_keys: (t.trim(e.getAttribute("data-keys") || "") + e.value).replace(/,/, " ") + })) : this.parsed.push({ + array_index: this.parsed.length, + options_index: this.options_index, + empty: !0 + }), this.options_index += 1 + }, e.prototype.escapeExpression = function (t) { + var e, i; + return null == t || t === !1 ? "" : /[\&\<\>\"\'\`]/.test(t) ? (e = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }, i = /&(?!\w+;)|[\<\>\"\'\`]/g, t.replace(i, function (t) { + return e[t] || "&" + })) : t + }, e + }(), n.select_to_array = function (t) { + var e, i, o, a, s; + for (i = new n, s = t.childNodes, o = 0, a = s.length; o < a; o++) e = s[o], i.add_node(e); + return i.parsed + }, e = function () { + function e(i, n) { + if (this.form_field = i, this.options = t.extend({}, l, null != n ? n : {}), e.browser_is_supported()) { + var o = this.options.lang || t.zui.clientLang ? t.zui.clientLang() : "en", + a = t.zui.clientLang ? t.zui.clientLang() : "en"; + t.isPlainObject(o) ? this.lang = t.zui.getLangData ? t.zui.getLangData("chosen", a, r) : t.extend(o, r.en, r[a]) : this.lang = t.zui.getLangData ? t.zui.getLangData("chosen", o, r) : r[o || a] || r.en, this.is_multiple = this.form_field.multiple, this.set_default_text(), this.set_default_values(), this.setup(), this.set_up_html(), this.register_observers() + } + } + + return e.prototype.set_default_values = function () { + var t = this, e = t.options; + t.click_test_action = function (e) { + return t.test_active_click(e) + }, t.activate_action = function (e) { + return t.activate_field(e) + }, t.active_field = !1, t.mouse_on_container = !1, t.results_showing = !1, t.result_highlighted = null, t.allow_single_deselect = null != e.allow_single_deselect && null != this.form_field.options[0] && "" === t.form_field.options[0].text && e.allow_single_deselect, t.disable_search_threshold = e.disable_search_threshold || 0, t.disable_search = e.disable_search || !1, t.enable_split_word_search = null == e.enable_split_word_search || e.enable_split_word_search, t.group_search = null == e.group_search || e.group_search, t.search_contains = e.search_contains || !1, t.single_backstroke_delete = null == e.single_backstroke_delete || e.single_backstroke_delete, t.max_selected_options = e.max_selected_options || 1 / 0, t.drop_direction = e.drop_direction || "auto", t.drop_item_height = void 0 !== e.drop_item_height ? e.drop_item_height : 25, t.max_drop_height = void 0 !== e.max_drop_height ? e.max_drop_height : 240, t.middle_highlight = e.middle_highlight, t.compact_search = e.compact_search || !1, t.inherit_select_classes = e.inherit_select_classes || !1, t.display_selected_options = null == e.display_selected_options || e.display_selected_options, t.sort_value_splitter = e.sort_value_spliter || e.sort_value_splitter || ",", t.sort_field = e.sort_field; + var i = e.max_drop_width; + return "string" == typeof i && i.indexOf("px") === i.length - 2 && (i = parseInt(i.substring(0, i.length - 2))), t.max_drop_width = i, t.display_disabled_options = null == e.display_disabled_options || e.display_disabled_options + }, e.prototype.set_default_text = function () { + return this.form_field.getAttribute("data-placeholder") ? this.default_text = this.form_field.getAttribute("data-placeholder") : this.is_multiple ? this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || e.default_multiple_text : this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || e.default_single_text, this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || this.lang.no_results_text || e.default_no_result_text + }, e.prototype.mouse_enter = function () { + return this.mouse_on_container = !0 + }, e.prototype.mouse_leave = function () { + return this.mouse_on_container = !1 + }, e.prototype.input_focus = function (t) { + var e = this; + if (this.is_multiple) { + if (!this.active_field) return setTimeout(function () { + return e.container_mousedown() + }, 50) + } else if (!this.active_field) return this.activate_field() + }, e.prototype.input_blur = function (t) { + var e = this; + if (!this.mouse_on_container) return this.active_field = !1, setTimeout(function () { + return e.blur_test() + }, 100) + }, e.prototype.results_option_build = function (e) { + var i, n, o, a, s; + i = "", s = this.results_data; + var r = e && e.first ? [] : null; + for (o = 0, a = s.length; o < a; o++) n = s[o], i += n.group ? this.result_add_group(n) : this.result_add_option(n), r && n.selected && r.push(n); + if (r) { + var l, h; + if (this.sort_field && this.is_multiple) { + l = t(this.sort_field); + var c = l.val(); + if (h = "string" == typeof c && c.length ? c.split(this.sort_value_splitter) : [], h.length) { + var d = {}; + for (o = 0; o < h.length; ++o) d[h[o]] = o; + r.sort(function (t, e) { + var i = d[t.value], n = d[e.value]; + return void 0 === i && (i = 0), void 0 === n && (n = 0), i - n + }) + } + } + for (h = [], o = 0; o < r.length; ++o) n = r[o], this.is_multiple ? (this.choice_build(n), h.push(n.value)) : this.single_set_selected_text(n.text); + l && l.length && l.val(h.join(this.sort_value_splitter)) + } + return i + }, e.prototype.result_add_option = function (t) { + var e, i; + return t.search_match && this.include_option_in_results(t) ? (e = [], t.disabled || t.selected && this.is_multiple || e.push("active-result"), !t.disabled || t.selected && this.is_multiple || e.push("disabled-result"), t.selected && e.push("result-selected"), null != t.group_array_index && e.push("group-option"), "" !== t.classes && e.push(t.classes), i = document.createElement("li"), i.className = e.join(" "), i.style.cssText = t.style, i.title = t.title, i.setAttribute("data-option-array-index", t.array_index), i.setAttribute("data-data", t.data), i.innerHTML = t.search_text, this.outerHTML(i)) : "" + }, e.prototype.result_add_group = function (t) { + var e; + return (t.search_match || t.group_match) && t.active_options > 0 ? (e = document.createElement("li"), e.className = "group-result", e.title = t.title, e.innerHTML = t.search_text, this.outerHTML(e)) : "" + }, e.prototype.results_update_field = function () { + this.set_default_text(), this.is_multiple || this.results_reset_cleanup(), this.result_clear_highlight(), this.results_build(), this.results_showing && (this.winnow_results(), this.autoResizeDrop()) + }, e.prototype.reset_single_select_options = function () { + var t, e, i, n, o; + for (n = this.results_data, o = [], e = 0, i = n.length; e < i; e++) t = n[e], t.selected ? o.push(t.selected = !1) : o.push(void 0); + return o + }, e.prototype.results_toggle = function () { + return this.results_showing ? this.results_hide() : this.results_show() + }, e.prototype.results_search = function (t) { + return this.results_showing ? this.winnow_results(1) : this.results_show() + }, e.prototype.winnow_results = function (t) { + var e, i, n, o, a, s, r, l, h, c, d, u, f; + for (this.no_results_clear(), a = 0, r = this.get_search_text(), e = r.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), o = this.search_contains ? "" : "^", n = new RegExp(o + e, "i"), c = new RegExp(e, "i"), f = this.results_data, d = 0, u = f.length; d < u; d++) i = f[d], i.search_match = !1, s = null, this.include_option_in_results(i) && (i.group && (i.group_match = !1, i.active_options = 0), null != i.group_array_index && this.results_data[i.group_array_index] && (s = this.results_data[i.group_array_index], 0 === s.active_options && s.search_match && (a += 1), s.active_options += 1), i.group && !this.group_search || (i.search_text = i.group ? i.label : i.html, i.search_keys_match = this.search_string_match(i.search_keys, n), i.search_text_match = this.search_string_match(i.search_text, n), i.search_match = i.search_text_match || i.search_keys_match, i.search_match && !i.group && (a += 1), i.search_match ? (i.search_text_match && i.search_text.length ? (l = i.search_text.search(c), h = i.search_text.substr(0, l + r.length) + "
        " + i.search_text.substr(l + r.length), i.search_text = h.substr(0, l) + "" + h.substr(l)) : i.search_keys_match && i.search_keys.length && (l = i.search_keys.search(c), h = i.search_keys.substr(0, l + r.length) + "" + i.search_keys.substr(l + r.length), i.search_text += '  ' + h.substr(0, l) + "" + h.substr(l) + ""), null != s && (s.group_match = !0)) : null != i.group_array_index && this.results_data[i.group_array_index].search_match && (i.search_match = !0))); + return this.result_clear_highlight(), a < 1 && r.length ? (this.update_results_content(""), this.no_results(r)) : (this.update_results_content(this.results_option_build()), this.winnow_results_set_highlight(t)) + }, e.prototype.search_string_match = function (t, e) { + var i, n, o, a; + if (e.test(t)) return !0; + if (this.enable_split_word_search && (t.indexOf(" ") >= 0 || 0 === t.indexOf("[")) && (n = t.replace(/\[|\]/g, "").split(" "), n.length)) for (o = 0, a = n.length; o < a; o++) if (i = n[o], e.test(i)) return !0 + }, e.prototype.choices_count = function () { + var t, e, i, n; + if (null != this.selected_option_count) return this.selected_option_count; + for (this.selected_option_count = 0, n = this.form_field.options, e = 0, i = n.length; e < i; e++) t = n[e], t.selected && "" != t.value && (this.selected_option_count += 1); + return this.selected_option_count + }, e.prototype.choices_click = function (t) { + if (t.preventDefault(), !this.results_showing && !this.is_disabled) return this.results_show() + }, e.prototype.keyup_checker = function (t) { + var e, i; + switch (e = null != (i = t.which) ? i : t.keyCode, this.search_field_scale(), e) { + case 8: + if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) return this.keydown_backstroke(); + if (!this.pending_backstroke) return this.result_clear_highlight(), this.results_search(); + break; + case 13: + if (t.preventDefault(), this.results_showing) return this.result_select(t); + break; + case 27: + return this.results_showing && this.results_hide(), !0; + case 9: + case 38: + case 40: + case 16: + case 91: + case 17: + break; + default: + return this.results_search() + } + }, e.prototype.clipboard_event_checker = function (t) { + var e = this; + return setTimeout(function () { + return e.results_search() + }, 50) + }, e.prototype.container_width = function () { + return null != this.options.width ? this.options.width : this.form_field && this.form_field.classList && this.form_field.classList.contains("form-control") ? "100%" : "" + this.form_field.offsetWidth + "px" + }, e.prototype.include_option_in_results = function (t) { + return !(this.is_multiple && !this.display_selected_options && t.selected) && (!(!this.display_disabled_options && t.disabled) && !t.empty) + }, e.prototype.search_results_touchstart = function (t) { + return this.touch_started = !0, this.search_results_mouseover(t) + }, e.prototype.search_results_touchmove = function (t) { + return this.touch_started = !1, this.search_results_mouseout(t) + }, e.prototype.search_results_touchend = function (t) { + if (this.touch_started) return this.search_results_mouseup(t) + }, e.prototype.outerHTML = function (t) { + var e; + return t.outerHTML ? t.outerHTML : (e = document.createElement("div"), e.appendChild(t), e.innerHTML) + }, e.browser_is_supported = function () { + return "Microsoft Internet Explorer" === window.navigator.appName ? document.documentMode >= 8 : !/iP(od|hone)/i.test(window.navigator.userAgent) && (!/Android/i.test(window.navigator.userAgent) || !/Mobile/i.test(window.navigator.userAgent)) + }, e.default_multiple_text = "", e.default_single_text = "", e.default_no_result_text = "No results match", e + }(), t = jQuery, t.fn.extend({ + chosen: function (n) { + return e.browser_is_supported() ? this.each(function (e) { + var o = t(this), a = o.data("chosen"); + "destroy" === n && a ? a.destroy() : a || o.data("chosen", new i(this, t.extend({}, o.data(), n))) + }) : this + } + }), i = function (e) { + function i() { + return o = i.__super__.constructor.apply(this, arguments) + } + + return s(i, e), i.prototype.setup = function () { + return this.form_field_jq = t(this.form_field), this.current_selectedIndex = this.form_field.selectedIndex, this.is_rtl = this.form_field_jq.hasClass("chosen-rtl") + }, i.prototype.set_up_html = function () { + var e, i; + e = ["chosen-container"], e.push("chosen-container-" + (this.is_multiple ? "multi" : "single")), this.inherit_select_classes && this.form_field.className && e.push(this.form_field.className), this.is_rtl && e.push("chosen-rtl"); + var n = this.form_field.getAttribute("data-css-class"); + return n && e.push(n), i = { + "class": e.join(" "), + style: "width: " + this.container_width() + ";", + title: this.form_field.title + }, this.form_field.id.length && (i.id = this.form_field.id.replace(/[^\w]/g, "_") + "_chosen"), this.container = t("
        ", i), this.is_multiple ? this.container.html('
          ') : (this.container.html('
          ' + this.default_text + '
            '), this.compact_search ? this.container.addClass("chosen-compact").find(".chosen-search").appendTo(this.container.find(".chosen-single")) : this.container.find(".chosen-search").prependTo(this.container.find(".chosen-drop")), this.options.highlight_selected !== !1 && this.container.addClass("chosen-highlight-selected")), this.form_field_jq.hide().after(this.container), this.dropdown = this.container.find("div.chosen-drop").first(), this.search_field = this.container.find("input").first(), this.search_results = this.container.find("ul.chosen-results").first(), this.search_field_scale(), this.search_no_results = this.container.find("li.no-results").first(), this.is_multiple ? (this.search_choices = this.container.find("ul.chosen-choices").first(), this.search_container = this.container.find("li.search-field").first()) : (this.search_container = this.container.find("div.chosen-search").first(), this.selected_item = this.container.find(".chosen-single").first()), this.options.drop_width && this.dropdown.css("width", this.options.drop_width).addClass("chosen-drop-size-limited"), this.max_drop_width && this.dropdown.addClass("chosen-auto-max-width"), this.options.no_wrap && this.dropdown.addClass("chosen-no-wrap"), this.results_build(), this.set_tab_index(), this.set_label_behavior(), this.form_field_jq.trigger("chosen:ready", {chosen: this}) + }, i.prototype.register_observers = function () { + var t = this; + return this.container.bind("mousedown.chosen", function (e) { + t.container_mousedown(e) + }), this.container.bind("mouseup.chosen", function (e) { + t.container_mouseup(e) + }), this.container.bind("mouseenter.chosen", function (e) { + t.mouse_enter(e) + }), this.container.bind("mouseleave.chosen", function (e) { + t.mouse_leave(e) + }), this.search_results.bind("mouseup.chosen", function (e) { + t.search_results_mouseup(e) + }), this.search_results.bind("mouseover.chosen", function (e) { + t.search_results_mouseover(e) + }), this.search_results.bind("mouseout.chosen", function (e) { + t.search_results_mouseout(e) + }), this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen", function (e) { + t.search_results_mousewheel(e) + }), this.search_results.bind("touchstart.chosen", function (e) { + t.search_results_touchstart(e) + }), this.search_results.bind("touchmove.chosen", function (e) { + t.search_results_touchmove(e) + }), this.search_results.bind("touchend.chosen", function (e) { + t.search_results_touchend(e) + }), this.form_field_jq.bind("chosen:updated.chosen", function (e) { + t.results_update_field(e) + }), this.form_field_jq.bind("chosen:activate.chosen", function (e) { + t.activate_field(e) + }), this.form_field_jq.bind("chosen:open.chosen", function (e) { + t.container_mousedown(e) + }), this.form_field_jq.bind("chosen:close.chosen", function (e) { + t.input_blur(e) + }), this.search_field.bind("blur.chosen", function (e) { + t.input_blur(e) + }), this.search_field.bind("keyup.chosen", function (e) { + t.keyup_checker(e) + }), this.search_field.bind("keydown.chosen", function (e) { + t.keydown_checker(e) + }), this.search_field.bind("focus.chosen", function (e) { + t.input_focus(e) + }), this.search_field.bind("cut.chosen", function (e) { + t.clipboard_event_checker(e) + }), this.search_field.bind("paste.chosen", function (e) { + t.clipboard_event_checker(e) + }), this.is_multiple ? this.search_choices.bind("click.chosen", function (e) { + t.choices_click(e) + }) : this.container.bind("click.chosen", function (t) { + t.preventDefault() + }) + }, i.prototype.destroy = function () { + return t(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action), this.search_field[0].tabIndex && (this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex), this.container.remove(), this.form_field_jq.removeData("chosen"), this.form_field_jq.show() + }, i.prototype.search_field_disabled = function () { + return this.is_disabled = this.form_field_jq[0].disabled, this.is_disabled ? (this.container.addClass("chosen-disabled"), this.search_field[0].disabled = !0, this.is_multiple || this.selected_item.unbind("focus.chosen", this.activate_action), this.close_field()) : (this.container.removeClass("chosen-disabled"), this.search_field[0].disabled = !1, this.is_multiple ? void 0 : this.selected_item.bind("focus.chosen", this.activate_action)) + }, i.prototype.container_mousedown = function (e) { + if (!this.is_disabled && (e && "mousedown" === e.type && !this.results_showing && e.preventDefault(), null == e || !t(e.target).hasClass("search-choice-close"))) return this.active_field ? this.is_multiple || !e || t(e.target)[0] !== this.selected_item[0] && !t(e.target).parents("a.chosen-single").length || (e.preventDefault(), this.results_toggle()) : (this.is_multiple && this.search_field.val(""), t(this.container[0].ownerDocument).bind("click.chosen", this.click_test_action), this.results_show()), this.activate_field() + }, i.prototype.container_mouseup = function (t) { + if ("ABBR" === t.target.nodeName && !this.is_disabled) return this.results_reset(t) + }, i.prototype.search_results_mousewheel = function (t) { + var e; + if (t.originalEvent && (e = -t.originalEvent.wheelDelta || t.originalEvent.detail), null != e) return t.preventDefault(), "DOMMouseScroll" === t.type && (e = 40 * e), this.search_results.scrollTop(e + this.search_results.scrollTop()) + }, i.prototype.blur_test = function (t) { + if (!this.active_field && this.container.hasClass("chosen-container-active")) return this.close_field() + }, i.prototype.close_field = function () { + return t(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action), this.active_field = !1, this.results_hide(), this.container.removeClass("chosen-container-active"), this.clear_backstroke(), this.show_search_field_default(), this.search_field_scale() + }, i.prototype.activate_field = function () { + return this.container.addClass("chosen-container-active"), this.active_field = !0, this.search_field.val(this.search_field.val()), this.search_field.focus() + }, i.prototype.test_active_click = function (e) { + var i; + return i = t(e.target).closest(".chosen-container"), i.length && this.container[0] === i[0] ? this.active_field = !0 : this.close_field() + }, i.prototype.results_build = function () { + return this.parsing = !0, this.selected_option_count = null, this.results_data = n.select_to_array(this.form_field), this.is_multiple ? this.search_choices.find("li.search-choice").remove() : this.is_multiple || (this.single_set_selected_text(), this.disable_search || this.form_field.options.length <= this.disable_search_threshold ? (this.search_field[0].readOnly = !0, this.container.addClass("chosen-container-single-nosearch"), this.container.removeClass("chosen-with-search")) : (this.search_field[0].readOnly = !1, this.container.removeClass("chosen-container-single-nosearch"), this.container.addClass("chosen-with-search"))), this.update_results_content(this.results_option_build({first: !0})), this.search_field_disabled(), this.show_search_field_default(), this.search_field_scale(), this.parsing = !1 + }, i.prototype.result_do_highlight = function (t, e) { + if (t.length) { + var i, n, o, a, s, r, l = -1; + this.result_clear_highlight(), this.result_highlight = t, this.result_highlight.addClass("highlighted"), o = parseInt(this.search_results.css("maxHeight"), 10), r = this.result_highlight.outerHeight(), s = this.search_results.scrollTop(), a = o + s, n = this.result_highlight.position().top + this.search_results.scrollTop(), i = n + r, this.middle_highlight && (e || "always" === this.middle_highlight) ? l = Math.min(n - r, Math.max(0, n - (o - r) / 2)) : i >= a ? l = i - o > 0 ? i - o : 0 : n < s && (l = n), l > -1 ? this.search_results.scrollTop(l) : this.result_highlight.scrollIntoView && this.result_highlight.scrollIntoView() + } + }, i.prototype.result_clear_highlight = function () { + return this.result_highlight && this.result_highlight.removeClass("highlighted"), this.result_highlight = null + }, i.prototype.results_show = function () { + var e = this; + if (e.is_multiple && e.max_selected_options <= e.choices_count()) return e.form_field_jq.trigger("chosen:maxselected", {chosen: this}), !1; + e.results_showing = !0, e.search_field.focus(), e.search_field.val(e.search_field.val()), e.container.addClass("chosen-with-drop"), e.winnow_results(1); + var i = e.drop_direction; + if ("function" == typeof i && (i = i.call(this)), "auto" === i) if (e.drop_directionFixed) i = e.drop_directionFixed; else { + var n = e.container.find(".chosen-drop"), o = n.outerHeight(); + e.drop_item_height && o < e.max_drop_height && (o = Math.min(e.max_drop_height, n.find(".chosen-results>.active-result").length * e.drop_item_height)); + var a = e.container.offset(); + a.top + o + 30 > t(window).height() + t(window).scrollTop() && (i = "up"), e.drop_directionFixed = i + } + return e.container.toggleClass("chosen-up", "up" === i), e.autoResizeDrop(), e.form_field_jq.trigger("chosen:showing_dropdown", {chosen: e}) + }, i.prototype.autoResizeDrop = function () { + var e = this, i = e.max_drop_width; + if (i) { + var n = e.container.find(".chosen-drop"); + n.removeClass("in"); + var o = 0, a = n.find(".chosen-results"), s = a.children("li"), + r = parseFloat(a.css("padding-left").replace("px", "")), + l = parseFloat(a.css("padding-right").replace("px", "")), + h = (isNaN(r) ? 0 : r) + (isNaN(l) ? 0 : l); + s.each(function () { + o = Math.max(o, t(this).outerWidth()) + }), n.css("width", Math.min(o + h + 20, i)), e.fixDropWidthTimer = setTimeout(function () { + e.fixDropWidthTimer = null, n.addClass("in"), e.winnow_results_set_highlight(1) + }, 50) + } + }, i.prototype.update_results_content = function (t) { + return this.search_results.html(t) + }, i.prototype.results_hide = function () { + var t = this; + return t.fixDropWidthTimer && (clearTimeout(t.fixDropWidthTimer), t.fixDropWidthTimer = null), t.results_showing && (t.result_clear_highlight(), t.container.removeClass("chosen-with-drop"), t.form_field_jq.trigger("chosen:hiding_dropdown", {chosen: t}), t.drop_directionFixed = 0), t.results_showing = !1 + }, i.prototype.set_tab_index = function (t) { + var e; + if (this.form_field.tabIndex) return e = this.form_field.tabIndex, this.form_field.tabIndex = -1, this.search_field[0].tabIndex = e + }, i.prototype.set_label_behavior = function () { + var e = this; + if (this.form_field_label = this.form_field_jq.parents("label"), !this.form_field_label.length && this.form_field.id.length && (this.form_field_label = t("label[for='" + this.form_field.id + "']")), this.form_field_label.length > 0) return this.form_field_label.bind("click.chosen", function (t) { + return e.is_multiple ? e.container_mousedown(t) : e.activate_field() + }) + }, i.prototype.show_search_field_default = function () { + return this.is_multiple && this.choices_count() < 1 && !this.active_field ? (this.search_field.val(this.default_text), this.search_field.addClass("default")) : (this.search_field.val(""), this.search_field.removeClass("default")) + }, i.prototype.search_results_mouseup = function (e) { + var i; + if (i = t(e.target).hasClass("active-result") ? t(e.target) : t(e.target).parents(".active-result").first(), i.length) return this.result_highlight = i, this.result_select(e), this.search_field.focus() + }, i.prototype.search_results_mouseover = function (e) { + var i; + if (i = t(e.target).hasClass("active-result") ? t(e.target) : t(e.target).parents(".active-result").first()) return this.result_do_highlight(i) + }, i.prototype.search_results_mouseout = function (e) { + if (t(e.target).hasClass("active-result")) return this.result_clear_highlight() + }, i.prototype.choice_build = function (e) { + var i, n, o = this; + return i = t("
          • ", {"class": "search-choice"}).html("" + e.html + ""), e.disabled ? i.addClass("search-choice-disabled") : (n = t("", { + "class": "search-choice-close", + "data-option-array-index": e.array_index + }), n.bind("click.chosen", function (t) { + return o.choice_destroy_link_click(t) + }), i.append(n)), this.search_container.before(i) + }, i.prototype.choice_destroy_link_click = function (e) { + if (e.preventDefault(), e.stopPropagation(), !this.is_disabled) return this.choice_destroy(t(e.target)) + }, i.prototype.choice_destroy = function (t) { + if (this.result_deselect(t[0].getAttribute("data-option-array-index"))) return this.show_search_field_default(), this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1 && this.results_hide(), t.parents("li").first().remove(), this.search_field_scale() + }, i.prototype.results_reset = function () { + var t = this.form_field_jq.val(); + this.reset_single_select_options(), this.form_field.options[0].selected = !0, this.single_set_selected_text(), this.show_search_field_default(), this.results_reset_cleanup(); + var e = this.form_field_jq.val(), i = {selected: e}; + if (t === e || e.length || (i.deselected = t), this.form_field_jq.trigger("change", i), this.sync_sort_field(), this.active_field) return this.results_hide() + }, i.prototype.results_reset_cleanup = function () { + return this.current_selectedIndex = this.form_field.selectedIndex, this.selected_item.find("abbr").remove() + }, i.prototype.result_select = function (t) { + var e, i; + if (this.result_highlight) return e = this.result_highlight, this.result_clear_highlight(), this.is_multiple && this.max_selected_options <= this.choices_count() ? (this.form_field_jq.trigger("chosen:maxselected", {chosen: this}), !1) : (this.is_multiple ? e.removeClass("active-result") : this.reset_single_select_options(), i = this.results_data[e[0].getAttribute("data-option-array-index")], i.selected = !0, this.form_field.options[i.options_index].selected = !0, this.selected_option_count = null, this.is_multiple ? this.choice_build(i) : this.single_set_selected_text(i.text), (t.metaKey || t.ctrlKey) && this.is_multiple || this.results_hide(), this.search_field.val(""), (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) && (this.form_field_jq.trigger("change", {selected: this.form_field.options[i.options_index].value}), this.sync_sort_field()), this.current_selectedIndex = this.form_field.selectedIndex, this.search_field_scale()) + }, i.prototype.single_set_selected_text = function (t) { + return null == t && (t = this.default_text), t === this.default_text ? this.selected_item.addClass("chosen-default") : (this.single_deselect_control_build(), this.selected_item.removeClass("chosen-default")), this.compact_search && this.search_field.attr("placeholder", t), this.selected_item.find("span").attr("title", t).text(t) + }, i.prototype.sync_sort_field = function () { + var e = this; + if (e.is_multiple && e.sort_field) { + var i = t(e.sort_field); + if (!i.length) return; + var n = []; + e.search_choices.find("li.search-choice").each(function () { + var i = t(this), o = i.children(".search-choice-close").first().data("optionArrayIndex"), + a = e.results_data[o]; + a && a.selected && n.push(a.value) + }), i.val(n.join(e.sort_value_splitter)).trigger("change") + } + }, i.prototype.result_deselect = function (t) { + var e; + return e = this.results_data[t], !this.form_field.options[e.options_index].disabled && (e.selected = !1, this.form_field.options[e.options_index].selected = !1, this.selected_option_count = null, this.result_clear_highlight(), this.results_showing && this.winnow_results(), this.form_field_jq.trigger("change", {deselected: this.form_field.options[e.options_index].value}), this.sync_sort_field(), this.search_field_scale(), !0) + }, i.prototype.single_deselect_control_build = function () { + if (this.allow_single_deselect) return this.selected_item.find("abbr").length || this.selected_item.find("span").first().after(''), this.selected_item.addClass("chosen-single-with-deselect") + }, i.prototype.get_search_text = function () { + return this.search_field.val() === this.default_text ? "" : t("
            ").text(t.trim(this.search_field.val())).html() + }, i.prototype.winnow_results_set_highlight = function (t) { + var e, i; + if (i = this.is_multiple ? [] : this.search_results.find(".result-selected.active-result"), e = i.length ? i.first() : this.search_results.find(".active-result").first(), null != e) return this.result_do_highlight(e, t) + }, i.prototype.no_results = function (e) { + var i; + return i = t('
          • ' + this.results_none_found + ' ""
          • '), i.find("span").first().html(e), this.search_results.append(i), this.form_field_jq.trigger("chosen:no_results", {chosen: this}) + }, i.prototype.no_results_clear = function () { + return this.search_results.find(".no-results").remove() + }, i.prototype.keydown_arrow = function () { + var t; + return this.results_showing && this.result_highlight ? (t = this.result_highlight.nextAll("li.active-result").first()) ? this.result_do_highlight(t) : void 0 : this.results_show() + }, i.prototype.keyup_arrow = function () { + var t; + return this.results_showing || this.is_multiple ? this.result_highlight ? (t = this.result_highlight.prevAll("li.active-result"), t.length ? this.result_do_highlight(t.first()) : (this.choices_count() > 0 && this.results_hide(), this.result_clear_highlight())) : void 0 : this.results_show() + }, i.prototype.keydown_backstroke = function () { + var t; + return this.pending_backstroke ? (this.choice_destroy(this.pending_backstroke.find("a").first()), this.clear_backstroke()) : (t = this.search_container.siblings("li.search-choice").last(), t.length && !t.hasClass("search-choice-disabled") ? (this.pending_backstroke = t, this.single_backstroke_delete ? this.keydown_backstroke() : this.pending_backstroke.addClass("search-choice-focus")) : void 0) + }, i.prototype.clear_backstroke = function () { + return this.pending_backstroke && this.pending_backstroke.removeClass("search-choice-focus"), this.pending_backstroke = null + }, i.prototype.keydown_checker = function (t) { + var e, i; + switch (e = null != (i = t.which) ? i : t.keyCode, this.search_field_scale(), 8 !== e && this.pending_backstroke && this.clear_backstroke(), e) { + case 8: + this.backstroke_length = this.search_field.val().length; + break; + case 9: + this.results_showing && !this.is_multiple && this.result_select(t), this.mouse_on_container = !1; + break; + case 13: + t.preventDefault(); + break; + case 38: + t.preventDefault(), this.keyup_arrow(); + break; + case 40: + t.preventDefault(), this.keydown_arrow() + } + }, i.prototype.search_field_scale = function () { + var e, i, n, o, a, s, r, l, h; + if (this.is_multiple) { + for (n = 0, r = 0, a = "position:absolute; left: -1000px; top: -1000px; display:none;", s = ["font-size", "font-style", "font-weight", "font-family", "line-height", "text-transform", "letter-spacing"], l = 0, h = s.length; l < h; l++) o = s[l], a += o + ":" + this.search_field.css(o) + ";"; + return e = t("
            ", {style: a}), e.text(this.search_field.val()), t("body").append(e), r = e.width() + 25, e.remove(), i = this.container.outerWidth(), r > i - 10 && (r = i - 10), this.search_field.css({width: r + "px"}) + } + }, i + }(e), i.DEFAULTS = l, i.LANGUAGES = r, t.fn.chosen.Constructor = i + }.call(this), function (t) { + "use strict"; + var e = "zui.selectable", i = function (i, n) { + this.name = e, this.$ = t(i), this.id = t.zui.uuid(), this.selectOrder = 1, this.selections = {}, this.getOptions(n), this._init() + }, n = function (t, e, i) { + return t >= i.left && t <= i.left + i.width && e >= i.top && e <= i.top + i.height + }, o = function (t, e) { + var i = Math.max(t.left, e.left), o = Math.max(t.top, e.top), a = Math.min(t.left + t.width, e.left + e.width), + s = Math.min(t.top + t.height, e.top + e.height); + return n(i, o, t) && n(a, s, t) && n(i, o, e) && n(a, s, e) + }; + i.DEFAULTS = { + selector: "li,tr,div", + trigger: "", + selectClass: "active", + rangeStyle: { + border: "1px solid " + (t.zui.colorset ? t.zui.colorset.primary : "#3280fc"), + backgroundColor: t.zui.colorset ? new t.zui.Color(t.zui.colorset.primary).fade(20).toCssStr() : "rgba(50, 128, 252, 0.2)" + }, + clickBehavior: "toggle", + ignoreVal: 3, + listenClick: !0 + }, i.prototype.getOptions = function (e) { + this.options = t.extend({}, i.DEFAULTS, this.$.data(), e) + }, i.prototype.select = function (t) { + this.toggle(t, !0) + }, i.prototype.unselect = function (t) { + this.toggle(t, !1) + }, i.prototype.toggle = function (e, i, n) { + var o, a, s = this.options.selector, r = this; + if (void 0 === e) return void this.$.find(s).each(function () { + r.toggle(this, i) + }); + if ("object" == typeof e ? (o = t(e).closest(s), a = o.data("id")) : (a = e, o = r.$.find('.slectable-item[data-id="' + a + '"]')), o && o.length) { + if (a || (a = t.zui.uuid(), o.attr("data-id", a)), void 0 !== i && null !== i || (i = !r.selections[a]), !!i != !!r.selections[a]) { + var l; + "function" == typeof n && (l = n(i)), l !== !0 && (r.selections[a] = !!i && r.selectOrder++, r.callEvent(i ? "select" : "unselect", { + id: a, selections: r.selections, target: o, + selected: r.getSelectedArray() + }, r)) + } + r.options.selectClass && o.toggleClass(r.options.selectClass, i) + } + }, i.prototype.getSelectedArray = function () { + var e = []; + return t.each(this.selections, function (t, i) { + i && e.push(t) + }), e + }, i.prototype.syncSelectionsFromClass = function () { + var e = this, i = e.$children = e.$.find(e.options.selector); + e.selections = {}, i.each(function () { + var i = t(this); + e.selections[i.data("id")] = i.hasClass(e.options.selectClass) + }) + }, i.prototype._init = function () { + var e, i, n, a, s, r, l, h = this.options, c = this, d = h.ignoreVal, u = !0, + f = "." + this.name + "." + this.id, p = "function" == typeof h.checkFunc ? h.checkFunc : null, + g = "function" == typeof h.rangeFunc ? h.rangeFunc : null, m = !1, v = null, y = "mousedown" + f, + b = function () { + a && c.$children.each(function () { + var e = t(this), i = e.offset(); + i.width = e.outerWidth(), i.height = e.outerHeight(); + var n = g ? g.call(this, a, i) : o(a, i); + if (p) { + var s = p.call(c, {intersect: n, target: e, range: a, targetRange: i}); + s === !0 ? c.select(e) : s === !1 && c.unselect(e) + } else n ? c.select(e) : c.multiKey || c.unselect(e) + }) + }, w = function (o) { + m && (s = o.pageX, r = o.pageY, a = { + width: Math.abs(s - e), + height: Math.abs(r - i), + left: s > e ? e : s, + top: r > i ? i : r + }, u && a.width < d && a.height < d || (n || (n = t('.selectable-range[data-id="' + c.id + '"]'), n.length || (n = t('
            ').css(t.extend({ + zIndex: 1060, + position: "absolute", + top: e, + left: i, + pointerEvents: "none" + }, c.options.rangeStyle)).appendTo(t("body")))), n.css(a), clearTimeout(l), l = setTimeout(b, 10), u = !1)) + }, x = function (e) { + t(document).off(f), clearTimeout(v), m && (m = !1, n && n.remove(), u || a && (clearTimeout(l), b(), a = null), c.callEvent("finish", { + selections: c.selections, + selected: c.getSelectedArray() + }), e.preventDefault()) + }, C = function (o) { + if (m) return x(o); + var a = t.zui.getMouseButtonCode(h.mouseButton); + if (!(a > -1 && o.button !== a || c.altKey || 3 === o.which || c.callEvent("start", o) === !1)) { + var s = c.$children = c.$.find(h.selector); + s.addClass("slectable-item"); + var r = c.multiKey ? "multi" : h.clickBehavior; + if ("single" === r && c.unselect(), h.listenClick && ("multi" === r ? c.toggle(o.target) : "single" === r ? c.select(o.target) : "toggle" === r && c.toggle(o.target, null, function (t) { + c.unselect() + })), c.callEvent("startDrag", o) === !1) return void c.callEvent("finish", { + selections: c.selections, + selected: c.getSelectedArray() + }); + e = o.pageX, i = o.pageY, n = null, u = !0, m = !0, t(document).on("mousemove" + f, w).on("mouseup" + f, x), v = setTimeout(function () { + t(document).on(y, x) + }, 10), o.preventDefault() + } + }, _ = h.container && "default" !== h.container ? t(h.container) : this.$; + h.trigger ? _.on(y, h.trigger, C) : _.on(y, C), t(document).on("keydown", function (t) { + var e = t.keyCode; + 17 === e || 91 == e ? c.multiKey = e : 18 === e && (c.altKey = !0) + }).on("keyup", function (t) { + c.multiKey = !1, c.altKey = !1 + }) + }, i.prototype.callEvent = function (e, i) { + var n = t.Event(e + "." + this.name); + this.$.trigger(n, i); + var o = n.result, a = this.options[e]; + return "function" == typeof a && (o = a.apply(this, Array.isArray(i) ? i : [i])), o + }, t.fn.selectable = function (n) { + return this.each(function () { + var o = t(this), a = o.data(e), s = "object" == typeof n && n; + a || o.data(e, a = new i(this, s)), "string" == typeof n && a[n]() + }) + }, t.fn.selectable.Constructor = i, t(function () { + t('[data-ride="selectable"]').selectable() + }) +}(jQuery), +function (t, e, i) { + "use strict"; + if (!t.fn.droppable) return void console.error("Sortable requires droppable.js"); + var n = "zui.sortable", o = {selector: "li,div", dragCssClass: "invisible", sortingClass: "sortable-sorting"}, + a = "order", s = function (e, i) { + var n = this; + n.$ = t(e), n.options = t.extend({}, o, n.$.data(), i), n.init() + }; + s.DEFAULTS = o, s.NAME = n, s.prototype.init = function () { + var e, i = this, n = i.$, o = i.options, s = o.selector, r = o.containerSelector, l = o.sortingClass, + h = o.dragCssClass, c = o.targetSelector, d = o.reverse, u = function (e) { + e = e || i.getItems(1); + var n = e.length; + n && e.each(function (e) { + var i = d ? n - e : e; + t(this).attr("data-" + a, i).data(a, i) + }) + }; + u(), n.droppable({ + handle: o.trigger, + target: c ? c : r ? s + "," + r : s, + selector: s, + container: n, + always: o.always, + flex: !0, + lazy: o.lazy, + canMoveHere: o.canMoveHere, + dropToClass: o.dropToClass, + before: o.before, + nested: !!r, + mouseButton: o.mouseButton, + stopPropagation: o.stopPropagation, + start: function (t) { + h && t.element.addClass(h), e = !1, i.trigger("start", t) + }, + drag: function (t) { + if (n.addClass(l), t.isIn) { + var o = t.element, h = t.target, c = r && h.is(r); + if (c) { + if (!h.children(s).filter(".dragging").length) { + h.append(o); + var f = i.getItems(1); + u(f), i.trigger(a, {list: f, element: o}) + } + return + } + var p = o.data(a), g = h.data(a); + if (p === g) return u(f); + p > g ? h[d ? "after" : "before"](o) : h[d ? "before" : "after"](o), e = !0; + var f = i.getItems(1); + u(f), i.trigger(a, {list: f, element: o}) + } + }, + finish: function (t) { + h && t.element && t.element.removeClass(h), n.removeClass(l), i.trigger("finish", { + list: i.getItems(), + element: t.element, + changed: e + }) + } + }) + }, s.prototype.destroy = function () { + this.$.droppable("destroy"), this.$.data(n, null) + }, s.prototype.reset = function () { + this.destroy(), this.init() + }, s.prototype.getItems = function (e) { + var i = this.$.find(this.options.selector).not(".drag-shadow"); + return e ? i : i.map(function () { + var e = t(this); + return {item: e, order: e.data("order")} + }) + }, s.prototype.trigger = function (e, i) { + return t.zui.callEvent(this.options[e], i, this) + }, t.fn.sortable = function (e) { + return this.each(function () { + var i = t(this), o = i.data(n), a = "object" == typeof e && e; + o ? "object" == typeof e && o.reset() : i.data(n, o = new s(this, a)), "string" == typeof e && o[e]() + }) + }, t.fn.sortable.Constructor = s +}(jQuery, window, document), function (t, e) { + "use strict"; + var i = "zui.contextmenu", n = { + animation: "fade", + menuTemplate: '', + toggleTrigger: !1, + duration: 200, + limitInsideWindow: !0 + }, o = !1, a = {}, s = "zui-contextmenu-" + t.zui.uuid(), r = 0, l = 0, h = function () { + return t(document).off("mousemove." + i).on("mousemove." + i, function (t) { + r = t.clientX, l = t.clientY + }), a + }, c = function (e, i) { + if ("string" == typeof e && (e = "seperator" === e || "divider" === e || "-" === e || "|" === e ? {type: "seperator"} : { + label: e, + id: i + }), "seperator" === e.type || "divider" === e.type) return t('
          • '); + var n = t("
            ").attr({href: e.url || "###", "class": e.className, style: e.style}).data("item", e); + return e.html ? e.html === !0 ? n.html(e.label || e.text) : n = t(e.html) : n.text(e.label || e.text), e.onClick && n.on("click", e.onClick), t("
          • ").toggleClass("disabled", e.disabled === !0).append(n) + }, d = function (e) { + var i = t("#" + s); + return i.length && i.hasClass("contextmenu-show") && (!e || (i.data("options") || {}).id === e) + }, u = null, f = function (e, i) { + "function" == typeof e && (i = e, e = null), u && (clearTimeout(u), u = null); + var n = t("#" + s); + if (n.length) { + var o = n.removeClass("contextmenu-show").data("options"); + if (!e || o.id === e) { + var r = function () { + n.find(".contextmenu-menu").removeClass("open"), o.onHidden && o.onHidden(), i && i() + }; + o.onHide && o.onHide(); + var l = o.animation; + n.find(".contextmenu-menu").removeClass("in"), l ? u = setTimeout(r, o.duration) : r() + } + } + return a + }, p = function (h, d, p) { + t.isPlainObject(h) && (p = d, d = h, h = d.items), o = !0, d = t.extend({}, n, d); + var g = t("#" + s); + g.length || (g = t('
            ').appendTo("body")); + var m = g.find(".contextmenu-menu").off("click." + i).on("click." + i, "a,.contextmenu-item", function (e) { + var i = t(this), n = d.onClickItem && d.onClickItem(i.data("item"), i, e, d); + n !== !1 && f() + }).empty(); + m.attr("class", "contextmenu-menu" + (d.className ? " " + d.className : "")), g.attr("class", "contextmenu contextmenu-show"); + var v = d.menuCreator; + if (v) m.append(v(h, d)); else { + m.append(d.menuTemplate); + var y = m.children().first(), b = d.itemCreator || c, w = typeof h; + if ("string" === w ? h = h.split(",") : "function" === w && (h = h(d)), !h) return !1; + t.each(h, function (t, e) { + y.append(b(e, t, d)) + }) + } + var x = d.animation, C = d.duration; + x === !0 && (d.animation = x = "fade"), u && (clearTimeout(u), u = null); + var _ = function () { + m.addClass("in"), d.onShown && d.onShown(), p && p() + }; + d.onShow && d.onShow(), g.data("options", { + animation: x, + onHide: d.onHide, + onHidden: d.onHidden, + id: d.id, + duration: C + }); + var k = d.x, T = d.y; + k === e && (k = (d.event || d).clientX), k === e && (k = r), T === e && (T = (d.event || d).clientY), T === e && (T = l); + var y = m.children().first(), S = y.outerWidth(), D = y.outerHeight(); + if (d.position) { + var M = d.position({x: k, y: T, width: S, height: D}, d, m); + M && (k = M.x, T = M.y) + } + if (d.limitInsideWindow) { + var P = t(window); + k = Math.max(0, Math.min(k, P.width() - S)), T = Math.max(0, Math.min(T, P.height() - D)) + } + return g.css({left: k, top: T}).show(), m.addClass("open"), x ? (m.addClass(x), u = setTimeout(function () { + _(), o = !1 + }, 10)) : (_(), o = !1), a + }; + t.extend(a, {NAME: i, DEFAULTS: n, show: p, hide: f, listenMouse: h, isShow: d}), t.zui({ContextMenu: a}); + var g = function (e, n) { + var o = this; + o.name = i, o.$ = t(e), o.id = t.zui.uuid(), n = o.options = t.extend({trigger: "contextmenu"}, a.DEFAULTS, this.$.data(), n); + var s = function (t) { + if ("mousedown" !== t.type || 2 === t.button) { + if (n.toggleTrigger && o.isShow()) o.hide(); else { + var e = {x: t.clientX, y: t.clientY, event: t}; + if (o.show(e) === !1) return + } + return t.preventDefault(), t.returnValue = !1, !1 + } + }, r = n.trigger, l = r + "." + i; + n.selector ? o.$.on(l, n.selector, s) : o.$.on(l, s), n.show && o.show("object" == typeof n.show ? n.show : null) + }; + g.prototype.destory = function () { + that.$.off("." + i) + }, g.prototype.hide = function (t) { + return a.hide(this.id, t) + }, g.prototype.show = function (e, i) { + return e = t.extend({id: this.id, $toggle: this.$}, this.options, e), a.show(e, i) + }, g.prototype.isShow = function () { + return d(this.id) + }, t.fn.contextmenu = function (e) { + return this.each(function () { + var n = t(this), o = n.data(i), a = "object" == typeof e && e; + o || n.data(i, o = new g(this, a)), "string" == typeof e && o[e]() + }) + }, t.fn.contextmenu.Constructor = g, t.fn.contextDropdown = function (e) { + t(this).contextmenu(t.extend({ + trigger: "click", animation: "fade", toggleTrigger: !0, menuCreator: function (e, i) { + var n = i.$toggle, o = n.attr("data-target"); + o || (o = n.attr("href"), o = o && /#/.test(o) && o.replace(/.*(?=#[^\s]*$)/, "")); + var a = o ? t(o) : n.next(".dropdown-menu"), s = i.transferEvent; + if (s !== !1) { + var r = "data-contextmenu-index"; + a.find("a,.contextmenu-item").each(function (e) { + t(this).attr(r, e) + }); + var l = a.clone(); + return l.on("string" == typeof s ? s : "click", "a,.contextmenu-item", function (e) { + var i = a.find("[" + r + '="' + t(this).attr(r) + '"]'), n = i[0]; + if (n) return n[e.type] ? n[e.type]() : i.trigger(e.type), e.preventDefault(), e.stopPropagation(), !1 + }), l + } + return a.clone() + }, position: function (t, e, i) { + var n = e.placement, o = e.$toggle; + if (!n) { + var a = i.find(".dropdown-menu"), s = a.hasClass("pull-right"), r = o.parent().hasClass("dropup"); + n = s ? r ? "top-right" : "bottom-right" : r ? "top-left" : "bottom-left", s && a.removeClass("pull-right") + } + var l = o[0].getBoundingClientRect(); + switch (n) { + case"top-left": + return {x: l.left, y: Math.floor(l.top - t.height)}; + case"top-right": + return {x: Math.floor(l.right - t.width), y: Math.floor(l.top - t.height)}; + case"bottom-left": + return {x: l.left, y: l.bottom}; + case"bottom-right": + return {x: Math.floor(l.right - t.width), y: l.bottom} + } + return t + } + }, e)) + }, t(document).on("click", function (e) { + var n = t(e.target), a = n.closest('[data-toggle="context-dropdown"]'); + if (a.length) { + var s = a.data(i); + s || a.contextDropdown({show: !0}) + } else o || n.closest(".contextmenu").length || f() + }) +}(jQuery, void 0),/*! * jQuery Form Plugin * version: 4.2.2 * Requires jQuery v1.7.2 or later @@ -63,7 +4751,430 @@ selected:r.getSelectedArray()},r))}r.options.selectClass&&o.toggleClass(r.option * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&module.exports?module.exports=function(e,i){return"undefined"==typeof i&&(i="undefined"!=typeof window?require("jquery"):require("jquery")(e)),t(i),i}:t(jQuery)}(function(t){"use strict";function e(e){var i=e.data;e.isDefaultPrevented()||(e.preventDefault(),t(e.target).closest("form").ajaxSubmit(i))}function i(e){var i=e.target,n=t(i);if(!n.is("[type=submit],[type=image]")){var o=n.closest("[type=submit]");if(0===o.length)return;i=o[0]}var a=i.form;if(a.clk=i,"image"===i.type)if("undefined"!=typeof e.offsetX)a.clk_x=e.offsetX,a.clk_y=e.offsetY;else if("function"==typeof t.fn.offset){var s=n.offset();a.clk_x=e.pageX-s.left,a.clk_y=e.pageY-s.top}else a.clk_x=e.pageX-i.offsetLeft,a.clk_y=e.pageY-i.offsetTop;setTimeout(function(){a.clk=a.clk_x=a.clk_y=null},100)}function n(){if(t.fn.ajaxSubmit.debug){var e="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(e):window.opera&&window.opera.postError&&window.opera.postError(e)}}var o=/\r?\n/g,a={};a.fileapi=void 0!==t('').get(0).files,a.formdata="undefined"!=typeof window.FormData;var s=!!t.fn.prop;t.fn.attr2=function(){if(!s)return this.attr.apply(this,arguments);var t=this.prop.apply(this,arguments);return t&&t.jquery||"string"==typeof t?t:this.attr.apply(this,arguments)},t.fn.ajaxSubmit=function(e,i,o,r){function l(i){var n,o,a=t.param(i,e.traditional).split("&"),s=a.length,r=[];for(n=0;n',T).val(c.extraData[u].value).appendTo(_)[0]):h.push(t('',T).val(c.extraData[u]).appendTo(_)[0]));c.iframeTarget||g.appendTo(S),m.attachEvent?m.attachEvent("onload",r):m.addEventListener("load",r,!1),setTimeout(e,15);try{_.submit()}catch(v){var y=document.createElement("form").submit;y.apply(_)}}finally{_.setAttribute("action",a),_.setAttribute("enctype",l),i?_.setAttribute("target",i):p.removeAttr("target"),t.each(h,function(){this.remove()})}}function r(e){if(!v.aborted&&!I){if(F=o(m),F||(n("cannot access response document"),e=M),e===D&&v)return v.abort("timeout"),void k.reject(v,"timeout");if(e===M&&v)return v.abort("server abort"),void k.reject(v,"error","server abort");if(F&&F.location.href!==c.iframeSrc||x){m.detachEvent?m.detachEvent("onload",r):m.removeEventListener("load",r,!1);var i,a="success";try{if(x)throw"timeout";var s="xml"===c.dataType||F.XMLDocument||t.isXMLDoc(F);if(n("isXml="+s),!s&&window.opera&&(null===F.body||!F.body.innerHTML)&&--$)return n("requeing onLoad callback, DOM not available"),void setTimeout(r,250);var l=F.body?F.body:F.documentElement;v.responseText=l?l.innerHTML:null,v.responseXML=F.XMLDocument?F.XMLDocument:F,s&&(c.dataType="xml"),v.getResponseHeader=function(t){var e={"content-type":c.dataType};return e[t.toLowerCase()]},l&&(v.status=Number(l.getAttribute("status"))||v.status,v.statusText=l.getAttribute("statusText")||v.statusText);var h=(c.dataType||"").toLowerCase(),d=/(json|script|text)/.test(h);if(d||c.textarea){var f=F.getElementsByTagName("textarea")[0];if(f)v.responseText=f.value,v.status=Number(f.getAttribute("status"))||v.status,v.statusText=f.getAttribute("statusText")||v.statusText;else if(d){var p=F.getElementsByTagName("pre")[0],y=F.getElementsByTagName("body")[0];p?v.responseText=p.textContent?p.textContent:p.innerText:y&&(v.responseText=y.textContent?y.textContent:y.innerText)}}else"xml"===h&&!v.responseXML&&v.responseText&&(v.responseXML=A(v.responseText));try{L=O(v,h,c)}catch(b){a="parsererror",v.error=i=b||a}}catch(b){n("error caught: ",b),a="error",v.error=i=b||a}v.aborted&&(n("upload aborted"),a=null),v.status&&(a=v.status>=200&&v.status<300||304===v.status?"success":"error"),"success"===a?(c.success&&c.success.call(c.context,L,"success",v),k.resolve(v.responseText,"success",v),u&&t.event.trigger("ajaxSuccess",[v,c])):a&&("undefined"==typeof i&&(i=v.statusText),c.error&&c.error.call(c.context,v,a,i),k.reject(v,"error",i),u&&t.event.trigger("ajaxError",[v,c,i])),u&&t.event.trigger("ajaxComplete",[v,c]),u&&!--t.active&&t.event.trigger("ajaxStop"),c.complete&&c.complete.call(c.context,v,a),I=!0,c.timeout&&clearTimeout(C),setTimeout(function(){c.iframeTarget?g.attr("src",c.iframeSrc):g.remove(),v.responseXML=null},100)}}}var l,h,c,u,f,g,m,v,b,w,x,C,_=p[0],k=t.Deferred();if(k.abort=function(t){v.abort(t)},i)for(h=0;h',T),g.css({position:"absolute",top:"-1000px",left:"-1000px"})),m=g[0],v={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(e){var i="timeout"===e?"timeout":"aborted";n("aborting upload... "+i),this.aborted=1;try{m.contentWindow.document.execCommand&&m.contentWindow.document.execCommand("Stop")}catch(o){}g.attr("src",c.iframeSrc),v.error=i,c.error&&c.error.call(c.context,v,i,e),u&&t.event.trigger("ajaxError",[v,c,i]),c.complete&&c.complete.call(c.context,v,i)}},u=c.global,u&&0===t.active++&&t.event.trigger("ajaxStart"),u&&t.event.trigger("ajaxSend",[v,c]),c.beforeSend&&c.beforeSend.call(c.context,v,c)===!1)return c.global&&t.active--,k.reject(),k;if(v.aborted)return k.reject(),k;b=_.clk,b&&(w=b.name,w&&!b.disabled&&(c.extraData=c.extraData||{},c.extraData[w]=b.value,"image"===b.type&&(c.extraData[w+".x"]=_.clk_x,c.extraData[w+".y"]=_.clk_y)));var D=1,M=2,P=t("meta[name=csrf-token]").attr("content"),z=t("meta[name=csrf-param]").attr("content");z&&P&&(c.extraData=c.extraData||{},c.extraData[z]=P),c.forceSync?a():setTimeout(a,10);var L,F,I,$=50,A=t.parseXML||function(t,e){return window.ActiveXObject?(e=new ActiveXObject("Microsoft.XMLDOM"),e.async="false",e.loadXML(t)):e=(new DOMParser).parseFromString(t,"text/xml"),e&&e.documentElement&&"parsererror"!==e.documentElement.nodeName?e:null},E=t.parseJSON||function(t){return window.eval("("+t+")")},O=function(e,i,n){var o=e.getResponseHeader("content-type")||"",a=("xml"===i||!i)&&o.indexOf("xml")>=0,s=a?e.responseXML:e.responseText;return a&&"parsererror"===s.documentElement.nodeName&&t.error&&t.error("parsererror"),n&&n.dataFilter&&(s=n.dataFilter(s,i)),"string"==typeof s&&(("json"===i||!i)&&o.indexOf("json")>=0?s=E(s):("script"===i||!i)&&o.indexOf("javascript")>=0&&t.globalEval(s)),s};return k}if(!this.length)return n("ajaxSubmit: skipping submit process - no element selected"),this;var d,u,f,p=this;"function"==typeof e?e={success:e}:"string"==typeof e||e===!1&&arguments.length>0?(e={url:e,data:i,dataType:o},"function"==typeof r&&(e.success=r)):"undefined"==typeof e&&(e={}),d=e.method||e.type||this.attr2("method"),u=e.url||this.attr2("action"),f="string"==typeof u?t.trim(u):"",f=f||window.location.href||"",f&&(f=(f.match(/^([^#]+)/)||[])[1]),e=t.extend(!0,{url:f,success:t.ajaxSettings.success,type:d||t.ajaxSettings.type,iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},e);var g={};if(this.trigger("form-pre-serialize",[this,e,g]),g.veto)return n("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(e.beforeSerialize&&e.beforeSerialize(this,e)===!1)return n("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var m=e.traditional;"undefined"==typeof m&&(m=t.ajaxSettings.traditional);var v,y=[],b=this.formToArray(e.semantic,y,e.filtering);if(e.data){var w="function"==typeof e.data?e.data(b):e.data;e.extraData=w,v=t.param(w,m)}if(e.beforeSubmit&&e.beforeSubmit(b,this,e)===!1)return n("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[b,this,e,g]),g.veto)return n("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var x=t.param(b,m);v&&(x=x?x+"&"+v:v),"GET"===e.type.toUpperCase()?(e.url+=(e.url.indexOf("?")>=0?"&":"?")+x,e.data=null):e.data=x;var C=[];if(e.resetForm&&C.push(function(){p.resetForm()}),e.clearForm&&C.push(function(){p.clearForm(e.includeHidden)}),!e.dataType&&e.target){var _=e.success||function(){};C.push(function(i,n,o){var a=arguments,s=e.replaceTarget?"replaceWith":"html";t(e.target)[s](i).each(function(){_.apply(this,a)})})}else e.success&&(Array.isArray(e.success)?t.merge(C,e.success):C.push(e.success));if(e.success=function(t,i,n){for(var o=e.context||this,a=0,s=C.length;a0,M="multipart/form-data",P=p.attr("enctype")===M||p.attr("encoding")===M,z=a.fileapi&&a.formdata;n("fileAPI :"+z);var L,F=(D||P)&&!z;e.iframe!==!1&&(e.iframe||F)?e.closeKeepAlive?t.get(e.closeKeepAlive,function(){L=c(b)}):L=c(b):L=(D||P)&&z?h(b):t.ajax(e),p.removeData("jqxhr").data("jqxhr",L);for(var I=0;I0)&&(o={url:o,data:a,dataType:s},"function"==typeof r&&(o.success=r)),o=o||{},o.delegation=o.delegation&&"function"==typeof t.fn.on,!o.delegation&&0===this.length){var l={s:this.selector,c:this.context};return!t.isReady&&l.s?(n("DOM not ready, queuing ajaxForm"),t(function(){t(l.s,l.c).ajaxForm(o)}),this):(n("terminating; zero elements found by selector"+(t.isReady?"":" (DOM not ready)")),this)}return o.delegation?(t(document).off("submit.form-plugin",this.selector,e).off("click.form-plugin",this.selector,i).on("submit.form-plugin",this.selector,o,e).on("click.form-plugin",this.selector,o,i),this):this.ajaxFormUnbind().on("submit.form-plugin",o,e).on("click.form-plugin",o,i)},t.fn.ajaxFormUnbind=function(){return this.off("submit.form-plugin click.form-plugin")},t.fn.formToArray=function(e,i,n){var o=[];if(0===this.length)return o;var s,r=this[0],l=this.attr("id"),h=e||"undefined"==typeof r.elements?r.getElementsByTagName("*"):r.elements;if(h&&(h=t.makeArray(h)),l&&(e||/(Edge|Trident)\//.test(navigator.userAgent))&&(s=t(':input[form="'+l+'"]').get(),s.length&&(h=(h||[]).concat(s))),!h||!h.length)return o;"function"==typeof n&&(h=t.map(h,n));var c,d,u,f,p,g,m;for(c=0,g=h.length;c').get(0).files, a.formdata = "undefined" != typeof window.FormData; + var s = !!t.fn.prop; + t.fn.attr2 = function () { + if (!s) return this.attr.apply(this, arguments); + var t = this.prop.apply(this, arguments); + return t && t.jquery || "string" == typeof t ? t : this.attr.apply(this, arguments) + }, t.fn.ajaxSubmit = function (e, i, o, r) { + function l(i) { + var n, o, a = t.param(i, e.traditional).split("&"), s = a.length, r = []; + for (n = 0; n < s; n++) a[n] = a[n].replace(/\+/g, " "), o = a[n].split("="), r.push([decodeURIComponent(o[0]), decodeURIComponent(o[1])]); + return r + } + + function h(i) { + for (var n = new FormData, o = 0; o < i.length; o++) n.append(i[o].name, i[o].value); + if (e.extraData) { + var a = l(e.extraData); + for (o = 0; o < a.length; o++) a[o] && n.append(a[o][0], a[o][1]) + } + e.data = null; + var s = t.extend(!0, {}, t.ajaxSettings, e, { + contentType: !1, + processData: !1, + cache: !1, + type: d || "POST" + }); + e.uploadProgress && (s.xhr = function () { + var i = t.ajaxSettings.xhr(); + return i.upload && i.upload.addEventListener("progress", function (t) { + var i = 0, n = t.loaded || t.position, o = t.total; + t.lengthComputable && (i = Math.ceil(n / o * 100)), e.uploadProgress(t, n, o, i) + }, !1), i + }), s.data = null; + var r = s.beforeSend; + return s.beforeSend = function (t, i) { + e.formData ? i.data = e.formData : i.data = n, r && r.call(this, t, i) + }, t.ajax(s) + } + + function c(i) { + function o(t) { + var e = null; + try { + t.contentWindow && (e = t.contentWindow.document) + } catch (i) { + n("cannot get iframe.contentWindow document: " + i) + } + if (e) return e; + try { + e = t.contentDocument ? t.contentDocument : t.document + } catch (i) { + n("cannot get iframe.contentDocument: " + i), e = t.document + } + return e + } + + function a() { + function e() { + try { + var t = o(m).readyState; + n("state = " + t), t && "uninitialized" === t.toLowerCase() && setTimeout(e, 50) + } catch (i) { + n("Server abort: ", i, " (", i.name, ")"), r(M), C && clearTimeout(C), C = void 0 + } + } + + var i = p.attr2("target"), a = p.attr2("action"), s = "multipart/form-data", + l = p.attr("enctype") || p.attr("encoding") || s; + _.setAttribute("target", f), d && !/post/i.test(d) || _.setAttribute("method", "POST"), a !== c.url && _.setAttribute("action", c.url), c.skipEncodingOverride || d && !/post/i.test(d) || p.attr({ + encoding: "multipart/form-data", + enctype: "multipart/form-data" + }), c.timeout && (C = setTimeout(function () { + x = !0, r(D) + }, c.timeout)); + var h = []; + try { + if (c.extraData) for (var u in c.extraData) c.extraData.hasOwnProperty(u) && (t.isPlainObject(c.extraData[u]) && c.extraData[u].hasOwnProperty("name") && c.extraData[u].hasOwnProperty("value") ? h.push(t('', T).val(c.extraData[u].value).appendTo(_)[0]) : h.push(t('', T).val(c.extraData[u]).appendTo(_)[0])); + c.iframeTarget || g.appendTo(S), m.attachEvent ? m.attachEvent("onload", r) : m.addEventListener("load", r, !1), setTimeout(e, 15); + try { + _.submit() + } catch (v) { + var y = document.createElement("form").submit; + y.apply(_) + } + } finally { + _.setAttribute("action", a), _.setAttribute("enctype", l), i ? _.setAttribute("target", i) : p.removeAttr("target"), t.each(h, function () { + this.remove() + }) + } + } + + function r(e) { + if (!v.aborted && !I) { + if (F = o(m), F || (n("cannot access response document"), e = M), e === D && v) return v.abort("timeout"), void k.reject(v, "timeout"); + if (e === M && v) return v.abort("server abort"), void k.reject(v, "error", "server abort"); + if (F && F.location.href !== c.iframeSrc || x) { + m.detachEvent ? m.detachEvent("onload", r) : m.removeEventListener("load", r, !1); + var i, a = "success"; + try { + if (x) throw"timeout"; + var s = "xml" === c.dataType || F.XMLDocument || t.isXMLDoc(F); + if (n("isXml=" + s), !s && window.opera && (null === F.body || !F.body.innerHTML) && --$) return n("requeing onLoad callback, DOM not available"), void setTimeout(r, 250); + var l = F.body ? F.body : F.documentElement; + v.responseText = l ? l.innerHTML : null, v.responseXML = F.XMLDocument ? F.XMLDocument : F, s && (c.dataType = "xml"), v.getResponseHeader = function (t) { + var e = {"content-type": c.dataType}; + return e[t.toLowerCase()] + }, l && (v.status = Number(l.getAttribute("status")) || v.status, v.statusText = l.getAttribute("statusText") || v.statusText); + var h = (c.dataType || "").toLowerCase(), d = /(json|script|text)/.test(h); + if (d || c.textarea) { + var f = F.getElementsByTagName("textarea")[0]; + if (f) v.responseText = f.value, v.status = Number(f.getAttribute("status")) || v.status, v.statusText = f.getAttribute("statusText") || v.statusText; else if (d) { + var p = F.getElementsByTagName("pre")[0], y = F.getElementsByTagName("body")[0]; + p ? v.responseText = p.textContent ? p.textContent : p.innerText : y && (v.responseText = y.textContent ? y.textContent : y.innerText) + } + } else "xml" === h && !v.responseXML && v.responseText && (v.responseXML = A(v.responseText)); + try { + L = O(v, h, c) + } catch (b) { + a = "parsererror", v.error = i = b || a + } + } catch (b) { + n("error caught: ", b), a = "error", v.error = i = b || a + } + v.aborted && (n("upload aborted"), a = null), v.status && (a = v.status >= 200 && v.status < 300 || 304 === v.status ? "success" : "error"), "success" === a ? (c.success && c.success.call(c.context, L, "success", v), k.resolve(v.responseText, "success", v), u && t.event.trigger("ajaxSuccess", [v, c])) : a && ("undefined" == typeof i && (i = v.statusText), c.error && c.error.call(c.context, v, a, i), k.reject(v, "error", i), u && t.event.trigger("ajaxError", [v, c, i])), u && t.event.trigger("ajaxComplete", [v, c]), u && !--t.active && t.event.trigger("ajaxStop"), c.complete && c.complete.call(c.context, v, a), I = !0, c.timeout && clearTimeout(C), setTimeout(function () { + c.iframeTarget ? g.attr("src", c.iframeSrc) : g.remove(), v.responseXML = null + }, 100) + } + } + } + + var l, h, c, u, f, g, m, v, b, w, x, C, _ = p[0], k = t.Deferred(); + if (k.abort = function (t) { + v.abort(t) + }, i) for (h = 0; h < y.length; h++) l = t(y[h]), s ? l.prop("disabled", !1) : l.removeAttr("disabled"); + c = t.extend(!0, {}, t.ajaxSettings, e), c.context = c.context || c, f = "jqFormIO" + (new Date).getTime(); + var T = _.ownerDocument, S = p.closest("body"); + if (c.iframeTarget ? (g = t(c.iframeTarget, T), w = g.attr2("name"), w ? f = w : g.attr2("name", f)) : (g = t('