diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6f313c6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +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/.env b/.env new file mode 100644 index 0000000..e2ff0a4 --- /dev/null +++ b/.env @@ -0,0 +1,45 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY=base64:bX6Fa5y3BcTGNaM36O4a3/aj58bSc7T5zD5kmFpcMog= +APP_DEBUG=true +APP_URL=http://erp.wanqian.tech + +LOG_CHANNEL=stack + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=stephen +DB_USERNAME=root +DB_PASSWORD= + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_DRIVER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" +TIMEZONE=Asia/Shanghai diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d058c34 --- /dev/null +++ b/.env.example @@ -0,0 +1,44 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://localhost + +LOG_CHANNEL=stack + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=homestead +DB_USERNAME=homestead +DB_PASSWORD=secret + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_DRIVER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..967315d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text=auto +*.css linguist-vendored +*.scss linguist-vendored +*.js linguist-vendored +CHANGELOG.md export-ignore diff --git a/.gitignore b/.gitignore index 297959a..f2286bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,9 @@ -/vendor/ -node_modules/ +/node_modules +/public/hot +/vendor +.phpunit.result.cache +Homestead.json +Homestead.yaml npm-debug.log yarn-error.log - -# Laravel 4 specific -bootstrap/compiled.php -app/storage/ - -# Laravel 5 & Lumen specific -public/storage -public/hot - -# Laravel 5 & Lumen specific with changed public path -public_html/storage -public_html/hot - -storage/*.key -.env -Homestead.yaml -Homestead.json -/.vagrant -.phpunit.result.cache +/.idea diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..1db61d9 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,13 @@ +php: + preset: laravel + disabled: + - unused_use + finder: + not-name: + - index.php + - server.php +js: + finder: + not-name: + - webpack.mix.js +css: true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3f3007e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Jiang qinghua + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index fed89e2..9000ba4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,160 @@ -# dcat-admin-inventory -基于DCAT ADMIN的库存管理系统 +# Dcat Admin + +本项目是[Dcat Admin](https://github.com/jqhph/dcat-admin)的DEMO源码,在线预览[点击这里](http://103.39.211.179:8080/admin)。 + + +仓库地址 + +- Github [https://github.com/jqhph/dcat-admin-demo](https://github.com/jqhph/dcat-admin-demo) +- Gitee [https://gitee.com/jqhph/dcat-admin-demo](https://gitee.com/jqhph/dcat-admin-demo) + +## 安装 + +运行 +```shell +composer install +``` + +安装完之后,复制一份`.env.example`文件并命名为`.env`,然后运行 +```shell +php artisan key:generate +``` + +然后配置好数据库连接信息运行以下命令 + +> 这里会提示文件夹已存在,忽略即可。 + +```php +php artisan admin:install +``` + +最后运行`php artisan serve`。然后打开`http://localhost:8000/admin`即可访问,账号`admin`,密码`admin`。 + + + +## 亚马逊反爬 +https://www.sohu.com/a/285133490_759197 + +## Laravel 表单 +https://blog.csdn.net/hualaoshuan/article/details/98481204?ops_request_misc=&request_id=&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2~all~es_rank~default-20-98481204.pc_search_all_es&utm_term=laravel&spm=1018.2226.3001.4187 + +## Laravel8开荒~正确安装前端Bootstrap CSS库 +https://learnku.com/articles/49892 + +## python3爬虫实战之selenium爬取亚马逊商品 - 改邮编 +https://blog.csdn.net/weixin_39020133/article/details/105966388 + + +## PHP调用Python和PHP向Python发送数据 +https://blog.csdn.net/qq_37035946/article/details/91492379 + + + +## 基于 Laravel 构建的适用于小公司和自由职业者的免费在线财务会计系统 —— Akaunting +https://laravelacademy.org/post/9483.html + + +## 基于 Laravel 构建的免费、开源 CRM 平台 —— Flarepoint +https://laravelacademy.org/post/5305.html + +## laravel-admin / Dcat admin 上传Excel并导入数据到数据库 +https://blog.csdn.net/qq_42468039/article/details/108277599 + +## Laragon工具 +git config --global http.sslVerify "false" +Github +derjoey2010@163.com +302019csf +githun token:githun123 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 + +php artisan key:generate + +php -S 127.0.0.1:8000 -t ./ -f serve.php + +php artisan sample-data:seed + +php artisan install --db-host=localhost --db-name=akaunting --db-username=root --db-password= --company-name=Stephen + +php artisan migrate + +详情看 +vendor +------dcat +----------laravel-admin +------------------------redame.md + + + + +## 遇到问题 +、、、 +1.不能RUI访问本地图片或文件 +执行命令:php artisan storage:link +命令执行完毕后,就会在项目里多出一个 public/storage, +这个 storage 就是一个软链接,它指向 storage/app/public 目录。 +public/storage(软连接) → storage/app/public +然后就可以用地址直接访问public里面的照片了 +、、、 +2.php artisan admin:install执行这一步命令可能会报以下错误 Specified key was too long ... 767 bytes,如果出现这个报错。 +请在 app/Providers/AppServiceProvider.php 文件的 boot方法中加上代码 +\Schema::defaultStringLength(191);, +然后删除掉数据库中的所有数据表,再重新运行一遍 php artisan admin:install 命令即可。 +、、、 + + +数据库table操作 +http://new.xiaosongit.com/article/805.html + + +内网穿透 +https://natapp.cn/ + +Discover ERP DEMO +http://erp.you-tang.com/admin/products + +Dcat Admin Demo +http://103.39.211.179:8080/admin + + +laravel Admin +https://laravel-admin.org/docs/en/model-grid-quick-create#Select + + +Laravel Currency +https://github.com/amrshawky/laravel-currency + +Dcat 图片插件 +https://github.com/de-memory/dcat-media-selector + +Laravel 视频教程 +https://github.com/johnlui/Learn-Laravel-5 + + +3D 头像 Meta 元宇宙 +https://readyplayer.me/avatar +https://docs.readyplayer.me/integration-guides/web +https://github.com/readyplayerme/Example-iframe +https://github.com/readyplayerme + +世界时间 +https://carbon.nesbot.com/docs/ +https://www.jb51.net/article/124259.htm +时区对照表:https://learnku.com/articles/39628 + + +1.选中列导出按钮 +2.添加文件上传按钮、添加文件下载按钮 +3.单位换算 + +分页条件记忆 +https://gitee.com/jqhph/dcat-admin/issues/I3H2KO + +亚马逊仓库 +http://www.jiufanglogistics.cn/channel/1/fbackfbt + +dcat媒体管理 +https://github.com/deatil/dcat-form-media +https://github.com/de-memory/dcat-media-selector + +ICON +https://fontawesome.com/v5.15/icons?d=gallery&p=2 \ No newline at end of file diff --git a/app/Admin/Actions/AdminSetting.php b/app/Admin/Actions/AdminSetting.php new file mode 100644 index 0000000..4983dfc --- /dev/null +++ b/app/Admin/Actions/AdminSetting.php @@ -0,0 +1,33 @@ + 网站设置'; + + public function render() + { + $modal = Modal::make() + ->id('admin-setting-config') // 导航栏显示弹窗,必须固定ID,随机ID会在刷新后失败 + ->title($this->title()) + ->body(AdminSettingForm::make()) + ->lg() + ->button( + << +
"+a(c)+"
"}j{18:c.18&&d.34(c.18),2c:c.2c&&d.34(c.2c),1Y:c.1Y&&d.34(c.1Y),1o:c.1o||b}}b.5U=8(c){j g(c).Q("5T")};b.5S=8(c){j g(c).Q("5R")};b.5Q=8(c){j g(c).Q("5O")};d.T(b.1b,t,{5N:8(c,a){8 b(){o b=g(\'<2a 2h="I-3G">2a>\').J(n.3G);o e=d.2b(a,8(a){a=g(\'<2W 2h="I-1o">2W>\').20(l.11.1o(a)).Q("5T",l.1m).Q("5R",l.4n(a)).Q("5O",a);a.2d().M(8(){g(4).J(n.69)});j a});b.20.1g(b,e);l.26&&C({2E:"I-26",19:b[0],1H:c});j b}8 e(){j l.11.2c({V:c,16:!m})}8 h(){j l.11.1Y({V:c,16:!m})}L(4.$U){o l=4;4.$U.18();o m=a&&a.K;!m&&4.11.18?4.$U.5I(l.11.18({V:c,16:!0})).44(l.11.2c?e():G).20(l.11.1Y?h():G):m&&4.$U.5I(b()).44(l.11.2c?e():G).20(l.11.1Y?h():G);4.P("43")}},5F:8(){j 4.$U},23:8(c){o a=4;4.V=c;4.3Z=!1;4.2i(c,8(b){a.3Z||c!==a.V||a.5N(c,b)})},2M:8(){4.3Z=!0},1N:8(){4.2M();4.$U.18();4.P("43")},16:8(){j 4.$U.2k(":18")},1p:8(){4.$U=G}});j b}(),D=8(){8 b(b){o c=4;b=b||{};b.N||g.1k("N 2k 2U");4.1A=!1;4.16=!0;4.1j=d.2b(b.1j,h);o a=d.12(4.5y,4);o e=d.12(4.5x,4);o k=d.12(4.5w,4);4.$N=g(b.N).1h("73.I",".I-1o",a).1h("74.I",".I-1o",e).1h("75.I",".I-1o",k);d.M(4.1j,8(a){c.$N.20(a.5F());a.R("43",c.5u,c)})}8 h(b){j O q(b)}d.T(b.1b,t,{5y:8(b){4.P("5t",g(b.5s))},5x:8(b){4.2m();4.3S(g(b.5s),!0)},5w:8(){4.2m()},5u:8(){(4.16=d.4B(4.1j,8(b){j b.16()}))?4.3Q():4.1A&&4.3P();4.P("5g")},3Q:8(){4.$N.7e()},3P:8(){4.$N.J("2t","3I")},3M:8(){j 4.$N.22(".I-1o")},3b:8(){j 4.$N.22(".I-3c").2D()},3S:8(b,c){b.2D().3z("I-3c");!c&&4.P("4V")},2m:8(){4.3b().4U("I-3c")},3y:8(b){L(4.1A){o c=4.3b();o a=4.3M();4.2m();b=a.1u(c)+b;b=(b+1)%(a.K+1)-1;-1===b?4.P("4Q"):(-1>b&&(b=a.K-1),4.3S(a=a.7o(b)),4.4P(a))}},4P:8(b){o c=b.1C().2x;b=c+b.7p(!0);o a=4.$N.3w();o e=4.$N.7r()+4E(4.$N.J("7t"),10)+4E(4.$N.J("7u"),10);0>c?4.$N.3w(a+c):e2a>\').J(n.5l);o f=g(\'<2a 2h="I-H-N">2a>\').J(n.H);o d=a.8h().J(n.Y).J(e(a));d.1d("").41().3z("I-Y").60("8k 1m 8l 2U").8m("8n",!0).1r({3e:"2f",3s:"8q",8r:-1});a.Q("4d",{1y:a.1r("1y"),3e:a.1r("3e"),3s:a.1r("3s"),3V:a.1r("3V")});a.3z("I-F").1r({3e:"2f",3s:!1}).J(c?n.F:n.5P);4K{!a.1r("1y")&&a.1r("1y","3D")}5q(m){}j a.8u(b).8v().44(c?d:G).20(f)}8 e(a){j{8w:a.J("1x-8y"),8z:a.J("1x-8A"),5M:a.J("1x-8B"),6i:a.J("1x-6n"),8C:a.J("1x-8D"),8E:a.J("1x-1C"),8F:a.J("1x-8G"),8H:a.J("1x-2n")}}8 c(a){o c=a.22(".I-F");d.M(c.Q("4d"),8(a,b){d.2p(a)?c.60(b):c.1r(b,a)});c.8I().41("4d").4U("I-F").5K(a);a.1B()}d.T(b.1b,{5f:8(a,c){o b;(b=4.H.3l(c))&&4.2J(b)},5e:8(){o a=4.H.3i();4.F.1S(a.1T,!0);4.1D.P("8K",a.3k,a.3j)},5d:8(){4.F.2Y();4.2z()},4S:8(){4.2z()},5b:8(){4.2z();4.1D.P("3x")},50:8(){4.F.1R();4.1D.P("3v")},4I:8(){4.35=!0;4.H.1f()},4y:8(){4.35=!1;4.H.18();4.H.1v()},4x:8(a,c){a=4.H.3i();o b=4.H.3d();a?(4.2J(a),c.24()):4.2A&&b&&(4.2J(b),c.24())},4w:8(a,c){(a=4.H.3i())?(4.2J(a),c.24()):4.3n(!0)},4v:8(){4.H.1v();4.F.2Y()},4u:8(){o a=4.F.2F();4.H.16&&a.K>=4.1F?4.H.23(a):4.H.6v();4.H.1f()},6s:8(){o a=4.F.2F();4.H.16&&a.K>=4.1F?4.H.23(a):4.H.6u();4.H.1f()},5Y:8(){"3A"===4.1y&&4.3n()},5G:8(){"2C"===4.1y&&4.3n()},56:8(a,c){4.F.3K();c.K>=4.1F?4.H.23(c):4.H.18();4.H.1f();4.2K()},55:8(){4.2z();4.H.1f()},2K:8(){o a;4.1y!==(a=4.F.6j())&&(4.1y=a,4.$19.J("6k",a),4.H.6w(a))},2z:8(){o a;L((a=4.H.3d())&&4.H.68()&&!4.F.4l()){o c=4.F.28();o b=x.3a(c);b=d.33(b);b=O 2R("^(?:"+b+")(.+$)","i");(a=b.4R(a.1T))?4.F.2Z(c+a[1]):4.F.1R()}4s 4.F.1R()},3n:8(a){o c=4.F.2v();o b=4.F.2F();a=a||4.F.6m();c&&b!==c&&a&&((c=4.H.3d())&&4.F.1S(c.1T),4.1D.P("8N",c.3k,c.3j))},2J:8(a){4.F.4i(a.1T);4.F.1S(a.1T,!0);4.2K();4.1D.P("8O",a.3k,a.3j);4.H.1v();d.1O(d.12(4.H.18,4.H))},1f:8(){4.H.1f()},1v:8(){4.H.1v()},4A:8(a){a=d.2H(a);4.35?4.F.1S(a):(4.F.4i(a),4.F.1S(a,!0));4.2K()},5p:8(){j 4.F.2F()},1p:8(){4.F.1p();4.H.1p();c(4.$19);4.$19=G}});j b}();(8(){o b=g.2V.2g;o h={3t:8(b,c){c=d.2I(c)?c:[].1i.1c(1e,1);b=b||{};j 4.M(8(){o a=g(4);d.M(c,8(a){a.26=!!b.26});o e=O E({F:a,1D:O w({U:a}),5B:d.2p(b.Y)?!0:!!b.Y,1F:b.1F,2A:b.2A,1j:c});a.Q("1G",e)})},1f:8(){j 4.M(8(){o b;(b=g(4).Q("1G"))&&b.1f()})},1v:8(){j 4.M(8(){o b;(b=g(4).Q("1G"))&&b.1v()})},1d:8(b){8 c(){o a;(a=g(4).Q("1G"))&&a.4A(b)}8 a(a){L(a=a.Q("1G"))o b=a.5p();j b}j 1e.K?4.M(c):a(4.2D())},1p:8(){j 4.M(8(){o b=g(4),c;L(c=b.Q("1G"))c.1p(),b.41("1G")})}};g.2V.2g=8(b){L(h[b]&&"3t"!==b){o c=4.1n(8(){j!!g(4).Q("1G")});j h[b].1g(c,[].1i.1c(1e,1))}j h.3t.1g(4,1e)};g.2V.2g.4L=8(){g.2V.2g=b;j 4}})()})(2q.8S);',62,551,'||||this||||function|||||||||||return|||||var|||||||||||||||||input|null|dropdown|tt|css|length|if|each|menu|new|trigger|data|onSync|remote|mixin|el|query||get|hint|ajax||templates|bind||url|for|isEmpty|prefetch|empty|node|storage|prototype|call|val|arguments|open|apply|on|slice|datasets|error|set|name|filter|suggestion|destroy|replace|attr|_callbacks|transport|index|close|add|background|dir|push|isOpen|remove|position|eventBus|noop|minLength|ttTypeahead|pattern|datums|next|trie|local|thumbprint|clear|defer|split|isFunction|clearHint|setInputValue|value|datumTokenizer|queryTokenizer|prev|head|footer|isNumber|append|reset|find|update|preventDefault|list|highlight||getInputValue|isMsie|span|map|header|children|_get|off|typeahead|class|source|font|is|limit|_removeCursor|size|text|isUndefined|window|_prefix|_ttlKey|display|delete|getHint|hash|top|left|_updateHint|autoselect|tail|ltr|first|className|getQuery|shift|toStr|isArray|_select|_setLanguageDirection|cacheKey|cancel|test|overflowHelper|protocol|setTimeout|RegExp|JSON|cancelled|required|fn|div|case|resetInputValue|setHint|removeItem|ids|Date|escapeRegExChars|templatify|isActivated|focus||||normalizeQuery|_getCursor|cursor|getDatumForTopSuggestion|autocomplete|blur|type|document|getDatumForCursor|datasetName|raw|getDatumForSuggestion|dataType|_autocomplete|rateLimitWait|onDeckRequestArgs|done|sorter|spellcheck|initialize|sync|closed|scrollTop|opened|_moveCursor|addClass|rtl|missing|_onInput|auto|right|whiteSpace|suggestions|absolute|block|relative|clearHintIfInvalid|initPromise|_getSuggestions|isString|pre|_show|_hide|Bloodhound|_setCursor|dupDetector|rateLimitBy|style|typeof|async|sort|canceled||removeData|resolve|rendered|prepend|Deferred|_cache|tab|rateLimiter|lastUrl|isExpired|setItem|_checkInputValue|ttAttrs|keyMatcher|break|join|prefix|setQuery|moveToFront|key|hasOverflow|100|displayFn|maxSize|concat|throttle|debounce|else|fail|_onUpKeyed|_onEscKeyed|_onTabKeyed|_onEnterKeyed|_onBlurred|some|setVal|every|getUniqueId|setImmediate|parseInt|onAsync|nonword|match|_onFocused|tagName|try|noConflict|wordsOnly|caseSensitive|childNodes|_ensureVisible|cursorRemoved|exec|_onDatasetRendered|splitText|removeClass|cursorMoved|_loadPrefetch|_saveToStorage|_readFromStorage|_getFromRemote|_onClosed|_onBlur|_onFocus|_onKeydown|_cancelLastRemoteRequest|_onWhitespaceChanged|_onQueryChanged|location|_initialize|keydown|_send|_onOpened|toLowerCase|_onCursorRemoved|_onCursorMoved|_onSuggestionClicked|datasetRendered|which|keyCode|navigator|whitespace|wrapper|bootstrap|hidden|clearTimeout|getVal|catch|cache|currentTarget|suggestionClicked|_onRendered|userAgent|_onSuggestionMouseLeave|_onSuggestionMouseEnter|_onSuggestionClick|serialize|__|withHint|spacing|transparent|none|getRoot|_onRightKeyed|parse|html|msie|insertAfter|verticalAlign|backgroundColor|_render|ttDatum|inputWithNoHint|extractDatum|ttValue|extractValue|ttDataset|extractDatasetName|getItem|ttl|up|_onLeftKeyed|down|removeAttr|blurred|focused|_managePreventDefault|_shouldTrigger|CLASS|switch|GET|isVisible|suggestionChild|default|resetCache|whitespaceChanged|queryChanged|json|requires|to|be|backgroundImage|getLanguageDirection|direction|width|isCursorAtEnd|image|selection|getTime|wildcard|dataset|_onDownKeyed|ttlKey|moveCursorDown|moveCursorUp|setLanguageDirection|normal|_a|Z0|invalid|character|moveStart|createRange|displayKey|selectionStart|indexOf|Keyed|trident|enter|esc|shiftKey|metaKey|ctrlKey|altKey|transform|textTransform|rendering|textRendering|indent|textIndent|letter|letterSpacing|word|wordSpacing|weight|fontWeight|variant|fontVariant|click|mouseenter|mouseleave|fontStyle|fontSize|family|fontFamily|visibility|true|aria|paste|hide|cut|keypress|String|replaceChild|parentNode|cloneNode|appendChild|createElement|nodeType|eq|outerHeight|strong|height|rv|paddingTop|paddingBottom|without|initialized|EventBus|isBlankString|1px|marginTop|yH5BAEAAAAALAAAAAABAAEAAAIBRAA7|R0lGODlhAQABAIAAAAAAAP|base64|gif|zA|pointer|nowrap|zIndex|opacity|boxShadow|borderColor|activeElement|has|stopImmediatePropagation|mousedown|inline|ttAdapter|clearRemoteCache|clearPrefetchCache|promise|encodeURIComponent|tokenizers|string|or|enterKeyed|of|tabKeyed|one|escKeyed|send|upKeyed|300|downKeyed|QUERY|leftKeyed|864E5|rightKeyed|number|both|are|and|twitter|clone|always|setMaxPendingRequests|id|placeholder|prop|readonly|reject|isObject|false|tabindex|localStorage|stringify|wrap|parent|backgroundAttachment|__ttl__|attachment|backgroundClip|clip|color|backgroundOrigin|origin|backgroundPosition|backgroundRepeat|repeat|backgroundSize|detach|isPlainObject|cursorchanged|undefined|obj|autocompleted|selected|proxy|grep|extend|jQuery'.split('|'),0,{})) \ No newline at end of file diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/resources/templates/assets/js/views/doc.js b/app/Admin/Extensions/dcat-admin-extension/dcat-page/resources/templates/assets/js/views/doc.js new file mode 100644 index 0000000..14b04eb --- /dev/null +++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/resources/templates/assets/js/views/doc.js @@ -0,0 +1,244 @@ + +const toc = require('./toc.js'); +const smallToc = require('./small-screen-toc.js'); + +function init() { + // gheading links + $('.docs-wrapper article').find("h2,h3,h4,h5").each(function (i, item) { + var $this = $(item), + tag = $this.get(0).tagName.toLowerCase(); + + if (tag != 'h5') { + $this.wrapInner($('')); + } + + // 判断标题是否设置了锚点 + if ($this.prev().find('a[name]').length) { + return; + } + + // 没有锚点则自动生成锚点 + var anchor = ($this.text().trim() + '-' + tag).replace(/[\?\#\&\<\>\=\'\"\\\/ ]/g, ''); + + $this.before(``); + + }); + + // 如果是自动生成的锚点,需要重新设置 location.href 属性 + function goAnchor() { + var url = location.href, path = window.document.location.pathname; + + if (url.indexOf('#') == -1) { + return; + } + + location.href = path + '#' + url.split('#')[1]; + + } + goAnchor(); + +// It's nice to just write in Markdown, so this will adjust +// our blockquote style to fill in the icon flag and label + $('.docs blockquote p').each(function() { + var str = $(this).html(); + var match = str.match(/\{(.*?)\}/); + + if (match) { + var icon = match[1] || false; + var word = match[1] || false; + } + + if (icon) { + switch (icon) { + case "note": + icon = ''; + break; + case "tip": + icon = '' + break; + case "laracasts": + case "video": + icon = ''; + break; + } + + $(this).html(str.replace(/\{(.*?)\}/, '{this.i18n.t('init')}
\nIssues`\n })\n }}/>\n
{this.i18n.t('please-contact', { user: [].concat(admin).map(u => `@${u}`).join(' ') })}
\n {(user && ~[].concat(admin).indexOf(user.login)) ?\n \n
: null}\n {!user && }\n{this.i18n.t('first-comment-person')}
}\n {(!isLoadOver && totalComments.length) ?简单、美观、轻量
+Laravel Horizon provides a beautiful dashboard and code-driven configuration for your Redis queues.
+ + +Laravel Nova is a beautiful administration panel designed by the creator of Laravel.
+ + +Event broadcasting, evolved. Bring the power of WebSockets to your application without the complexity.
+ +{$item['email']}
>";
+ }
+
+ return join('$data")->class('mb-0', true); + } +} diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Admin/DcatPageExtension.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Admin/DcatPageExtension.php new file mode 100644 index 0000000..8f61cf1 --- /dev/null +++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Admin/DcatPageExtension.php @@ -0,0 +1,44 @@ +registerMenu(); + + $this->routes(function () { + Route::get('dcat-page', Controllers\AdminController::class.'@index'); + Route::post('dcat-page/create-app', Controllers\AdminController::class.'@createApp'); + Route::post('dcat-page/compile-app', Controllers\AdminController::class.'@compileApp'); + Route::post('dcat-page/index-app', Controllers\AdminController::class.'@indexApp'); + }); + } + + public function registerMenu() + { + Admin::menu()->add([ + [ + 'id' => 'dcat-page', + 'title' => 'Dcat Page', + 'icon' => 'fa-file-text-o', + 'uri' => 'dcat-page', + 'parent_id' => 0, + 'permission_id' => 'dcat-page', + ], + ]); + } +} diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Admin/Grid/CompileButton.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Admin/Grid/CompileButton.php new file mode 100644 index 0000000..0f6955e --- /dev/null +++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Admin/Grid/CompileButton.php @@ -0,0 +1,102 @@ +setupScript(); + + return " "; + } + + protected function setupScript() + { + $submit = trans('admin.submit'); + + $url = admin_base_path('dcat-page/compile-app'); + + Admin::html( + << +
]*)>([^<]*)<\/code>/u', function (&$text) {
+ $attrs = $text[1] ?? '';
+ $text = e($text[2] ?? '');
+
+ return "{$text}
";
+ }, $content);
+ }
+
+ /**
+ * @param $content
+ *
+ * @return string
+ */
+ protected function htmlspecialcharsDecode($content)
+ {
+ return preg_replace_callback('/]*)>([^<]*)<\/code>/u', function (&$text) {
+ $attrs = $text[1] ?? '';
+ $text = htmlspecialchars_decode($text[2] ?? '');
+
+ return "{$text}
";
+ }, $content);
+ }
+
+ /**
+ * @param $url
+ *
+ * @return string
+ */
+ protected function getDocumentAssetsUrl($url)
+ {
+ if (
+ $url
+ && !in_array($url, ['#'])
+ && strpos($url, '#') !== 0
+ && !Str::contains($url, 'javascript:')
+ && !Str::contains($url, '//')
+ ) {
+ $url = '../../'.$url;
+ }
+
+ return $url;
+ }
+
+ /**
+ * 复制静态资源.
+ *
+ * @param $name
+ */
+ protected function copyAssets($name)
+ {
+ $from = $this->path($name.DIRECTORY_SEPARATOR.'public');
+ $dist = $this->getDistPath();
+
+ collect($this->files->allFiles($from, true))->each(function (SplFileInfo $fileInfo) use ($from, $dist) {
+ $realPath = $fileInfo->getRealPath();
+
+ $to = $dist.str_replace($from, '', $realPath);
+ $dir = dirname($to);
+ if (!is_dir($dir)) {
+ $this->files->makeDirectory($dir, 0755, true);
+ }
+
+ $this->files->copy($realPath, $to);
+ });
+ }
+
+ /**
+ * 获取页面目录.
+ *
+ * @param $name
+ *
+ * @return string
+ */
+ public function getPagesPath($name)
+ {
+ return $this->path($name).DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'pages';
+ }
+
+ /**
+ * 获取编译目录.
+ *
+ * @return mixed
+ */
+ public function getDistPath()
+ {
+ return $this->distPath;
+ }
+
+ /**
+ * 拼接编译目录.
+ *
+ * @param $name
+ *
+ * @return string
+ */
+ protected function createDistPath($name)
+ {
+ $dirName = $this->getDir($name);
+
+ return $this->getDistBasePath($name, $dirName);
+ }
+
+ /**
+ * 拼接编译目录.
+ *
+ * @param $name
+ * @param $dirName
+ *
+ * @return string
+ */
+ public function getDistBasePath($name, $dirName)
+ {
+ if (!$path = $this->option('path')) {
+ return $this->path($name.DIRECTORY_SEPARATOR.'_dist_'.DIRECTORY_SEPARATOR.$dirName);
+ }
+
+ // 如果指定了路径
+ $path = $this->replaceDistPath($path, $name);
+
+ if (!is_dir($path)) {
+ $this->files->makeDirectory($path, 0755, true);
+ }
+
+ return $path.DIRECTORY_SEPARATOR.$dirName;
+ }
+
+ /**
+ * 获取编译文件夹名称.
+ *
+ * @param $name
+ *
+ * @return false|string
+ */
+ public function getDir($name)
+ {
+ $dir = $this->replaceDistPath($this->option('dir') ?: date('Ymd-His'), $name);
+
+ $fullPath = rtrim($this->getDistBasePath($name, ''), '/');
+
+ if (!is_dir($fullPath)) {
+ return $dir;
+ }
+
+ $same = 0;
+ collect($this->files->directories($fullPath))->map(function ($v) use ($dir, &$same) {
+ $v = preg_replace('(-[0-9]+$)', '', basename($v));
+
+ if ($v == $dir) {
+ $same++;
+ }
+ });
+
+ if (!$same) {
+ return $dir;
+ }
+
+ return $dir.'-'.($same);
+ }
+
+ /**
+ * @param string $path
+ * @param string $name
+ *
+ * @return string
+ */
+ protected function replaceDistPath($path, $name)
+ {
+ return str_replace(':app', $name, $path);
+ }
+
+ /**
+ * 获取所有应用名称.
+ *
+ * @return array
+ */
+ public function getAllAppNames()
+ {
+ return DcatPage::getAllAppNames();
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/CreateCommand.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/CreateCommand.php
new file mode 100644
index 0000000..f7040e8
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/CreateCommand.php
@@ -0,0 +1,126 @@
+getAppName();
+
+ if ($this->exist($name)) {
+ return $this->error("[$name] already exists!");
+ }
+
+ $path = $this->path($name);
+
+ $from = $this->getTemplatePath();
+
+ $this->makeDirectories($from, $path);
+ $this->copy($from, $path);
+
+ $this->showTree($path);
+ }
+
+ protected function showTree($path)
+ {
+ $tree = <<info($tree);
+ }
+
+ protected function copy($from, $to)
+ {
+ /* @var Filesystem $files */
+ $files = app('files');
+
+ $allFiles = collect($files->allFiles($from, true))->map(function (SplFileInfo $fileInfo) {
+ return $fileInfo->getRealPath();
+ })->toArray();
+
+ foreach ($allFiles as $path) {
+ $files->copy($path, $to.str_replace($from, '', $path));
+ }
+ }
+
+ protected function makeDirectories($from, $to)
+ {
+ if (!is_dir($from)) {
+ return;
+ }
+
+ /* @var Filesystem $files */
+ $files = app('files');
+
+ if (!is_dir($to)) {
+ $files->makeDirectory($to, 0755, true);
+ }
+
+ foreach ($files->directories($from) as $dir) {
+ $dir = basename($dir);
+
+ $files->makeDirectory($to.'/'.$dir);
+
+ $this->makeDirectories($from.'/'.$dir, $to.'/'.$dir);
+ }
+ }
+
+ protected function getTemplatePath()
+ {
+ return dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'templates';
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/DcatApp.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/DcatApp.php
new file mode 100644
index 0000000..3a72d39
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/DcatApp.php
@@ -0,0 +1,111 @@
+appName) {
+ return $this->appName;
+ }
+
+ if (!$this->hasArgument('name')) {
+ return null;
+ }
+
+ $name = str_replace('.', '-', $this->argument('name'));
+
+ return slug($name);
+ }
+
+ /**
+ * 设置应用名称.
+ *
+ * @param $name
+ */
+ protected function setAppName($name)
+ {
+ $this->appName = $name;
+ }
+
+ /**
+ * 获取应用目录.
+ *
+ * @param $name
+ *
+ * @return string
+ */
+ public function path($name)
+ {
+ return resource_path(DcatPage::NAME.DIRECTORY_SEPARATOR.$name);
+ }
+
+ /**
+ * 判断应用目录是否存在.
+ *
+ * @param $name
+ *
+ * @return bool
+ */
+ public function exist($name)
+ {
+ return is_dir($this->path($name));
+ }
+
+ /**
+ * 写文件.
+ *
+ * @param $path
+ * @param $content
+ *
+ * @return bool|int
+ */
+ public function putContent($path, $content)
+ {
+ if (!isset($this->files) || !$this->files) {
+ $this->files = app('files');
+ }
+
+ $dir = dirname($path);
+ if (!is_dir($dir)) {
+ $this->files->makeDirectory($dir, 0755, true);
+ }
+
+ if (isset($this->counter)) {
+ $this->counter++;
+ }
+
+ return $this->files->put($path, $content);
+ }
+
+ /**
+ * @param $doc
+ *
+ * @return bool
+ */
+ public function shouldSkip($doc)
+ {
+ if (!isset($this->skipDocs)) {
+ $this->skipDocs = array_map(function ($v) {
+ return $v.'.md';
+ }, array_merge([
+ \DcatPage\config('doc.index'),
+ 'LICENSE',
+ 'README',
+ ], (array) \DcatPage\config('doc.ignore')));
+ }
+
+ return in_array($doc, $this->skipDocs);
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/IndexCommand.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/IndexCommand.php
new file mode 100644
index 0000000..a757890
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Console/IndexCommand.php
@@ -0,0 +1,399 @@
+getAppName();
+
+ if ($name && !$this->exist($name)) {
+ return $this->error("[$name] not found!");
+ }
+
+ $this->files = app('files');
+
+ if (!$name) {
+ $name = DcatPage::getAllAppNames();
+ }
+
+ foreach ((array) $name as $app) {
+ $this->generate($app);
+ }
+ }
+
+ /**
+ * 生成json格式文档.
+ *
+ * @param $name
+ */
+ protected function generate($name)
+ {
+ DcatPage::init($name, true);
+
+ $docBasePath = str_replace('\\', '/', path('docs'));
+
+ collect($this->files->directories($docBasePath))->map(function ($dir) use ($name) {
+ $version = basename($dir);
+
+ $nodes = $this->generateIndices($dir, $name, $version);
+
+ $base = 'public/assets/indices/'.$version.'.js';
+ $path = path($base);
+
+ $this->putContent($path, $this->formatIndices($nodes));
+
+ $this->info("[{$name} --- {$base}] created successfully.");
+ });
+ }
+
+ /**
+ * 生成索引节点.
+ *
+ * @param $path
+ * @param $name
+ * @param $version
+ *
+ * @return array
+ */
+ protected function generateIndices($path, $name, $version)
+ {
+ $values = [];
+
+ collect($this->files->allFiles($path, true))->each(function (SplFileInfo $fileInfo) use (&$values, $name, $version) {
+ if ($this->shouldSkip(basename($fileInfo->getRealPath()))) {
+ return;
+ }
+
+ try {
+ $content = $this->getDocContent($fileInfo->getRealPath());
+
+ $crawler = new Crawler(markdown($content));
+
+ // 获取总标题下的内容
+ $node = $this->filterTopContent($crawler);
+
+ // 获取所有下级内容
+ $nodes = $this->filterWithTag($crawler, $this->tags);
+ $nodes = $this->unique($nodes, 'name');
+
+ $node && array_unshift($nodes, $node);
+
+ $link = str_replace('.md', '', slug(basename($fileInfo->getRealPath())));
+
+ $title = $crawler->count() ? $crawler->filterXPath('//h1')->text() : null;
+ } catch (\Exception $e) {
+ }
+
+ if (!empty($title) || !empty($nodes)) {
+ $values[] = [
+ 'title' => $title ?? null,
+ 'link' => $link ?? null,
+ 'nodes' => $nodes ?? [],
+ ];
+ }
+ });
+
+ return array_filter($values);
+ }
+
+ /**
+ * 获取总标题下的内容.
+ *
+ * @param Crawler $crawler
+ *
+ * @return array
+ */
+ protected function filterTopContent(Crawler $crawler)
+ {
+ $end = false;
+
+ try {
+ $values = $crawler->children()->first()->children()->each(function (Crawler $node) use (&$end) {
+ if ($node->nodeName() == 'h1' || !$node->count()) {
+ return;
+ }
+ if ($end || in_array($node->nodeName(), $this->tags)) {
+ $end = true;
+
+ return;
+ }
+
+ return $node->text();
+ });
+ } catch (\Exception $e) {
+ $values = [];
+ }
+
+ $text = implode(' ', array_filter($values));
+
+ if (!$text) {
+ return [];
+ }
+
+ return [
+ 'h2' => '',
+ 'h3' => '',
+ 'h4' => '',
+ 'name' => '',
+ 'content' => $this->replaceText($text),
+ ];
+ }
+
+ /**
+ * 按标题分类生成索引数组.
+ *
+ * @param Crawler $crawler
+ * @param array $tags
+ * @param array $prevTags
+ * @param array $titles
+ *
+ * @return array
+ */
+ protected function filterWithTag(Crawler $crawler, array $tags, array $prevTags = [], array $titles = [])
+ {
+ if (!$tags) {
+ return [];
+ }
+
+ $tag = array_shift($tags);
+
+ $nodes = $crawler->filter($tag);
+
+ if (!$nodes->count()) {
+ // 如果中间有标题“断层”(如:h2,h4,中间少了h3),会一直往下找
+ // 但是会有获取到重复的数据,所以需要在获取到所有数据后进行去重
+ array_unshift($prevTags, $tag);
+
+ return $this->filterWithTag($crawler, $tags, $prevTags, $titles);
+ }
+
+ $values = $nodes->each(function (Crawler $node) use (&$prevTags, &$tags, &$titles) {
+ $currentTag = $node->nodeName();
+
+ // 标题
+ $titles[$currentTag] = $node->text();
+
+ // 锚点名称
+ $name = $this->getAnchorName($node);
+
+ // 合并所有标题标签名称
+ $allTags = array_merge($prevTags, $tags, [$currentTag]);
+
+ // 获取标题下最顶部文本(不属于任何子标题的文本)
+ $topContent = null;
+ if ($topText = $this->getNextAllText($node, $allTags)) {
+ $topContent = array_merge([
+ 'h2' => '',
+ 'h3' => '',
+ 'h4' => '',
+ 'name' => $name,
+ 'content' => $topText,
+ ], $titles);
+ }
+
+ if (!in_array($currentTag, $prevTags)) {
+ array_unshift($prevTags, $currentTag);
+ }
+
+ $end = false;
+ $allNextNodes = $node->count() ? $node->nextAll()->each(function (Crawler $node) use (&$end, &$tags, &$titles, &$prevTags) {
+ if (!$node->count()) {
+ return;
+ }
+
+ if ($end || in_array($node->nodeName(), $prevTags)) {
+ $end = true;
+
+ return;
+ }
+
+ // 递归获取所有子标题下的内容
+ return $this->filterWithTag($node, $tags, $prevTags, $titles);
+ }) : [];
+
+ // 过滤空数组
+ $allNextNodes = array_values(array_filter($allNextNodes, function ($v) {
+ return !empty($v);
+ }));
+
+ // 三维数组转为二维
+ if ($allNextNodes && !Arr::isAssoc($allNextNodes[0])) {
+ $allNextNodes = Arr::flatten($allNextNodes, 1);
+ }
+
+ $topContent && array_unshift($allNextNodes, $topContent);
+
+ return $allNextNodes;
+ });
+
+ return Arr::flatten($values, 1);
+ }
+
+ /**
+ * 获取下面所有相邻节点的文本内容.
+ *
+ * @param Crawler $node
+ * @param $endTag
+ *
+ * @return string
+ */
+ protected function getNextAllText(Crawler $node, $endTag)
+ {
+ if (!$node->count()) {
+ return '';
+ }
+
+ $end = false;
+ $endTag = (array) $endTag;
+
+ $contents = $node->nextAll()->each(function (Crawler $node) use (&$end, $endTag) {
+ if (!$node->count()) {
+ return;
+ }
+ if ($end || in_array($node->nodeName(), $endTag)) {
+ $end = true;
+
+ return;
+ }
+
+ return $this->replaceText($node->text());
+ });
+
+ return implode(' ', array_filter($contents));
+ }
+
+ /**
+ * 获取锚点名称.
+ *
+ * @param Crawler $node
+ *
+ * @return string|null
+ */
+ protected function getAnchorName(Crawler $node)
+ {
+ if (!$node->count()) {
+ return;
+ }
+
+ $name = $node->previousAll()->first()->filter('a[name]');
+
+ return $name->count() ? $name->attr('name') :
+ (trim(str_replace([' ', '?', '#', '/', '\\', '&', '\'', '"', '<', '>', '='], '', $node->text())).'-'.$node->nodeName());
+ }
+
+ /**
+ * 获取文档内容.
+ *
+ * @param $path
+ *
+ * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+ *
+ * @return string
+ */
+ protected function getDocContent($path)
+ {
+ $content = $this->files->get($path);
+
+ // 过滤导航标题
+ // - [xxx](xxx)
+ return preg_replace("/((?:-\s*){1}\[[^\]]*?\]\([^\)]*?\))/", '', trim($content));
+ }
+
+ /**
+ * @param $content
+ *
+ * @return string
+ */
+ protected function replaceText($content)
+ {
+ // 过滤无意义字符
+ $content = str_replace(['{tip}', '{note}', '{vedio}', "\r"], '', $content);
+ $content = preg_replace('/(.*?<\/a>)/', '', $content);
+ $content = preg_replace('/([\s]+)/', ' ', $content);
+ $content = str_replace(["\n"], ' ', $content);
+
+ return $content;
+ }
+
+ /**
+ * @param array $indices
+ *
+ * @return string
+ */
+ protected function formatIndices(array $indices)
+ {
+ $indices = json_encode($indices, JSON_UNESCAPED_UNICODE);
+
+ return 'window.CURRENT_INDICES='.str_replace('\/', '/', $indices);
+ }
+
+ /**
+ * 二维数组按指定键去重.
+ *
+ * @param array $values
+ * @param string $key
+ *
+ * @return array
+ */
+ protected function unique(array $values, ?string $key)
+ {
+ $keys = [];
+
+ foreach ($values as $k => $v) {
+ if (!isset($v[$key]) || in_array($v[$key], $keys)) {
+ unset($values[$k]);
+ continue;
+ }
+
+ $keys[] = $v[$key];
+ }
+
+ return array_values($values);
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/DcatPage.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/DcatPage.php
new file mode 100644
index 0000000..6b78e07
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/DcatPage.php
@@ -0,0 +1,126 @@
+ $config]);
+ }
+
+ /**
+ * @param bool $isCompiling
+ */
+ public static function setIsCompiling(bool $isCompiling)
+ {
+ self::$isCompiling = $isCompiling;
+ }
+
+ /**
+ * 判断项目是否在编译中.
+ *
+ * @return bool
+ */
+ public static function isCompiling()
+ {
+ return static::$isCompiling;
+ }
+
+ /**
+ * 监听编译事件.
+ *
+ * @param $listener
+ */
+ public static function compiling($listener)
+ {
+ Event::listen('dcat-page:compiling', $listener);
+ }
+
+ /**
+ * 触发编译中事件.
+ *
+ * @param Console\CompileCommand $comman
+ */
+ public static function callCompiling(Console\CompileCommand $command)
+ {
+ Event::dispatch('dcat-page:compiling', $command);
+ }
+
+ /**
+ * 设置当前应用名称.
+ *
+ * @param string|null $app
+ */
+ public static function setCurrentAppName(?string $app)
+ {
+ static::$appName = $app;
+ }
+
+ /**
+ * 获取当前应用名称.
+ *
+ * @return string
+ */
+ public static function getCurrentAppName()
+ {
+ return static::$appName;
+ }
+
+ /**
+ * 获取所有应用名称.
+ *
+ * @return array
+ */
+ public static function getAllAppNames()
+ {
+ return static::$allAppNames ?: (static::$allAppNames = array_map(
+ 'basename',
+ app('files')->directories(Fun\path())
+ ));
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/DcatPageServiceProvider.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/DcatPageServiceProvider.php
new file mode 100644
index 0000000..7b8c98b
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/DcatPageServiceProvider.php
@@ -0,0 +1,77 @@
+boot();
+ }
+
+ $this->registerRoutes();
+
+ $this->loadViewsFrom(resource_path(DcatPage::NAME), DcatPage::NAME);
+ }
+
+ /**
+ * Register routes.
+ */
+ public function registerRoutes()
+ {
+ $this->app->make('router')->group([
+ 'prefix' => DcatPage::NAME,
+ 'middleware' => $this->middlewares,
+ 'namespace' => 'Dcat\Page\Http\Controllers',
+ ], function () {
+ Route::get('{app}/resource/{path}', 'PageController@resource')->where('path', '.*');
+ Route::get('{app}/docs/{version?}/{doc?}', 'PageController@doc');
+ Route::get('{app}/{view?}', 'PageController@page')->where('view', '.*');
+ });
+ }
+
+ /**
+ * Register any application services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ $this->commands($this->commands);
+
+ if (!defined('DCAT_PAGE_VERSION')) {
+ include __DIR__.'/helpers.php';
+ }
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Documentation.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Documentation.php
new file mode 100644
index 0000000..28815ff
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Documentation.php
@@ -0,0 +1,171 @@
+files = $files;
+ $this->setBasePath($basePath);
+ }
+
+ /**
+ * @param $basePath
+ */
+ public function setBasePath($basePath)
+ {
+ $this->basePath = $basePath;
+ }
+
+ /**
+ * @param string $path
+ *
+ * @return string
+ */
+ public function fullPath($path)
+ {
+ $path = $this->basePath.'/'.trim($path, '/');
+
+ if (!Str::contains($path, '.md')) {
+ $path .= '.md';
+ }
+
+ return $path;
+ }
+
+ /**
+ * Get the documentation index page.
+ *
+ * @param string $version
+ *
+ * @return string
+ */
+ public function getIndex($version, $index = 'documentation')
+ {
+ $path = $this->fullPath("{$version}/{$index}");
+
+ if ($this->files->exists($path)) {
+ return $this->replaceLinks($version, markdown($this->files->get($path)));
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the given documentation page.
+ *
+ * @param string $version
+ * @param string $page
+ *
+ * @return string
+ */
+ public function get($version, $page)
+ {
+ $path = $this->fullPath($version.'/'.$page);
+
+ if ($this->files->exists($path)) {
+ return $this->replaceLinks($version, markdown($this->files->get($path)));
+ }
+
+ return null;
+ }
+
+ /**
+ * Replace the version place-holder in links.
+ *
+ * @param string $version
+ * @param string $content
+ *
+ * @return string
+ */
+ public static function replaceLinks($version, $content)
+ {
+ if (!$content) {
+ return $content;
+ }
+
+ $path = '/'.trim(asset('/'), '/');
+
+ if (DcatPage::isCompiling()) {
+ $path = '';
+
+ $content = preg_replace_callback('/href[\s]*=[\s]*[\"\']([\s]*[\w-]+.md[^\"\']*)[\"\']/u', function (&$text) use ($version) {
+ $text = $text[1] ?? '';
+
+ return 'href="'.generate_doc_path_when_compiling($version, $text).'"';
+ }, $content);
+
+ $content = str_replace('{{public}}/', '{{public}}', $content);
+ }
+
+ $content = str_replace(['{{version}}', '{{public}}'], [$version, $path], $content);
+ $content = str_replace('{', '{', $content);
+
+ return $content;
+ }
+
+ /**
+ * Check if the given section exists.
+ *
+ * @param string $version
+ * @param string $page
+ *
+ * @return bool
+ */
+ public function sectionExists($version, $page)
+ {
+ return $this->files->exists(
+ $this->fullPath($version.'/'.$page)
+ );
+ }
+
+ /**
+ * @param null $basePath
+ *
+ * @return static
+ */
+ public static function make($basePath = null)
+ {
+ $basePath = $basePath ?: path('docs');
+
+ return new static(app('files'), $basePath);
+ }
+
+ /**
+ * @return array
+ */
+ public function getVersions()
+ {
+ if (!isset($this->versions)) {
+ $this->versions = array_map('basename', $this->files->directories($this->basePath));
+ }
+
+ return $this->versions;
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Assets.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Assets.php
new file mode 100644
index 0000000..9bf650e
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Assets.php
@@ -0,0 +1,139 @@
+ 'application/json',
+ 'css' => 'text/css',
+ 'js' => 'text/javascript',
+ 'html' => 'text/html',
+ 'htm' => 'text/html',
+ 'txt' => 'text/plain',
+ 'text' => 'text/plain',
+ 'conf' => 'text/plain',
+ 'log' => 'text/plain',
+ 'gif' => 'image/gif',
+ 'jpg' => 'image/jpg',
+ 'jpeg' => 'image/jpeg',
+ 'pjpeg' => 'image/pjpeg',
+ 'jp2' => 'image/jp2',
+ 'jpg2' => 'image/jp2',
+ 'jpm' => 'image/jpm',
+ 'jpgm' => 'image/jpm',
+ 'jpx' => 'image/jpx',
+ 'jpf' => 'image/jpx',
+ 'svg' => 'image/svg+xml',
+ 'svgz' => 'image/svg+xml-compressed',
+ '3ds' => 'image/x-3ds',
+ 'png' => 'image/png',
+ 'x-png' => 'image/x-png',
+ 'webp' => 'image/webp',
+ 'x-webp' => 'image/x-webp',
+ 'bmp' => 'image/bmp',
+ 'ico' => 'image/icon',
+ 'icon' => 'image/icon',
+ 'avi' => 'video/avi',
+ 'avf' => 'video/avi',
+ 'divx' => 'video/avi',
+ 'dv' => 'video/dv',
+ 'flv' => 'video/flv',
+ 'mp4' => 'video/mp4',
+ 'mp4v' => 'video/mp4',
+ 'mpg4' => 'video/mp4',
+ 'f4v' => 'video/mp4',
+ 'lrv' => 'video/mp4',
+ 'wmv' => 'video/x-ms-wmv',
+ 'wm' => 'video/x-ms-wm',
+ 'asf' => 'video/x-ms-wm',
+ 'ogv' => 'video/x-ogg',
+ 'ogg' => 'video/x-ogg',
+ 'mp3' => 'audio/mp3',
+ 'flac' => 'audio/flac',
+ 'wma' => 'audio/wma',
+ 'amr' => 'audio/amr-encrypted',
+ '3gp' => 'audio/3gpp',
+ '3gpp' => 'audio/3gpp',
+ '3ga' => 'audio/3gpp',
+ ];
+
+ public static function addMimeType(string $extension, string $type)
+ {
+ if (!$extension || !$type) {
+ return;
+ }
+ static::$mimeTypeMap[$extension] = $type;
+ }
+
+ /**
+ * 读取请求文件.
+ *
+ * @param $path
+ *
+ * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+ *
+ * @return Response
+ */
+ public static function response($path)
+ {
+ if ($fullPath = static::getFullPath($path)) {
+ return static::makeResponseWithPath($fullPath);
+ }
+
+ abort(404);
+ }
+
+ /**
+ * 发送文件.
+ *
+ * @param string $path 文件完整路径
+ *
+ * @return Response
+ */
+ public static function makeResponseWithPath(string $path)
+ {
+ $fileInfo = pathinfo($path);
+ $extension = isset($fileInfo['extension']) ? $fileInfo['extension'] : '';
+
+ $headers = [
+ 'Content-Type' => 'application/octet-stream',
+ 'Content-Disposition' => '',
+ 'Connection' => 'keep-alive',
+ ];
+
+ if (!empty(static::$mimeTypeMap[$extension])) {
+ $headers['Content-Type'] = static::$mimeTypeMap[$extension];
+ } else {
+ $headers['Content-Type'] = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
+ }
+
+ return response(file_get_contents($path), 200, $headers);
+ }
+
+ /**
+ * 根据请求地址查找文件路径.
+ *
+ * @param string $path
+ *
+ * @return null|string
+ */
+ public static function getFullPath(string $path)
+ {
+ if (is_file($path)) {
+ return $path;
+ }
+
+ return null;
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Controllers/PageController.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Controllers/PageController.php
new file mode 100644
index 0000000..f22c07f
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Controllers/PageController.php
@@ -0,0 +1,122 @@
+isVersion($docs, $version)) {
+ return redirect(DcatPage\url('docs/'.DcatPage\default_version().'/'.$page));
+ }
+
+ $sectionPage = $page ?: 'installation';
+ $content = $docs->get($version, $sectionPage);
+
+ if (is_null($content)) {
+ return response()->view(DcatPage\view_name('pages.docs'), [
+ 'title' => 'Page not found',
+ 'index' => $docs->getIndex($version),
+ 'content' => DcatPage\view('partials.doc-missing'),
+ 'currentVersion' => $version,
+ 'versions' => $docs->getVersions(),
+ 'currentSection' => $page,
+ 'canonical' => null,
+ 'showSwitcher' => true,
+ ], 404);
+ }
+
+ $title = (new Crawler($content))->filterXPath('//h1');
+
+ $section = '';
+
+ if ($docs->sectionExists($version, $page)) {
+ $section .= '/'.$page;
+ } elseif (!is_null($page)) {
+ return redirect(DcatPage\url('/docs/'.$version));
+ }
+
+ $canonical = null;
+
+ if ($docs->sectionExists(DcatPage\default_version(), $sectionPage)) {
+ $canonical = 'docs/'.DcatPage\default_version().'/'.$sectionPage;
+ }
+
+ return DcatPage\page('docs')->with([
+ 'title' => count($title) ? $title->text() : null,
+ 'index' => $docs->getIndex($version),
+ 'content' => $content,
+ 'currentVersion' => $version,
+ 'versions' => $docs->getVersions(),
+ 'currentSection' => $section,
+ 'canonical' => $canonical,
+ 'showSwitcher' => true,
+ ]);
+ }
+
+ /**
+ * 应用静态资源加载.
+ *
+ * @param $app
+ * @param $path
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function resource($app, $path)
+ {
+ return Assets::response(DcatPage\path(
+ 'public/'.trim($path, '/')
+ ));
+ }
+
+ /**
+ * 判断版本号.
+ *
+ * @param Documentation $docs
+ * @param $version
+ *
+ * @return bool
+ */
+ protected function isVersion(Documentation $docs, $version)
+ {
+ return in_array($version, $docs->getVersions());
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Middleware/Initialization.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Middleware/Initialization.php
new file mode 100644
index 0000000..b4e259e
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/Http/Middleware/Initialization.php
@@ -0,0 +1,24 @@
+route()->parameter('app')
+ );
+
+ return $next($request);
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/helpers.php b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/helpers.php
new file mode 100644
index 0000000..b53d7fc
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/dcat-page/src/helpers.php
@@ -0,0 +1,301 @@
+text($text);
+ }
+
+ /**
+ * 获取静态资源路径.
+ *
+ * @param $path
+ * @param null $app 应用名称
+ *
+ * @return string
+ */
+ function asset($path, $app = null)
+ {
+ if (Str::contains($path, '//')) {
+ return $path;
+ }
+
+ if (DcatPage::isCompiling()) {
+ return trim($path, '/');
+ }
+
+ $app = $app ?: DcatPage::getCurrentAppName();
+
+ $name = DcatPage::NAME;
+
+ return "/$name/$app/resource/".trim($path, '/');
+ }
+
+ /**
+ * 获取页面链接.
+ *
+ * @param $url
+ * @param null $app
+ *
+ * @return string
+ */
+ function url($url, $app = null)
+ {
+ if (\url()->isValidUrl($url)) {
+ return $url;
+ }
+
+ if (DcatPage::isCompiling()) {
+ if (!$url = trim($url, '/')) {
+ return 'index.html';
+ }
+
+ if (!Str::contains($url, '.html')) {
+ $url .= '.html';
+ }
+
+ return str_replace('/', '-', slug($url));
+ }
+
+ $app = $app ?: DcatPage::getCurrentAppName();
+
+ $name = DcatPage::NAME;
+
+ return "/$name/$app/".trim($url, '/');
+ }
+
+ /**
+ * 获取文档链接.
+ *
+ * @param $doc
+ * @param null $version
+ *
+ * @return mixed|string
+ */
+ function doc_url($doc, $version = null)
+ {
+ $version = $version ?: default_version();
+
+ if (DcatPage::isCompiling()) {
+ return generate_doc_path_when_compiling($version, $doc);
+ }
+
+ return url("docs/$version/$doc");
+ }
+
+ /**
+ * 生成编译环境的文档路径.
+ *
+ * @param string $version
+ * @param string $doc
+ *
+ * @return mixed
+ */
+ function generate_doc_path_when_compiling($version, $doc)
+ {
+ if (!Str::contains($doc, '.md')) {
+ $doc .= '.md';
+ }
+
+ return slug("docs/{$version}/".str_replace('.md', '.html', $doc));
+ }
+
+ /**
+ * 获取页面视图.
+ *
+ * @param $view
+ * @param null $app
+ *
+ * @return \Illuminate\View\View
+ */
+ function page($view, $app = null)
+ {
+ $app = $app ?: DcatPage::getCurrentAppName();
+
+ $name = DcatPage::NAME;
+
+ $view = "$name::{$app}.views.pages.{$view}";
+
+ abort_if(!\view()->exists($view), 404);
+
+ return \view($view);
+ }
+
+ /**
+ * 获取页面视图名称.
+ *
+ * @param $view
+ * @param null $app
+ *
+ * @return string
+ */
+ function view_name($view, $app = null)
+ {
+ $app = $app ?: DcatPage::getCurrentAppName();
+
+ $name = DcatPage::NAME;
+
+ return "$name::{$app}.views.{$view}";
+ }
+
+ /**
+ * 获取视图.
+ *
+ * @param $view
+ * @param null $app
+ *
+ * @return \Illuminate\View\View
+ */
+ function view($view, $app = null)
+ {
+ $view = view_name($view, $app);
+
+ abort_if(!\view()->exists($view), 404);
+
+ return \view($view);
+ }
+
+ /**
+ * 渲染视图.
+ *
+ * @param $view
+ * @param null $app
+ *
+ * @return string
+ */
+ function render($view, array $vars = [])
+ {
+ return view($view)->with($vars)->render();
+ }
+
+ /**
+ * 获取css引入html.
+ *
+ * @param $path
+ * @param null $app
+ *
+ * @return string
+ */
+ function html_css($path, $app = null)
+ {
+ $path = asset($path, $app);
+
+ return <<
+HTML;
+ }
+
+ /**
+ * 获取js引入html.
+ *
+ * @param $path
+ * @param null $app
+ *
+ * @return string
+ */
+ function html_js($path, $app = null)
+ {
+ $path = asset($path, $app);
+
+ return <<
+HTML;
+ }
+
+ /**
+ * Generate a URL friendly "slug" from a given string.
+ *
+ * @param string $name
+ * @param string $symbol
+ *
+ * @return mixed
+ */
+ function slug(string $name, string $symbol = '-')
+ {
+ $text = preg_replace_callback('/([A-Z])/', function (&$text) use ($symbol) {
+ return $symbol.strtolower($text[1]);
+ }, $name);
+
+ return str_replace('_', $symbol, ltrim($text, $symbol));
+ }
+
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/LICENSE b/app/Admin/Extensions/dcat-admin-extension/gank/LICENSE
new file mode 100644
index 0000000..8a6acd5
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 jqh
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/README.md b/app/Admin/Extensions/dcat-admin-extension/gank/README.md
new file mode 100644
index 0000000..2939467
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/README.md
@@ -0,0 +1,26 @@
+Dcat Admin扩展 - 干货集中营
+======
+
+这是一个`Dcat Admin`的扩展包,写着玩的。
+
+## 安装
+
+请先确保安装了[Dcat Admin](https://github.com/jqhph/dcat-admin),执行
+```php
+composer require dcat-admin-extension/gank
+```
+
+最后用浏览器打开`http://localhost:8000/admin/helpers/extensions`找到`gank`这一行,点击`启用`按钮,即可使用。
+
+除了通过界面启用扩展,也可以手动开启扩展:打开`config/admin-extensions.php`(如果文件不存在请手动创建),加入以下代码:
+```php
+return [
+ 'gank' => [
+ 'enable' => true,
+ ],
+];
+```
+
+## 使用
+
+以上步骤都完成之后刷新页面,就可以看到`干货集中营`的菜单了。
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/composer.json b/app/Admin/Extensions/dcat-admin-extension/gank/composer.json
new file mode 100644
index 0000000..40d2aea
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "dcat-admin-extension/gank",
+ "description": "每日分享妹子图 和 技术干货",
+ "type": "library",
+ "keywords": ["dcat-admin", "extension", "gank"],
+ "homepage": "https://github.com/jqhph",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "jqh",
+ "email": "841324345@qq.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.1.0",
+ "guzzlehttp/guzzle": "^6.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~6.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Dcat\\Admin\\Extension\\Gank\\": "src/"
+ },
+ "files": [
+ "src/bootstrap.php"
+ ]
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/resources/assets/index.js b/app/Admin/Extensions/dcat-admin-extension/gank/resources/assets/index.js
new file mode 100644
index 0000000..7bf9477
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/resources/assets/index.js
@@ -0,0 +1,2 @@
+
+console.log('Hello gank');
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/resources/views/index.blade.php b/app/Admin/Extensions/dcat-admin-extension/gank/resources/views/index.blade.php
new file mode 100644
index 0000000..3bffab8
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/resources/views/index.blade.php
@@ -0,0 +1 @@
+Welcome to dcat-admin
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/routes/web.php b/app/Admin/Extensions/dcat-admin-extension/gank/routes/web.php
new file mode 100644
index 0000000..6de83ba
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/routes/web.php
@@ -0,0 +1,8 @@
+ 'var(--purple)',
+ '前端' => 'var(--primary)',
+ '拓展资源' => 'var(--primary-dark)',
+ '瞎推荐' => 'var(--blue)',
+ '福利' => 'var(--danger)',
+ 'Android' => 'var(--purple-dark)',
+ 'iOS' => 'var(--info)',
+ '休息视频' => 'var(--warning)',
+ ];
+
+ public static function navbar()
+ {
+ $items = array_keys(self::$categoryColorsMap);
+ array_unshift($items, '全部');
+
+ return Navbar::make('#', array_combine($items, $items))
+ ->checked(request(Grid\Filter\Scope::QUERY_NAME, '全部'))
+ ->click()
+ ->map(function ($v) {
+ if ($v == '全部') {
+ $url = '?';
+ } else {
+ $url = '?'.Grid\Filter\Scope::QUERY_NAME.'='.$v;
+ }
+
+ return "$v";
+ })
+ ->style('max-width:705px');
+ }
+
+ /**
+ * Make a grid builder.
+ *
+ * @return Grid
+ */
+ public static function grid($repository = null)
+ {
+ static::defineGridColumn();
+
+ $grid = new Grid($repository);
+
+ $grid->wrap(function ($view) {
+ return "$view";
+ });
+
+ $grid->number();
+ $grid->desc('描述')->width('300px');
+ $grid->images('图片')->image(150);
+ $grid->type('类别');
+ $grid->who('作者')->label();
+ $grid->publishedAt('发布于');
+
+ $grid->disableActions();
+ $grid->disableBatchDelete();
+ $grid->disableCreateButton();
+ $grid->disableFilterButton();
+
+ return $grid;
+ }
+
+ public static function defineGridColumn()
+ {
+ Grid\Column::define('desc', function ($v, $column) {
+ if ($this->type == '福利') {
+ $width = '150';
+ $height = '200';
+ return "
";
+ }
+
+ return sprintf('%s', $this->url, $v);
+ });
+
+ Grid\Column::define('publishedAt', function ($v) {
+ return date('Y-m-d', strtotime($v));
+ });
+ Grid\Column::define('datetime', function ($v) {
+ return date('Y-m-d H:i:s', strtotime($v));
+ });
+
+ Grid\Column::define('type', function ($v) {
+ $map = Gank::$categoryColorsMap;
+
+ return "$v";
+ });
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/src/GankServiceProvider.php b/app/Admin/Extensions/dcat-admin-extension/gank/src/GankServiceProvider.php
new file mode 100644
index 0000000..470ea40
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/src/GankServiceProvider.php
@@ -0,0 +1,76 @@
+views()) {
+ $this->loadViewsFrom($views, Gank::NAME);
+ }
+
+ if ($lang = $extension->lang()) {
+ $this->loadTranslationsFrom($lang, Gank::NAME);
+ }
+
+ if ($migrations = $extension->migrations()) {
+ $this->loadMigrationsFrom($migrations);
+ }
+
+ $this->app->booted(function () use ($extension) {
+ $extension->routes(__DIR__.'/../routes/web.php');
+ });
+
+ // 添加菜单
+ $this->registerMenus();
+ }
+
+ protected function registerMenus()
+ {
+ Admin::menu()->add([
+ [
+ 'id' => 1,
+ 'title' => '干货集中营',
+ 'icon' => ' fa-newspaper-o',
+ 'uri' => 'gank',
+ 'parent_id' => 0,
+ 'permission_id' => 'gank',
+ ],
+ [
+ 'id' => 2,
+ 'title' => '今日最新干货',
+ 'icon' => 'fa-smile-o',
+ 'uri' => 'gank/latest',
+ 'parent_id' => 1,
+ 'permission_id' => 'gank',
+ ],
+ [
+ 'id' => 3,
+ 'title' => '所有干货',
+ 'icon' => 'fa-smile-o',
+ 'uri' => 'gank',
+ 'parent_id' => 1,
+ 'permission_id' => 'gank',
+ ],
+ ]);
+ }
+
+ /**
+ * Register the service provider.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ }
+
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/src/Http/Controllers/GankController.php b/app/Admin/Extensions/dcat-admin-extension/gank/src/Http/Controllers/GankController.php
new file mode 100644
index 0000000..456f447
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/src/Http/Controllers/GankController.php
@@ -0,0 +1,56 @@
+grid();
+
+ $grid->disableFilter();
+ $grid->filter()
+ ->panel()
+ ->withoutInputBorder()
+ ->expand()
+ ->resetPosition()
+ ->hiddenResetButtonText();
+
+ return $content
+ ->header('所有干货')
+ ->description('每日分享妹子图 和 技术干货')
+ ->body($grid->filter())
+ ->body(function (Row $row) {
+ $row->column(7, Gank::navbar());
+ })
+ ->body($grid);
+ }
+
+ /**
+ * Make a grid builder.
+ *
+ * @return Grid
+ */
+ protected function grid()
+ {
+ return Gank::grid(new Ganks)->perPages([])->filter(function (Grid\Filter $filter) {
+ $category = $filter->input(Grid\Filter\Scope::QUERY_NAME, '全部');
+
+ if ($category != '福利') {
+ $filter->like('keyword', ucfirst($category))->width('300px')->placeholder('请输入');
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/src/Http/Controllers/LatestController.php b/app/Admin/Extensions/dcat-admin-extension/gank/src/Http/Controllers/LatestController.php
new file mode 100644
index 0000000..cc22c59
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/src/Http/Controllers/LatestController.php
@@ -0,0 +1,42 @@
+header('今日最新干货')
+ ->description('每日分享妹子图 和 技术干货')
+ ->body(function (Row $row) {
+ $row->column(7, Gank::navbar());
+
+ })
+ ->body($this->grid());
+ }
+
+ /**
+ * Make a grid builder.
+ *
+ * @return Grid
+ */
+ protected function grid()
+ {
+ return Gank::grid(new Latest)->disablePagination();
+ }
+
+
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/src/Repositories/Ganks.php b/app/Admin/Extensions/dcat-admin-extension/gank/src/Repositories/Ganks.php
new file mode 100644
index 0000000..3b8c52e
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/src/Repositories/Ganks.php
@@ -0,0 +1,63 @@
+getCurrentPage();
+ $perPage = $model->getPerPage();
+
+ // 获取筛选参数
+ $category = $model->filter()->input(Grid\Filter\Scope::QUERY_NAME, 'all');
+ $keyword = trim($model->filter()->input('keyword'));
+
+ $api = $keyword ? $this->searchApi : $this->api;
+
+ $client = new \GuzzleHttp\Client();
+
+ $response = $client->get(str_replace(
+ ['{category}', '{limit}', '{page}', '{key}'],
+ [$category, $perPage, $currentPage, $keyword],
+ $api
+ ));
+ $data = collect(
+ json_decode((string) $response->getBody(), true)['results'] ?? []
+ );
+
+ $total = $keyword ? 400 : ($category == 'all' ? 1000 : 500);
+
+ $paginator = new LengthAwarePaginator(
+ $data,
+ $category == '福利' ? 680 : $total,
+ $perPage, // 传入每页显示行数
+ $currentPage // 传入当前页码
+ );
+
+ $paginator->setPath(\url()->current());
+
+ return $paginator;
+ }
+
+ public function getKeyName()
+ {
+ return '_id';
+ }
+
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/src/Repositories/Latest.php b/app/Admin/Extensions/dcat-admin-extension/gank/src/Repositories/Latest.php
new file mode 100644
index 0000000..427c8b2
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/src/Repositories/Latest.php
@@ -0,0 +1,67 @@
+filter()->input(Grid\Filter\Scope::QUERY_NAME);
+
+ $client = new \GuzzleHttp\Client();
+
+ $response = $client->get($this->api);
+ $data = collect(
+ json_decode((string) $response->getBody(), true)['results'] ?? []
+ );
+
+ if ($type) {
+ $data = $data->filter(function ($v, $k) use ($type) {
+ return $type == $k;
+ });
+ } else {
+ $data = $data->reject(function ($v, $k) {
+ return in_array($k, ['iOS', 'Android', '休息视频']);
+ });
+ }
+
+ return $data->flatten(1);
+ }
+
+ public function getKeyName()
+ {
+ return '_id';
+ }
+
+ function post($url, $data = [])
+ {
+ $postdata = http_build_query(
+ $data
+ );
+
+ $opts = array('http' =>
+ array(
+ 'method' => 'POST',
+ 'header' => 'Content-type: application/x-www-form-urlencoded',
+ 'content' => $postdata
+ )
+ );
+ $context = stream_context_create($opts);
+ $result = file_get_contents($url, false, $context);
+ return $result;
+ }
+
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/gank/src/bootstrap.php b/app/Admin/Extensions/dcat-admin-extension/gank/src/bootstrap.php
new file mode 100644
index 0000000..166f687
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/gank/src/bootstrap.php
@@ -0,0 +1,4 @@
+
+
+# DCAT-ADMIN GRID-SORTABLE
+
+
+
+这个插件可以帮助你通过拖动数据列表的行来进行排序,前端基于[SortableJS](https://github.com/SortableJS/Sortable), 后端基于[eloquent-sortable](https://github.com/spatie/eloquent-sortable)。
+
+
+
+
+## 安装
+
+```shell
+composer require dcat-admin-extension/grid-sortable -vvv
+```
+
+然后打开`http://yourhost/admin/helpers/extensions`,依次点击`启用`和`导入`。
+
+## 使用
+
+修改模型
+
+```php
+ 'order_column',
+ 'sort_when_creating' => true,
+ ];
+}
+```
+
+在表格中使用
+
+```php
+$grid = new Grid(new MyModel());
+
+$grid->sortable();
+```
+
+## 翻译
+
+在对应的语言种类文件夹下的`global.php`中可以修改按钮文本,以简体中文为例:翻译文件是`resources/lang/zh-CN.json`
+```php
+return [
+ 'fields' => [...],
+ 'labels' => [
+ ...
+ 'Save order' => '保存排序',
+ ],
+];
+```
+
+License
+------------
+Licensed under [The MIT License (MIT)](LICENSE).
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/composer.json b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/composer.json
new file mode 100644
index 0000000..cf79a85
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "dcat-admin-extension/grid-sortable",
+ "description": "description...",
+ "type": "library",
+ "keywords": ["dcat-admin", "extension", "grid-sortable"],
+ "homepage": "https://github.com/dcat-admin-extension/grid-sortable",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "jqh",
+ "email": "841324345@qq.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.1.0",
+ "spatie/eloquent-sortable": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~6.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Dcat\\Admin\\Extension\\GridSortable\\": "src/"
+ },
+ "files": [
+ "src/bootstrap.php"
+ ]
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/resources/assets/sortable.js b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/resources/assets/sortable.js
new file mode 100644
index 0000000..19291fc
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/resources/assets/sortable.js
@@ -0,0 +1,3709 @@
+/**!
+ * Sortable 1.10.2
+ * @author RubaXa
+ * @author owenm
+ * @license MIT
+ */
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, global.Sortable = factory());
+}(this, function () { 'use strict';
+
+ function _typeof(obj) {
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
+ _typeof = function (obj) {
+ return typeof obj;
+ };
+ } else {
+ _typeof = function (obj) {
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+ };
+ }
+
+ return _typeof(obj);
+ }
+
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
+ function _extends() {
+ _extends = Object.assign || function (target) {
+ for (var i = 1; i < arguments.length; i++) {
+ var source = arguments[i];
+
+ for (var key in source) {
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ target[key] = source[key];
+ }
+ }
+ }
+
+ return target;
+ };
+
+ return _extends.apply(this, arguments);
+ }
+
+ function _objectSpread(target) {
+ for (var i = 1; i < arguments.length; i++) {
+ var source = arguments[i] != null ? arguments[i] : {};
+ var ownKeys = Object.keys(source);
+
+ if (typeof Object.getOwnPropertySymbols === 'function') {
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
+ }));
+ }
+
+ ownKeys.forEach(function (key) {
+ _defineProperty(target, key, source[key]);
+ });
+ }
+
+ return target;
+ }
+
+ function _objectWithoutPropertiesLoose(source, excluded) {
+ if (source == null) return {};
+ var target = {};
+ var sourceKeys = Object.keys(source);
+ var key, i;
+
+ for (i = 0; i < sourceKeys.length; i++) {
+ key = sourceKeys[i];
+ if (excluded.indexOf(key) >= 0) continue;
+ target[key] = source[key];
+ }
+
+ return target;
+ }
+
+ function _objectWithoutProperties(source, excluded) {
+ if (source == null) return {};
+
+ var target = _objectWithoutPropertiesLoose(source, excluded);
+
+ var key, i;
+
+ if (Object.getOwnPropertySymbols) {
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
+
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
+ key = sourceSymbolKeys[i];
+ if (excluded.indexOf(key) >= 0) continue;
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
+ target[key] = source[key];
+ }
+ }
+
+ return target;
+ }
+
+ function _toConsumableArray(arr) {
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
+ }
+
+ function _arrayWithoutHoles(arr) {
+ if (Array.isArray(arr)) {
+ for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
+
+ return arr2;
+ }
+ }
+
+ function _iterableToArray(iter) {
+ if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
+ }
+
+ function _nonIterableSpread() {
+ throw new TypeError("Invalid attempt to spread non-iterable instance");
+ }
+
+ var version = "1.10.2";
+
+ function userAgent(pattern) {
+ if (typeof window !== 'undefined' && window.navigator) {
+ return !!
+ /*@__PURE__*/
+ navigator.userAgent.match(pattern);
+ }
+ }
+
+ var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
+ var Edge = userAgent(/Edge/i);
+ var FireFox = userAgent(/firefox/i);
+ var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
+ var IOS = userAgent(/iP(ad|od|hone)/i);
+ var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
+
+ var captureMode = {
+ capture: false,
+ passive: false
+ };
+
+ function on(el, event, fn) {
+ el.addEventListener(event, fn, !IE11OrLess && captureMode);
+ }
+
+ function off(el, event, fn) {
+ el.removeEventListener(event, fn, !IE11OrLess && captureMode);
+ }
+
+ function matches(
+ /**HTMLElement*/
+ el,
+ /**String*/
+ selector) {
+ if (!selector) return;
+ selector[0] === '>' && (selector = selector.substring(1));
+
+ if (el) {
+ try {
+ if (el.matches) {
+ return el.matches(selector);
+ } else if (el.msMatchesSelector) {
+ return el.msMatchesSelector(selector);
+ } else if (el.webkitMatchesSelector) {
+ return el.webkitMatchesSelector(selector);
+ }
+ } catch (_) {
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ function getParentOrHost(el) {
+ return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode;
+ }
+
+ function closest(
+ /**HTMLElement*/
+ el,
+ /**String*/
+ selector,
+ /**HTMLElement*/
+ ctx, includeCTX) {
+ if (el) {
+ ctx = ctx || document;
+
+ do {
+ if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
+ return el;
+ }
+
+ if (el === ctx) break;
+ /* jshint boss:true */
+ } while (el = getParentOrHost(el));
+ }
+
+ return null;
+ }
+
+ var R_SPACE = /\s+/g;
+
+ function toggleClass(el, name, state) {
+ if (el && name) {
+ if (el.classList) {
+ el.classList[state ? 'add' : 'remove'](name);
+ } else {
+ var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
+ el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
+ }
+ }
+ }
+
+ function css(el, prop, val) {
+ var style = el && el.style;
+
+ if (style) {
+ if (val === void 0) {
+ if (document.defaultView && document.defaultView.getComputedStyle) {
+ val = document.defaultView.getComputedStyle(el, '');
+ } else if (el.currentStyle) {
+ val = el.currentStyle;
+ }
+
+ return prop === void 0 ? val : val[prop];
+ } else {
+ if (!(prop in style) && prop.indexOf('webkit') === -1) {
+ prop = '-webkit-' + prop;
+ }
+
+ style[prop] = val + (typeof val === 'string' ? '' : 'px');
+ }
+ }
+ }
+
+ function matrix(el, selfOnly) {
+ var appliedTransforms = '';
+
+ if (typeof el === 'string') {
+ appliedTransforms = el;
+ } else {
+ do {
+ var transform = css(el, 'transform');
+
+ if (transform && transform !== 'none') {
+ appliedTransforms = transform + ' ' + appliedTransforms;
+ }
+ /* jshint boss:true */
+
+ } while (!selfOnly && (el = el.parentNode));
+ }
+
+ var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
+ /*jshint -W056 */
+
+ return matrixFn && new matrixFn(appliedTransforms);
+ }
+
+ function find(ctx, tagName, iterator) {
+ if (ctx) {
+ var list = ctx.getElementsByTagName(tagName),
+ i = 0,
+ n = list.length;
+
+ if (iterator) {
+ for (; i < n; i++) {
+ iterator(list[i], i);
+ }
+ }
+
+ return list;
+ }
+
+ return [];
+ }
+
+ function getWindowScrollingElement() {
+ var scrollingElement = document.scrollingElement;
+
+ if (scrollingElement) {
+ return scrollingElement;
+ } else {
+ return document.documentElement;
+ }
+ }
+ /**
+ * Returns the "bounding client rect" of given element
+ * @param {HTMLElement} el The element whose boundingClientRect is wanted
+ * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
+ * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
+ * @param {[Boolean]} undoScale Whether the container's scale() should be undone
+ * @param {[HTMLElement]} container The parent the element will be placed in
+ * @return {Object} The boundingClientRect of el, with specified adjustments
+ */
+
+
+ function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
+ if (!el.getBoundingClientRect && el !== window) return;
+ var elRect, top, left, bottom, right, height, width;
+
+ if (el !== window && el !== getWindowScrollingElement()) {
+ elRect = el.getBoundingClientRect();
+ top = elRect.top;
+ left = elRect.left;
+ bottom = elRect.bottom;
+ right = elRect.right;
+ height = elRect.height;
+ width = elRect.width;
+ } else {
+ top = 0;
+ left = 0;
+ bottom = window.innerHeight;
+ right = window.innerWidth;
+ height = window.innerHeight;
+ width = window.innerWidth;
+ }
+
+ if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
+ // Adjust for translate()
+ container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
+ // Not needed on <= IE11
+
+ if (!IE11OrLess) {
+ do {
+ if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
+ var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container
+
+ top -= containerRect.top + parseInt(css(container, 'border-top-width'));
+ left -= containerRect.left + parseInt(css(container, 'border-left-width'));
+ bottom = top + elRect.height;
+ right = left + elRect.width;
+ break;
+ }
+ /* jshint boss:true */
+
+ } while (container = container.parentNode);
+ }
+ }
+
+ if (undoScale && el !== window) {
+ // Adjust for scale()
+ var elMatrix = matrix(container || el),
+ scaleX = elMatrix && elMatrix.a,
+ scaleY = elMatrix && elMatrix.d;
+
+ if (elMatrix) {
+ top /= scaleY;
+ left /= scaleX;
+ width /= scaleX;
+ height /= scaleY;
+ bottom = top + height;
+ right = left + width;
+ }
+ }
+
+ return {
+ top: top,
+ left: left,
+ bottom: bottom,
+ right: right,
+ width: width,
+ height: height
+ };
+ }
+ /**
+ * Checks if a side of an element is scrolled past a side of its parents
+ * @param {HTMLElement} el The element who's side being scrolled out of view is in question
+ * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
+ * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
+ * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
+ */
+
+
+ function isScrolledPast(el, elSide, parentSide) {
+ var parent = getParentAutoScrollElement(el, true),
+ elSideVal = getRect(el)[elSide];
+ /* jshint boss:true */
+
+ while (parent) {
+ var parentSideVal = getRect(parent)[parentSide],
+ visible = void 0;
+
+ if (parentSide === 'top' || parentSide === 'left') {
+ visible = elSideVal >= parentSideVal;
+ } else {
+ visible = elSideVal <= parentSideVal;
+ }
+
+ if (!visible) return parent;
+ if (parent === getWindowScrollingElement()) break;
+ parent = getParentAutoScrollElement(parent, false);
+ }
+
+ return false;
+ }
+ /**
+ * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
+ * and non-draggable elements
+ * @param {HTMLElement} el The parent element
+ * @param {Number} childNum The index of the child
+ * @param {Object} options Parent Sortable's options
+ * @return {HTMLElement} The child at index childNum, or null if not found
+ */
+
+
+ function getChild(el, childNum, options) {
+ var currentChild = 0,
+ i = 0,
+ children = el.children;
+
+ while (i < children.length) {
+ if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && children[i] !== Sortable.dragged && closest(children[i], options.draggable, el, false)) {
+ if (currentChild === childNum) {
+ return children[i];
+ }
+
+ currentChild++;
+ }
+
+ i++;
+ }
+
+ return null;
+ }
+ /**
+ * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
+ * @param {HTMLElement} el Parent element
+ * @param {selector} selector Any other elements that should be ignored
+ * @return {HTMLElement} The last child, ignoring ghostEl
+ */
+
+
+ function lastChild(el, selector) {
+ var last = el.lastElementChild;
+
+ while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
+ last = last.previousElementSibling;
+ }
+
+ return last || null;
+ }
+ /**
+ * Returns the index of an element within its parent for a selected set of
+ * elements
+ * @param {HTMLElement} el
+ * @param {selector} selector
+ * @return {number}
+ */
+
+
+ function index(el, selector) {
+ var index = 0;
+
+ if (!el || !el.parentNode) {
+ return -1;
+ }
+ /* jshint boss:true */
+
+
+ while (el = el.previousElementSibling) {
+ if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
+ index++;
+ }
+ }
+
+ return index;
+ }
+ /**
+ * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
+ * The value is returned in real pixels.
+ * @param {HTMLElement} el
+ * @return {Array} Offsets in the format of [left, top]
+ */
+
+
+ function getRelativeScrollOffset(el) {
+ var offsetLeft = 0,
+ offsetTop = 0,
+ winScroller = getWindowScrollingElement();
+
+ if (el) {
+ do {
+ var elMatrix = matrix(el),
+ scaleX = elMatrix.a,
+ scaleY = elMatrix.d;
+ offsetLeft += el.scrollLeft * scaleX;
+ offsetTop += el.scrollTop * scaleY;
+ } while (el !== winScroller && (el = el.parentNode));
+ }
+
+ return [offsetLeft, offsetTop];
+ }
+ /**
+ * Returns the index of the object within the given array
+ * @param {Array} arr Array that may or may not hold the object
+ * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find
+ * @return {Number} The index of the object in the array, or -1
+ */
+
+
+ function indexOfObject(arr, obj) {
+ for (var i in arr) {
+ if (!arr.hasOwnProperty(i)) continue;
+
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
+ }
+ }
+
+ return -1;
+ }
+
+ function getParentAutoScrollElement(el, includeSelf) {
+ // skip to window
+ if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
+ var elem = el;
+ var gotSelf = false;
+
+ do {
+ // we don't need to get elem css if it isn't even overflowing in the first place (performance)
+ if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
+ var elemCSS = css(elem);
+
+ if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
+ if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
+ if (gotSelf || includeSelf) return elem;
+ gotSelf = true;
+ }
+ }
+ /* jshint boss:true */
+
+ } while (elem = elem.parentNode);
+
+ return getWindowScrollingElement();
+ }
+
+ function extend(dst, src) {
+ if (dst && src) {
+ for (var key in src) {
+ if (src.hasOwnProperty(key)) {
+ dst[key] = src[key];
+ }
+ }
+ }
+
+ return dst;
+ }
+
+ function isRectEqual(rect1, rect2) {
+ return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width);
+ }
+
+ var _throttleTimeout;
+
+ function throttle(callback, ms) {
+ return function () {
+ if (!_throttleTimeout) {
+ var args = arguments,
+ _this = this;
+
+ if (args.length === 1) {
+ callback.call(_this, args[0]);
+ } else {
+ callback.apply(_this, args);
+ }
+
+ _throttleTimeout = setTimeout(function () {
+ _throttleTimeout = void 0;
+ }, ms);
+ }
+ };
+ }
+
+ function cancelThrottle() {
+ clearTimeout(_throttleTimeout);
+ _throttleTimeout = void 0;
+ }
+
+ function scrollBy(el, x, y) {
+ el.scrollLeft += x;
+ el.scrollTop += y;
+ }
+
+ function clone(el) {
+ var Polymer = window.Polymer;
+ var $ = window.jQuery || window.Zepto;
+
+ if (Polymer && Polymer.dom) {
+ return Polymer.dom(el).cloneNode(true);
+ } else if ($) {
+ return $(el).clone(true)[0];
+ } else {
+ return el.cloneNode(true);
+ }
+ }
+
+ function setRect(el, rect) {
+ css(el, 'position', 'absolute');
+ css(el, 'top', rect.top);
+ css(el, 'left', rect.left);
+ css(el, 'width', rect.width);
+ css(el, 'height', rect.height);
+ }
+
+ function unsetRect(el) {
+ css(el, 'position', '');
+ css(el, 'top', '');
+ css(el, 'left', '');
+ css(el, 'width', '');
+ css(el, 'height', '');
+ }
+
+ var expando = 'Sortable' + new Date().getTime();
+
+ function AnimationStateManager() {
+ var animationStates = [],
+ animationCallbackId;
+ return {
+ captureAnimationState: function captureAnimationState() {
+ animationStates = [];
+ if (!this.options.animation) return;
+ var children = [].slice.call(this.el.children);
+ children.forEach(function (child) {
+ if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
+ animationStates.push({
+ target: child,
+ rect: getRect(child)
+ });
+
+ var fromRect = _objectSpread({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation
+
+
+ if (child.thisAnimationDuration) {
+ var childMatrix = matrix(child, true);
+
+ if (childMatrix) {
+ fromRect.top -= childMatrix.f;
+ fromRect.left -= childMatrix.e;
+ }
+ }
+
+ child.fromRect = fromRect;
+ });
+ },
+ addAnimationState: function addAnimationState(state) {
+ animationStates.push(state);
+ },
+ removeAnimationState: function removeAnimationState(target) {
+ animationStates.splice(indexOfObject(animationStates, {
+ target: target
+ }), 1);
+ },
+ animateAll: function animateAll(callback) {
+ var _this = this;
+
+ if (!this.options.animation) {
+ clearTimeout(animationCallbackId);
+ if (typeof callback === 'function') callback();
+ return;
+ }
+
+ var animating = false,
+ animationTime = 0;
+ animationStates.forEach(function (state) {
+ var time = 0,
+ target = state.target,
+ fromRect = target.fromRect,
+ toRect = getRect(target),
+ prevFromRect = target.prevFromRect,
+ prevToRect = target.prevToRect,
+ animatingRect = state.rect,
+ targetMatrix = matrix(target, true);
+
+ if (targetMatrix) {
+ // Compensate for current animation
+ toRect.top -= targetMatrix.f;
+ toRect.left -= targetMatrix.e;
+ }
+
+ target.toRect = toRect;
+
+ if (target.thisAnimationDuration) {
+ // Could also check if animatingRect is between fromRect and toRect
+ if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect
+ (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
+ // If returning to same place as started from animation and on same axis
+ time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
+ }
+ } // if fromRect != toRect: animate
+
+
+ if (!isRectEqual(toRect, fromRect)) {
+ target.prevFromRect = fromRect;
+ target.prevToRect = toRect;
+
+ if (!time) {
+ time = _this.options.animation;
+ }
+
+ _this.animate(target, animatingRect, toRect, time);
+ }
+
+ if (time) {
+ animating = true;
+ animationTime = Math.max(animationTime, time);
+ clearTimeout(target.animationResetTimer);
+ target.animationResetTimer = setTimeout(function () {
+ target.animationTime = 0;
+ target.prevFromRect = null;
+ target.fromRect = null;
+ target.prevToRect = null;
+ target.thisAnimationDuration = null;
+ }, time);
+ target.thisAnimationDuration = time;
+ }
+ });
+ clearTimeout(animationCallbackId);
+
+ if (!animating) {
+ if (typeof callback === 'function') callback();
+ } else {
+ animationCallbackId = setTimeout(function () {
+ if (typeof callback === 'function') callback();
+ }, animationTime);
+ }
+
+ animationStates = [];
+ },
+ animate: function animate(target, currentRect, toRect, duration) {
+ if (duration) {
+ css(target, 'transition', '');
+ css(target, 'transform', '');
+ var elMatrix = matrix(this.el),
+ scaleX = elMatrix && elMatrix.a,
+ scaleY = elMatrix && elMatrix.d,
+ translateX = (currentRect.left - toRect.left) / (scaleX || 1),
+ translateY = (currentRect.top - toRect.top) / (scaleY || 1);
+ target.animatingX = !!translateX;
+ target.animatingY = !!translateY;
+ css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
+ repaint(target); // repaint
+
+ css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
+ css(target, 'transform', 'translate3d(0,0,0)');
+ typeof target.animated === 'number' && clearTimeout(target.animated);
+ target.animated = setTimeout(function () {
+ css(target, 'transition', '');
+ css(target, 'transform', '');
+ target.animated = false;
+ target.animatingX = false;
+ target.animatingY = false;
+ }, duration);
+ }
+ }
+ };
+ }
+
+ function repaint(target) {
+ return target.offsetWidth;
+ }
+
+ function calculateRealTime(animatingRect, fromRect, toRect, options) {
+ return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation;
+ }
+
+ var plugins = [];
+ var defaults = {
+ initializeByDefault: true
+ };
+ var PluginManager = {
+ mount: function mount(plugin) {
+ // Set default static properties
+ for (var option in defaults) {
+ if (defaults.hasOwnProperty(option) && !(option in plugin)) {
+ plugin[option] = defaults[option];
+ }
+ }
+
+ plugins.push(plugin);
+ },
+ pluginEvent: function pluginEvent(eventName, sortable, evt) {
+ var _this = this;
+
+ this.eventCanceled = false;
+
+ evt.cancel = function () {
+ _this.eventCanceled = true;
+ };
+
+ var eventNameGlobal = eventName + 'Global';
+ plugins.forEach(function (plugin) {
+ if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable
+
+ if (sortable[plugin.pluginName][eventNameGlobal]) {
+ sortable[plugin.pluginName][eventNameGlobal](_objectSpread({
+ sortable: sortable
+ }, evt));
+ } // Only fire plugin event if plugin is enabled in this sortable,
+ // and plugin has event defined
+
+
+ if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
+ sortable[plugin.pluginName][eventName](_objectSpread({
+ sortable: sortable
+ }, evt));
+ }
+ });
+ },
+ initializePlugins: function initializePlugins(sortable, el, defaults, options) {
+ plugins.forEach(function (plugin) {
+ var pluginName = plugin.pluginName;
+ if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
+ var initialized = new plugin(sortable, el, sortable.options);
+ initialized.sortable = sortable;
+ initialized.options = sortable.options;
+ sortable[pluginName] = initialized; // Add default options from plugin
+
+ _extends(defaults, initialized.defaults);
+ });
+
+ for (var option in sortable.options) {
+ if (!sortable.options.hasOwnProperty(option)) continue;
+ var modified = this.modifyOption(sortable, option, sortable.options[option]);
+
+ if (typeof modified !== 'undefined') {
+ sortable.options[option] = modified;
+ }
+ }
+ },
+ getEventProperties: function getEventProperties(name, sortable) {
+ var eventProperties = {};
+ plugins.forEach(function (plugin) {
+ if (typeof plugin.eventProperties !== 'function') return;
+
+ _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
+ });
+ return eventProperties;
+ },
+ modifyOption: function modifyOption(sortable, name, value) {
+ var modifiedValue;
+ plugins.forEach(function (plugin) {
+ // Plugin must exist on the Sortable
+ if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
+
+ if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
+ modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
+ }
+ });
+ return modifiedValue;
+ }
+ };
+
+ function dispatchEvent(_ref) {
+ var sortable = _ref.sortable,
+ rootEl = _ref.rootEl,
+ name = _ref.name,
+ targetEl = _ref.targetEl,
+ cloneEl = _ref.cloneEl,
+ toEl = _ref.toEl,
+ fromEl = _ref.fromEl,
+ oldIndex = _ref.oldIndex,
+ newIndex = _ref.newIndex,
+ oldDraggableIndex = _ref.oldDraggableIndex,
+ newDraggableIndex = _ref.newDraggableIndex,
+ originalEvent = _ref.originalEvent,
+ putSortable = _ref.putSortable,
+ extraEventProperties = _ref.extraEventProperties;
+ sortable = sortable || rootEl && rootEl[expando];
+ if (!sortable) return;
+ var evt,
+ options = sortable.options,
+ onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature
+
+ if (window.CustomEvent && !IE11OrLess && !Edge) {
+ evt = new CustomEvent(name, {
+ bubbles: true,
+ cancelable: true
+ });
+ } else {
+ evt = document.createEvent('Event');
+ evt.initEvent(name, true, true);
+ }
+
+ evt.to = toEl || rootEl;
+ evt.from = fromEl || rootEl;
+ evt.item = targetEl || rootEl;
+ evt.clone = cloneEl;
+ evt.oldIndex = oldIndex;
+ evt.newIndex = newIndex;
+ evt.oldDraggableIndex = oldDraggableIndex;
+ evt.newDraggableIndex = newDraggableIndex;
+ evt.originalEvent = originalEvent;
+ evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
+
+ var allEventProperties = _objectSpread({}, extraEventProperties, PluginManager.getEventProperties(name, sortable));
+
+ for (var option in allEventProperties) {
+ evt[option] = allEventProperties[option];
+ }
+
+ if (rootEl) {
+ rootEl.dispatchEvent(evt);
+ }
+
+ if (options[onName]) {
+ options[onName].call(sortable, evt);
+ }
+ }
+
+ var pluginEvent = function pluginEvent(eventName, sortable) {
+ var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
+ originalEvent = _ref.evt,
+ data = _objectWithoutProperties(_ref, ["evt"]);
+
+ PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread({
+ dragEl: dragEl,
+ parentEl: parentEl,
+ ghostEl: ghostEl,
+ rootEl: rootEl,
+ nextEl: nextEl,
+ lastDownEl: lastDownEl,
+ cloneEl: cloneEl,
+ cloneHidden: cloneHidden,
+ dragStarted: moved,
+ putSortable: putSortable,
+ activeSortable: Sortable.active,
+ originalEvent: originalEvent,
+ oldIndex: oldIndex,
+ oldDraggableIndex: oldDraggableIndex,
+ newIndex: newIndex,
+ newDraggableIndex: newDraggableIndex,
+ hideGhostForTarget: _hideGhostForTarget,
+ unhideGhostForTarget: _unhideGhostForTarget,
+ cloneNowHidden: function cloneNowHidden() {
+ cloneHidden = true;
+ },
+ cloneNowShown: function cloneNowShown() {
+ cloneHidden = false;
+ },
+ dispatchSortableEvent: function dispatchSortableEvent(name) {
+ _dispatchEvent({
+ sortable: sortable,
+ name: name,
+ originalEvent: originalEvent
+ });
+ }
+ }, data));
+ };
+
+ function _dispatchEvent(info) {
+ dispatchEvent(_objectSpread({
+ putSortable: putSortable,
+ cloneEl: cloneEl,
+ targetEl: dragEl,
+ rootEl: rootEl,
+ oldIndex: oldIndex,
+ oldDraggableIndex: oldDraggableIndex,
+ newIndex: newIndex,
+ newDraggableIndex: newDraggableIndex
+ }, info));
+ }
+
+ var dragEl,
+ parentEl,
+ ghostEl,
+ rootEl,
+ nextEl,
+ lastDownEl,
+ cloneEl,
+ cloneHidden,
+ oldIndex,
+ newIndex,
+ oldDraggableIndex,
+ newDraggableIndex,
+ activeGroup,
+ putSortable,
+ awaitingDragStarted = false,
+ ignoreNextClick = false,
+ sortables = [],
+ tapEvt,
+ touchEvt,
+ lastDx,
+ lastDy,
+ tapDistanceLeft,
+ tapDistanceTop,
+ moved,
+ lastTarget,
+ lastDirection,
+ pastFirstInvertThresh = false,
+ isCircumstantialInvert = false,
+ targetMoveDistance,
+ // For positioning ghost absolutely
+ ghostRelativeParent,
+ ghostRelativeParentInitialScroll = [],
+ // (left, top)
+ _silent = false,
+ savedInputChecked = [];
+ /** @const */
+
+ var documentExists = typeof document !== 'undefined',
+ PositionGhostAbsolutely = IOS,
+ CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
+ // This will not pass for IE9, because IE9 DnD only works on anchors
+ supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
+ supportCssPointerEvents = function () {
+ if (!documentExists) return; // false when <= IE11
+
+ if (IE11OrLess) {
+ return false;
+ }
+
+ var el = document.createElement('x');
+ el.style.cssText = 'pointer-events:auto';
+ return el.style.pointerEvents === 'auto';
+ }(),
+ _detectDirection = function _detectDirection(el, options) {
+ var elCSS = css(el),
+ elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
+ child1 = getChild(el, 0, options),
+ child2 = getChild(el, 1, options),
+ firstChildCSS = child1 && css(child1),
+ secondChildCSS = child2 && css(child2),
+ firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
+ secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
+
+ if (elCSS.display === 'flex') {
+ return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
+ }
+
+ if (elCSS.display === 'grid') {
+ return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
+ }
+
+ if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
+ var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
+ return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
+ }
+
+ return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal';
+ },
+ _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
+ var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
+ dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
+ dragElOppLength = vertical ? dragRect.width : dragRect.height,
+ targetS1Opp = vertical ? targetRect.left : targetRect.top,
+ targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
+ targetOppLength = vertical ? targetRect.width : targetRect.height;
+ return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
+ },
+
+ /**
+ * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
+ * @param {Number} x X position
+ * @param {Number} y Y position
+ * @return {HTMLElement} Element of the first found nearest Sortable
+ */
+ _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
+ var ret;
+ sortables.some(function (sortable) {
+ if (lastChild(sortable)) return;
+ var rect = getRect(sortable),
+ threshold = sortable[expando].options.emptyInsertThreshold,
+ insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
+ insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
+
+ if (threshold && insideHorizontally && insideVertically) {
+ return ret = sortable;
+ }
+ });
+ return ret;
+ },
+ _prepareGroup = function _prepareGroup(options) {
+ function toFn(value, pull) {
+ return function (to, from, dragEl, evt) {
+ var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
+
+ if (value == null && (pull || sameGroup)) {
+ // Default pull value
+ // Default pull and put value if same group
+ return true;
+ } else if (value == null || value === false) {
+ return false;
+ } else if (pull && value === 'clone') {
+ return value;
+ } else if (typeof value === 'function') {
+ return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
+ } else {
+ var otherGroup = (pull ? to : from).options.group.name;
+ return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
+ }
+ };
+ }
+
+ var group = {};
+ var originalGroup = options.group;
+
+ if (!originalGroup || _typeof(originalGroup) != 'object') {
+ originalGroup = {
+ name: originalGroup
+ };
+ }
+
+ group.name = originalGroup.name;
+ group.checkPull = toFn(originalGroup.pull, true);
+ group.checkPut = toFn(originalGroup.put);
+ group.revertClone = originalGroup.revertClone;
+ options.group = group;
+ },
+ _hideGhostForTarget = function _hideGhostForTarget() {
+ if (!supportCssPointerEvents && ghostEl) {
+ css(ghostEl, 'display', 'none');
+ }
+ },
+ _unhideGhostForTarget = function _unhideGhostForTarget() {
+ if (!supportCssPointerEvents && ghostEl) {
+ css(ghostEl, 'display', '');
+ }
+ }; // #1184 fix - Prevent click event on fallback if dragged but item not changed position
+
+
+ if (documentExists) {
+ document.addEventListener('click', function (evt) {
+ if (ignoreNextClick) {
+ evt.preventDefault();
+ evt.stopPropagation && evt.stopPropagation();
+ evt.stopImmediatePropagation && evt.stopImmediatePropagation();
+ ignoreNextClick = false;
+ return false;
+ }
+ }, true);
+ }
+
+ var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
+ if (dragEl) {
+ evt = evt.touches ? evt.touches[0] : evt;
+
+ var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
+
+ if (nearest) {
+ // Create imitation event
+ var event = {};
+
+ for (var i in evt) {
+ if (evt.hasOwnProperty(i)) {
+ event[i] = evt[i];
+ }
+ }
+
+ event.target = event.rootEl = nearest;
+ event.preventDefault = void 0;
+ event.stopPropagation = void 0;
+
+ nearest[expando]._onDragOver(event);
+ }
+ }
+ };
+
+ var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
+ if (dragEl) {
+ dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
+ }
+ };
+ /**
+ * @class Sortable
+ * @param {HTMLElement} el
+ * @param {Object} [options]
+ */
+
+
+ function Sortable(el, options) {
+ if (!(el && el.nodeType && el.nodeType === 1)) {
+ throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
+ }
+
+ this.el = el; // root element
+
+ this.options = options = _extends({}, options); // Export instance
+
+ el[expando] = this;
+ var defaults = {
+ group: null,
+ sort: true,
+ disabled: false,
+ store: null,
+ handle: null,
+ draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
+ swapThreshold: 1,
+ // percentage; 0 <= x <= 1
+ invertSwap: false,
+ // invert always
+ invertedSwapThreshold: null,
+ // will be set to same as swapThreshold if default
+ removeCloneOnHide: true,
+ direction: function direction() {
+ return _detectDirection(el, this.options);
+ },
+ ghostClass: 'sortable-ghost',
+ chosenClass: 'sortable-chosen',
+ dragClass: 'sortable-drag',
+ ignore: 'a, img',
+ filter: null,
+ preventOnFilter: true,
+ animation: 0,
+ easing: null,
+ setData: function setData(dataTransfer, dragEl) {
+ dataTransfer.setData('Text', dragEl.textContent);
+ },
+ dropBubble: false,
+ dragoverBubble: false,
+ dataIdAttr: 'data-id',
+ delay: 0,
+ delayOnTouchOnly: false,
+ touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
+ forceFallback: false,
+ fallbackClass: 'sortable-fallback',
+ fallbackOnBody: false,
+ fallbackTolerance: 0,
+ fallbackOffset: {
+ x: 0,
+ y: 0
+ },
+ supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window,
+ emptyInsertThreshold: 5
+ };
+ PluginManager.initializePlugins(this, el, defaults); // Set default options
+
+ for (var name in defaults) {
+ !(name in options) && (options[name] = defaults[name]);
+ }
+
+ _prepareGroup(options); // Bind all private methods
+
+
+ for (var fn in this) {
+ if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
+ this[fn] = this[fn].bind(this);
+ }
+ } // Setup drag mode
+
+
+ this.nativeDraggable = options.forceFallback ? false : supportDraggable;
+
+ if (this.nativeDraggable) {
+ // Touch start threshold cannot be greater than the native dragstart threshold
+ this.options.touchStartThreshold = 1;
+ } // Bind events
+
+
+ if (options.supportPointer) {
+ on(el, 'pointerdown', this._onTapStart);
+ } else {
+ on(el, 'mousedown', this._onTapStart);
+ on(el, 'touchstart', this._onTapStart);
+ }
+
+ if (this.nativeDraggable) {
+ on(el, 'dragover', this);
+ on(el, 'dragenter', this);
+ }
+
+ sortables.push(this.el); // Restore sorting
+
+ options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager
+
+ _extends(this, AnimationStateManager());
+ }
+
+ Sortable.prototype =
+ /** @lends Sortable.prototype */
+ {
+ constructor: Sortable,
+ _isOutsideThisEl: function _isOutsideThisEl(target) {
+ if (!this.el.contains(target) && target !== this.el) {
+ lastTarget = null;
+ }
+ },
+ _getDirection: function _getDirection(evt, target) {
+ return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
+ },
+ _onTapStart: function _onTapStart(
+ /** Event|TouchEvent */
+ evt) {
+ if (!evt.cancelable) return;
+
+ var _this = this,
+ el = this.el,
+ options = this.options,
+ preventOnFilter = options.preventOnFilter,
+ type = evt.type,
+ touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
+ target = (touch || evt).target,
+ originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
+ filter = options.filter;
+
+ _saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
+
+
+ if (dragEl) {
+ return;
+ }
+
+ if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
+ return; // only left button and enabled
+ } // cancel dnd if original target is content editable
+
+
+ if (originalTarget.isContentEditable) {
+ return;
+ }
+
+ target = closest(target, options.draggable, el, false);
+
+ if (target && target.animated) {
+ return;
+ }
+
+ if (lastDownEl === target) {
+ // Ignoring duplicate `down`
+ return;
+ } // Get the index of the dragged element within its parent
+
+
+ oldIndex = index(target);
+ oldDraggableIndex = index(target, options.draggable); // Check filter
+
+ if (typeof filter === 'function') {
+ if (filter.call(this, evt, target, this)) {
+ _dispatchEvent({
+ sortable: _this,
+ rootEl: originalTarget,
+ name: 'filter',
+ targetEl: target,
+ toEl: el,
+ fromEl: el
+ });
+
+ pluginEvent('filter', _this, {
+ evt: evt
+ });
+ preventOnFilter && evt.cancelable && evt.preventDefault();
+ return; // cancel dnd
+ }
+ } else if (filter) {
+ filter = filter.split(',').some(function (criteria) {
+ criteria = closest(originalTarget, criteria.trim(), el, false);
+
+ if (criteria) {
+ _dispatchEvent({
+ sortable: _this,
+ rootEl: criteria,
+ name: 'filter',
+ targetEl: target,
+ fromEl: el,
+ toEl: el
+ });
+
+ pluginEvent('filter', _this, {
+ evt: evt
+ });
+ return true;
+ }
+ });
+
+ if (filter) {
+ preventOnFilter && evt.cancelable && evt.preventDefault();
+ return; // cancel dnd
+ }
+ }
+
+ if (options.handle && !closest(originalTarget, options.handle, el, false)) {
+ return;
+ } // Prepare `dragstart`
+
+
+ this._prepareDragStart(evt, touch, target);
+ },
+ _prepareDragStart: function _prepareDragStart(
+ /** Event */
+ evt,
+ /** Touch */
+ touch,
+ /** HTMLElement */
+ target) {
+ var _this = this,
+ el = _this.el,
+ options = _this.options,
+ ownerDocument = el.ownerDocument,
+ dragStartFn;
+
+ if (target && !dragEl && target.parentNode === el) {
+ var dragRect = getRect(target);
+ rootEl = el;
+ dragEl = target;
+ parentEl = dragEl.parentNode;
+ nextEl = dragEl.nextSibling;
+ lastDownEl = target;
+ activeGroup = options.group;
+ Sortable.dragged = dragEl;
+ tapEvt = {
+ target: dragEl,
+ clientX: (touch || evt).clientX,
+ clientY: (touch || evt).clientY
+ };
+ tapDistanceLeft = tapEvt.clientX - dragRect.left;
+ tapDistanceTop = tapEvt.clientY - dragRect.top;
+ this._lastX = (touch || evt).clientX;
+ this._lastY = (touch || evt).clientY;
+ dragEl.style['will-change'] = 'all';
+
+ dragStartFn = function dragStartFn() {
+ pluginEvent('delayEnded', _this, {
+ evt: evt
+ });
+
+ if (Sortable.eventCanceled) {
+ _this._onDrop();
+
+ return;
+ } // Delayed drag has been triggered
+ // we can re-enable the events: touchmove/mousemove
+
+
+ _this._disableDelayedDragEvents();
+
+ if (!FireFox && _this.nativeDraggable) {
+ dragEl.draggable = true;
+ } // Bind the events: dragstart/dragend
+
+
+ _this._triggerDragStart(evt, touch); // Drag start event
+
+
+ _dispatchEvent({
+ sortable: _this,
+ name: 'choose',
+ originalEvent: evt
+ }); // Chosen item
+
+
+ toggleClass(dragEl, options.chosenClass, true);
+ }; // Disable "draggable"
+
+
+ options.ignore.split(',').forEach(function (criteria) {
+ find(dragEl, criteria.trim(), _disableDraggable);
+ });
+ on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
+ on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
+ on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
+ on(ownerDocument, 'mouseup', _this._onDrop);
+ on(ownerDocument, 'touchend', _this._onDrop);
+ on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox)
+
+ if (FireFox && this.nativeDraggable) {
+ this.options.touchStartThreshold = 4;
+ dragEl.draggable = true;
+ }
+
+ pluginEvent('delayStart', this, {
+ evt: evt
+ }); // Delay is impossible for native DnD in Edge or IE
+
+ if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
+ if (Sortable.eventCanceled) {
+ this._onDrop();
+
+ return;
+ } // If the user moves the pointer or let go the click or touch
+ // before the delay has been reached:
+ // disable the delayed drag
+
+
+ on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
+ on(ownerDocument, 'touchend', _this._disableDelayedDrag);
+ on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
+ on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
+ on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
+ options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
+ _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
+ } else {
+ dragStartFn();
+ }
+ }
+ },
+ _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler(
+ /** TouchEvent|PointerEvent **/
+ e) {
+ var touch = e.touches ? e.touches[0] : e;
+
+ if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) {
+ this._disableDelayedDrag();
+ }
+ },
+ _disableDelayedDrag: function _disableDelayedDrag() {
+ dragEl && _disableDraggable(dragEl);
+ clearTimeout(this._dragStartTimer);
+
+ this._disableDelayedDragEvents();
+ },
+ _disableDelayedDragEvents: function _disableDelayedDragEvents() {
+ var ownerDocument = this.el.ownerDocument;
+ off(ownerDocument, 'mouseup', this._disableDelayedDrag);
+ off(ownerDocument, 'touchend', this._disableDelayedDrag);
+ off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
+ off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
+ off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
+ off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
+ },
+ _triggerDragStart: function _triggerDragStart(
+ /** Event */
+ evt,
+ /** Touch */
+ touch) {
+ touch = touch || evt.pointerType == 'touch' && evt;
+
+ if (!this.nativeDraggable || touch) {
+ if (this.options.supportPointer) {
+ on(document, 'pointermove', this._onTouchMove);
+ } else if (touch) {
+ on(document, 'touchmove', this._onTouchMove);
+ } else {
+ on(document, 'mousemove', this._onTouchMove);
+ }
+ } else {
+ on(dragEl, 'dragend', this);
+ on(rootEl, 'dragstart', this._onDragStart);
+ }
+
+ try {
+ if (document.selection) {
+ // Timeout neccessary for IE9
+ _nextTick(function () {
+ document.selection.empty();
+ });
+ } else {
+ window.getSelection().removeAllRanges();
+ }
+ } catch (err) {}
+ },
+ _dragStarted: function _dragStarted(fallback, evt) {
+
+ awaitingDragStarted = false;
+
+ if (rootEl && dragEl) {
+ pluginEvent('dragStarted', this, {
+ evt: evt
+ });
+
+ if (this.nativeDraggable) {
+ on(document, 'dragover', _checkOutsideTargetEl);
+ }
+
+ var options = this.options; // Apply effect
+
+ !fallback && toggleClass(dragEl, options.dragClass, false);
+ toggleClass(dragEl, options.ghostClass, true);
+ Sortable.active = this;
+ fallback && this._appendGhost(); // Drag start event
+
+ _dispatchEvent({
+ sortable: this,
+ name: 'start',
+ originalEvent: evt
+ });
+ } else {
+ this._nulling();
+ }
+ },
+ _emulateDragOver: function _emulateDragOver() {
+ if (touchEvt) {
+ this._lastX = touchEvt.clientX;
+ this._lastY = touchEvt.clientY;
+
+ _hideGhostForTarget();
+
+ var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
+ var parent = target;
+
+ while (target && target.shadowRoot) {
+ target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
+ if (target === parent) break;
+ parent = target;
+ }
+
+ dragEl.parentNode[expando]._isOutsideThisEl(target);
+
+ if (parent) {
+ do {
+ if (parent[expando]) {
+ var inserted = void 0;
+ inserted = parent[expando]._onDragOver({
+ clientX: touchEvt.clientX,
+ clientY: touchEvt.clientY,
+ target: target,
+ rootEl: parent
+ });
+
+ if (inserted && !this.options.dragoverBubble) {
+ break;
+ }
+ }
+
+ target = parent; // store last element
+ }
+ /* jshint boss:true */
+ while (parent = parent.parentNode);
+ }
+
+ _unhideGhostForTarget();
+ }
+ },
+ _onTouchMove: function _onTouchMove(
+ /**TouchEvent*/
+ evt) {
+ if (tapEvt) {
+ var options = this.options,
+ fallbackTolerance = options.fallbackTolerance,
+ fallbackOffset = options.fallbackOffset,
+ touch = evt.touches ? evt.touches[0] : evt,
+ ghostMatrix = ghostEl && matrix(ghostEl, true),
+ scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
+ scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
+ relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
+ dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
+ dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging
+
+ if (!Sortable.active && !awaitingDragStarted) {
+ if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
+ return;
+ }
+
+ this._onDragStart(evt, true);
+ }
+
+ if (ghostEl) {
+ if (ghostMatrix) {
+ ghostMatrix.e += dx - (lastDx || 0);
+ ghostMatrix.f += dy - (lastDy || 0);
+ } else {
+ ghostMatrix = {
+ a: 1,
+ b: 0,
+ c: 0,
+ d: 1,
+ e: dx,
+ f: dy
+ };
+ }
+
+ var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
+ css(ghostEl, 'webkitTransform', cssMatrix);
+ css(ghostEl, 'mozTransform', cssMatrix);
+ css(ghostEl, 'msTransform', cssMatrix);
+ css(ghostEl, 'transform', cssMatrix);
+ lastDx = dx;
+ lastDy = dy;
+ touchEvt = touch;
+ }
+
+ evt.cancelable && evt.preventDefault();
+ }
+ },
+ _appendGhost: function _appendGhost() {
+ // Bug if using scale(): https://stackoverflow.com/questions/2637058
+ // Not being adjusted for
+ if (!ghostEl) {
+ var container = this.options.fallbackOnBody ? document.body : rootEl,
+ rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
+ options = this.options; // Position absolutely
+
+ if (PositionGhostAbsolutely) {
+ // Get relatively positioned parent
+ ghostRelativeParent = container;
+
+ while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
+ ghostRelativeParent = ghostRelativeParent.parentNode;
+ }
+
+ if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
+ if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
+ rect.top += ghostRelativeParent.scrollTop;
+ rect.left += ghostRelativeParent.scrollLeft;
+ } else {
+ ghostRelativeParent = getWindowScrollingElement();
+ }
+
+ ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
+ }
+
+ ghostEl = dragEl.cloneNode(true);
+ toggleClass(ghostEl, options.ghostClass, false);
+ toggleClass(ghostEl, options.fallbackClass, true);
+ toggleClass(ghostEl, options.dragClass, true);
+ css(ghostEl, 'transition', '');
+ css(ghostEl, 'transform', '');
+ css(ghostEl, 'box-sizing', 'border-box');
+ css(ghostEl, 'margin', 0);
+ css(ghostEl, 'top', rect.top);
+ css(ghostEl, 'left', rect.left);
+ css(ghostEl, 'width', rect.width);
+ css(ghostEl, 'height', rect.height);
+ css(ghostEl, 'opacity', '0.8');
+ css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
+ css(ghostEl, 'zIndex', '100000');
+ css(ghostEl, 'pointerEvents', 'none');
+ Sortable.ghost = ghostEl;
+ container.appendChild(ghostEl); // Set transform-origin
+
+ css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
+ }
+ },
+ _onDragStart: function _onDragStart(
+ /**Event*/
+ evt,
+ /**boolean*/
+ fallback) {
+ var _this = this;
+
+ var dataTransfer = evt.dataTransfer;
+ var options = _this.options;
+ pluginEvent('dragStart', this, {
+ evt: evt
+ });
+
+ if (Sortable.eventCanceled) {
+ this._onDrop();
+
+ return;
+ }
+
+ pluginEvent('setupClone', this);
+
+ if (!Sortable.eventCanceled) {
+ cloneEl = clone(dragEl);
+ cloneEl.draggable = false;
+ cloneEl.style['will-change'] = '';
+
+ this._hideClone();
+
+ toggleClass(cloneEl, this.options.chosenClass, false);
+ Sortable.clone = cloneEl;
+ } // #1143: IFrame support workaround
+
+
+ _this.cloneId = _nextTick(function () {
+ pluginEvent('clone', _this);
+ if (Sortable.eventCanceled) return;
+
+ if (!_this.options.removeCloneOnHide) {
+ rootEl.insertBefore(cloneEl, dragEl);
+ }
+
+ _this._hideClone();
+
+ _dispatchEvent({
+ sortable: _this,
+ name: 'clone'
+ });
+ });
+ !fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events
+
+ if (fallback) {
+ ignoreNextClick = true;
+ _this._loopId = setInterval(_this._emulateDragOver, 50);
+ } else {
+ // Undo what was set in _prepareDragStart before drag started
+ off(document, 'mouseup', _this._onDrop);
+ off(document, 'touchend', _this._onDrop);
+ off(document, 'touchcancel', _this._onDrop);
+
+ if (dataTransfer) {
+ dataTransfer.effectAllowed = 'move';
+ options.setData && options.setData.call(_this, dataTransfer, dragEl);
+ }
+
+ on(document, 'drop', _this); // #1276 fix:
+
+ css(dragEl, 'transform', 'translateZ(0)');
+ }
+
+ awaitingDragStarted = true;
+ _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
+ on(document, 'selectstart', _this);
+ moved = true;
+
+ if (Safari) {
+ css(document.body, 'user-select', 'none');
+ }
+ },
+ // Returns true - if no further action is needed (either inserted or another condition)
+ _onDragOver: function _onDragOver(
+ /**Event*/
+ evt) {
+ var el = this.el,
+ target = evt.target,
+ dragRect,
+ targetRect,
+ revert,
+ options = this.options,
+ group = options.group,
+ activeSortable = Sortable.active,
+ isOwner = activeGroup === group,
+ canSort = options.sort,
+ fromSortable = putSortable || activeSortable,
+ vertical,
+ _this = this,
+ completedFired = false;
+
+ if (_silent) return;
+
+ function dragOverEvent(name, extra) {
+ pluginEvent(name, _this, _objectSpread({
+ evt: evt,
+ isOwner: isOwner,
+ axis: vertical ? 'vertical' : 'horizontal',
+ revert: revert,
+ dragRect: dragRect,
+ targetRect: targetRect,
+ canSort: canSort,
+ fromSortable: fromSortable,
+ target: target,
+ completed: completed,
+ onMove: function onMove(target, after) {
+ return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
+ },
+ changed: changed
+ }, extra));
+ } // Capture animation state
+
+
+ function capture() {
+ dragOverEvent('dragOverAnimationCapture');
+
+ _this.captureAnimationState();
+
+ if (_this !== fromSortable) {
+ fromSortable.captureAnimationState();
+ }
+ } // Return invocation when dragEl is inserted (or completed)
+
+
+ function completed(insertion) {
+ dragOverEvent('dragOverCompleted', {
+ insertion: insertion
+ });
+
+ if (insertion) {
+ // Clones must be hidden before folding animation to capture dragRectAbsolute properly
+ if (isOwner) {
+ activeSortable._hideClone();
+ } else {
+ activeSortable._showClone(_this);
+ }
+
+ if (_this !== fromSortable) {
+ // Set ghost class to new sortable's ghost class
+ toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
+ toggleClass(dragEl, options.ghostClass, true);
+ }
+
+ if (putSortable !== _this && _this !== Sortable.active) {
+ putSortable = _this;
+ } else if (_this === Sortable.active && putSortable) {
+ putSortable = null;
+ } // Animation
+
+
+ if (fromSortable === _this) {
+ _this._ignoreWhileAnimating = target;
+ }
+
+ _this.animateAll(function () {
+ dragOverEvent('dragOverAnimationComplete');
+ _this._ignoreWhileAnimating = null;
+ });
+
+ if (_this !== fromSortable) {
+ fromSortable.animateAll();
+ fromSortable._ignoreWhileAnimating = null;
+ }
+ } // Null lastTarget if it is not inside a previously swapped element
+
+
+ if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
+ lastTarget = null;
+ } // no bubbling and not fallback
+
+
+ if (!options.dragoverBubble && !evt.rootEl && target !== document) {
+ dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted
+
+
+ !insertion && nearestEmptyInsertDetectEvent(evt);
+ }
+
+ !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
+ return completedFired = true;
+ } // Call when dragEl has been inserted
+
+
+ function changed() {
+ newIndex = index(dragEl);
+ newDraggableIndex = index(dragEl, options.draggable);
+
+ _dispatchEvent({
+ sortable: _this,
+ name: 'change',
+ toEl: el,
+ newIndex: newIndex,
+ newDraggableIndex: newDraggableIndex,
+ originalEvent: evt
+ });
+ }
+
+ if (evt.preventDefault !== void 0) {
+ evt.cancelable && evt.preventDefault();
+ }
+
+ target = closest(target, options.draggable, el, true);
+ dragOverEvent('dragOver');
+ if (Sortable.eventCanceled) return completedFired;
+
+ if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
+ return completed(false);
+ }
+
+ ignoreNextClick = false;
+
+ if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list
+ : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
+ vertical = this._getDirection(evt, target) === 'vertical';
+ dragRect = getRect(dragEl);
+ dragOverEvent('dragOverValid');
+ if (Sortable.eventCanceled) return completedFired;
+
+ if (revert) {
+ parentEl = rootEl; // actualization
+
+ capture();
+
+ this._hideClone();
+
+ dragOverEvent('revert');
+
+ if (!Sortable.eventCanceled) {
+ if (nextEl) {
+ rootEl.insertBefore(dragEl, nextEl);
+ } else {
+ rootEl.appendChild(dragEl);
+ }
+ }
+
+ return completed(true);
+ }
+
+ var elLastChild = lastChild(el, options.draggable);
+
+ if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
+ // If already at end of list: Do not insert
+ if (elLastChild === dragEl) {
+ return completed(false);
+ } // assign target only if condition is true
+
+
+ if (elLastChild && el === evt.target) {
+ target = elLastChild;
+ }
+
+ if (target) {
+ targetRect = getRect(target);
+ }
+
+ if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
+ capture();
+ el.appendChild(dragEl);
+ parentEl = el; // actualization
+
+ changed();
+ return completed(true);
+ }
+ } else if (target.parentNode === el) {
+ targetRect = getRect(target);
+ var direction = 0,
+ targetBeforeFirstSwap,
+ differentLevel = dragEl.parentNode !== el,
+ differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
+ side1 = vertical ? 'top' : 'left',
+ scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
+ scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
+
+ if (lastTarget !== target) {
+ targetBeforeFirstSwap = targetRect[side1];
+ pastFirstInvertThresh = false;
+ isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
+ }
+
+ direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
+ var sibling;
+
+ if (direction !== 0) {
+ // Check if target is beside dragEl in respective direction (ignoring hidden elements)
+ var dragIndex = index(dragEl);
+
+ do {
+ dragIndex -= direction;
+ sibling = parentEl.children[dragIndex];
+ } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
+ } // If dragEl is already beside target: Do not insert
+
+
+ if (direction === 0 || sibling === target) {
+ return completed(false);
+ }
+
+ lastTarget = target;
+ lastDirection = direction;
+ var nextSibling = target.nextElementSibling,
+ after = false;
+ after = direction === 1;
+
+ var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
+
+ if (moveVector !== false) {
+ if (moveVector === 1 || moveVector === -1) {
+ after = moveVector === 1;
+ }
+
+ _silent = true;
+ setTimeout(_unsilent, 30);
+ capture();
+
+ if (after && !nextSibling) {
+ el.appendChild(dragEl);
+ } else {
+ target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
+ } // Undo chrome's scroll adjustment (has no effect on other browsers)
+
+
+ if (scrolledPastTop) {
+ scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
+ }
+
+ parentEl = dragEl.parentNode; // actualization
+ // must be done before animation
+
+ if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
+ targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
+ }
+
+ changed();
+ return completed(true);
+ }
+ }
+
+ if (el.contains(dragEl)) {
+ return completed(false);
+ }
+ }
+
+ return false;
+ },
+ _ignoreWhileAnimating: null,
+ _offMoveEvents: function _offMoveEvents() {
+ off(document, 'mousemove', this._onTouchMove);
+ off(document, 'touchmove', this._onTouchMove);
+ off(document, 'pointermove', this._onTouchMove);
+ off(document, 'dragover', nearestEmptyInsertDetectEvent);
+ off(document, 'mousemove', nearestEmptyInsertDetectEvent);
+ off(document, 'touchmove', nearestEmptyInsertDetectEvent);
+ },
+ _offUpEvents: function _offUpEvents() {
+ var ownerDocument = this.el.ownerDocument;
+ off(ownerDocument, 'mouseup', this._onDrop);
+ off(ownerDocument, 'touchend', this._onDrop);
+ off(ownerDocument, 'pointerup', this._onDrop);
+ off(ownerDocument, 'touchcancel', this._onDrop);
+ off(document, 'selectstart', this);
+ },
+ _onDrop: function _onDrop(
+ /**Event*/
+ evt) {
+ var el = this.el,
+ options = this.options; // Get the index of the dragged element within its parent
+
+ newIndex = index(dragEl);
+ newDraggableIndex = index(dragEl, options.draggable);
+ pluginEvent('drop', this, {
+ evt: evt
+ });
+ parentEl = dragEl && dragEl.parentNode; // Get again after plugin event
+
+ newIndex = index(dragEl);
+ newDraggableIndex = index(dragEl, options.draggable);
+
+ if (Sortable.eventCanceled) {
+ this._nulling();
+
+ return;
+ }
+
+ awaitingDragStarted = false;
+ isCircumstantialInvert = false;
+ pastFirstInvertThresh = false;
+ clearInterval(this._loopId);
+ clearTimeout(this._dragStartTimer);
+
+ _cancelNextTick(this.cloneId);
+
+ _cancelNextTick(this._dragStartId); // Unbind events
+
+
+ if (this.nativeDraggable) {
+ off(document, 'drop', this);
+ off(el, 'dragstart', this._onDragStart);
+ }
+
+ this._offMoveEvents();
+
+ this._offUpEvents();
+
+ if (Safari) {
+ css(document.body, 'user-select', '');
+ }
+
+ css(dragEl, 'transform', '');
+
+ if (evt) {
+ if (moved) {
+ evt.cancelable && evt.preventDefault();
+ !options.dropBubble && evt.stopPropagation();
+ }
+
+ ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
+
+ if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
+ // Remove clone(s)
+ cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
+ }
+
+ if (dragEl) {
+ if (this.nativeDraggable) {
+ off(dragEl, 'dragend', this);
+ }
+
+ _disableDraggable(dragEl);
+
+ dragEl.style['will-change'] = ''; // Remove classes
+ // ghostClass is added in dragStarted
+
+ if (moved && !awaitingDragStarted) {
+ toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
+ }
+
+ toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event
+
+ _dispatchEvent({
+ sortable: this,
+ name: 'unchoose',
+ toEl: parentEl,
+ newIndex: null,
+ newDraggableIndex: null,
+ originalEvent: evt
+ });
+
+ if (rootEl !== parentEl) {
+ if (newIndex >= 0) {
+ // Add event
+ _dispatchEvent({
+ rootEl: parentEl,
+ name: 'add',
+ toEl: parentEl,
+ fromEl: rootEl,
+ originalEvent: evt
+ }); // Remove event
+
+
+ _dispatchEvent({
+ sortable: this,
+ name: 'remove',
+ toEl: parentEl,
+ originalEvent: evt
+ }); // drag from one list and drop into another
+
+
+ _dispatchEvent({
+ rootEl: parentEl,
+ name: 'sort',
+ toEl: parentEl,
+ fromEl: rootEl,
+ originalEvent: evt
+ });
+
+ _dispatchEvent({
+ sortable: this,
+ name: 'sort',
+ toEl: parentEl,
+ originalEvent: evt
+ });
+ }
+
+ putSortable && putSortable.save();
+ } else {
+ if (newIndex !== oldIndex) {
+ if (newIndex >= 0) {
+ // drag & drop within the same list
+ _dispatchEvent({
+ sortable: this,
+ name: 'update',
+ toEl: parentEl,
+ originalEvent: evt
+ });
+
+ _dispatchEvent({
+ sortable: this,
+ name: 'sort',
+ toEl: parentEl,
+ originalEvent: evt
+ });
+ }
+ }
+ }
+
+ if (Sortable.active) {
+ /* jshint eqnull:true */
+ if (newIndex == null || newIndex === -1) {
+ newIndex = oldIndex;
+ newDraggableIndex = oldDraggableIndex;
+ }
+
+ _dispatchEvent({
+ sortable: this,
+ name: 'end',
+ toEl: parentEl,
+ originalEvent: evt
+ }); // Save sorting
+
+
+ this.save();
+ }
+ }
+ }
+
+ this._nulling();
+ },
+ _nulling: function _nulling() {
+ pluginEvent('nulling', this);
+ rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null;
+ savedInputChecked.forEach(function (el) {
+ el.checked = true;
+ });
+ savedInputChecked.length = lastDx = lastDy = 0;
+ },
+ handleEvent: function handleEvent(
+ /**Event*/
+ evt) {
+ switch (evt.type) {
+ case 'drop':
+ case 'dragend':
+ this._onDrop(evt);
+
+ break;
+
+ case 'dragenter':
+ case 'dragover':
+ if (dragEl) {
+ this._onDragOver(evt);
+
+ _globalDragOver(evt);
+ }
+
+ break;
+
+ case 'selectstart':
+ evt.preventDefault();
+ break;
+ }
+ },
+
+ /**
+ * Serializes the item into an array of string.
+ * @returns {String[]}
+ */
+ toArray: function toArray() {
+ var order = [],
+ el,
+ children = this.el.children,
+ i = 0,
+ n = children.length,
+ options = this.options;
+
+ for (; i < n; i++) {
+ el = children[i];
+
+ if (closest(el, options.draggable, this.el, false)) {
+ order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
+ }
+ }
+
+ return order;
+ },
+
+ /**
+ * Sorts the elements according to the array.
+ * @param {String[]} order order of the items
+ */
+ sort: function sort(order) {
+ var items = {},
+ rootEl = this.el;
+ this.toArray().forEach(function (id, i) {
+ var el = rootEl.children[i];
+
+ if (closest(el, this.options.draggable, rootEl, false)) {
+ items[id] = el;
+ }
+ }, this);
+ order.forEach(function (id) {
+ if (items[id]) {
+ rootEl.removeChild(items[id]);
+ rootEl.appendChild(items[id]);
+ }
+ });
+ },
+
+ /**
+ * Save the current sorting
+ */
+ save: function save() {
+ var store = this.options.store;
+ store && store.set && store.set(this);
+ },
+
+ /**
+ * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
+ * @param {HTMLElement} el
+ * @param {String} [selector] default: `options.draggable`
+ * @returns {HTMLElement|null}
+ */
+ closest: function closest$1(el, selector) {
+ return closest(el, selector || this.options.draggable, this.el, false);
+ },
+
+ /**
+ * Set/get option
+ * @param {string} name
+ * @param {*} [value]
+ * @returns {*}
+ */
+ option: function option(name, value) {
+ var options = this.options;
+
+ if (value === void 0) {
+ return options[name];
+ } else {
+ var modifiedValue = PluginManager.modifyOption(this, name, value);
+
+ if (typeof modifiedValue !== 'undefined') {
+ options[name] = modifiedValue;
+ } else {
+ options[name] = value;
+ }
+
+ if (name === 'group') {
+ _prepareGroup(options);
+ }
+ }
+ },
+
+ /**
+ * Destroy
+ */
+ destroy: function destroy() {
+ pluginEvent('destroy', this);
+ var el = this.el;
+ el[expando] = null;
+ off(el, 'mousedown', this._onTapStart);
+ off(el, 'touchstart', this._onTapStart);
+ off(el, 'pointerdown', this._onTapStart);
+
+ if (this.nativeDraggable) {
+ off(el, 'dragover', this);
+ off(el, 'dragenter', this);
+ } // Remove draggable attributes
+
+
+ Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
+ el.removeAttribute('draggable');
+ });
+
+ this._onDrop();
+
+ this._disableDelayedDragEvents();
+
+ sortables.splice(sortables.indexOf(this.el), 1);
+ this.el = el = null;
+ },
+ _hideClone: function _hideClone() {
+ if (!cloneHidden) {
+ pluginEvent('hideClone', this);
+ if (Sortable.eventCanceled) return;
+ css(cloneEl, 'display', 'none');
+
+ if (this.options.removeCloneOnHide && cloneEl.parentNode) {
+ cloneEl.parentNode.removeChild(cloneEl);
+ }
+
+ cloneHidden = true;
+ }
+ },
+ _showClone: function _showClone(putSortable) {
+ if (putSortable.lastPutMode !== 'clone') {
+ this._hideClone();
+
+ return;
+ }
+
+ if (cloneHidden) {
+ pluginEvent('showClone', this);
+ if (Sortable.eventCanceled) return; // show clone at dragEl or original position
+
+ if (rootEl.contains(dragEl) && !this.options.group.revertClone) {
+ rootEl.insertBefore(cloneEl, dragEl);
+ } else if (nextEl) {
+ rootEl.insertBefore(cloneEl, nextEl);
+ } else {
+ rootEl.appendChild(cloneEl);
+ }
+
+ if (this.options.group.revertClone) {
+ this.animate(dragEl, cloneEl);
+ }
+
+ css(cloneEl, 'display', '');
+ cloneHidden = false;
+ }
+ }
+ };
+
+ function _globalDragOver(
+ /**Event*/
+ evt) {
+ if (evt.dataTransfer) {
+ evt.dataTransfer.dropEffect = 'move';
+ }
+
+ evt.cancelable && evt.preventDefault();
+ }
+
+ function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
+ var evt,
+ sortable = fromEl[expando],
+ onMoveFn = sortable.options.onMove,
+ retVal; // Support for new CustomEvent feature
+
+ if (window.CustomEvent && !IE11OrLess && !Edge) {
+ evt = new CustomEvent('move', {
+ bubbles: true,
+ cancelable: true
+ });
+ } else {
+ evt = document.createEvent('Event');
+ evt.initEvent('move', true, true);
+ }
+
+ evt.to = toEl;
+ evt.from = fromEl;
+ evt.dragged = dragEl;
+ evt.draggedRect = dragRect;
+ evt.related = targetEl || toEl;
+ evt.relatedRect = targetRect || getRect(toEl);
+ evt.willInsertAfter = willInsertAfter;
+ evt.originalEvent = originalEvent;
+ fromEl.dispatchEvent(evt);
+
+ if (onMoveFn) {
+ retVal = onMoveFn.call(sortable, evt, originalEvent);
+ }
+
+ return retVal;
+ }
+
+ function _disableDraggable(el) {
+ el.draggable = false;
+ }
+
+ function _unsilent() {
+ _silent = false;
+ }
+
+ function _ghostIsLast(evt, vertical, sortable) {
+ var rect = getRect(lastChild(sortable.el, sortable.options.draggable));
+ var spacer = 10;
+ return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer;
+ }
+
+ function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
+ var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
+ targetLength = vertical ? targetRect.height : targetRect.width,
+ targetS1 = vertical ? targetRect.top : targetRect.left,
+ targetS2 = vertical ? targetRect.bottom : targetRect.right,
+ invert = false;
+
+ if (!invertSwap) {
+ // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
+ if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
+ // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
+ // check if past first invert threshold on side opposite of lastDirection
+ if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
+ // past first invert threshold, do not restrict inverted threshold to dragEl shadow
+ pastFirstInvertThresh = true;
+ }
+
+ if (!pastFirstInvertThresh) {
+ // dragEl shadow (target move distance shadow)
+ if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
+ : mouseOnAxis > targetS2 - targetMoveDistance) {
+ return -lastDirection;
+ }
+ } else {
+ invert = true;
+ }
+ } else {
+ // Regular
+ if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
+ return _getInsertDirection(target);
+ }
+ }
+ }
+
+ invert = invert || invertSwap;
+
+ if (invert) {
+ // Invert of regular
+ if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
+ return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
+ }
+ }
+
+ return 0;
+ }
+ /**
+ * Gets the direction dragEl must be swapped relative to target in order to make it
+ * seem that dragEl has been "inserted" into that element's position
+ * @param {HTMLElement} target The target whose position dragEl is being inserted at
+ * @return {Number} Direction dragEl must be swapped
+ */
+
+
+ function _getInsertDirection(target) {
+ if (index(dragEl) < index(target)) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+ /**
+ * Generate id
+ * @param {HTMLElement} el
+ * @returns {String}
+ * @private
+ */
+
+
+ function _generateId(el) {
+ var str = el.tagName + el.className + el.src + el.href + el.textContent,
+ i = str.length,
+ sum = 0;
+
+ while (i--) {
+ sum += str.charCodeAt(i);
+ }
+
+ return sum.toString(36);
+ }
+
+ function _saveInputCheckedState(root) {
+ savedInputChecked.length = 0;
+ var inputs = root.getElementsByTagName('input');
+ var idx = inputs.length;
+
+ while (idx--) {
+ var el = inputs[idx];
+ el.checked && savedInputChecked.push(el);
+ }
+ }
+
+ function _nextTick(fn) {
+ return setTimeout(fn, 0);
+ }
+
+ function _cancelNextTick(id) {
+ return clearTimeout(id);
+ } // Fixed #973:
+
+
+ if (documentExists) {
+ on(document, 'touchmove', function (evt) {
+ if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
+ evt.preventDefault();
+ }
+ });
+ } // Export utils
+
+
+ Sortable.utils = {
+ on: on,
+ off: off,
+ css: css,
+ find: find,
+ is: function is(el, selector) {
+ return !!closest(el, selector, el, false);
+ },
+ extend: extend,
+ throttle: throttle,
+ closest: closest,
+ toggleClass: toggleClass,
+ clone: clone,
+ index: index,
+ nextTick: _nextTick,
+ cancelNextTick: _cancelNextTick,
+ detectDirection: _detectDirection,
+ getChild: getChild
+ };
+ /**
+ * Get the Sortable instance of an element
+ * @param {HTMLElement} element The element
+ * @return {Sortable|undefined} The instance of Sortable
+ */
+
+ Sortable.get = function (element) {
+ return element[expando];
+ };
+ /**
+ * Mount a plugin to Sortable
+ * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
+ */
+
+
+ Sortable.mount = function () {
+ for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
+ plugins[_key] = arguments[_key];
+ }
+
+ if (plugins[0].constructor === Array) plugins = plugins[0];
+ plugins.forEach(function (plugin) {
+ if (!plugin.prototype || !plugin.prototype.constructor) {
+ throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
+ }
+
+ if (plugin.utils) Sortable.utils = _objectSpread({}, Sortable.utils, plugin.utils);
+ PluginManager.mount(plugin);
+ });
+ };
+ /**
+ * Create sortable instance
+ * @param {HTMLElement} el
+ * @param {Object} [options]
+ */
+
+
+ Sortable.create = function (el, options) {
+ return new Sortable(el, options);
+ }; // Export
+
+
+ Sortable.version = version;
+
+ var autoScrolls = [],
+ scrollEl,
+ scrollRootEl,
+ scrolling = false,
+ lastAutoScrollX,
+ lastAutoScrollY,
+ touchEvt$1,
+ pointerElemChangedInterval;
+
+ function AutoScrollPlugin() {
+ function AutoScroll() {
+ this.defaults = {
+ scroll: true,
+ scrollSensitivity: 30,
+ scrollSpeed: 10,
+ bubbleScroll: true
+ }; // Bind all private methods
+
+ for (var fn in this) {
+ if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
+ this[fn] = this[fn].bind(this);
+ }
+ }
+ }
+
+ AutoScroll.prototype = {
+ dragStarted: function dragStarted(_ref) {
+ var originalEvent = _ref.originalEvent;
+
+ if (this.sortable.nativeDraggable) {
+ on(document, 'dragover', this._handleAutoScroll);
+ } else {
+ if (this.options.supportPointer) {
+ on(document, 'pointermove', this._handleFallbackAutoScroll);
+ } else if (originalEvent.touches) {
+ on(document, 'touchmove', this._handleFallbackAutoScroll);
+ } else {
+ on(document, 'mousemove', this._handleFallbackAutoScroll);
+ }
+ }
+ },
+ dragOverCompleted: function dragOverCompleted(_ref2) {
+ var originalEvent = _ref2.originalEvent;
+
+ // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
+ if (!this.options.dragOverBubble && !originalEvent.rootEl) {
+ this._handleAutoScroll(originalEvent);
+ }
+ },
+ drop: function drop() {
+ if (this.sortable.nativeDraggable) {
+ off(document, 'dragover', this._handleAutoScroll);
+ } else {
+ off(document, 'pointermove', this._handleFallbackAutoScroll);
+ off(document, 'touchmove', this._handleFallbackAutoScroll);
+ off(document, 'mousemove', this._handleFallbackAutoScroll);
+ }
+
+ clearPointerElemChangedInterval();
+ clearAutoScrolls();
+ cancelThrottle();
+ },
+ nulling: function nulling() {
+ touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
+ autoScrolls.length = 0;
+ },
+ _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
+ this._handleAutoScroll(evt, true);
+ },
+ _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
+ var _this = this;
+
+ var x = (evt.touches ? evt.touches[0] : evt).clientX,
+ y = (evt.touches ? evt.touches[0] : evt).clientY,
+ elem = document.elementFromPoint(x, y);
+ touchEvt$1 = evt; // IE does not seem to have native autoscroll,
+ // Edge's autoscroll seems too conditional,
+ // MACOS Safari does not have autoscroll,
+ // Firefox and Chrome are good
+
+ if (fallback || Edge || IE11OrLess || Safari) {
+ autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change
+
+ var ogElemScroller = getParentAutoScrollElement(elem, true);
+
+ if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
+ pointerElemChangedInterval && clearPointerElemChangedInterval(); // Detect for pointer elem change, emulating native DnD behaviour
+
+ pointerElemChangedInterval = setInterval(function () {
+ var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
+
+ if (newElem !== ogElemScroller) {
+ ogElemScroller = newElem;
+ clearAutoScrolls();
+ }
+
+ autoScroll(evt, _this.options, newElem, fallback);
+ }, 10);
+ lastAutoScrollX = x;
+ lastAutoScrollY = y;
+ }
+ } else {
+ // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
+ if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
+ clearAutoScrolls();
+ return;
+ }
+
+ autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
+ }
+ }
+ };
+ return _extends(AutoScroll, {
+ pluginName: 'scroll',
+ initializeByDefault: true
+ });
+ }
+
+ function clearAutoScrolls() {
+ autoScrolls.forEach(function (autoScroll) {
+ clearInterval(autoScroll.pid);
+ });
+ autoScrolls = [];
+ }
+
+ function clearPointerElemChangedInterval() {
+ clearInterval(pointerElemChangedInterval);
+ }
+
+ var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
+ // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
+ if (!options.scroll) return;
+ var x = (evt.touches ? evt.touches[0] : evt).clientX,
+ y = (evt.touches ? evt.touches[0] : evt).clientY,
+ sens = options.scrollSensitivity,
+ speed = options.scrollSpeed,
+ winScroller = getWindowScrollingElement();
+ var scrollThisInstance = false,
+ scrollCustomFn; // New scroll root, set scrollEl
+
+ if (scrollRootEl !== rootEl) {
+ scrollRootEl = rootEl;
+ clearAutoScrolls();
+ scrollEl = options.scroll;
+ scrollCustomFn = options.scrollFn;
+
+ if (scrollEl === true) {
+ scrollEl = getParentAutoScrollElement(rootEl, true);
+ }
+ }
+
+ var layersOut = 0;
+ var currentParent = scrollEl;
+
+ do {
+ var el = currentParent,
+ rect = getRect(el),
+ top = rect.top,
+ bottom = rect.bottom,
+ left = rect.left,
+ right = rect.right,
+ width = rect.width,
+ height = rect.height,
+ canScrollX = void 0,
+ canScrollY = void 0,
+ scrollWidth = el.scrollWidth,
+ scrollHeight = el.scrollHeight,
+ elCSS = css(el),
+ scrollPosX = el.scrollLeft,
+ scrollPosY = el.scrollTop;
+
+ if (el === winScroller) {
+ canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
+ canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
+ } else {
+ canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
+ canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
+ }
+
+ var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
+ var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
+
+ if (!autoScrolls[layersOut]) {
+ for (var i = 0; i <= layersOut; i++) {
+ if (!autoScrolls[i]) {
+ autoScrolls[i] = {};
+ }
+ }
+ }
+
+ if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
+ autoScrolls[layersOut].el = el;
+ autoScrolls[layersOut].vx = vx;
+ autoScrolls[layersOut].vy = vy;
+ clearInterval(autoScrolls[layersOut].pid);
+
+ if (vx != 0 || vy != 0) {
+ scrollThisInstance = true;
+ /* jshint loopfunc:true */
+
+ autoScrolls[layersOut].pid = setInterval(function () {
+ // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
+ if (isFallback && this.layer === 0) {
+ Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
+
+ }
+
+ var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
+ var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
+
+ if (typeof scrollCustomFn === 'function') {
+ if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
+ return;
+ }
+ }
+
+ scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
+ }.bind({
+ layer: layersOut
+ }), 24);
+ }
+ }
+
+ layersOut++;
+ } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
+
+ scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
+ }, 30);
+
+ var drop = function drop(_ref) {
+ var originalEvent = _ref.originalEvent,
+ putSortable = _ref.putSortable,
+ dragEl = _ref.dragEl,
+ activeSortable = _ref.activeSortable,
+ dispatchSortableEvent = _ref.dispatchSortableEvent,
+ hideGhostForTarget = _ref.hideGhostForTarget,
+ unhideGhostForTarget = _ref.unhideGhostForTarget;
+ if (!originalEvent) return;
+ var toSortable = putSortable || activeSortable;
+ hideGhostForTarget();
+ var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
+ var target = document.elementFromPoint(touch.clientX, touch.clientY);
+ unhideGhostForTarget();
+
+ if (toSortable && !toSortable.el.contains(target)) {
+ dispatchSortableEvent('spill');
+ this.onSpill({
+ dragEl: dragEl,
+ putSortable: putSortable
+ });
+ }
+ };
+
+ function Revert() {}
+
+ Revert.prototype = {
+ startIndex: null,
+ dragStart: function dragStart(_ref2) {
+ var oldDraggableIndex = _ref2.oldDraggableIndex;
+ this.startIndex = oldDraggableIndex;
+ },
+ onSpill: function onSpill(_ref3) {
+ var dragEl = _ref3.dragEl,
+ putSortable = _ref3.putSortable;
+ this.sortable.captureAnimationState();
+
+ if (putSortable) {
+ putSortable.captureAnimationState();
+ }
+
+ var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
+
+ if (nextSibling) {
+ this.sortable.el.insertBefore(dragEl, nextSibling);
+ } else {
+ this.sortable.el.appendChild(dragEl);
+ }
+
+ this.sortable.animateAll();
+
+ if (putSortable) {
+ putSortable.animateAll();
+ }
+ },
+ drop: drop
+ };
+
+ _extends(Revert, {
+ pluginName: 'revertOnSpill'
+ });
+
+ function Remove() {}
+
+ Remove.prototype = {
+ onSpill: function onSpill(_ref4) {
+ var dragEl = _ref4.dragEl,
+ putSortable = _ref4.putSortable;
+ var parentSortable = putSortable || this.sortable;
+ parentSortable.captureAnimationState();
+ dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
+ parentSortable.animateAll();
+ },
+ drop: drop
+ };
+
+ _extends(Remove, {
+ pluginName: 'removeOnSpill'
+ });
+
+ var lastSwapEl;
+
+ function SwapPlugin() {
+ function Swap() {
+ this.defaults = {
+ swapClass: 'sortable-swap-highlight'
+ };
+ }
+
+ Swap.prototype = {
+ dragStart: function dragStart(_ref) {
+ var dragEl = _ref.dragEl;
+ lastSwapEl = dragEl;
+ },
+ dragOverValid: function dragOverValid(_ref2) {
+ var completed = _ref2.completed,
+ target = _ref2.target,
+ onMove = _ref2.onMove,
+ activeSortable = _ref2.activeSortable,
+ changed = _ref2.changed,
+ cancel = _ref2.cancel;
+ if (!activeSortable.options.swap) return;
+ var el = this.sortable.el,
+ options = this.options;
+
+ if (target && target !== el) {
+ var prevSwapEl = lastSwapEl;
+
+ if (onMove(target) !== false) {
+ toggleClass(target, options.swapClass, true);
+ lastSwapEl = target;
+ } else {
+ lastSwapEl = null;
+ }
+
+ if (prevSwapEl && prevSwapEl !== lastSwapEl) {
+ toggleClass(prevSwapEl, options.swapClass, false);
+ }
+ }
+
+ changed();
+ completed(true);
+ cancel();
+ },
+ drop: function drop(_ref3) {
+ var activeSortable = _ref3.activeSortable,
+ putSortable = _ref3.putSortable,
+ dragEl = _ref3.dragEl;
+ var toSortable = putSortable || this.sortable;
+ var options = this.options;
+ lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
+
+ if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
+ if (dragEl !== lastSwapEl) {
+ toSortable.captureAnimationState();
+ if (toSortable !== activeSortable) activeSortable.captureAnimationState();
+ swapNodes(dragEl, lastSwapEl);
+ toSortable.animateAll();
+ if (toSortable !== activeSortable) activeSortable.animateAll();
+ }
+ }
+ },
+ nulling: function nulling() {
+ lastSwapEl = null;
+ }
+ };
+ return _extends(Swap, {
+ pluginName: 'swap',
+ eventProperties: function eventProperties() {
+ return {
+ swapItem: lastSwapEl
+ };
+ }
+ });
+ }
+
+ function swapNodes(n1, n2) {
+ var p1 = n1.parentNode,
+ p2 = n2.parentNode,
+ i1,
+ i2;
+ if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
+ i1 = index(n1);
+ i2 = index(n2);
+
+ if (p1.isEqualNode(p2) && i1 < i2) {
+ i2++;
+ }
+
+ p1.insertBefore(n2, p1.children[i1]);
+ p2.insertBefore(n1, p2.children[i2]);
+ }
+
+ var multiDragElements = [],
+ multiDragClones = [],
+ lastMultiDragSelect,
+ // for selection with modifier key down (SHIFT)
+ multiDragSortable,
+ initialFolding = false,
+ // Initial multi-drag fold when drag started
+ folding = false,
+ // Folding any other time
+ dragStarted = false,
+ dragEl$1,
+ clonesFromRect,
+ clonesHidden;
+
+ function MultiDragPlugin() {
+ function MultiDrag(sortable) {
+ // Bind all private methods
+ for (var fn in this) {
+ if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
+ this[fn] = this[fn].bind(this);
+ }
+ }
+
+ if (sortable.options.supportPointer) {
+ on(document, 'pointerup', this._deselectMultiDrag);
+ } else {
+ on(document, 'mouseup', this._deselectMultiDrag);
+ on(document, 'touchend', this._deselectMultiDrag);
+ }
+
+ on(document, 'keydown', this._checkKeyDown);
+ on(document, 'keyup', this._checkKeyUp);
+ this.defaults = {
+ selectedClass: 'sortable-selected',
+ multiDragKey: null,
+ setData: function setData(dataTransfer, dragEl) {
+ var data = '';
+
+ if (multiDragElements.length && multiDragSortable === sortable) {
+ multiDragElements.forEach(function (multiDragElement, i) {
+ data += (!i ? '' : ', ') + multiDragElement.textContent;
+ });
+ } else {
+ data = dragEl.textContent;
+ }
+
+ dataTransfer.setData('Text', data);
+ }
+ };
+ }
+
+ MultiDrag.prototype = {
+ multiDragKeyDown: false,
+ isMultiDrag: false,
+ delayStartGlobal: function delayStartGlobal(_ref) {
+ var dragged = _ref.dragEl;
+ dragEl$1 = dragged;
+ },
+ delayEnded: function delayEnded() {
+ this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
+ },
+ setupClone: function setupClone(_ref2) {
+ var sortable = _ref2.sortable,
+ cancel = _ref2.cancel;
+ if (!this.isMultiDrag) return;
+
+ for (var i = 0; i < multiDragElements.length; i++) {
+ multiDragClones.push(clone(multiDragElements[i]));
+ multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
+ multiDragClones[i].draggable = false;
+ multiDragClones[i].style['will-change'] = '';
+ toggleClass(multiDragClones[i], this.options.selectedClass, false);
+ multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
+ }
+
+ sortable._hideClone();
+
+ cancel();
+ },
+ clone: function clone(_ref3) {
+ var sortable = _ref3.sortable,
+ rootEl = _ref3.rootEl,
+ dispatchSortableEvent = _ref3.dispatchSortableEvent,
+ cancel = _ref3.cancel;
+ if (!this.isMultiDrag) return;
+
+ if (!this.options.removeCloneOnHide) {
+ if (multiDragElements.length && multiDragSortable === sortable) {
+ insertMultiDragClones(true, rootEl);
+ dispatchSortableEvent('clone');
+ cancel();
+ }
+ }
+ },
+ showClone: function showClone(_ref4) {
+ var cloneNowShown = _ref4.cloneNowShown,
+ rootEl = _ref4.rootEl,
+ cancel = _ref4.cancel;
+ if (!this.isMultiDrag) return;
+ insertMultiDragClones(false, rootEl);
+ multiDragClones.forEach(function (clone) {
+ css(clone, 'display', '');
+ });
+ cloneNowShown();
+ clonesHidden = false;
+ cancel();
+ },
+ hideClone: function hideClone(_ref5) {
+ var _this = this;
+
+ var sortable = _ref5.sortable,
+ cloneNowHidden = _ref5.cloneNowHidden,
+ cancel = _ref5.cancel;
+ if (!this.isMultiDrag) return;
+ multiDragClones.forEach(function (clone) {
+ css(clone, 'display', 'none');
+
+ if (_this.options.removeCloneOnHide && clone.parentNode) {
+ clone.parentNode.removeChild(clone);
+ }
+ });
+ cloneNowHidden();
+ clonesHidden = true;
+ cancel();
+ },
+ dragStartGlobal: function dragStartGlobal(_ref6) {
+ var sortable = _ref6.sortable;
+
+ if (!this.isMultiDrag && multiDragSortable) {
+ multiDragSortable.multiDrag._deselectMultiDrag();
+ }
+
+ multiDragElements.forEach(function (multiDragElement) {
+ multiDragElement.sortableIndex = index(multiDragElement);
+ }); // Sort multi-drag elements
+
+ multiDragElements = multiDragElements.sort(function (a, b) {
+ return a.sortableIndex - b.sortableIndex;
+ });
+ dragStarted = true;
+ },
+ dragStarted: function dragStarted(_ref7) {
+ var _this2 = this;
+
+ var sortable = _ref7.sortable;
+ if (!this.isMultiDrag) return;
+
+ if (this.options.sort) {
+ // Capture rects,
+ // hide multi drag elements (by positioning them absolute),
+ // set multi drag elements rects to dragRect,
+ // show multi drag elements,
+ // animate to rects,
+ // unset rects & remove from DOM
+ sortable.captureAnimationState();
+
+ if (this.options.animation) {
+ multiDragElements.forEach(function (multiDragElement) {
+ if (multiDragElement === dragEl$1) return;
+ css(multiDragElement, 'position', 'absolute');
+ });
+ var dragRect = getRect(dragEl$1, false, true, true);
+ multiDragElements.forEach(function (multiDragElement) {
+ if (multiDragElement === dragEl$1) return;
+ setRect(multiDragElement, dragRect);
+ });
+ folding = true;
+ initialFolding = true;
+ }
+ }
+
+ sortable.animateAll(function () {
+ folding = false;
+ initialFolding = false;
+
+ if (_this2.options.animation) {
+ multiDragElements.forEach(function (multiDragElement) {
+ unsetRect(multiDragElement);
+ });
+ } // Remove all auxiliary multidrag items from el, if sorting enabled
+
+
+ if (_this2.options.sort) {
+ removeMultiDragElements();
+ }
+ });
+ },
+ dragOver: function dragOver(_ref8) {
+ var target = _ref8.target,
+ completed = _ref8.completed,
+ cancel = _ref8.cancel;
+
+ if (folding && ~multiDragElements.indexOf(target)) {
+ completed(false);
+ cancel();
+ }
+ },
+ revert: function revert(_ref9) {
+ var fromSortable = _ref9.fromSortable,
+ rootEl = _ref9.rootEl,
+ sortable = _ref9.sortable,
+ dragRect = _ref9.dragRect;
+
+ if (multiDragElements.length > 1) {
+ // Setup unfold animation
+ multiDragElements.forEach(function (multiDragElement) {
+ sortable.addAnimationState({
+ target: multiDragElement,
+ rect: folding ? getRect(multiDragElement) : dragRect
+ });
+ unsetRect(multiDragElement);
+ multiDragElement.fromRect = dragRect;
+ fromSortable.removeAnimationState(multiDragElement);
+ });
+ folding = false;
+ insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
+ }
+ },
+ dragOverCompleted: function dragOverCompleted(_ref10) {
+ var sortable = _ref10.sortable,
+ isOwner = _ref10.isOwner,
+ insertion = _ref10.insertion,
+ activeSortable = _ref10.activeSortable,
+ parentEl = _ref10.parentEl,
+ putSortable = _ref10.putSortable;
+ var options = this.options;
+
+ if (insertion) {
+ // Clones must be hidden before folding animation to capture dragRectAbsolute properly
+ if (isOwner) {
+ activeSortable._hideClone();
+ }
+
+ initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location
+
+ if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
+ // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
+ var dragRectAbsolute = getRect(dragEl$1, false, true, true);
+ multiDragElements.forEach(function (multiDragElement) {
+ if (multiDragElement === dragEl$1) return;
+ setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
+ // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
+
+ parentEl.appendChild(multiDragElement);
+ });
+ folding = true;
+ } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
+
+
+ if (!isOwner) {
+ // Only remove if not folding (folding will remove them anyways)
+ if (!folding) {
+ removeMultiDragElements();
+ }
+
+ if (multiDragElements.length > 1) {
+ var clonesHiddenBefore = clonesHidden;
+
+ activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden
+
+
+ if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
+ multiDragClones.forEach(function (clone) {
+ activeSortable.addAnimationState({
+ target: clone,
+ rect: clonesFromRect
+ });
+ clone.fromRect = clonesFromRect;
+ clone.thisAnimationDuration = null;
+ });
+ }
+ } else {
+ activeSortable._showClone(sortable);
+ }
+ }
+ }
+ },
+ dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
+ var dragRect = _ref11.dragRect,
+ isOwner = _ref11.isOwner,
+ activeSortable = _ref11.activeSortable;
+ multiDragElements.forEach(function (multiDragElement) {
+ multiDragElement.thisAnimationDuration = null;
+ });
+
+ if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
+ clonesFromRect = _extends({}, dragRect);
+ var dragMatrix = matrix(dragEl$1, true);
+ clonesFromRect.top -= dragMatrix.f;
+ clonesFromRect.left -= dragMatrix.e;
+ }
+ },
+ dragOverAnimationComplete: function dragOverAnimationComplete() {
+ if (folding) {
+ folding = false;
+ removeMultiDragElements();
+ }
+ },
+ drop: function drop(_ref12) {
+ var evt = _ref12.originalEvent,
+ rootEl = _ref12.rootEl,
+ parentEl = _ref12.parentEl,
+ sortable = _ref12.sortable,
+ dispatchSortableEvent = _ref12.dispatchSortableEvent,
+ oldIndex = _ref12.oldIndex,
+ putSortable = _ref12.putSortable;
+ var toSortable = putSortable || this.sortable;
+ if (!evt) return;
+ var options = this.options,
+ children = parentEl.children; // Multi-drag selection
+
+ if (!dragStarted) {
+ if (options.multiDragKey && !this.multiDragKeyDown) {
+ this._deselectMultiDrag();
+ }
+
+ toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
+
+ if (!~multiDragElements.indexOf(dragEl$1)) {
+ multiDragElements.push(dragEl$1);
+ dispatchEvent({
+ sortable: sortable,
+ rootEl: rootEl,
+ name: 'select',
+ targetEl: dragEl$1,
+ originalEvt: evt
+ }); // Modifier activated, select from last to dragEl
+
+ if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
+ var lastIndex = index(lastMultiDragSelect),
+ currentIndex = index(dragEl$1);
+
+ if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
+ // Must include lastMultiDragSelect (select it), in case modified selection from no selection
+ // (but previous selection existed)
+ var n, i;
+
+ if (currentIndex > lastIndex) {
+ i = lastIndex;
+ n = currentIndex;
+ } else {
+ i = currentIndex;
+ n = lastIndex + 1;
+ }
+
+ for (; i < n; i++) {
+ if (~multiDragElements.indexOf(children[i])) continue;
+ toggleClass(children[i], options.selectedClass, true);
+ multiDragElements.push(children[i]);
+ dispatchEvent({
+ sortable: sortable,
+ rootEl: rootEl,
+ name: 'select',
+ targetEl: children[i],
+ originalEvt: evt
+ });
+ }
+ }
+ } else {
+ lastMultiDragSelect = dragEl$1;
+ }
+
+ multiDragSortable = toSortable;
+ } else {
+ multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
+ lastMultiDragSelect = null;
+ dispatchEvent({
+ sortable: sortable,
+ rootEl: rootEl,
+ name: 'deselect',
+ targetEl: dragEl$1,
+ originalEvt: evt
+ });
+ }
+ } // Multi-drag drop
+
+
+ if (dragStarted && this.isMultiDrag) {
+ // Do not "unfold" after around dragEl if reverted
+ if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
+ var dragRect = getRect(dragEl$1),
+ multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
+ if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
+ toSortable.captureAnimationState();
+
+ if (!initialFolding) {
+ if (options.animation) {
+ dragEl$1.fromRect = dragRect;
+ multiDragElements.forEach(function (multiDragElement) {
+ multiDragElement.thisAnimationDuration = null;
+
+ if (multiDragElement !== dragEl$1) {
+ var rect = folding ? getRect(multiDragElement) : dragRect;
+ multiDragElement.fromRect = rect; // Prepare unfold animation
+
+ toSortable.addAnimationState({
+ target: multiDragElement,
+ rect: rect
+ });
+ }
+ });
+ } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
+ // properly they must all be removed
+
+
+ removeMultiDragElements();
+ multiDragElements.forEach(function (multiDragElement) {
+ if (children[multiDragIndex]) {
+ parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
+ } else {
+ parentEl.appendChild(multiDragElement);
+ }
+
+ multiDragIndex++;
+ }); // If initial folding is done, the elements may have changed position because they are now
+ // unfolding around dragEl, even though dragEl may not have his index changed, so update event
+ // must be fired here as Sortable will not.
+
+ if (oldIndex === index(dragEl$1)) {
+ var update = false;
+ multiDragElements.forEach(function (multiDragElement) {
+ if (multiDragElement.sortableIndex !== index(multiDragElement)) {
+ update = true;
+ return;
+ }
+ });
+
+ if (update) {
+ dispatchSortableEvent('update');
+ }
+ }
+ } // Must be done after capturing individual rects (scroll bar)
+
+
+ multiDragElements.forEach(function (multiDragElement) {
+ unsetRect(multiDragElement);
+ });
+ toSortable.animateAll();
+ }
+
+ multiDragSortable = toSortable;
+ } // Remove clones if necessary
+
+
+ if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
+ multiDragClones.forEach(function (clone) {
+ clone.parentNode && clone.parentNode.removeChild(clone);
+ });
+ }
+ },
+ nullingGlobal: function nullingGlobal() {
+ this.isMultiDrag = dragStarted = false;
+ multiDragClones.length = 0;
+ },
+ destroyGlobal: function destroyGlobal() {
+ this._deselectMultiDrag();
+
+ off(document, 'pointerup', this._deselectMultiDrag);
+ off(document, 'mouseup', this._deselectMultiDrag);
+ off(document, 'touchend', this._deselectMultiDrag);
+ off(document, 'keydown', this._checkKeyDown);
+ off(document, 'keyup', this._checkKeyUp);
+ },
+ _deselectMultiDrag: function _deselectMultiDrag(evt) {
+ if (typeof dragStarted !== "undefined" && dragStarted) return; // Only deselect if selection is in this sortable
+
+ if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable
+
+ if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click
+
+ if (evt && evt.button !== 0) return;
+
+ while (multiDragElements.length) {
+ var el = multiDragElements[0];
+ toggleClass(el, this.options.selectedClass, false);
+ multiDragElements.shift();
+ dispatchEvent({
+ sortable: this.sortable,
+ rootEl: this.sortable.el,
+ name: 'deselect',
+ targetEl: el,
+ originalEvt: evt
+ });
+ }
+ },
+ _checkKeyDown: function _checkKeyDown(evt) {
+ if (evt.key === this.options.multiDragKey) {
+ this.multiDragKeyDown = true;
+ }
+ },
+ _checkKeyUp: function _checkKeyUp(evt) {
+ if (evt.key === this.options.multiDragKey) {
+ this.multiDragKeyDown = false;
+ }
+ }
+ };
+ return _extends(MultiDrag, {
+ // Static methods & properties
+ pluginName: 'multiDrag',
+ utils: {
+ /**
+ * Selects the provided multi-drag item
+ * @param {HTMLElement} el The element to be selected
+ */
+ select: function select(el) {
+ var sortable = el.parentNode[expando];
+ if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
+
+ if (multiDragSortable && multiDragSortable !== sortable) {
+ multiDragSortable.multiDrag._deselectMultiDrag();
+
+ multiDragSortable = sortable;
+ }
+
+ toggleClass(el, sortable.options.selectedClass, true);
+ multiDragElements.push(el);
+ },
+
+ /**
+ * Deselects the provided multi-drag item
+ * @param {HTMLElement} el The element to be deselected
+ */
+ deselect: function deselect(el) {
+ var sortable = el.parentNode[expando],
+ index = multiDragElements.indexOf(el);
+ if (!sortable || !sortable.options.multiDrag || !~index) return;
+ toggleClass(el, sortable.options.selectedClass, false);
+ multiDragElements.splice(index, 1);
+ }
+ },
+ eventProperties: function eventProperties() {
+ var _this3 = this;
+
+ var oldIndicies = [],
+ newIndicies = [];
+ multiDragElements.forEach(function (multiDragElement) {
+ oldIndicies.push({
+ multiDragElement: multiDragElement,
+ index: multiDragElement.sortableIndex
+ }); // multiDragElements will already be sorted if folding
+
+ var newIndex;
+
+ if (folding && multiDragElement !== dragEl$1) {
+ newIndex = -1;
+ } else if (folding) {
+ newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
+ } else {
+ newIndex = index(multiDragElement);
+ }
+
+ newIndicies.push({
+ multiDragElement: multiDragElement,
+ index: newIndex
+ });
+ });
+ return {
+ items: _toConsumableArray(multiDragElements),
+ clones: [].concat(multiDragClones),
+ oldIndicies: oldIndicies,
+ newIndicies: newIndicies
+ };
+ },
+ optionListeners: {
+ multiDragKey: function multiDragKey(key) {
+ key = key.toLowerCase();
+
+ if (key === 'ctrl') {
+ key = 'Control';
+ } else if (key.length > 1) {
+ key = key.charAt(0).toUpperCase() + key.substr(1);
+ }
+
+ return key;
+ }
+ }
+ });
+ }
+
+ function insertMultiDragElements(clonesInserted, rootEl) {
+ multiDragElements.forEach(function (multiDragElement, i) {
+ var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
+
+ if (target) {
+ rootEl.insertBefore(multiDragElement, target);
+ } else {
+ rootEl.appendChild(multiDragElement);
+ }
+ });
+ }
+ /**
+ * Insert multi-drag clones
+ * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
+ * @param {HTMLElement} rootEl
+ */
+
+
+ function insertMultiDragClones(elementsInserted, rootEl) {
+ multiDragClones.forEach(function (clone, i) {
+ var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
+
+ if (target) {
+ rootEl.insertBefore(clone, target);
+ } else {
+ rootEl.appendChild(clone);
+ }
+ });
+ }
+
+ function removeMultiDragElements() {
+ multiDragElements.forEach(function (multiDragElement) {
+ if (multiDragElement === dragEl$1) return;
+ multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
+ });
+ }
+
+ Sortable.mount(new AutoScrollPlugin());
+ Sortable.mount(Remove, Revert);
+
+ Sortable.mount(new SwapPlugin());
+ Sortable.mount(new MultiDragPlugin());
+
+ return Sortable;
+
+}));
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/resources/assets/sortable.min.js b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/resources/assets/sortable.min.js
new file mode 100644
index 0000000..e5137bf
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/resources/assets/sortable.min.js
@@ -0,0 +1 @@
+eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('!6(t,e){"5H"==1j 80&&"5N"!=1j 7c?7c.80=e():"6"==1j 5i&&5i.aY?5i(e):(t=t||aX).4M=e()}(3,6(){"aS aR";6 o(t){12(o="6"==1j 34&&"7f"==1j 34.7j?6(t){12 1j t}:6(t){12 t&&"6"==1j 34&&t.3V===34&&t!==34.1Q?"7f":1j t})(t)}6 a(){12(a=1O.aQ||6(t){1d(7 e=1;e<2g.1f;e++){7 n=2g[e];1d(7 o 1t n)1O.1Q.2L.1A(n,o)&&(t[o]=n[o])}12 t}).7u(3,2g)}6 I(i){1d(7 t=1;t<2g.1f;t++){7 r=18!=2g[t]?2g[t]:{},e=1O.6Y(r);"6"==1j 1O.4F&&(e=e.2c(1O.4F(r).2Y(6(t){12 1O.aN(r,t).7K}))),e.1c(6(t){7 e,n,o;e=i,o=r[n=t],n 1t e?1O.aM(e,n,{aL:o,7K:!0,aJ:!0,aI:!0}):e[n]=o})}12 i}6 l(t,e){9(18==t)12{};7 n,o,i=6(t,e){9(18==t)12{};7 n,o,i={},r=1O.6Y(t);1d(o=0;o"===e[0]&&(e=e.a6(1)),t)6s{9(t.6u)12 t.6u(e);9(t.6D)12 t.6D(e);9(t.6H)12 t.6H(e)}6I(t){12!1}12!1}}6 P(t,e,n,o){9(t){n=n||14;2X{9(18!=e&&(">"===e[0]?t.19===n&&h(t,e):h(t,e))||o&&t===n)12 t;9(t===n)3r}2H(t=(i=t).5B&&i!==14&&i.5B.5C?i.5B:i.19)}7 i;12 18}7 f,p=/\\s+/g;6 k(t,e,n){9(t&&e)9(t.82)t.82[n?"83":"6d"](e);1P{7 o=(" "+t.5U+" ").5Y(p," ").5Y(" "+e+" "," ");t.5U=(o+(n?" "+e:"")).5Y(p," ")}}6 R(t,e,n){7 o=t&&t.2a;9(o){9(1l 0===n)12 14.4Z&&14.4Z.6v?n=14.4Z.6v(t,""):t.6w&&(n=t.6w),1l 0===e?n:n[e];e 1t o||-1!==e.1M("6y")||(e="-6y-"+e),o[e]=n+("54"==1j n?"":"5b")}}6 v(t,e){7 n="";9("54"==1j t)n=t;1P 2X{7 o=R(t,"1K");o&&"1C"!==o&&(n=o+" "+n)}2H(!e&&(t=t.19));7 i=1k.a4||1k.a3||1k.a2||1k.a1;12 i&&1V i(n)}6 g(t,e,n){9(t){7 o=t.78(e),i=0,r=o.1f;9(n)1d(;i=e.1b-n&&r<=e.1Y+n,i=a>=e.1a-n&&a<=e.2m+n;12 n&&o&&i?l=t:1l 0}}),l}((t=t.1x?t.1x[0]:t).1m,t.1o);9(e){7 n={};1d(7 o 1t t)t.2L(o)&&(n[o]=t[o]);n.1r=n.1u=e,n.26=1l 0,n.3q=1l 0,e[j].43(n)}}}6 6n(t){z&&z.19[j].44(t.1r)}6 15(t,e){9(!t||!t.5C||1!==t.5C)5h"4M: `1e` 6p 6q an 8V, 45 ".2c({}.4t.1A(t));3.1e=t,3.13=e=a({},e),t[j]=3;7 n={1L:18,1W:!0,55:!1,3X:18,57:18,1n:/^[8T]l$/i.6z(t.6S)?">8S":">*",59:1,6C:!1,5a:18,3p:!0,49:6(){12 5Z(t,3.13)},2x:"16-3k",3O:"16-8R",4d:"16-8Q",6L:"a, 8P",2Y:18,6N:!0,1X:0,4W:18,3i:6(t,e){t.3i("6P",e.4f)},6R:!1,4g:!1,6T:"8O-8N",5m:0,6X:!1,4h:(3Y.1E?3Y:1k).1E(1k.6Z,10)||1,71:!1,72:"16-8M",74:!1,75:0,76:{x:0,y:0},2N:!1!==15.2N&&"8K"1t 1k,6i:5};1d(7 o 1t O.6G(3,t,n),n)o 1t e||(e[o]=n[o]);1d(7 i 1t 4P(e),3)"1R"===i.3Z(0)&&"6"==1j 3[i]&&(3[i]=3[i].35(3));3.1I=!e.71&&7o,3.1I&&(3.13.4h=1),e.2N?u(t,"5t",3.2R):(u(t,"5v",3.2R),u(t,"7e",3.2R)),3.1I&&(u(t,"2v",3),u(t,"5x",3)),3F.1T(3.1e),e.3X&&e.3X.5y&&3.1W(e.3X.5y(3)||[]),a(3,T())}6 4o(t,e,n,o,i,r,a,l){7 s,c,u=t[j],d=u.13.5A;12!1k.4L||w||E?(s=14.7k("7m")).7p("40",!0,!0):s=1V 4L("40",{7t:!0,2b:!0}),s.5J=e,s.5c=t,s.3D=n,s.8I=o,s.8H=i||e,s.8G=r||X(e),s.8F=l,s.1s=a,t.7E(s),d&&(c=d.1A(u,s,a)),c}6 4s(t){t.1n=!1}6 7q(){4c=!1}6 7r(t){1d(7 e=t.8E+t.5U+t.8D+t.8C+t.4f,n=e.1f,o=0;n--;)o+=e.8B(n);12 o.4t(36)}6 3G(t){12 2P(t,0)}6 4v(t){12 2s(t)}15.1Q={3V:15,44:6(t){3.1e.2S(t)||t===3.1e||(2W=18)},7A:6(t,e){12"6"==1j 3.13.49?3.13.49.1A(3,t,e,z):3.13.49},2R:6(e){9(e.2b){7 n=3,o=3.1e,t=3.13,i=t.6N,r=e.7B,a=e.1x&&e.1x[0]||e.5L&&"7D"===e.5L&&e,l=(a||e).1r,s=e.1r.5M&&(e.7F&&e.7F[0]||e.7G&&e.7G()[0])||l,c=t.2Y;9(6(t){3K.1f=0;7 e=t.78("8t"),n=e.1f;1d(;n--;){7 o=e[n];o.7I&&3K.1T(o)}}(o),!z&&!(/5v|5t/.6z(r)&&0!==e.7J||t.55||s.8o||(l=P(l,t.1n,o,!1))&&l.20||Z===l)){9(J=F(l),3d=F(l,t.1n),"6"==1j c){9(c.1A(3,e,l,3))12 W({16:n,1u:s,1g:"2Y",2A:l,1Z:o,3B:o}),K("2Y",n,{28:e}),1l(i&&e.2b&&e.26())}1P 9(c&&(c=c.65(",").6h(6(t){9(t=P(s,t.7L(),o,!1))12 W({16:n,1u:t,1g:"2Y",2A:l,3B:o,1Z:o}),K("2Y",n,{28:e}),!0})))12 1l(i&&e.2b&&e.26());t.57&&!P(s,t.57,o,!1)||3.7M(e,a,l)}}},7M:6(t,e,n){7 o,i=3,r=i.1e,a=i.13,l=r.5O;9(n&&!z&&n.19===r){7 s=X(n);9(q=r,G=(z=n).19,V=z.8n,Z=n,3v=a.1L,2C={1r:15.3D=z,1m:(e||t).1m,1o:(e||t).1o},5p=2C.1m-s.1b,5q=2C.1o-s.1a,3.4y=(e||t).1m,3.4z=(e||t).1o,z.2a["4A-3z"]="8m",o=6(){K("7U",i,{28:t}),15.1N?i.1z():(i.4D(),!c&&i.1I&&(z.1n=!0),i.7X(t,e),W({16:i,1g:"8k",1s:t}),k(z,a.3O,!0))},a.6L.65(",").1c(6(t){g(z,t.7L(),4s)}),u(l,"2v",2y),u(l,"2u",2y),u(l,"2k",2y),u(l,"2T",i.1z),u(l,"2I",i.1z),u(l,"3S",i.1z),c&&3.1I&&(3.13.4h=4,z.1n=!0),K("9C",3,{28:t}),!a.5m||a.6X&&!e||3.1I&&(E||w))o();1P{9(15.1N)12 1l 3.1z();u(l,"2T",i.2z),u(l,"2I",i.2z),u(l,"3S",i.2z),u(l,"2u",i.2U),u(l,"2k",i.2U),a.2N&&u(l,"33",i.2U),i.64=2P(o,a.5m)}}},2U:6(t){7 e=t.1x?t.1x[0]:t;1i.62(1i.2i(e.1m-3.4y),1i.2i(e.1o-3.4z))>=1i.8g(3.13.4h/(3.1I&&1k.6Z||1))&&3.2z()},2z:6(){z&&4s(z),2s(3.64),3.4D()},4D:6(){7 t=3.1e.5O;d(t,"2T",3.2z),d(t,"2I",3.2z),d(t,"3S",3.2z),d(t,"2u",3.2U),d(t,"2k",3.2U),d(t,"33",3.2U)},7X:6(t,e){e=e||"7D"==t.5L&&t,!3.1I||e?3.13.2N?u(14,"33",3.2F):u(14,e?"2k":"2u",3.2F):(u(z,"5K",3),u(q,"8e",3.4N));6s{14.85?3G(6(){14.85.8h()}):1k.8i().8j()}6I(t){}},84:6(t,e){9(2Q=!1,q&&z){K("4r",3,{28:e}),3.1I&&u(14,"2v",6n);7 n=3.13;t||k(z,n.4d,!1),k(z,n.2x,!0),15.2h=3,t&&3.7Y(),W({16:3,1g:"8l",1s:e})}1P 3.5T()},7O:6(){9(at){3.4y=at.1m,3.4z=at.1o,5e();1d(7 t=14.3A(at.1m,at.1o),e=t;t&&t.5M&&(t=t.5M.3A(at.1m,at.1o))!==e;)e=t;9(z.19[j].44(t),e)2X{9(e[j]){9(e[j].43({1m:at.1m,1o:at.1o,1r:t,1u:e})&&!3.13.4g)3r}t=e}2H(e=e.19);5f()}},2F:6(t){9(2C){7 e=3.13,n=e.75,o=e.76,i=t.1x?t.1x[0]:t,r=U&&v(U,!0),a=U&&r&&r.a,l=U&&r&&r.d,s=3M&&1w&&b(1w),c=(i.1m-2C.1m+o.x)/(a||1)+(s?s[0]-4e[0]:0)/(a||1),u=(i.1o-2C.1o+o.y)/(l||1)+(s?s[1]-4e[1]:0)/(l||1);9(!15.2h&&!2Q){9(n&&1i.62(1i.2i(i.1m-3.4y),1i.2i(i.1o-3.4z))o.1Y+10||t.1m<=o.1Y&&t.1o>o.2m&&t.1m>=o.1b:t.1m>o.1Y&&t.1o>o.1a||t.1m<=o.1Y&&t.1o>o.2m+10}(n,a,3)&&!g.20){9(g===z)12 A(!1);9(g&&l===n.1r&&(s=g),s&&(i=X(s)),!1!==4o(q,l,z,o,s,i,n,!!s))12 O(),l.21(z),G=l,N(),A(!0)}1P 9(s.19===l){i=X(s);7 v,m,b,y=z.19!==l,w=!6(t,e,n){7 o=n?t.1b:t.1a,i=n?t.1Y:t.2m,r=n?t.1q:t.1B,a=n?e.1b:e.1a,l=n?e.1Y:e.2m,s=n?e.1q:e.1B;12 o===a||i===l||o+r/2===a+s/2}(z.20&&z.5S||o,s.20&&s.5S||i,a),E=a?"1a":"1b",D=Y(s,"1a","1a")||Y(z,"1a","1a"),S=D?D.3g:1l 0;9(2W!==s&&(m=i[E],3j=!1,3H=!w&&e.6C||y),0!==(v=6(t,e,n,o,i,r,a,l){7 s=o?t.1o:t.1m,c=o?n.1B:n.1q,u=o?n.1a:n.1b,d=o?n.2m:n.1Y,h=!1;9(!a)9(l&&3Cname('dcat-admin-grid-sortable');
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/GridSortable.php b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/GridSortable.php
new file mode 100644
index 0000000..e763cce
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/GridSortable.php
@@ -0,0 +1,36 @@
+column;
+
+ Grid::macro('sortable', function ($sortName = 'order') use ($column) {
+ /* @var $this Grid */
+ $this->tools(new SaveOrderButton($sortName));
+
+ if (!request()->has($sortName)) {
+ $this->model()->ordered();
+ }
+
+ $this->column($column, ' ')
+ ->displayUsing(SortableDisplay::class, [$sortName]);
+ });
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/GridSortableServiceProvider.php b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/GridSortableServiceProvider.php
new file mode 100644
index 0000000..0564ee6
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/GridSortableServiceProvider.php
@@ -0,0 +1,35 @@
+views()) {
+ $this->loadViewsFrom($views, GridSortable::NAME);
+ }
+
+ if ($lang = $extension->lang()) {
+ $this->loadTranslationsFrom($lang, GridSortable::NAME);
+ }
+
+ if ($migrations = $extension->migrations()) {
+ $this->loadMigrationsFrom($migrations);
+ }
+
+ $this->app->booted(function () use ($extension) {
+ $extension->routes(__DIR__.'/../routes/web.php');
+ });
+
+ $extension->boot();
+ }
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/Http/Controllers/GridSortableController.php b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/Http/Controllers/GridSortableController.php
new file mode 100644
index 0000000..1e6eca5
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/Http/Controllers/GridSortableController.php
@@ -0,0 +1,42 @@
+get('_column');
+ $message = trans('admin.save_succeeded');
+ $repository = $request->get('_model');
+
+ $sorts = $request->get('_sort');
+ $sorts = collect($sorts)
+ ->pluck('key')
+ ->combine(
+ collect($sorts)->pluck('sort')->sort()
+ );
+
+ try {
+ $sorts->each(function ($v, $k) use ($repository, $column) {
+ $form = new Form(new $repository);
+
+ $form->text($column);
+
+ $form->update($k, [$column => $v]);
+ });
+
+ } catch (\Exception $exception) {
+ $status = false;
+ $message = $exception->getMessage();
+ }
+
+ return response()->json(compact('status', 'message'));
+ }
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/SaveOrderButton.php b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/SaveOrderButton.php
new file mode 100644
index 0000000..f479d11
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/SaveOrderButton.php
@@ -0,0 +1,57 @@
+sortColumn = $column;
+ }
+
+ protected function script()
+ {
+ $route = admin_base_path('extension/grid-sort');
+ $class = $this->parent->model()->getRepository()->getOriginalClassName();
+ $class = str_replace('\\', '\\\\', $class);
+
+ return <<sortColumn}',
+ },
+ function(data){
+
+ if (data.status) {
+ LA.success(data.message);
+ LA.reload();
+ } else {
+ LA.error(data.message);
+ }
+ });
+});
+JS;
+ }
+
+ public function render()
+ {
+ Admin::script($this->script());
+
+ $text = admin_trans_label('Save order');
+
+ return <<
+ {$text}
+
+HTML;
+ }
+}
+
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/SortableDisplay.php b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/SortableDisplay.php
new file mode 100644
index 0000000..d3a99c3
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/SortableDisplay.php
@@ -0,0 +1,54 @@
+grid->tableId();
+
+ $script = <<row->{$sortName};
+ }
+
+ public function display($sortName = null)
+ {
+ $this->script();
+
+ $key = $this->key();
+ $sort = $this->getRowSort($sortName);
+
+ return <<
+
+
+
+HTML;
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/bootstrap.php b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/bootstrap.php
new file mode 100644
index 0000000..e97717f
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/grid-sortable/src/bootstrap.php
@@ -0,0 +1,4 @@
+ 文件上传功能是参照了[laravel-ueditor](https://github.com/overtrue/laravel-ueditor)实现的。
+
+## 安装
+
+请先确保安装了[Dcat Admin](https://github.com/jqhph/dcat-admin),执行
+```php
+composer require dcat-admin-extension/ueditor
+```
+
+然后执行以下命令导入前端静态文件:
+```php
+php artisan admin:import ueditor
+```
+
+最后用浏览器打开`http://localhost:8000/admin/helpers/extensions`找到`ueditor`这一行,点击`启用`按钮,即可使用。
+
+除了通过界面启用扩展,也可以手动开启扩展:打开`config/admin-extensions.php`(如果文件不存在请手动创建),加入以下代码:
+```php
+return [
+ 'ueditor' => [
+ 'enable' => true,
+ ],
+];
+```
+
+## 配置
+`ueditor`文件上传相关配置在`config/ueditor.php`。
+```php
+/* 前后端通信相关的配置,注释只允许使用多行方式 */
+return [
+ /* 上传图片配置项 */
+ 'imageActionName' => 'uploadimage', /* 执行上传图片的action名称 */
+ 'imageFieldName' => 'upfile', /* 提交的图片表单名称 */
+ 'imageMaxSize' => 2048000, /* 上传大小限制,单位B */
+ 'imageAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 上传图片格式显示 */
+ 'imageCompressEnable' => true, /* 是否压缩图片,默认是true */
+ 'imageCompressBorder' => 1600, /* 图片压缩最长边限制 */
+ 'imageInsertAlign' => 'none', /* 插入的图片浮动方式 */
+ 'imageUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'imagePathFormat' => '/ueditor/image/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
+ /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
+ /* {time} 会替换成时间戳 */
+ /* {yyyy} 会替换成四位年份 */
+ /* {yy} 会替换成两位年份 */
+ /* {mm} 会替换成两位月份 */
+ /* {dd} 会替换成两位日期 */
+ /* {hh} 会替换成两位小时 */
+ /* {ii} 会替换成两位分钟 */
+ /* {ss} 会替换成两位秒 */
+ /* 非法字符 \ => * ? ' < > | */
+ /* 具请体看线上文档 => fex.baidu.com/ueditor/#use-format_upload_filename */
+
+ /* 涂鸦图片上传配置项 */
+ 'scrawlActionName' => 'uploadscrawl', /* 执行上传涂鸦的action名称 */
+ 'scrawlFieldName' => 'upfile', /* 提交的图片表单名称 */
+ 'scrawlPathFormat' => '/ueditor/image/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'scrawlMaxSize' => 2048000, /* 上传大小限制,单位B */
+ 'scrawlUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'scrawlInsertAlign' => 'none',
+
+ /* 截图工具上传 */
+ 'snapscreenActionName' => 'uploadimage', /* 执行上传截图的action名称 */
+ 'snapscreenPathFormat' => '/ueditor/php/image/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'snapscreenUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'snapscreenInsertAlign' => 'none', /* 插入的图片浮动方式 */
+
+ /* 抓取远程图片配置 */
+ 'catcherLocalDomain' => ['127.0.0.1', 'localhost', 'img.baidu.com'],
+ 'catcherActionName' => 'catchimage', /* 执行抓取远程图片的action名称 */
+ 'catcherFieldName' => 'source', /* 提交的图片列表表单名称 */
+ 'catcherPathFormat' => '/ueditor/php/image/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'catcherUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'catcherMaxSize' => 2048000, /* 上传大小限制,单位B */
+ 'catcherAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 抓取图片格式显示 */
+
+ /* 上传视频配置 */
+ 'videoActionName' => 'uploadvideo', /* 执行上传视频的action名称 */
+ 'videoFieldName' => 'upfile', /* 提交的视频表单名称 */
+ 'videoPathFormat' => '/ueditor/video/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'videoUrlPrefix' => '', /* 视频访问路径前缀 */
+ 'videoMaxSize' => 102400000, /* 上传大小限制,单位B,默认100MB */
+ 'videoAllowFiles' => [
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid'], /* 上传视频格式显示 */
+
+ /* 上传文件配置 */
+ 'fileActionName' => 'uploadfile', /* controller里,执行上传视频的action名称 */
+ 'fileFieldName' => 'upfile', /* 提交的文件表单名称 */
+ 'filePathFormat' => '/ueditor/file/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'fileUrlPrefix' => '', /* 文件访问路径前缀 */
+ 'fileMaxSize' => 51200000, /* 上传大小限制,单位B,默认50MB */
+ 'fileAllowFiles' => [
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp',
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid',
+ '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso',
+ '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml'
+ ], /* 上传文件格式显示 */
+ /* 列出指定目录下的图片 */
+ 'imageManagerActionName' => 'listimage', /* 执行图片管理的action名称 */
+ 'imageManagerListPath' => '/ueditor/image/', /* 指定要列出图片的目录 */
+ 'imageManagerListSize' => 20, /* 每次列出文件数量 */
+ 'imageManagerUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'imageManagerInsertAlign' => 'none', /* 插入的图片浮动方式 */
+ 'imageManagerAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 列出的文件类型 */
+
+ /* 列出指定目录下的文件 */
+ 'fileManagerActionName' => 'listfile', /* 执行文件管理的action名称 */
+ 'fileManagerListPath' => '/ueditor/file/', /* 指定要列出文件的目录 */
+ 'fileManagerUrlPrefix' => '', /* 文件访问路径前缀 */
+ 'fileManagerListSize' => 20, /* 每次列出文件数量 */
+ 'fileManagerAllowFiles' => [
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp',
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid',
+ '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso',
+ '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml'
+ ] /* 列出的文件类型 */
+];
+```
+
+### 更改文件存储Storage
+
+百度编辑器默认是使用文件存储的,即`file`,如果需要改为其他的存储方式,可以在`config/admin.php`中加上如下配置:
+```php
+return [
+ ...
+
+ /*
+ |--------------------------------------------------------------------------
+ | Settings for extensions.
+ |--------------------------------------------------------------------------
+ |
+ | You can find all available extensions here
+ | https://github.com/dcat-admin-extensions.
+ |
+ */
+ 'extensions' => [
+ 'ueditor' => [
+ 'disk' => 'oss',
+ ],
+ ],
+];
+```
+
+
+## 使用
+
+### 基本使用
+```php
+$form->ueditor('content');
+```
+
+### 修改编辑器高度
+```php
+$form->ueditor('content')->height(500);
+```
+
+### 修改文件存储storage
+```php
+$form->ueditor('content')->disk('oss');
+```
+
+### 修改文件上传接口
+如果你需要用到自定义的文件上传接口,可以通过这个方法覆盖掉默认的上传接口
+```php
+$form->ueditor('content')->server('file-upload');
+```
+
+### 修改ueditor配置
+```php
+$form->ueditor('content')->options([
+ 'maximumWords' => 1000,
+]);
+```
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/composer.json b/app/Admin/Extensions/dcat-admin-extension/ueditor/composer.json
new file mode 100644
index 0000000..408160e
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/composer.json
@@ -0,0 +1,28 @@
+{
+ "name": "dcat-admin-extension/ueditor",
+ "description": "百度在线编辑器",
+ "type": "library",
+ "keywords": ["dcat-admin", "extension"],
+ "homepage": "https://github.com/jqhph",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "jqh",
+ "email": "841324345@qq.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~6.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Dcat\\Admin\\Extension\\UEditor\\": "src/"
+ },
+ "files": [
+ "src/bootstrap.php"
+ ]
+ }
+}
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/config/ueditor.php b/app/Admin/Extensions/dcat-admin-extension/ueditor/config/ueditor.php
new file mode 100644
index 0000000..ca60a92
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/config/ueditor.php
@@ -0,0 +1,96 @@
+ 'uploadimage', /* 执行上传图片的action名称 */
+ 'imageFieldName' => 'upfile', /* 提交的图片表单名称 */
+ 'imageMaxSize' => 2048000, /* 上传大小限制,单位B */
+ 'imageAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 上传图片格式显示 */
+ 'imageCompressEnable' => true, /* 是否压缩图片,默认是true */
+ 'imageCompressBorder' => 1600, /* 图片压缩最长边限制 */
+ 'imageInsertAlign' => 'none', /* 插入的图片浮动方式 */
+ 'imageUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'imagePathFormat' => '/ueditor/image/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
+ /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
+ /* {time} 会替换成时间戳 */
+ /* {yyyy} 会替换成四位年份 */
+ /* {yy} 会替换成两位年份 */
+ /* {mm} 会替换成两位月份 */
+ /* {dd} 会替换成两位日期 */
+ /* {hh} 会替换成两位小时 */
+ /* {ii} 会替换成两位分钟 */
+ /* {ss} 会替换成两位秒 */
+ /* 非法字符 \ => * ? ' < > | */
+ /* 具请体看线上文档 => fex.baidu.com/ueditor/#use-format_upload_filename */
+
+ /* 涂鸦图片上传配置项 */
+ 'scrawlActionName' => 'uploadscrawl', /* 执行上传涂鸦的action名称 */
+ 'scrawlFieldName' => 'upfile', /* 提交的图片表单名称 */
+ 'scrawlPathFormat' => '/ueditor/image/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'scrawlMaxSize' => 2048000, /* 上传大小限制,单位B */
+ 'scrawlUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'scrawlInsertAlign' => 'none',
+
+ /* 截图工具上传 */
+ 'snapscreenActionName' => 'uploadimage', /* 执行上传截图的action名称 */
+ 'snapscreenPathFormat' => '/ueditor/php/image/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'snapscreenUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'snapscreenInsertAlign' => 'none', /* 插入的图片浮动方式 */
+
+ /* 抓取远程图片配置 */
+ 'catcherLocalDomain' => ['127.0.0.1', 'localhost', 'img.baidu.com'],
+ 'catcherActionName' => 'catchimage', /* 执行抓取远程图片的action名称 */
+ 'catcherFieldName' => 'source', /* 提交的图片列表表单名称 */
+ 'catcherPathFormat' => '/ueditor/php/image/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'catcherUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'catcherMaxSize' => 2048000, /* 上传大小限制,单位B */
+ 'catcherAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 抓取图片格式显示 */
+
+ /* 上传视频配置 */
+ 'videoActionName' => 'uploadvideo', /* 执行上传视频的action名称 */
+ 'videoFieldName' => 'upfile', /* 提交的视频表单名称 */
+ 'videoPathFormat' => '/ueditor/video/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'videoUrlPrefix' => '', /* 视频访问路径前缀 */
+ 'videoMaxSize' => 102400000, /* 上传大小限制,单位B,默认100MB */
+ 'videoAllowFiles' => [
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid'], /* 上传视频格式显示 */
+
+ /* 上传文件配置 */
+ 'fileActionName' => 'uploadfile', /* controller里,执行上传视频的action名称 */
+ 'fileFieldName' => 'upfile', /* 提交的文件表单名称 */
+ 'filePathFormat' => '/ueditor/file/{yyyy}{mm}{dd}/{time}{rand:6}', /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ 'fileUrlPrefix' => '', /* 文件访问路径前缀 */
+ 'fileMaxSize' => 51200000, /* 上传大小限制,单位B,默认50MB */
+ 'fileAllowFiles' => [
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp',
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid',
+ '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso',
+ '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml'
+ ], /* 上传文件格式显示 */
+
+ /* 列出指定目录下的图片 */
+ 'imageManagerActionName' => 'listimage', /* 执行图片管理的action名称 */
+ 'imageManagerListPath' => '/ueditor/image/', /* 指定要列出图片的目录 */
+ 'imageManagerListSize' => 20, /* 每次列出文件数量 */
+ 'imageManagerUrlPrefix' => '', /* 图片访问路径前缀 */
+ 'imageManagerInsertAlign' => 'none', /* 插入的图片浮动方式 */
+ 'imageManagerAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 列出的文件类型 */
+
+ /* 列出指定目录下的文件 */
+ 'fileManagerActionName' => 'listfile', /* 执行文件管理的action名称 */
+ 'fileManagerListPath' => '/ueditor/file/', /* 指定要列出文件的目录 */
+ 'fileManagerUrlPrefix' => '', /* 文件访问路径前缀 */
+ 'fileManagerListSize' => 20, /* 每次列出文件数量 */
+ 'fileManagerAllowFiles' => [
+ '.png', '.jpg', '.jpeg', '.gif', '.bmp',
+ '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
+ '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid',
+ '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso',
+ '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml'
+ ] /* 列出的文件类型 */
+
+];
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/anchor/anchor.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/anchor/anchor.html
new file mode 100644
index 0000000..f277847
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/anchor/anchor.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.css b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.css
new file mode 100644
index 0000000..548b428
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.css
@@ -0,0 +1,681 @@
+@charset "utf-8";
+/* dialog样式 */
+.wrapper {
+ zoom: 1;
+ width: 630px;
+ *width: 626px;
+ height: 380px;
+ margin: 0 auto;
+ padding: 10px;
+ position: relative;
+ font-family: sans-serif;
+}
+
+/*tab样式框大小*/
+.tabhead {
+ float:left;
+}
+.tabbody {
+ width: 100%;
+ height: 346px;
+ position: relative;
+ clear: both;
+}
+
+.tabbody .panel {
+ position: absolute;
+ width: 0;
+ height: 0;
+ background: #fff;
+ overflow: hidden;
+ display: none;
+}
+
+.tabbody .panel.focus {
+ width: 100%;
+ height: 346px;
+ display: block;
+}
+
+/* 上传附件 */
+.tabbody #upload.panel {
+ width: 0;
+ height: 0;
+ overflow: hidden;
+ position: absolute !important;
+ clip: rect(1px, 1px, 1px, 1px);
+ background: #fff;
+ display: block;
+}
+
+.tabbody #upload.panel.focus {
+ width: 100%;
+ height: 346px;
+ display: block;
+ clip: auto;
+}
+
+#upload .queueList {
+ margin: 0;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ overflow: hidden;
+}
+
+#upload p {
+ margin: 0;
+}
+
+.element-invisible {
+ width: 0 !important;
+ height: 0 !important;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ overflow: hidden;
+ position: absolute !important;
+ clip: rect(1px, 1px, 1px, 1px);
+}
+
+#upload .placeholder {
+ margin: 10px;
+ border: 2px dashed #e6e6e6;
+ *border: 0px dashed #e6e6e6;
+ height: 172px;
+ padding-top: 150px;
+ text-align: center;
+ background: url(./images/image.png) center 70px no-repeat;
+ color: #cccccc;
+ font-size: 18px;
+ position: relative;
+ top:0;
+ *top: 10px;
+}
+
+#upload .placeholder .webuploader-pick {
+ font-size: 18px;
+ background: #00b7ee;
+ border-radius: 3px;
+ line-height: 44px;
+ padding: 0 30px;
+ *width: 120px;
+ color: #fff;
+ display: inline-block;
+ margin: 0 auto 20px auto;
+ cursor: pointer;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+}
+
+#upload .placeholder .webuploader-pick-hover {
+ background: #00a2d4;
+}
+
+
+#filePickerContainer {
+ text-align: center;
+}
+
+#upload .placeholder .flashTip {
+ color: #666666;
+ font-size: 12px;
+ position: absolute;
+ width: 100%;
+ text-align: center;
+ bottom: 20px;
+}
+
+#upload .placeholder .flashTip a {
+ color: #0785d1;
+ text-decoration: none;
+}
+
+#upload .placeholder .flashTip a:hover {
+ text-decoration: underline;
+}
+
+#upload .placeholder.webuploader-dnd-over {
+ border-color: #999999;
+}
+
+#upload .filelist {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ overflow-x: hidden;
+ overflow-y: auto;
+ position: relative;
+ height: 300px;
+}
+
+#upload .filelist:after {
+ content: '';
+ display: block;
+ width: 0;
+ height: 0;
+ overflow: hidden;
+ clear: both;
+}
+
+#upload .filelist li {
+ width: 113px;
+ height: 113px;
+ background: url(./images/bg.png);
+ text-align: center;
+ margin: 9px 0 0 9px;
+ *margin: 6px 0 0 6px;
+ position: relative;
+ display: block;
+ float: left;
+ overflow: hidden;
+ font-size: 12px;
+}
+
+#upload .filelist li p.log {
+ position: relative;
+ top: -45px;
+}
+
+#upload .filelist li p.title {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ top: 5px;
+ text-indent: 5px;
+ text-align: left;
+}
+
+#upload .filelist li p.progress {
+ position: absolute;
+ width: 100%;
+ bottom: 0;
+ left: 0;
+ height: 8px;
+ overflow: hidden;
+ z-index: 50;
+ margin: 0;
+ border-radius: 0;
+ background: none;
+ -webkit-box-shadow: 0 0 0;
+}
+
+#upload .filelist li p.progress span {
+ display: none;
+ overflow: hidden;
+ width: 0;
+ height: 100%;
+ background: #1483d8 url(./images/progress.png) repeat-x;
+
+ -webit-transition: width 200ms linear;
+ -moz-transition: width 200ms linear;
+ -o-transition: width 200ms linear;
+ -ms-transition: width 200ms linear;
+ transition: width 200ms linear;
+
+ -webkit-animation: progressmove 2s linear infinite;
+ -moz-animation: progressmove 2s linear infinite;
+ -o-animation: progressmove 2s linear infinite;
+ -ms-animation: progressmove 2s linear infinite;
+ animation: progressmove 2s linear infinite;
+
+ -webkit-transform: translateZ(0);
+}
+
+@-webkit-keyframes progressmove {
+ 0% {
+ background-position: 0 0;
+ }
+ 100% {
+ background-position: 17px 0;
+ }
+}
+
+@-moz-keyframes progressmove {
+ 0% {
+ background-position: 0 0;
+ }
+ 100% {
+ background-position: 17px 0;
+ }
+}
+
+@keyframes progressmove {
+ 0% {
+ background-position: 0 0;
+ }
+ 100% {
+ background-position: 17px 0;
+ }
+}
+
+#upload .filelist li p.imgWrap {
+ position: relative;
+ z-index: 2;
+ line-height: 113px;
+ vertical-align: middle;
+ overflow: hidden;
+ width: 113px;
+ height: 113px;
+
+ -webkit-transform-origin: 50% 50%;
+ -moz-transform-origin: 50% 50%;
+ -o-transform-origin: 50% 50%;
+ -ms-transform-origin: 50% 50%;
+ transform-origin: 50% 50%;
+
+ -webit-transition: 200ms ease-out;
+ -moz-transition: 200ms ease-out;
+ -o-transition: 200ms ease-out;
+ -ms-transition: 200ms ease-out;
+ transition: 200ms ease-out;
+}
+#upload .filelist li p.imgWrap.notimage {
+ margin-top: 0;
+ width: 111px;
+ height: 111px;
+ border: 1px #eeeeee solid;
+}
+#upload .filelist li p.imgWrap.notimage i.file-preview {
+ margin-top: 15px;
+}
+
+#upload .filelist li img {
+ width: 100%;
+}
+
+#upload .filelist li p.error {
+ background: #f43838;
+ color: #fff;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ height: 28px;
+ line-height: 28px;
+ width: 100%;
+ z-index: 100;
+ display:none;
+}
+
+#upload .filelist li .success {
+ display: block;
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ height: 40px;
+ width: 100%;
+ z-index: 200;
+ background: url(./images/success.png) no-repeat right bottom;
+ background-image: url(./images/success.gif) \9;
+}
+
+#upload .filelist li.filePickerBlock {
+ width: 113px;
+ height: 113px;
+ background: url(./images/image.png) no-repeat center 12px;
+ border: 1px solid #eeeeee;
+ border-radius: 0;
+}
+#upload .filelist li.filePickerBlock div.webuploader-pick {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ opacity: 0;
+ background: none;
+ font-size: 0;
+}
+
+#upload .filelist div.file-panel {
+ position: absolute;
+ height: 0;
+ filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \0;
+ background: rgba(0, 0, 0, 0.5);
+ width: 100%;
+ top: 0;
+ left: 0;
+ overflow: hidden;
+ z-index: 300;
+}
+
+#upload .filelist div.file-panel span {
+ width: 24px;
+ height: 24px;
+ display: inline;
+ float: right;
+ text-indent: -9999px;
+ overflow: hidden;
+ background: url(./images/icons.png) no-repeat;
+ background: url(./images/icons.gif) no-repeat \9;
+ margin: 5px 1px 1px;
+ cursor: pointer;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+#upload .filelist div.file-panel span.rotateLeft {
+ display:none;
+ background-position: 0 -24px;
+}
+
+#upload .filelist div.file-panel span.rotateLeft:hover {
+ background-position: 0 0;
+}
+
+#upload .filelist div.file-panel span.rotateRight {
+ display:none;
+ background-position: -24px -24px;
+}
+
+#upload .filelist div.file-panel span.rotateRight:hover {
+ background-position: -24px 0;
+}
+
+#upload .filelist div.file-panel span.cancel {
+ background-position: -48px -24px;
+}
+
+#upload .filelist div.file-panel span.cancel:hover {
+ background-position: -48px 0;
+}
+
+#upload .statusBar {
+ height: 45px;
+ border-bottom: 1px solid #dadada;
+ margin: 0 10px;
+ padding: 0;
+ line-height: 45px;
+ vertical-align: middle;
+ position: relative;
+}
+
+#upload .statusBar .progress {
+ border: 1px solid #1483d8;
+ width: 198px;
+ background: #fff;
+ height: 18px;
+ position: absolute;
+ top: 12px;
+ display: none;
+ text-align: center;
+ line-height: 18px;
+ color: #6dbfff;
+ margin: 0 10px 0 0;
+}
+#upload .statusBar .progress span.percentage {
+ width: 0;
+ height: 100%;
+ left: 0;
+ top: 0;
+ background: #1483d8;
+ position: absolute;
+}
+#upload .statusBar .progress span.text {
+ position: relative;
+ z-index: 10;
+}
+
+#upload .statusBar .info {
+ display: inline-block;
+ font-size: 14px;
+ color: #666666;
+}
+
+#upload .statusBar .btns {
+ position: absolute;
+ top: 7px;
+ right: 0;
+ line-height: 30px;
+}
+
+#filePickerBtn {
+ display: inline-block;
+ float: left;
+}
+#upload .statusBar .btns .webuploader-pick,
+#upload .statusBar .btns .uploadBtn,
+#upload .statusBar .btns .uploadBtn.state-uploading,
+#upload .statusBar .btns .uploadBtn.state-paused {
+ background: #ffffff;
+ border: 1px solid #cfcfcf;
+ color: #565656;
+ padding: 0 18px;
+ display: inline-block;
+ border-radius: 3px;
+ margin-left: 10px;
+ cursor: pointer;
+ font-size: 14px;
+ float: left;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+#upload .statusBar .btns .webuploader-pick-hover,
+#upload .statusBar .btns .uploadBtn:hover,
+#upload .statusBar .btns .uploadBtn.state-uploading:hover,
+#upload .statusBar .btns .uploadBtn.state-paused:hover {
+ background: #f0f0f0;
+}
+
+#upload .statusBar .btns .uploadBtn,
+#upload .statusBar .btns .uploadBtn.state-paused{
+ background: #00b7ee;
+ color: #fff;
+ border-color: transparent;
+}
+#upload .statusBar .btns .uploadBtn:hover,
+#upload .statusBar .btns .uploadBtn.state-paused:hover{
+ background: #00a2d4;
+}
+
+#upload .statusBar .btns .uploadBtn.disabled {
+ pointer-events: none;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ -khtml-opacity: 0.6;
+ opacity: 0.6;
+}
+
+
+
+/* 图片管理样式 */
+#online {
+ width: 100%;
+ height: 336px;
+ padding: 10px 0 0 0;
+}
+#online #fileList{
+ width: 100%;
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ position: relative;
+}
+#online ul {
+ display: block;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+#online li {
+ float: left;
+ display: block;
+ list-style: none;
+ padding: 0;
+ width: 113px;
+ height: 113px;
+ margin: 0 0 9px 9px;
+ *margin: 0 0 6px 6px;
+ background-color: #eee;
+ overflow: hidden;
+ cursor: pointer;
+ position: relative;
+}
+#online li.clearFloat {
+ float: none;
+ clear: both;
+ display: block;
+ width:0;
+ height:0;
+ margin: 0;
+ padding: 0;
+}
+#online li img {
+ cursor: pointer;
+}
+#online li div.file-wrapper {
+ cursor: pointer;
+ position: absolute;
+ display: block;
+ width: 111px;
+ height: 111px;
+ border: 1px solid #eee;
+ background: url("./images/bg.png") repeat;
+}
+#online li div span.file-title{
+ display: block;
+ padding: 0 3px;
+ margin: 3px 0 0 0;
+ font-size: 12px;
+ height: 13px;
+ color: #555555;
+ text-align: center;
+ width: 107px;
+ white-space: nowrap;
+ word-break: break-all;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+#online li .icon {
+ cursor: pointer;
+ width: 113px;
+ height: 113px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ border: 0;
+ background-repeat: no-repeat;
+}
+#online li .icon:hover {
+ width: 107px;
+ height: 107px;
+ border: 3px solid #1094fa;
+}
+#online li.selected .icon {
+ background-image: url(images/success.png);
+ background-image: url(images/success.gif) \9;
+ background-position: 75px 75px;
+}
+#online li.selected .icon:hover {
+ width: 107px;
+ height: 107px;
+ border: 3px solid #1094fa;
+ background-position: 72px 72px;
+}
+
+
+/* 在线文件的文件预览图标 */
+i.file-preview {
+ display: block;
+ margin: 10px auto;
+ width: 70px;
+ height: 70px;
+ background-image: url("./images/file-icons.png");
+ background-image: url("./images/file-icons.gif") \9;
+ background-position: -140px center;
+ background-repeat: no-repeat;
+}
+i.file-preview.file-type-dir{
+ background-position: 0 center;
+}
+i.file-preview.file-type-file{
+ background-position: -140px center;
+}
+i.file-preview.file-type-filelist{
+ background-position: -210px center;
+}
+i.file-preview.file-type-zip,
+i.file-preview.file-type-rar,
+i.file-preview.file-type-7z,
+i.file-preview.file-type-tar,
+i.file-preview.file-type-gz,
+i.file-preview.file-type-bz2{
+ background-position: -280px center;
+}
+i.file-preview.file-type-xls,
+i.file-preview.file-type-xlsx{
+ background-position: -350px center;
+}
+i.file-preview.file-type-doc,
+i.file-preview.file-type-docx{
+ background-position: -420px center;
+}
+i.file-preview.file-type-ppt,
+i.file-preview.file-type-pptx{
+ background-position: -490px center;
+}
+i.file-preview.file-type-vsd{
+ background-position: -560px center;
+}
+i.file-preview.file-type-pdf{
+ background-position: -630px center;
+}
+i.file-preview.file-type-txt,
+i.file-preview.file-type-md,
+i.file-preview.file-type-json,
+i.file-preview.file-type-htm,
+i.file-preview.file-type-xml,
+i.file-preview.file-type-html,
+i.file-preview.file-type-js,
+i.file-preview.file-type-css,
+i.file-preview.file-type-php,
+i.file-preview.file-type-jsp,
+i.file-preview.file-type-asp{
+ background-position: -700px center;
+}
+i.file-preview.file-type-apk{
+ background-position: -770px center;
+}
+i.file-preview.file-type-exe{
+ background-position: -840px center;
+}
+i.file-preview.file-type-ipa{
+ background-position: -910px center;
+}
+i.file-preview.file-type-mp4,
+i.file-preview.file-type-swf,
+i.file-preview.file-type-mkv,
+i.file-preview.file-type-avi,
+i.file-preview.file-type-flv,
+i.file-preview.file-type-mov,
+i.file-preview.file-type-mpg,
+i.file-preview.file-type-mpeg,
+i.file-preview.file-type-ogv,
+i.file-preview.file-type-webm,
+i.file-preview.file-type-rm,
+i.file-preview.file-type-rmvb{
+ background-position: -980px center;
+}
+i.file-preview.file-type-ogg,
+i.file-preview.file-type-wav,
+i.file-preview.file-type-wmv,
+i.file-preview.file-type-mid,
+i.file-preview.file-type-mp3{
+ background-position: -1050px center;
+}
+i.file-preview.file-type-jpg,
+i.file-preview.file-type-jpeg,
+i.file-preview.file-type-gif,
+i.file-preview.file-type-bmp,
+i.file-preview.file-type-png,
+i.file-preview.file-type-psd{
+ background-position: -140px center;
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.html
new file mode 100644
index 0000000..2ae9282
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.html
@@ -0,0 +1,60 @@
+
+
+
+
+ ueditor图片对话框
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.js
new file mode 100644
index 0000000..ce3be63
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/attachment.js
@@ -0,0 +1,754 @@
+/**
+ * User: Jinqn
+ * Date: 14-04-08
+ * Time: 下午16:34
+ * 上传图片对话框逻辑代码,包括tab: 远程图片/上传图片/在线图片/搜索图片
+ */
+
+(function () {
+
+ var uploadFile,
+ onlineFile;
+
+ window.onload = function () {
+ initTabs();
+ initButtons();
+ };
+
+ /* 初始化tab标签 */
+ function initTabs() {
+ var tabs = $G('tabhead').children;
+ for (var i = 0; i < tabs.length; i++) {
+ domUtils.on(tabs[i], "click", function (e) {
+ var target = e.target || e.srcElement;
+ setTabFocus(target.getAttribute('data-content-id'));
+ });
+ }
+
+ setTabFocus('upload');
+ }
+
+ /* 初始化tabbody */
+ function setTabFocus(id) {
+ if(!id) return;
+ var i, bodyId, tabs = $G('tabhead').children;
+ for (i = 0; i < tabs.length; i++) {
+ bodyId = tabs[i].getAttribute('data-content-id')
+ if (bodyId == id) {
+ domUtils.addClass(tabs[i], 'focus');
+ domUtils.addClass($G(bodyId), 'focus');
+ } else {
+ domUtils.removeClasses(tabs[i], 'focus');
+ domUtils.removeClasses($G(bodyId), 'focus');
+ }
+ }
+ switch (id) {
+ case 'upload':
+ uploadFile = uploadFile || new UploadFile('queueList');
+ break;
+ case 'online':
+ onlineFile = onlineFile || new OnlineFile('fileList');
+ break;
+ }
+ }
+
+ /* 初始化onok事件 */
+ function initButtons() {
+
+ dialog.onok = function () {
+ var list = [], id, tabs = $G('tabhead').children;
+ for (var i = 0; i < tabs.length; i++) {
+ if (domUtils.hasClass(tabs[i], 'focus')) {
+ id = tabs[i].getAttribute('data-content-id');
+ break;
+ }
+ }
+
+ switch (id) {
+ case 'upload':
+ list = uploadFile.getInsertList();
+ var count = uploadFile.getQueueCount();
+ if (count) {
+ $('.info', '#queueList').html('' + '还有2个未上传文件'.replace(/[\d]/, count) + '');
+ return false;
+ }
+ break;
+ case 'online':
+ list = onlineFile.getInsertList();
+ break;
+ }
+
+ editor.execCommand('insertfile', list);
+ };
+ }
+
+
+ /* 上传附件 */
+ function UploadFile(target) {
+ this.$wrap = target.constructor == String ? $('#' + target) : $(target);
+ this.init();
+ }
+ UploadFile.prototype = {
+ init: function () {
+ this.fileList = [];
+ this.initContainer();
+ this.initUploader();
+ },
+ initContainer: function () {
+ this.$queue = this.$wrap.find('.filelist');
+ },
+ /* 初始化容器 */
+ initUploader: function () {
+ var _this = this,
+ $ = jQuery, // just in case. Make sure it's not an other libaray.
+ $wrap = _this.$wrap,
+ // 图片容器
+ $queue = $wrap.find('.filelist'),
+ // 状态栏,包括进度和控制按钮
+ $statusBar = $wrap.find('.statusBar'),
+ // 文件总体选择信息。
+ $info = $statusBar.find('.info'),
+ // 上传按钮
+ $upload = $wrap.find('.uploadBtn'),
+ // 上传按钮
+ $filePickerBtn = $wrap.find('.filePickerBtn'),
+ // 上传按钮
+ $filePickerBlock = $wrap.find('.filePickerBlock'),
+ // 没选择文件之前的内容。
+ $placeHolder = $wrap.find('.placeholder'),
+ // 总体进度条
+ $progress = $statusBar.find('.progress').hide(),
+ // 添加的文件数量
+ fileCount = 0,
+ // 添加的文件总大小
+ fileSize = 0,
+ // 优化retina, 在retina下这个值是2
+ ratio = window.devicePixelRatio || 1,
+ // 缩略图大小
+ thumbnailWidth = 113 * ratio,
+ thumbnailHeight = 113 * ratio,
+ // 可能有pedding, ready, uploading, confirm, done.
+ state = '',
+ // 所有文件的进度信息,key为file id
+ percentages = {},
+ supportTransition = (function () {
+ var s = document.createElement('p').style,
+ r = 'transition' in s ||
+ 'WebkitTransition' in s ||
+ 'MozTransition' in s ||
+ 'msTransition' in s ||
+ 'OTransition' in s;
+ s = null;
+ return r;
+ })(),
+ // WebUploader实例
+ uploader,
+ actionUrl = editor.getActionUrl(editor.getOpt('fileActionName')),
+ fileMaxSize = editor.getOpt('fileMaxSize'),
+ acceptExtensions = (editor.getOpt('fileAllowFiles') || []).join('').replace(/\./g, ',').replace(/^[,]/, '');;
+
+ if (!WebUploader.Uploader.support()) {
+ $('#filePickerReady').after($('').html(lang.errorNotSupport)).hide();
+ return;
+ } else if (!editor.getOpt('fileActionName')) {
+ $('#filePickerReady').after($('').html(lang.errorLoadConfig)).hide();
+ return;
+ }
+
+ uploader = _this.uploader = WebUploader.create({
+ pick: {
+ id: '#filePickerReady',
+ label: lang.uploadSelectFile
+ },
+ swf: '../../third-party/webuploader/Uploader.swf',
+ server: actionUrl,
+ fileVal: editor.getOpt('fileFieldName'),
+ duplicate: true,
+ fileSingleSizeLimit: fileMaxSize,
+ compress: false
+ });
+ uploader.addButton({
+ id: '#filePickerBlock'
+ });
+ uploader.addButton({
+ id: '#filePickerBtn',
+ label: lang.uploadAddFile
+ });
+
+ setState('pedding');
+
+ // 当有文件添加进来时执行,负责view的创建
+ function addFile(file) {
+ var $li = $('' +
+ '' + file.name + '
' +
+ '' +
+ '
' +
+ ' '),
+
+ $btns = $('' +
+ '' + lang.uploadDelete + '' +
+ '' + lang.uploadTurnRight + '' +
+ '' + lang.uploadTurnLeft + '').appendTo($li),
+ $prgress = $li.find('p.progress span'),
+ $wrap = $li.find('p.imgWrap'),
+ $info = $('').hide().appendTo($li),
+
+ showError = function (code) {
+ switch (code) {
+ case 'exceed_size':
+ text = lang.errorExceedSize;
+ break;
+ case 'interrupt':
+ text = lang.errorInterrupt;
+ break;
+ case 'http':
+ text = lang.errorHttp;
+ break;
+ case 'not_allow_type':
+ text = lang.errorFileType;
+ break;
+ default:
+ text = lang.errorUploadRetry;
+ break;
+ }
+ $info.text(text).show();
+ };
+
+ if (file.getStatus() === 'invalid') {
+ showError(file.statusText);
+ } else {
+ $wrap.text(lang.uploadPreview);
+ if ('|png|jpg|jpeg|bmp|gif|'.indexOf('|'+file.ext.toLowerCase()+'|') == -1) {
+ $wrap.empty().addClass('notimage').append('' +
+ '' + file.name + '');
+ } else {
+ if (browser.ie && browser.version <= 7) {
+ $wrap.text(lang.uploadNoPreview);
+ } else {
+ uploader.makeThumb(file, function (error, src) {
+ if (error || !src) {
+ $wrap.text(lang.uploadNoPreview);
+ } else {
+ var $img = $('
');
+ $wrap.empty().append($img);
+ $img.on('error', function () {
+ $wrap.text(lang.uploadNoPreview);
+ });
+ }
+ }, thumbnailWidth, thumbnailHeight);
+ }
+ }
+ percentages[ file.id ] = [ file.size, 0 ];
+ file.rotation = 0;
+
+ /* 检查文件格式 */
+ if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) {
+ showError('not_allow_type');
+ uploader.removeFile(file);
+ }
+ }
+
+ file.on('statuschange', function (cur, prev) {
+ if (prev === 'progress') {
+ $prgress.hide().width(0);
+ } else if (prev === 'queued') {
+ $li.off('mouseenter mouseleave');
+ $btns.remove();
+ }
+ // 成功
+ if (cur === 'error' || cur === 'invalid') {
+ showError(file.statusText);
+ percentages[ file.id ][ 1 ] = 1;
+ } else if (cur === 'interrupt') {
+ showError('interrupt');
+ } else if (cur === 'queued') {
+ percentages[ file.id ][ 1 ] = 0;
+ } else if (cur === 'progress') {
+ $info.hide();
+ $prgress.css('display', 'block');
+ } else if (cur === 'complete') {
+ }
+
+ $li.removeClass('state-' + prev).addClass('state-' + cur);
+ });
+
+ $li.on('mouseenter', function () {
+ $btns.stop().animate({height: 30});
+ });
+ $li.on('mouseleave', function () {
+ $btns.stop().animate({height: 0});
+ });
+
+ $btns.on('click', 'span', function () {
+ var index = $(this).index(),
+ deg;
+
+ switch (index) {
+ case 0:
+ uploader.removeFile(file);
+ return;
+ case 1:
+ file.rotation += 90;
+ break;
+ case 2:
+ file.rotation -= 90;
+ break;
+ }
+
+ if (supportTransition) {
+ deg = 'rotate(' + file.rotation + 'deg)';
+ $wrap.css({
+ '-webkit-transform': deg,
+ '-mos-transform': deg,
+ '-o-transform': deg,
+ 'transform': deg
+ });
+ } else {
+ $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');
+ }
+
+ });
+
+ $li.insertBefore($filePickerBlock);
+ }
+
+ // 负责view的销毁
+ function removeFile(file) {
+ var $li = $('#' + file.id);
+ delete percentages[ file.id ];
+ updateTotalProgress();
+ $li.off().find('.file-panel').off().end().remove();
+ }
+
+ function updateTotalProgress() {
+ var loaded = 0,
+ total = 0,
+ spans = $progress.children(),
+ percent;
+
+ $.each(percentages, function (k, v) {
+ total += v[ 0 ];
+ loaded += v[ 0 ] * v[ 1 ];
+ });
+
+ percent = total ? loaded / total : 0;
+
+ spans.eq(0).text(Math.round(percent * 100) + '%');
+ spans.eq(1).css('width', Math.round(percent * 100) + '%');
+ updateStatus();
+ }
+
+ function setState(val, files) {
+
+ if (val != state) {
+
+ var stats = uploader.getStats();
+
+ $upload.removeClass('state-' + state);
+ $upload.addClass('state-' + val);
+
+ switch (val) {
+
+ /* 未选择文件 */
+ case 'pedding':
+ $queue.addClass('element-invisible');
+ $statusBar.addClass('element-invisible');
+ $placeHolder.removeClass('element-invisible');
+ $progress.hide(); $info.hide();
+ uploader.refresh();
+ break;
+
+ /* 可以开始上传 */
+ case 'ready':
+ $placeHolder.addClass('element-invisible');
+ $queue.removeClass('element-invisible');
+ $statusBar.removeClass('element-invisible');
+ $progress.hide(); $info.show();
+ $upload.text(lang.uploadStart);
+ uploader.refresh();
+ break;
+
+ /* 上传中 */
+ case 'uploading':
+ $progress.show(); $info.hide();
+ $upload.text(lang.uploadPause);
+ break;
+
+ /* 暂停上传 */
+ case 'paused':
+ $progress.show(); $info.hide();
+ $upload.text(lang.uploadContinue);
+ break;
+
+ case 'confirm':
+ $progress.show(); $info.hide();
+ $upload.text(lang.uploadStart);
+
+ stats = uploader.getStats();
+ if (stats.successNum && !stats.uploadFailNum) {
+ setState('finish');
+ return;
+ }
+ break;
+
+ case 'finish':
+ $progress.hide(); $info.show();
+ if (stats.uploadFailNum) {
+ $upload.text(lang.uploadRetry);
+ } else {
+ $upload.text(lang.uploadStart);
+ }
+ break;
+ }
+
+ state = val;
+ updateStatus();
+
+ }
+
+ if (!_this.getQueueCount()) {
+ $upload.addClass('disabled')
+ } else {
+ $upload.removeClass('disabled')
+ }
+
+ }
+
+ function updateStatus() {
+ var text = '', stats;
+
+ if (state === 'ready') {
+ text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize));
+ } else if (state === 'confirm') {
+ stats = uploader.getStats();
+ if (stats.uploadFailNum) {
+ text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum);
+ }
+ } else {
+ stats = uploader.getStats();
+ text = lang.updateStatusFinish.replace('_', fileCount).
+ replace('_KB', WebUploader.formatSize(fileSize)).
+ replace('_', stats.successNum);
+
+ if (stats.uploadFailNum) {
+ text += lang.updateStatusError.replace('_', stats.uploadFailNum);
+ }
+ }
+
+ $info.html(text);
+ }
+
+ uploader.on('fileQueued', function (file) {
+ fileCount++;
+ fileSize += file.size;
+
+ if (fileCount === 1) {
+ $placeHolder.addClass('element-invisible');
+ $statusBar.show();
+ }
+
+ addFile(file);
+ });
+
+ uploader.on('fileDequeued', function (file) {
+ fileCount--;
+ fileSize -= file.size;
+
+ removeFile(file);
+ updateTotalProgress();
+ });
+
+ uploader.on('filesQueued', function (file) {
+ if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) {
+ setState('ready');
+ }
+ updateTotalProgress();
+ });
+
+ uploader.on('all', function (type, files) {
+ switch (type) {
+ case 'uploadFinished':
+ setState('confirm', files);
+ break;
+ case 'startUpload':
+ /* 添加额外的GET参数 */
+ var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '',
+ url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params);
+ uploader.option('server', url);
+ setState('uploading', files);
+ break;
+ case 'stopUpload':
+ setState('paused', files);
+ break;
+ }
+ });
+
+ uploader.on('uploadBeforeSend', function (file, data, header) {
+ //这里可以通过data对象添加POST参数
+ header['X_Requested_With'] = 'XMLHttpRequest';
+ });
+
+ uploader.on('uploadProgress', function (file, percentage) {
+ var $li = $('#' + file.id),
+ $percent = $li.find('.progress span');
+
+ $percent.css('width', percentage * 100 + '%');
+ percentages[ file.id ][ 1 ] = percentage;
+ updateTotalProgress();
+ });
+
+ uploader.on('uploadSuccess', function (file, ret) {
+ var $file = $('#' + file.id);
+ try {
+ var responseText = (ret._raw || ret),
+ json = utils.str2json(responseText);
+ if (json.state == 'SUCCESS') {
+ _this.fileList.push(json);
+ $file.append('');
+ } else {
+ $file.find('.error').text(json.state).show();
+ }
+ } catch (e) {
+ $file.find('.error').text(lang.errorServerUpload).show();
+ }
+ });
+
+ uploader.on('uploadError', function (file, code) {
+ });
+ uploader.on('error', function (code, file) {
+ if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') {
+ addFile(file);
+ }
+ });
+ uploader.on('uploadComplete', function (file, ret) {
+ });
+
+ $upload.on('click', function () {
+ if ($(this).hasClass('disabled')) {
+ return false;
+ }
+
+ if (state === 'ready') {
+ uploader.upload();
+ } else if (state === 'paused') {
+ uploader.upload();
+ } else if (state === 'uploading') {
+ uploader.stop();
+ }
+ });
+
+ $upload.addClass('state-' + state);
+ updateTotalProgress();
+ },
+ getQueueCount: function () {
+ var file, i, status, readyFile = 0, files = this.uploader.getFiles();
+ for (i = 0; file = files[i++]; ) {
+ status = file.getStatus();
+ if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++;
+ }
+ return readyFile;
+ },
+ getInsertList: function () {
+ var i, link, data, list = [],
+ prefix = editor.getOpt('fileUrlPrefix');
+ for (i = 0; i < this.fileList.length; i++) {
+ data = this.fileList[i];
+ link = data.url;
+ list.push({
+ title: data.original || link.substr(link.lastIndexOf('/') + 1),
+ url: prefix + link
+ });
+ }
+ return list;
+ }
+ };
+
+
+ /* 在线附件 */
+ function OnlineFile(target) {
+ this.container = utils.isString(target) ? document.getElementById(target) : target;
+ this.init();
+ }
+ OnlineFile.prototype = {
+ init: function () {
+ this.initContainer();
+ this.initEvents();
+ this.initData();
+ },
+ /* 初始化容器 */
+ initContainer: function () {
+ this.container.innerHTML = '';
+ this.list = document.createElement('ul');
+ this.clearFloat = document.createElement('li');
+
+ domUtils.addClass(this.list, 'list');
+ domUtils.addClass(this.clearFloat, 'clearFloat');
+
+ this.list.appendChild(this.clearFloat);
+ this.container.appendChild(this.list);
+ },
+ /* 初始化滚动事件,滚动到地步自动拉取数据 */
+ initEvents: function () {
+ var _this = this;
+
+ /* 滚动拉取图片 */
+ domUtils.on($G('fileList'), 'scroll', function(e){
+ var panel = this;
+ if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) {
+ _this.getFileData();
+ }
+ });
+ /* 选中图片 */
+ domUtils.on(this.list, 'click', function (e) {
+ var target = e.target || e.srcElement,
+ li = target.parentNode;
+
+ if (li.tagName.toLowerCase() == 'li') {
+ if (domUtils.hasClass(li, 'selected')) {
+ domUtils.removeClasses(li, 'selected');
+ } else {
+ domUtils.addClass(li, 'selected');
+ }
+ }
+ });
+ },
+ /* 初始化第一次的数据 */
+ initData: function () {
+
+ /* 拉取数据需要使用的值 */
+ this.state = 0;
+ this.listSize = editor.getOpt('fileManagerListSize');
+ this.listIndex = 0;
+ this.listEnd = false;
+
+ /* 第一次拉取数据 */
+ this.getFileData();
+ },
+ /* 向后台拉取图片列表数据 */
+ getFileData: function () {
+ var _this = this;
+
+ if(!_this.listEnd && !this.isLoadingData) {
+ this.isLoadingData = true;
+ ajax.request(editor.getActionUrl(editor.getOpt('fileManagerActionName')), {
+ timeout: 100000,
+ data: utils.extend({
+ start: this.listIndex,
+ size: this.listSize
+ }, editor.queryCommandValue('serverparam')),
+ method: 'get',
+ onsuccess: function (r) {
+ try {
+ var json = eval('(' + r.responseText + ')');
+ if (json.state == 'SUCCESS') {
+ _this.pushData(json.list);
+ _this.listIndex = parseInt(json.start) + parseInt(json.list.length);
+ if(_this.listIndex >= json.total) {
+ _this.listEnd = true;
+ }
+ _this.isLoadingData = false;
+ }
+ } catch (e) {
+ if(r.responseText.indexOf('ue_separate_ue') != -1) {
+ var list = r.responseText.split(r.responseText);
+ _this.pushData(list);
+ _this.listIndex = parseInt(list.length);
+ _this.listEnd = true;
+ _this.isLoadingData = false;
+ }
+ }
+ },
+ onerror: function () {
+ _this.isLoadingData = false;
+ }
+ });
+ }
+ },
+ /* 添加图片到列表界面上 */
+ pushData: function (list) {
+ var i, item, img, filetype, preview, icon, _this = this,
+ urlPrefix = editor.getOpt('fileManagerUrlPrefix');
+ for (i = 0; i < list.length; i++) {
+ if(list[i] && list[i].url) {
+ item = document.createElement('li');
+ icon = document.createElement('span');
+ filetype = list[i].url.substr(list[i].url.lastIndexOf('.') + 1);
+
+ if ( "png|jpg|jpeg|gif|bmp".indexOf(filetype) != -1 ) {
+ preview = document.createElement('img');
+ domUtils.on(preview, 'load', (function(image){
+ return function(){
+ _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight);
+ };
+ })(preview));
+ preview.width = 113;
+ preview.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) );
+ } else {
+ var ic = document.createElement('i'),
+ textSpan = document.createElement('span');
+ textSpan.innerHTML = list[i].url.substr(list[i].url.lastIndexOf('/') + 1);
+ preview = document.createElement('div');
+ preview.appendChild(ic);
+ preview.appendChild(textSpan);
+ domUtils.addClass(preview, 'file-wrapper');
+ domUtils.addClass(textSpan, 'file-title');
+ domUtils.addClass(ic, 'file-type-' + filetype);
+ domUtils.addClass(ic, 'file-preview');
+ }
+ domUtils.addClass(icon, 'icon');
+ item.setAttribute('data-url', urlPrefix + list[i].url);
+ if (list[i].original) {
+ item.setAttribute('data-title', list[i].original);
+ }
+
+ item.appendChild(preview);
+ item.appendChild(icon);
+ this.list.insertBefore(item, this.clearFloat);
+ }
+ }
+ },
+ /* 改变图片大小 */
+ scale: function (img, w, h, type) {
+ var ow = img.width,
+ oh = img.height;
+
+ if (type == 'justify') {
+ if (ow >= oh) {
+ img.width = w;
+ img.height = h * oh / ow;
+ img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+ } else {
+ img.width = w * ow / oh;
+ img.height = h;
+ img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+ }
+ } else {
+ if (ow >= oh) {
+ img.width = w * ow / oh;
+ img.height = h;
+ img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+ } else {
+ img.width = w;
+ img.height = h * oh / ow;
+ img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+ }
+ }
+ },
+ getInsertList: function () {
+ var i, lis = this.list.children, list = [];
+ for (i = 0; i < lis.length; i++) {
+ if (domUtils.hasClass(lis[i], 'selected')) {
+ var url = lis[i].getAttribute('data-url');
+ var title = lis[i].getAttribute('data-title') || url.substr(url.lastIndexOf('/') + 1);
+ list.push({
+ title: title,
+ url: url
+ });
+ }
+ }
+ return list;
+ }
+ };
+
+
+})();
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_chm.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_chm.gif
new file mode 100644
index 0000000..9ca4fb6
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_chm.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_default.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_default.png
new file mode 100644
index 0000000..50ac1cb
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_default.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_doc.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_doc.gif
new file mode 100644
index 0000000..206fede
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_doc.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_exe.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_exe.gif
new file mode 100644
index 0000000..2e3b7a2
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_exe.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_jpg.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_jpg.gif
new file mode 100644
index 0000000..5d5dec0
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_jpg.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_mp3.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_mp3.gif
new file mode 100644
index 0000000..b351a1f
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_mp3.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_mv.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_mv.gif
new file mode 100644
index 0000000..26019b0
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_mv.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_pdf.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_pdf.gif
new file mode 100644
index 0000000..bbb65c8
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_pdf.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_ppt.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_ppt.gif
new file mode 100644
index 0000000..ccb26fb
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_ppt.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_psd.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_psd.gif
new file mode 100644
index 0000000..2e8743a
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_psd.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_rar.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_rar.gif
new file mode 100644
index 0000000..5359e46
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_rar.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_txt.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_txt.gif
new file mode 100644
index 0000000..e7b8dd2
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_txt.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_xls.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_xls.gif
new file mode 100644
index 0000000..e86c1c6
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/fileTypeImages/icon_xls.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/alignicon.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/alignicon.gif
new file mode 100644
index 0000000..005a5ac
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/alignicon.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/alignicon.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/alignicon.png
new file mode 100644
index 0000000..4b6c444
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/alignicon.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/bg.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/bg.png
new file mode 100644
index 0000000..580be0a
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/bg.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/file-icons.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/file-icons.gif
new file mode 100644
index 0000000..d8c02c2
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/file-icons.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/file-icons.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/file-icons.png
new file mode 100644
index 0000000..3ff82c8
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/file-icons.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/icons.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/icons.gif
new file mode 100644
index 0000000..78459de
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/icons.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/icons.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/icons.png
new file mode 100644
index 0000000..12e4700
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/icons.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/image.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/image.png
new file mode 100644
index 0000000..19699f6
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/image.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/progress.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/progress.png
new file mode 100644
index 0000000..717c486
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/progress.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/success.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/success.gif
new file mode 100644
index 0000000..8d4f311
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/success.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/success.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/success.png
new file mode 100644
index 0000000..94f968d
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/attachment/images/success.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.css b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.css
new file mode 100644
index 0000000..5c41fe9
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.css
@@ -0,0 +1,94 @@
+.wrapper{ width: 424px;margin: 10px auto; zoom:1;position: relative}
+.tabbody{height:225px;}
+.tabbody .panel { position: absolute;width:100%; height:100%;background: #fff; display: none;}
+.tabbody .focus { display: block;}
+
+body{font-size: 12px;color: #888;overflow: hidden;}
+input,label{vertical-align:middle}
+.clear{clear: both;}
+.pl{padding-left: 18px;padding-left: 23px\9;}
+
+#imageList {width: 420px;height: 215px;margin-top: 10px;overflow: hidden;overflow-y: auto;}
+#imageList div {float: left;width: 100px;height: 95px;margin: 5px 10px;}
+#imageList img {cursor: pointer;border: 2px solid white;}
+
+.bgarea{margin: 10px;padding: 5px;height: 84%;border: 1px solid #A8A297;}
+.content div{margin: 10px 0 10px 5px;}
+.content .iptradio{margin: 0px 5px 5px 0px;}
+.txt{width:280px;}
+
+.wrapcolor{height: 19px;}
+div.color{float: left;margin: 0;}
+#colorPicker{width: 17px;height: 17px;border: 1px solid #CCC;display: inline-block;border-radius: 3px;box-shadow: 2px 2px 5px #D3D6DA;margin: 0;float: left;}
+div.alignment,#custom{margin-left: 23px;margin-left: 28px\9;}
+#custom input{height: 15px;min-height: 15px;width:20px;}
+#repeatType{width:100px;}
+
+
+/* 图片管理样式 */
+#imgManager {
+ width: 100%;
+ height: 225px;
+}
+#imgManager #imageList{
+ width: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+#imgManager ul {
+ display: block;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+#imgManager li {
+ float: left;
+ display: block;
+ list-style: none;
+ padding: 0;
+ width: 113px;
+ height: 113px;
+ margin: 9px 0 0 19px;
+ background-color: #eee;
+ overflow: hidden;
+ cursor: pointer;
+ position: relative;
+}
+#imgManager li.clearFloat {
+ float: none;
+ clear: both;
+ display: block;
+ width:0;
+ height:0;
+ margin: 0;
+ padding: 0;
+}
+#imgManager li img {
+ cursor: pointer;
+}
+#imgManager li .icon {
+ cursor: pointer;
+ width: 113px;
+ height: 113px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ border: 0;
+ background-repeat: no-repeat;
+}
+#imgManager li .icon:hover {
+ width: 107px;
+ height: 107px;
+ border: 3px solid #1094fa;
+}
+#imgManager li.selected .icon {
+ background-image: url(images/success.png);
+ background-position: 75px 75px;
+}
+#imgManager li.selected .icon:hover {
+ width: 107px;
+ height: 107px;
+ border: 3px solid #1094fa;
+ background-position: 72px 72px;
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.html
new file mode 100644
index 0000000..3cc2ac1
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.js
new file mode 100644
index 0000000..9a4a131
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/background.js
@@ -0,0 +1,376 @@
+(function () {
+
+ var onlineImage,
+ backupStyle = editor.queryCommandValue('background');
+
+ window.onload = function () {
+ initTabs();
+ initColorSelector();
+ };
+
+ /* 初始化tab标签 */
+ function initTabs(){
+ var tabs = $G('tabHeads').children;
+ for (var i = 0; i < tabs.length; i++) {
+ domUtils.on(tabs[i], "click", function (e) {
+ var target = e.target || e.srcElement;
+ for (var j = 0; j < tabs.length; j++) {
+ if(tabs[j] == target){
+ tabs[j].className = "focus";
+ var contentId = tabs[j].getAttribute('data-content-id');
+ $G(contentId).style.display = "block";
+ if(contentId == 'imgManager') {
+ initImagePanel();
+ }
+ }else {
+ tabs[j].className = "";
+ $G(tabs[j].getAttribute('data-content-id')).style.display = "none";
+ }
+ }
+ });
+ }
+ }
+
+ /* 初始化颜色设置 */
+ function initColorSelector () {
+ var obj = editor.queryCommandValue('background');
+ if (obj) {
+ var color = obj['background-color'],
+ repeat = obj['background-repeat'] || 'repeat',
+ image = obj['background-image'] || '',
+ position = obj['background-position'] || 'center center',
+ pos = position.split(' '),
+ x = parseInt(pos[0]) || 0,
+ y = parseInt(pos[1]) || 0;
+
+ if(repeat == 'no-repeat' && (x || y)) repeat = 'self';
+
+ image = image.match(/url[\s]*\(([^\)]*)\)/);
+ image = image ? image[1]:'';
+ updateFormState('colored', color, image, repeat, x, y);
+ } else {
+ updateFormState();
+ }
+
+ var updateHandler = function () {
+ updateFormState();
+ updateBackground();
+ }
+ domUtils.on($G('nocolorRadio'), 'click', updateBackground);
+ domUtils.on($G('coloredRadio'), 'click', updateHandler);
+ domUtils.on($G('url'), 'keyup', function(){
+ if($G('url').value && $G('alignment').style.display == "none") {
+ utils.each($G('repeatType').children, function(item){
+ item.selected = ('repeat' == item.getAttribute('value') ? 'selected':false);
+ });
+ }
+ updateHandler();
+ });
+ domUtils.on($G('repeatType'), 'change', updateHandler);
+ domUtils.on($G('x'), 'keyup', updateBackground);
+ domUtils.on($G('y'), 'keyup', updateBackground);
+
+ initColorPicker();
+ }
+
+ /* 初始化颜色选择器 */
+ function initColorPicker() {
+ var me = editor,
+ cp = $G("colorPicker");
+
+ /* 生成颜色选择器ui对象 */
+ var popup = new UE.ui.Popup({
+ content: new UE.ui.ColorPicker({
+ noColorText: me.getLang("clearColor"),
+ editor: me,
+ onpickcolor: function (t, color) {
+ updateFormState('colored', color);
+ updateBackground();
+ UE.ui.Popup.postHide();
+ },
+ onpicknocolor: function (t, color) {
+ updateFormState('colored', 'transparent');
+ updateBackground();
+ UE.ui.Popup.postHide();
+ }
+ }),
+ editor: me,
+ onhide: function () {
+ }
+ });
+
+ /* 设置颜色选择器 */
+ domUtils.on(cp, "click", function () {
+ popup.showAnchor(this);
+ });
+ domUtils.on(document, 'mousedown', function (evt) {
+ var el = evt.target || evt.srcElement;
+ UE.ui.Popup.postHide(el);
+ });
+ domUtils.on(window, 'scroll', function () {
+ UE.ui.Popup.postHide();
+ });
+ }
+
+ /* 初始化在线图片列表 */
+ function initImagePanel() {
+ onlineImage = onlineImage || new OnlineImage('imageList');
+ }
+
+ /* 更新背景色设置面板 */
+ function updateFormState (radio, color, url, align, x, y) {
+ var nocolorRadio = $G('nocolorRadio'),
+ coloredRadio = $G('coloredRadio');
+
+ if(radio) {
+ nocolorRadio.checked = (radio == 'colored' ? false:'checked');
+ coloredRadio.checked = (radio == 'colored' ? 'checked':false);
+ }
+ if(color) {
+ domUtils.setStyle($G("colorPicker"), "background-color", color);
+ }
+
+ if(url && /^\//.test(url)) {
+ var a = document.createElement('a');
+ a.href = url;
+ browser.ie && (a.href = a.href);
+ url = browser.ie ? a.href:(a.protocol + '//' + a.host + a.pathname + a.search + a.hash);
+ }
+
+ if(url || url === '') {
+ $G('url').value = url;
+ }
+ if(align) {
+ utils.each($G('repeatType').children, function(item){
+ item.selected = (align == item.getAttribute('value') ? 'selected':false);
+ });
+ }
+ if(x || y) {
+ $G('x').value = parseInt(x) || 0;
+ $G('y').value = parseInt(y) || 0;
+ }
+
+ $G('alignment').style.display = coloredRadio.checked && $G('url').value ? '':'none';
+ $G('custom').style.display = coloredRadio.checked && $G('url').value && $G('repeatType').value == 'self' ? '':'none';
+ }
+
+ /* 更新背景颜色 */
+ function updateBackground () {
+ if ($G('coloredRadio').checked) {
+ var color = domUtils.getStyle($G("colorPicker"), "background-color"),
+ bgimg = $G("url").value,
+ align = $G("repeatType").value,
+ backgroundObj = {
+ "background-repeat": "no-repeat",
+ "background-position": "center center"
+ };
+
+ if (color) backgroundObj["background-color"] = color;
+ if (bgimg) backgroundObj["background-image"] = 'url(' + bgimg + ')';
+ if (align == 'self') {
+ backgroundObj["background-position"] = $G("x").value + "px " + $G("y").value + "px";
+ } else if (align == 'repeat-x' || align == 'repeat-y' || align == 'repeat') {
+ backgroundObj["background-repeat"] = align;
+ }
+
+ editor.execCommand('background', backgroundObj);
+ } else {
+ editor.execCommand('background', null);
+ }
+ }
+
+
+ /* 在线图片 */
+ function OnlineImage(target) {
+ this.container = utils.isString(target) ? document.getElementById(target) : target;
+ this.init();
+ }
+ OnlineImage.prototype = {
+ init: function () {
+ this.reset();
+ this.initEvents();
+ },
+ /* 初始化容器 */
+ initContainer: function () {
+ this.container.innerHTML = '';
+ this.list = document.createElement('ul');
+ this.clearFloat = document.createElement('li');
+
+ domUtils.addClass(this.list, 'list');
+ domUtils.addClass(this.clearFloat, 'clearFloat');
+
+ this.list.id = 'imageListUl';
+ this.list.appendChild(this.clearFloat);
+ this.container.appendChild(this.list);
+ },
+ /* 初始化滚动事件,滚动到地步自动拉取数据 */
+ initEvents: function () {
+ var _this = this;
+
+ /* 滚动拉取图片 */
+ domUtils.on($G('imageList'), 'scroll', function(e){
+ var panel = this;
+ if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) {
+ _this.getImageData();
+ }
+ });
+ /* 选中图片 */
+ domUtils.on(this.container, 'click', function (e) {
+ var target = e.target || e.srcElement,
+ li = target.parentNode,
+ nodes = $G('imageListUl').childNodes;
+
+ if (li.tagName.toLowerCase() == 'li') {
+ updateFormState('nocolor', null, '');
+ for (var i = 0, node; node = nodes[i++];) {
+ if (node == li && !domUtils.hasClass(node, 'selected')) {
+ domUtils.addClass(node, 'selected');
+ updateFormState('colored', null, li.firstChild.getAttribute("_src"), 'repeat');
+ } else {
+ domUtils.removeClasses(node, 'selected');
+ }
+ }
+ updateBackground();
+ }
+ });
+ },
+ /* 初始化第一次的数据 */
+ initData: function () {
+
+ /* 拉取数据需要使用的值 */
+ this.state = 0;
+ this.listSize = editor.getOpt('imageManagerListSize');
+ this.listIndex = 0;
+ this.listEnd = false;
+
+ /* 第一次拉取数据 */
+ this.getImageData();
+ },
+ /* 重置界面 */
+ reset: function() {
+ this.initContainer();
+ this.initData();
+ },
+ /* 向后台拉取图片列表数据 */
+ getImageData: function () {
+ var _this = this;
+
+ if(!_this.listEnd && !this.isLoadingData) {
+ this.isLoadingData = true;
+ var url = editor.getActionUrl(editor.getOpt('imageManagerActionName')),
+ isJsonp = utils.isCrossDomainUrl(url);
+ ajax.request(url, {
+ 'timeout': 100000,
+ 'dataType': isJsonp ? 'jsonp':'',
+ 'data': utils.extend({
+ start: this.listIndex,
+ size: this.listSize
+ }, editor.queryCommandValue('serverparam')),
+ 'method': 'get',
+ 'onsuccess': function (r) {
+ try {
+ var json = isJsonp ? r:eval('(' + r.responseText + ')');
+ if (json.state == 'SUCCESS') {
+ _this.pushData(json.list);
+ _this.listIndex = parseInt(json.start) + parseInt(json.list.length);
+ if(_this.listIndex >= json.total) {
+ _this.listEnd = true;
+ }
+ _this.isLoadingData = false;
+ }
+ } catch (e) {
+ if(r.responseText.indexOf('ue_separate_ue') != -1) {
+ var list = r.responseText.split(r.responseText);
+ _this.pushData(list);
+ _this.listIndex = parseInt(list.length);
+ _this.listEnd = true;
+ _this.isLoadingData = false;
+ }
+ }
+ },
+ 'onerror': function () {
+ _this.isLoadingData = false;
+ }
+ });
+ }
+ },
+ /* 添加图片到列表界面上 */
+ pushData: function (list) {
+ var i, item, img, icon, _this = this,
+ urlPrefix = editor.getOpt('imageManagerUrlPrefix');
+ for (i = 0; i < list.length; i++) {
+ if(list[i] && list[i].url) {
+ item = document.createElement('li');
+ img = document.createElement('img');
+ icon = document.createElement('span');
+
+ domUtils.on(img, 'load', (function(image){
+ return function(){
+ _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight);
+ }
+ })(img));
+ img.width = 113;
+ img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) );
+ img.setAttribute('_src', urlPrefix + list[i].url);
+ domUtils.addClass(icon, 'icon');
+
+ item.appendChild(img);
+ item.appendChild(icon);
+ this.list.insertBefore(item, this.clearFloat);
+ }
+ }
+ },
+ /* 改变图片大小 */
+ scale: function (img, w, h, type) {
+ var ow = img.width,
+ oh = img.height;
+
+ if (type == 'justify') {
+ if (ow >= oh) {
+ img.width = w;
+ img.height = h * oh / ow;
+ img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+ } else {
+ img.width = w * ow / oh;
+ img.height = h;
+ img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+ }
+ } else {
+ if (ow >= oh) {
+ img.width = w * ow / oh;
+ img.height = h;
+ img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+ } else {
+ img.width = w;
+ img.height = h * oh / ow;
+ img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+ }
+ }
+ },
+ getInsertList: function () {
+ var i, lis = this.list.children, list = [], align = getAlign();
+ for (i = 0; i < lis.length; i++) {
+ if (domUtils.hasClass(lis[i], 'selected')) {
+ var img = lis[i].firstChild,
+ src = img.getAttribute('_src');
+ list.push({
+ src: src,
+ _src: src,
+ floatStyle: align
+ });
+ }
+
+ }
+ return list;
+ }
+ };
+
+ dialog.onok = function () {
+ updateBackground();
+ editor.fireEvent('saveScene');
+ };
+ dialog.oncancel = function () {
+ editor.execCommand('background', backupStyle);
+ };
+
+})();
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/images/bg.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/images/bg.png
new file mode 100644
index 0000000..580be0a
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/images/bg.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/images/success.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/images/success.png
new file mode 100644
index 0000000..94f968d
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/background/images/success.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/chart.config.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/chart.config.js
new file mode 100644
index 0000000..678b00d
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/chart.config.js
@@ -0,0 +1,65 @@
+/*
+ * 图表配置文件
+ * */
+
+
+//不同类型的配置
+var typeConfig = [
+ {
+ chart: {
+ type: 'line'
+ },
+ plotOptions: {
+ line: {
+ dataLabels: {
+ enabled: false
+ },
+ enableMouseTracking: true
+ }
+ }
+ }, {
+ chart: {
+ type: 'line'
+ },
+ plotOptions: {
+ line: {
+ dataLabels: {
+ enabled: true
+ },
+ enableMouseTracking: false
+ }
+ }
+ }, {
+ chart: {
+ type: 'area'
+ }
+ }, {
+ chart: {
+ type: 'bar'
+ }
+ }, {
+ chart: {
+ type: 'column'
+ }
+ }, {
+ chart: {
+ plotBackgroundColor: null,
+ plotBorderWidth: null,
+ plotShadow: false
+ },
+ plotOptions: {
+ pie: {
+ allowPointSelect: true,
+ cursor: 'pointer',
+ dataLabels: {
+ enabled: true,
+ color: '#000000',
+ connectorColor: '#000000',
+ formatter: function() {
+ return ''+ this.point.name +': '+ ( Math.round( this.point.percentage*100 ) / 100 ) +' %';
+ }
+ }
+ }
+ }
+ }
+];
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.css b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.css
new file mode 100644
index 0000000..ac3c764
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.css
@@ -0,0 +1,165 @@
+html, body {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ overflow-x: hidden;
+}
+
+.main {
+ width: 100%;
+ overflow: hidden;
+}
+
+.table-view {
+ height: 100%;
+ float: left;
+ margin: 20px;
+ width: 40%;
+}
+
+.table-view .table-container {
+ width: 100%;
+ margin-bottom: 50px;
+ overflow: scroll;
+}
+
+.table-view th {
+ padding: 5px 10px;
+ background-color: #F7F7F7;
+}
+
+.table-view td {
+ width: 50px;
+ text-align: center;
+ padding:0;
+}
+
+.table-container input {
+ width: 40px;
+ padding: 5px;
+ border: none;
+ outline: none;
+}
+
+.table-view caption {
+ font-size: 18px;
+ text-align: left;
+}
+
+.charts-view {
+ /*margin-left: 49%!important;*/
+ width: 50%;
+ margin-left: 49%;
+ height: 400px;
+}
+
+.charts-container {
+ border-left: 1px solid #c3c3c3;
+}
+
+.charts-format fieldset {
+ padding-left: 20px;
+ margin-bottom: 50px;
+}
+
+.charts-format legend {
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+.format-item-container {
+ padding: 20px;
+}
+
+.format-item-container label {
+ display: block;
+ margin: 10px 0;
+}
+
+.charts-format .data-item {
+ border: 1px solid black;
+ outline: none;
+ padding: 2px 3px;
+}
+
+/* 图表类型 */
+
+.charts-type {
+ margin-top: 50px;
+ height: 300px;
+}
+
+.scroll-view {
+ border: 1px solid #c3c3c3;
+ border-left: none;
+ border-right: none;
+ overflow: hidden;
+}
+
+.scroll-container {
+ margin: 20px;
+ width: 100%;
+ overflow: hidden;
+}
+
+.scroll-bed {
+ width: 10000px;
+ _margin-top: 20px;
+ -webkit-transition: margin-left .5s ease;
+ -moz-transition: margin-left .5s ease;
+ transition: margin-left .5s ease;
+}
+
+.view-box {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+ margin-right: 20px;
+ border: 2px solid white;
+ line-height: 0;
+ overflow: hidden;
+ cursor: pointer;
+}
+
+.view-box img {
+ border: 1px solid #cecece;
+}
+
+.view-box.selected {
+ border-color: #7274A7;
+}
+
+.button-container {
+ margin-bottom: 20px;
+ text-align: center;
+}
+
+.button-container a {
+ display: inline-block;
+ width: 100px;
+ height: 25px;
+ line-height: 25px;
+ border: 1px solid #c2ccd1;
+ margin-right: 30px;
+ text-decoration: none;
+ color: black;
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+}
+
+.button-container a:HOVER {
+ background: #fcfcfc;
+}
+
+.button-container a:ACTIVE {
+ border-top-color: #c2ccd1;
+ box-shadow:inset 0 5px 4px -4px rgba(49, 49, 64, 0.1);
+}
+
+.edui-charts-not-data {
+ height: 100px;
+ line-height: 100px;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.html
new file mode 100644
index 0000000..70e2314
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.html
@@ -0,0 +1,89 @@
+
+
+
+ chart
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.js
new file mode 100644
index 0000000..37344fd
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/charts.js
@@ -0,0 +1,519 @@
+/*
+ * 图片转换对话框脚本
+ **/
+
+var tableData = [],
+ //编辑器页面table
+ editorTable = null,
+ chartsConfig = window.typeConfig,
+ resizeTimer = null,
+ //初始默认图表类型
+ currentChartType = 0;
+
+window.onload = function () {
+
+ editorTable = domUtils.findParentByTagName( editor.selection.getRange().startContainer, 'table', true);
+
+ //未找到表格, 显示错误页面
+ if ( !editorTable ) {
+ document.body.innerHTML = "未找到数据";
+ return;
+ }
+
+ //初始化图表类型选择
+ initChartsTypeView();
+ renderTable( editorTable );
+ initEvent();
+ initUserConfig( editorTable.getAttribute( "data-chart" ) );
+ $( "#scrollBed .view-box:eq("+ currentChartType +")" ).trigger( "click" );
+ updateViewType( currentChartType );
+
+ dialog.addListener( "resize", function () {
+
+ if ( resizeTimer != null ) {
+ window.clearTimeout( resizeTimer );
+ }
+
+ resizeTimer = window.setTimeout( function () {
+
+ resizeTimer = null;
+
+ renderCharts();
+
+ }, 500 );
+
+ } );
+
+};
+
+function initChartsTypeView () {
+
+ var contents = [];
+
+ for ( var i = 0, len = chartsConfig.length; i
' );
+
+ }
+
+ $( "#scrollBed" ).html( contents.join( "" ) );
+
+}
+
+//渲染table, 以便用户修改数据
+function renderTable ( table ) {
+
+ var tableHtml = [];
+
+ //构造数据
+ for ( var i = 0, row; row = table.rows[ i ]; i++ ) {
+
+ tableData[ i ] = [];
+ tableHtml[ i ] = [];
+
+ for ( var j = 0, cell; cell = row.cells[ j ]; j++ ) {
+
+ var value = getCellValue( cell );
+
+ if ( i > 0 && j > 0 ) {
+ value = +value;
+ }
+
+ if ( i === 0 || j === 0 ) {
+ tableHtml[ i ].push( ''+ value +' ' );
+ } else {
+ tableHtml[ i ].push( ' ' );
+ }
+
+ tableData[ i ][ j ] = value;
+
+ }
+
+ tableHtml[ i ] = tableHtml[ i ].join( "" );
+
+ }
+
+ //draw 表格
+ $( "#tableContainer" ).html( ''+ tableHtml.join( " " ) +'
' );
+
+}
+
+/*
+ * 根据表格已有的图表属性初始化当前图表属性
+ */
+function initUserConfig ( config ) {
+
+ var parsedConfig = {};
+
+ if ( !config ) {
+ return;
+ }
+
+ config = config.split( ";" );
+
+ $.each( config, function ( index, item ) {
+
+ item = item.split( ":" );
+ parsedConfig[ item[ 0 ] ] = item[ 1 ];
+
+ } );
+
+ setUserConfig( parsedConfig );
+
+}
+
+function initEvent () {
+
+ var cacheValue = null,
+ //图表类型数
+ typeViewCount = chartsConfig.length- 1,
+ $chartsTypeViewBox = $( '#scrollBed .view-box' );
+
+ $( ".charts-format" ).delegate( ".format-ctrl", "change", function () {
+
+ renderCharts();
+
+ } )
+
+ $( ".table-view" ).delegate( ".data-item", "focus", function () {
+
+ cacheValue = this.value;
+
+ } ).delegate( ".data-item", "blur", function () {
+
+ if ( this.value !== cacheValue ) {
+ renderCharts();
+ }
+
+ cacheValue = null;
+
+ } );
+
+ $( "#buttonContainer" ).delegate( "a", "click", function (e) {
+
+ e.preventDefault();
+
+ if ( this.getAttribute( "data-title" ) === 'prev' ) {
+
+ if ( currentChartType > 0 ) {
+ currentChartType--;
+ updateViewType( currentChartType );
+ }
+
+ } else {
+
+ if ( currentChartType < typeViewCount ) {
+ currentChartType++;
+ updateViewType( currentChartType );
+ }
+
+ }
+
+ } );
+
+ //图表类型变化
+ $( '#scrollBed' ).delegate( ".view-box", "click", function (e) {
+
+ var index = $( this ).attr( "data-chart-type" );
+ $chartsTypeViewBox.removeClass( "selected" );
+ $( $chartsTypeViewBox[ index ] ).addClass( "selected" );
+
+ currentChartType = index | 0;
+
+ //饼图, 禁用部分配置
+ if ( currentChartType === chartsConfig.length - 1 ) {
+
+ disableNotPieConfig();
+
+ //启用完整配置
+ } else {
+
+ enableNotPieConfig();
+
+ }
+
+ renderCharts();
+
+ } );
+
+}
+
+function renderCharts () {
+
+ var data = collectData();
+
+ $('#chartsContainer').highcharts( $.extend( {}, chartsConfig[ currentChartType ], {
+
+ credits: {
+ enabled: false
+ },
+ exporting: {
+ enabled: false
+ },
+ title: {
+ text: data.title,
+ x: -20 //center
+ },
+ subtitle: {
+ text: data.subTitle,
+ x: -20
+ },
+ xAxis: {
+ title: {
+ text: data.xTitle
+ },
+ categories: data.categories
+ },
+ yAxis: {
+ title: {
+ text: data.yTitle
+ },
+ plotLines: [{
+ value: 0,
+ width: 1,
+ color: '#808080'
+ }]
+ },
+ tooltip: {
+ enabled: true,
+ valueSuffix: data.suffix
+ },
+ legend: {
+ layout: 'vertical',
+ align: 'right',
+ verticalAlign: 'middle',
+ borderWidth: 1
+ },
+ series: data.series
+
+ } ));
+
+}
+
+function updateViewType ( index ) {
+
+ $( "#scrollBed" ).css( 'marginLeft', -index*324+'px' );
+
+}
+
+function collectData () {
+
+ var form = document.forms[ 'data-form' ],
+ data = null;
+
+ if ( currentChartType !== chartsConfig.length - 1 ) {
+
+ data = getSeriesAndCategories();
+ $.extend( data, getUserConfig() );
+
+ //饼图数据格式
+ } else {
+ data = getSeriesForPieChart();
+ data.title = form[ 'title' ].value;
+ data.suffix = form[ 'unit' ].value;
+ }
+
+ return data;
+
+}
+
+/**
+ * 获取用户配置信息
+ */
+function getUserConfig () {
+
+ var form = document.forms[ 'data-form' ],
+ info = {
+ title: form[ 'title' ].value,
+ subTitle: form[ 'sub-title' ].value,
+ xTitle: form[ 'x-title' ].value,
+ yTitle: form[ 'y-title' ].value,
+ suffix: form[ 'unit' ].value,
+ //数据对齐方式
+ tableDataFormat: getTableDataFormat (),
+ //饼图提示文字
+ tip: $( "#tipInput" ).val()
+ };
+
+ return info;
+
+}
+
+function setUserConfig ( config ) {
+
+ var form = document.forms[ 'data-form' ];
+
+ config.title && ( form[ 'title' ].value = config.title );
+ config.subTitle && ( form[ 'sub-title' ].value = config.subTitle );
+ config.xTitle && ( form[ 'x-title' ].value = config.xTitle );
+ config.yTitle && ( form[ 'y-title' ].value = config.yTitle );
+ config.suffix && ( form[ 'unit' ].value = config.suffix );
+ config.dataFormat == "-1" && ( form[ 'charts-format' ][ 1 ].checked = true );
+ config.tip && ( form[ 'tip' ].value = config.tip );
+ currentChartType = config.chartType || 0;
+
+}
+
+function getSeriesAndCategories () {
+
+ var form = document.forms[ 'data-form' ],
+ series = [],
+ categories = [],
+ tmp = [],
+ tableData = getTableData();
+
+ //反转数据
+ if ( getTableDataFormat() === "-1" ) {
+
+ for ( var i = 0, len = tableData.length; i < len; i++ ) {
+
+ for ( var j = 0, jlen = tableData[ i ].length; j < jlen; j++ ) {
+
+ if ( !tmp[ j ] ) {
+ tmp[ j ] = [];
+ }
+
+ tmp[ j ][ i ] = tableData[ i ][ j ];
+
+ }
+
+ }
+
+ tableData = tmp;
+
+ }
+
+ categories = tableData[0].slice( 1 );
+
+ for ( var i = 1, data; data = tableData[ i ]; i++ ) {
+
+ series.push( {
+ name: data[ 0 ],
+ data: data.slice( 1 )
+ } );
+
+ }
+
+ return {
+ series: series,
+ categories: categories
+ };
+
+}
+
+/*
+ * 获取数据源数据对齐方式
+ */
+function getTableDataFormat () {
+
+ var form = document.forms[ 'data-form' ],
+ items = form['charts-format'];
+
+ return items[ 0 ].checked ? items[ 0 ].value : items[ 1 ].value;
+
+}
+
+/*
+ * 禁用非饼图类型的配置项
+ */
+function disableNotPieConfig() {
+
+ updateConfigItem( 'disable' );
+
+}
+
+/*
+ * 启用非饼图类型的配置项
+ */
+function enableNotPieConfig() {
+
+ updateConfigItem( 'enable' );
+
+}
+
+function updateConfigItem ( value ) {
+
+ var table = $( "#showTable" )[ 0 ],
+ isDisable = value === 'disable' ? true : false;
+
+ //table中的input处理
+ for ( var i = 2 , row; row = table.rows[ i ]; i++ ) {
+
+ for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {
+
+ $( "input", cell ).attr( "disabled", isDisable );
+
+ }
+
+ }
+
+ //其他项处理
+ $( "input.not-pie-item" ).attr( "disabled", isDisable );
+ $( "#tipInput" ).attr( "disabled", !isDisable )
+
+}
+
+/*
+ * 获取饼图数据
+ * 饼图的数据只取第一行的
+ **/
+function getSeriesForPieChart () {
+
+ var series = {
+ type: 'pie',
+ name: $("#tipInput").val(),
+ data: []
+ },
+ tableData = getTableData();
+
+
+ for ( var j = 1, jlen = tableData[ 0 ].length; j < jlen; j++ ) {
+
+ var title = tableData[ 0 ][ j ],
+ val = tableData[ 1 ][ j ];
+
+ series.data.push( [ title, val ] );
+
+ }
+
+ return {
+ series: [ series ]
+ };
+
+}
+
+function getTableData () {
+
+ var table = document.getElementById( "showTable" ),
+ xCount = table.rows[0].cells.length - 1,
+ values = getTableInputValue();
+
+ for ( var i = 0, value; value = values[ i ]; i++ ) {
+
+ tableData[ Math.floor( i / xCount ) + 1 ][ i % xCount + 1 ] = values[ i ];
+
+ }
+
+ return tableData;
+
+}
+
+function getTableInputValue () {
+
+ var table = document.getElementById( "showTable" ),
+ inputs = table.getElementsByTagName( "input" ),
+ values = [];
+
+ for ( var i = 0, input; input = inputs[ i ]; i++ ) {
+ values.push( input.value | 0 );
+ }
+
+ return values;
+
+}
+
+function getCellValue ( cell ) {
+
+ var value = utils.trim( ( cell.innerText || cell.textContent || '' ) );
+
+ return value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\s+|\s+$/g, '' );
+
+}
+
+
+//dialog确认事件
+dialog.onok = function () {
+
+ //收集信息
+ var form = document.forms[ 'data-form' ],
+ info = getUserConfig();
+
+ //添加图表类型
+ info.chartType = currentChartType;
+
+ //同步表格数据到编辑器
+ syncTableData();
+
+ //执行图表命令
+ editor.execCommand( 'charts', info );
+
+};
+
+/*
+ * 同步图表编辑视图的表格数据到编辑器里的原始表格
+ */
+function syncTableData () {
+
+ var tableData = getTableData();
+
+ for ( var i = 1, row; row = editorTable.rows[ i ]; i++ ) {
+
+ for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {
+
+ cell.innerHTML = tableData[ i ] [ j ];
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts0.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts0.png
new file mode 100644
index 0000000..9485e5e
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts0.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts1.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts1.png
new file mode 100644
index 0000000..b5a0039
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts1.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts2.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts2.png
new file mode 100644
index 0000000..7c91a39
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts2.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts3.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts3.png
new file mode 100644
index 0000000..a6bc29b
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts3.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts4.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts4.png
new file mode 100644
index 0000000..742006a
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts4.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts5.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts5.png
new file mode 100644
index 0000000..c49a296
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/charts/images/charts5.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.css b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.css
new file mode 100644
index 0000000..f801105
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.css
@@ -0,0 +1,43 @@
+.jd img{
+ background:transparent url(images/jxface2.gif?v=1.1) no-repeat scroll left top;
+ cursor:pointer;width:35px;height:35px;display:block;
+}
+.pp img{
+ background:transparent url(images/fface.gif?v=1.1) no-repeat scroll left top;
+ cursor:pointer;width:25px;height:25px;display:block;
+}
+.ldw img{
+ background:transparent url(images/wface.gif?v=1.1) no-repeat scroll left top;
+ cursor:pointer;width:35px;height:35px;display:block;
+}
+.tsj img{
+ background:transparent url(images/tface.gif?v=1.1) no-repeat scroll left top;
+ cursor:pointer;width:35px;height:35px;display:block;
+}
+.cat img{
+ background:transparent url(images/cface.gif?v=1.1) no-repeat scroll left top;
+ cursor:pointer;width:35px;height:35px;display:block;
+}
+.bb img{
+ background:transparent url(images/bface.gif?v=1.1) no-repeat scroll left top;
+ cursor:pointer;width:35px;height:35px;display:block;
+}
+.youa img{
+ background:transparent url(images/yface.gif?v=1.1) no-repeat scroll left top;
+ cursor:pointer;width:35px;height:35px;display:block;
+}
+
+.smileytable td {height: 37px;}
+#tabPanel{margin-left:5px;overflow: hidden;}
+#tabContent {float:left;background:#FFFFFF;}
+#tabContent div{display: none;width:480px;overflow:hidden;}
+#tabIconReview.show{left:17px;display:block;}
+.menuFocus{background:#ACCD3C;}
+.menuDefault{background:#FFFFFF;}
+#tabIconReview{position:absolute;left:406px;left:398px \9;top:41px;z-index:65533;width:90px;height:76px;}
+img.review{width:90px;height:76px;border:2px solid #9cb945;background:#FFFFFF;background-position:center;background-repeat:no-repeat;}
+
+.wrapper .tabbody{position:relative;float:left;clear:both;padding:10px;width: 95%;}
+.tabbody table{width: 100%;}
+.tabbody td{border:1px solid #BAC498;}
+.tabbody td span{display: block;zoom:1;padding:0 4px;}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.html
new file mode 100644
index 0000000..fca0850
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.js
new file mode 100644
index 0000000..6e158a9
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/emotion.js
@@ -0,0 +1,186 @@
+window.onload = function () {
+ editor.setOpt({
+ emotionLocalization:false
+ });
+
+ emotion.SmileyPath = editor.options.emotionLocalization === true ? 'images/' : "http://img.baidu.com/hi/";
+ emotion.SmileyBox = createTabList( emotion.tabNum );
+ emotion.tabExist = createArr( emotion.tabNum );
+
+ initImgName();
+ initEvtHandler( "tabHeads" );
+};
+
+function initImgName() {
+ for ( var pro in emotion.SmilmgName ) {
+ var tempName = emotion.SmilmgName[pro],
+ tempBox = emotion.SmileyBox[pro],
+ tempStr = "";
+
+ if ( tempBox.length ) return;
+ for ( var i = 1; i <= tempName[1]; i++ ) {
+ tempStr = tempName[0];
+ if ( i < 10 ) tempStr = tempStr + '0';
+ tempStr = tempStr + i + '.gif';
+ tempBox.push( tempStr );
+ }
+ }
+}
+
+function initEvtHandler( conId ) {
+ var tabHeads = $G( conId );
+ for ( var i = 0, j = 0; i < tabHeads.childNodes.length; i++ ) {
+ var tabObj = tabHeads.childNodes[i];
+ if ( tabObj.nodeType == 1 ) {
+ domUtils.on( tabObj, "click", (function ( index ) {
+ return function () {
+ switchTab( index );
+ };
+ })( j ) );
+ j++;
+ }
+ }
+ switchTab( 0 );
+ $G( "tabIconReview" ).style.display = 'none';
+}
+
+function InsertSmiley( url, evt ) {
+ var obj = {
+ src:editor.options.emotionLocalization ? editor.options.UEDITOR_HOME_URL + "dialogs/emotion/" + url : url
+ };
+ obj._src = obj.src;
+ editor.execCommand( 'insertimage', obj );
+ if ( !evt.ctrlKey ) {
+ dialog.popup.hide();
+ }
+}
+
+function switchTab( index ) {
+
+ autoHeight( index );
+ if ( emotion.tabExist[index] == 0 ) {
+ emotion.tabExist[index] = 1;
+ createTab( 'tab' + index );
+ }
+ //获取呈现元素句柄数组
+ var tabHeads = $G( "tabHeads" ).getElementsByTagName( "span" ),
+ tabBodys = $G( "tabBodys" ).getElementsByTagName( "div" ),
+ i = 0, L = tabHeads.length;
+ //隐藏所有呈现元素
+ for ( ; i < L; i++ ) {
+ tabHeads[i].className = "";
+ tabBodys[i].style.display = "none";
+ }
+ //显示对应呈现元素
+ tabHeads[index].className = "focus";
+ tabBodys[index].style.display = "block";
+}
+
+function autoHeight( index ) {
+ var iframe = dialog.getDom( "iframe" ),
+ parent = iframe.parentNode.parentNode;
+ switch ( index ) {
+ case 0:
+ iframe.style.height = "380px";
+ parent.style.height = "392px";
+ break;
+ case 1:
+ iframe.style.height = "220px";
+ parent.style.height = "232px";
+ break;
+ case 2:
+ iframe.style.height = "260px";
+ parent.style.height = "272px";
+ break;
+ case 3:
+ iframe.style.height = "300px";
+ parent.style.height = "312px";
+ break;
+ case 4:
+ iframe.style.height = "140px";
+ parent.style.height = "152px";
+ break;
+ case 5:
+ iframe.style.height = "260px";
+ parent.style.height = "272px";
+ break;
+ case 6:
+ iframe.style.height = "230px";
+ parent.style.height = "242px";
+ break;
+ default:
+
+ }
+}
+
+
+function createTab( tabName ) {
+ var faceVersion = "?v=1.1", //版本号
+ tab = $G( tabName ), //获取将要生成的Div句柄
+ imagePath = emotion.SmileyPath + emotion.imageFolders[tabName], //获取显示表情和预览表情的路径
+ positionLine = 11 / 2, //中间数
+ iWidth = iHeight = 35, //图片长宽
+ iColWidth = 3, //表格剩余空间的显示比例
+ tableCss = emotion.imageCss[tabName],
+ cssOffset = emotion.imageCssOffset[tabName],
+ textHTML = [''],
+ i = 0, imgNum = emotion.SmileyBox[tabName].length, imgColNum = 11, faceImage,
+ sUrl, realUrl, posflag, offset, infor;
+
+ for ( ; i < imgNum; ) {
+ textHTML.push( '' );
+ for ( var j = 0; j < imgColNum; j++, i++ ) {
+ faceImage = emotion.SmileyBox[tabName][i];
+ if ( faceImage ) {
+ sUrl = imagePath + faceImage + faceVersion;
+ realUrl = imagePath + faceImage;
+ posflag = j < positionLine ? 0 : 1;
+ offset = cssOffset * i * (-1) - 1;
+ infor = emotion.SmileyInfor[tabName][i];
+
+ textHTML.push( '' );
+ textHTML.push( '' );
+ textHTML.push( '
' );
+ textHTML.push( '' );
+ } else {
+ textHTML.push( ' ' );
+ }
+ textHTML.push( ' ' );
+ }
+ textHTML.push( ' ' );
+ }
+ textHTML.push( '
' );
+ textHTML = textHTML.join( "" );
+ tab.innerHTML = textHTML;
+}
+
+function over( td, srcPath, posFlag ) {
+ td.style.backgroundColor = "#ACCD3C";
+ $G( 'faceReview' ).style.backgroundImage = "url(" + srcPath + ")";
+ if ( posFlag == 1 ) $G( "tabIconReview" ).className = "show";
+ $G( "tabIconReview" ).style.display = 'block';
+}
+
+function out( td ) {
+ td.style.backgroundColor = "transparent";
+ var tabIconRevew = $G( "tabIconReview" );
+ tabIconRevew.className = "";
+ tabIconRevew.style.display = 'none';
+}
+
+function createTabList( tabNum ) {
+ var obj = {};
+ for ( var i = 0; i < tabNum; i++ ) {
+ obj["tab" + i] = [];
+ }
+ return obj;
+}
+
+function createArr( tabNum ) {
+ var arr = [];
+ for ( var i = 0; i < tabNum; i++ ) {
+ arr[i] = 0;
+ }
+ return arr;
+}
+
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/0.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/0.gif
new file mode 100644
index 0000000..6964168
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/0.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/bface.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/bface.gif
new file mode 100644
index 0000000..14fe618
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/bface.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/cface.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/cface.gif
new file mode 100644
index 0000000..bff947f
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/cface.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/fface.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/fface.gif
new file mode 100644
index 0000000..0d8a6af
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/fface.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/jxface2.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/jxface2.gif
new file mode 100644
index 0000000..a959c90
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/jxface2.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/neweditor-tab-bg.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/neweditor-tab-bg.png
new file mode 100644
index 0000000..8f398b0
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/neweditor-tab-bg.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/tface.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/tface.gif
new file mode 100644
index 0000000..1354f54
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/tface.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/wface.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/wface.gif
new file mode 100644
index 0000000..5667160
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/wface.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/yface.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/yface.gif
new file mode 100644
index 0000000..51608be
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/emotion/images/yface.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/gmap/gmap.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/gmap/gmap.html
new file mode 100644
index 0000000..c4cbfe6
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/gmap/gmap.html
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.css b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.css
new file mode 100644
index 0000000..4478475
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.css
@@ -0,0 +1,7 @@
+.wrapper{width: 370px;margin: 10px auto;zoom: 1;}
+.tabbody{height: 360px;}
+.tabbody .panel{width:100%;height: 360px;position: absolute;background: #fff;}
+.tabbody .panel h1{font-size:26px;margin: 5px 0 0 5px;}
+.tabbody .panel p{font-size:12px;margin: 5px 0 0 5px;}
+.tabbody table{width:90%;line-height: 20px;margin: 5px 0 0 5px;;}
+.tabbody table thead{font-weight: bold;line-height: 25px;}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.html
new file mode 100644
index 0000000..9e50060
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.html
@@ -0,0 +1,82 @@
+
+
+
+ 帮助
+
+
+
+
+
+
+
+
+
+
+
+
+ UEditor
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ctrl+b
+
+
+
+ ctrl+c
+
+
+
+ ctrl+x
+
+
+
+ ctrl+v
+
+
+
+ ctrl+y
+
+
+
+ ctrl+z
+
+
+
+ ctrl+i
+
+
+
+ ctrl+u
+
+
+
+ ctrl+a
+
+
+
+ shift+enter
+
+
+
+ alt+z
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.js
new file mode 100644
index 0000000..9a2272e
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/help/help.js
@@ -0,0 +1,56 @@
+/**
+ * Created with JetBrains PhpStorm.
+ * User: xuheng
+ * Date: 12-9-26
+ * Time: 下午1:06
+ * To change this template use File | Settings | File Templates.
+ */
+/**
+ * tab点击处理事件
+ * @param tabHeads
+ * @param tabBodys
+ * @param obj
+ */
+function clickHandler( tabHeads,tabBodys,obj ) {
+ //head样式更改
+ for ( var k = 0, len = tabHeads.length; k < len; k++ ) {
+ tabHeads[k].className = "";
+ }
+ obj.className = "focus";
+ //body显隐
+ var tabSrc = obj.getAttribute( "tabSrc" );
+ for ( var j = 0, length = tabBodys.length; j < length; j++ ) {
+ var body = tabBodys[j],
+ id = body.getAttribute( "id" );
+ body.onclick = function(){
+ this.style.zoom = 1;
+ };
+ if ( id != tabSrc ) {
+ body.style.zIndex = 1;
+ } else {
+ body.style.zIndex = 200;
+ }
+ }
+
+}
+
+/**
+ * TAB切换
+ * @param tabParentId tab的父节点ID或者对象本身
+ */
+function switchTab( tabParentId ) {
+ var tabElements = $G( tabParentId ).children,
+ tabHeads = tabElements[0].children,
+ tabBodys = tabElements[1].children;
+
+ for ( var i = 0, length = tabHeads.length; i < length; i++ ) {
+ var head = tabHeads[i];
+ if ( head.className === "focus" )clickHandler(tabHeads,tabBodys, head );
+ head.onclick = function () {
+ clickHandler(tabHeads,tabBodys,this);
+ }
+ }
+}
+switchTab("helptab");
+
+document.getElementById('version').innerHTML = parent.UE.version;
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.css b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.css
new file mode 100644
index 0000000..52c2295
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.css
@@ -0,0 +1,894 @@
+@charset "utf-8";
+/* dialog样式 */
+.wrapper {
+ zoom: 1;
+ width: 630px;
+ *width: 626px;
+ height: 380px;
+ margin: 0 auto;
+ padding: 10px;
+ position: relative;
+ font-family: sans-serif;
+}
+
+/*tab样式框大小*/
+.tabhead {
+ float:left;
+}
+.tabbody {
+ width: 100%;
+ height: 346px;
+ position: relative;
+ clear: both;
+}
+
+.tabbody .panel {
+ position: absolute;
+ width: 0;
+ height: 0;
+ background: #fff;
+ overflow: hidden;
+ display: none;
+}
+
+.tabbody .panel.focus {
+ width: 100%;
+ height: 346px;
+ display: block;
+}
+
+/* 图片对齐方式 */
+.alignBar{
+ float:right;
+ margin-top: 5px;
+ position: relative;
+}
+
+.alignBar .algnLabel{
+ float:left;
+ height: 20px;
+ line-height: 20px;
+}
+
+.alignBar #alignIcon{
+ zoom:1;
+ _display: inline;
+ display: inline-block;
+ position: relative;
+}
+.alignBar #alignIcon span{
+ float: left;
+ cursor: pointer;
+ display: block;
+ width: 19px;
+ height: 17px;
+ margin-right: 3px;
+ margin-left: 3px;
+ background-image: url(./images/alignicon.jpg);
+}
+.alignBar #alignIcon .none-align{
+ background-position: 0 -18px;
+}
+.alignBar #alignIcon .left-align{
+ background-position: -20px -18px;
+}
+.alignBar #alignIcon .right-align{
+ background-position: -40px -18px;
+}
+.alignBar #alignIcon .center-align{
+ background-position: -60px -18px;
+}
+.alignBar #alignIcon .none-align.focus{
+ background-position: 0 0;
+}
+.alignBar #alignIcon .left-align.focus{
+ background-position: -20px 0;
+}
+.alignBar #alignIcon .right-align.focus{
+ background-position: -40px 0;
+}
+.alignBar #alignIcon .center-align.focus{
+ background-position: -60px 0;
+}
+
+
+
+
+/* 远程图片样式 */
+#remote {
+ z-index: 200;
+}
+
+#remote .top{
+ width: 100%;
+ margin-top: 25px;
+}
+#remote .left{
+ display: block;
+ float: left;
+ width: 300px;
+ height:10px;
+}
+#remote .right{
+ display: block;
+ float: right;
+ width: 300px;
+ height:10px;
+}
+#remote .row{
+ margin-left: 20px;
+ clear: both;
+ height: 40px;
+}
+
+#remote .row label{
+ text-align: center;
+ width: 50px;
+ zoom:1;
+ _display: inline;
+ display:inline-block;
+ vertical-align: middle;
+}
+#remote .row label.algnLabel{
+ float: left;
+
+}
+
+#remote input.text{
+ width: 150px;
+ padding: 3px 6px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+#remote input.text:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+}
+#remote #url{
+ width: 500px;
+ margin-bottom: 2px;
+}
+#remote #width,
+#remote #height{
+ width: 20px;
+ margin-left: 2px;
+ margin-right: 2px;
+}
+#remote #border,
+#remote #vhSpace,
+#remote #title{
+ width: 180px;
+ margin-right: 5px;
+}
+#remote #lock{
+}
+#remote #lockicon{
+ zoom: 1;
+ _display:inline;
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ background: url("../../themes/default/images/lock.gif") -13px -13px no-repeat;
+ vertical-align: middle;
+}
+#remote #preview{
+ clear: both;
+ width: 260px;
+ height: 240px;
+ z-index: 9999;
+ margin-top: 10px;
+ background-color: #eee;
+ overflow: hidden;
+}
+
+/* 上传图片 */
+.tabbody #upload.panel {
+ width: 0;
+ height: 0;
+ overflow: hidden;
+ position: absolute !important;
+ clip: rect(1px, 1px, 1px, 1px);
+ background: #fff;
+ display: block;
+}
+
+.tabbody #upload.panel.focus {
+ width: 100%;
+ height: 346px;
+ display: block;
+ clip: auto;
+}
+
+#upload .queueList {
+ margin: 0;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ overflow: hidden;
+}
+
+#upload p {
+ margin: 0;
+}
+
+.element-invisible {
+ width: 0 !important;
+ height: 0 !important;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ overflow: hidden;
+ position: absolute !important;
+ clip: rect(1px, 1px, 1px, 1px);
+}
+
+#upload .placeholder {
+ margin: 10px;
+ border: 2px dashed #e6e6e6;
+ *border: 0px dashed #e6e6e6;
+ height: 172px;
+ padding-top: 150px;
+ text-align: center;
+ background: url(./images/image.png) center 70px no-repeat;
+ color: #cccccc;
+ font-size: 18px;
+ position: relative;
+ top:0;
+ *top: 10px;
+}
+
+#upload .placeholder .webuploader-pick {
+ font-size: 18px;
+ background: #00b7ee;
+ border-radius: 3px;
+ line-height: 44px;
+ padding: 0 30px;
+ *width: 120px;
+ color: #fff;
+ display: inline-block;
+ margin: 0 auto 20px auto;
+ cursor: pointer;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+}
+
+#upload .placeholder .webuploader-pick-hover {
+ background: #00a2d4;
+}
+
+
+#filePickerContainer {
+ text-align: center;
+}
+
+#upload .placeholder .flashTip {
+ color: #666666;
+ font-size: 12px;
+ position: absolute;
+ width: 100%;
+ text-align: center;
+ bottom: 20px;
+}
+
+#upload .placeholder .flashTip a {
+ color: #0785d1;
+ text-decoration: none;
+}
+
+#upload .placeholder .flashTip a:hover {
+ text-decoration: underline;
+}
+
+#upload .placeholder.webuploader-dnd-over {
+ border-color: #999999;
+}
+
+#upload .filelist {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ overflow-x: hidden;
+ overflow-y: auto;
+ position: relative;
+ height: 300px;
+}
+
+#upload .filelist:after {
+ content: '';
+ display: block;
+ width: 0;
+ height: 0;
+ overflow: hidden;
+ clear: both;
+ position: relative;
+}
+
+#upload .filelist li {
+ width: 113px;
+ height: 113px;
+ background: url(./images/bg.png);
+ text-align: center;
+ margin: 9px 0 0 9px;
+ *margin: 6px 0 0 6px;
+ position: relative;
+ display: block;
+ float: left;
+ overflow: hidden;
+ font-size: 12px;
+}
+
+#upload .filelist li p.log {
+ position: relative;
+ top: -45px;
+}
+
+#upload .filelist li p.title {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ top: 5px;
+ text-indent: 5px;
+ text-align: left;
+}
+
+#upload .filelist li p.progress {
+ position: absolute;
+ width: 100%;
+ bottom: 0;
+ left: 0;
+ height: 8px;
+ overflow: hidden;
+ z-index: 50;
+ margin: 0;
+ border-radius: 0;
+ background: none;
+ -webkit-box-shadow: 0 0 0;
+}
+
+#upload .filelist li p.progress span {
+ display: none;
+ overflow: hidden;
+ width: 0;
+ height: 100%;
+ background: #1483d8 url(./images/progress.png) repeat-x;
+
+ -webit-transition: width 200ms linear;
+ -moz-transition: width 200ms linear;
+ -o-transition: width 200ms linear;
+ -ms-transition: width 200ms linear;
+ transition: width 200ms linear;
+
+ -webkit-animation: progressmove 2s linear infinite;
+ -moz-animation: progressmove 2s linear infinite;
+ -o-animation: progressmove 2s linear infinite;
+ -ms-animation: progressmove 2s linear infinite;
+ animation: progressmove 2s linear infinite;
+
+ -webkit-transform: translateZ(0);
+}
+
+@-webkit-keyframes progressmove {
+ 0% {
+ background-position: 0 0;
+ }
+ 100% {
+ background-position: 17px 0;
+ }
+}
+
+@-moz-keyframes progressmove {
+ 0% {
+ background-position: 0 0;
+ }
+ 100% {
+ background-position: 17px 0;
+ }
+}
+
+@keyframes progressmove {
+ 0% {
+ background-position: 0 0;
+ }
+ 100% {
+ background-position: 17px 0;
+ }
+}
+
+#upload .filelist li p.imgWrap {
+ position: relative;
+ z-index: 2;
+ line-height: 113px;
+ vertical-align: middle;
+ overflow: hidden;
+ width: 113px;
+ height: 113px;
+
+ -webkit-transform-origin: 50% 50%;
+ -moz-transform-origin: 50% 50%;
+ -o-transform-origin: 50% 50%;
+ -ms-transform-origin: 50% 50%;
+ transform-origin: 50% 50%;
+
+ -webit-transition: 200ms ease-out;
+ -moz-transition: 200ms ease-out;
+ -o-transition: 200ms ease-out;
+ -ms-transition: 200ms ease-out;
+ transition: 200ms ease-out;
+}
+
+#upload .filelist li img {
+ width: 100%;
+}
+
+#upload .filelist li p.error {
+ background: #f43838;
+ color: #fff;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ height: 28px;
+ line-height: 28px;
+ width: 100%;
+ z-index: 100;
+ display:none;
+}
+
+#upload .filelist li .success {
+ display: block;
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ height: 40px;
+ width: 100%;
+ z-index: 200;
+ background: url(./images/success.png) no-repeat right bottom;
+ background: url(./images/success.gif) no-repeat right bottom \9;
+}
+
+#upload .filelist li.filePickerBlock {
+ width: 113px;
+ height: 113px;
+ background: url(./images/image.png) no-repeat center 12px;
+ border: 1px solid #eeeeee;
+ border-radius: 0;
+}
+#upload .filelist li.filePickerBlock div.webuploader-pick {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ opacity: 0;
+ background: none;
+ font-size: 0;
+}
+
+#upload .filelist div.file-panel {
+ position: absolute;
+ height: 0;
+ filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \0;
+ background: rgba(0, 0, 0, 0.5);
+ width: 100%;
+ top: 0;
+ left: 0;
+ overflow: hidden;
+ z-index: 300;
+}
+
+#upload .filelist div.file-panel span {
+ width: 24px;
+ height: 24px;
+ display: inline;
+ float: right;
+ text-indent: -9999px;
+ overflow: hidden;
+ background: url(./images/icons.png) no-repeat;
+ background: url(./images/icons.gif) no-repeat \9;
+ margin: 5px 1px 1px;
+ cursor: pointer;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+#upload .filelist div.file-panel span.rotateLeft {
+ display:none;
+ background-position: 0 -24px;
+}
+
+#upload .filelist div.file-panel span.rotateLeft:hover {
+ background-position: 0 0;
+}
+
+#upload .filelist div.file-panel span.rotateRight {
+ display:none;
+ background-position: -24px -24px;
+}
+
+#upload .filelist div.file-panel span.rotateRight:hover {
+ background-position: -24px 0;
+}
+
+#upload .filelist div.file-panel span.cancel {
+ background-position: -48px -24px;
+}
+
+#upload .filelist div.file-panel span.cancel:hover {
+ background-position: -48px 0;
+}
+
+#upload .statusBar {
+ height: 45px;
+ border-bottom: 1px solid #dadada;
+ margin: 0 10px;
+ padding: 0;
+ line-height: 45px;
+ vertical-align: middle;
+ position: relative;
+}
+
+#upload .statusBar .progress {
+ border: 1px solid #1483d8;
+ width: 198px;
+ background: #fff;
+ height: 18px;
+ position: absolute;
+ top: 12px;
+ display: none;
+ text-align: center;
+ line-height: 18px;
+ color: #6dbfff;
+ margin: 0 10px 0 0;
+}
+#upload .statusBar .progress span.percentage {
+ width: 0;
+ height: 100%;
+ left: 0;
+ top: 0;
+ background: #1483d8;
+ position: absolute;
+}
+#upload .statusBar .progress span.text {
+ position: relative;
+ z-index: 10;
+}
+
+#upload .statusBar .info {
+ display: inline-block;
+ font-size: 14px;
+ color: #666666;
+}
+
+#upload .statusBar .btns {
+ position: absolute;
+ top: 7px;
+ right: 0;
+ line-height: 30px;
+}
+
+#filePickerBtn {
+ display: inline-block;
+ float: left;
+}
+#upload .statusBar .btns .webuploader-pick,
+#upload .statusBar .btns .uploadBtn,
+#upload .statusBar .btns .uploadBtn.state-uploading,
+#upload .statusBar .btns .uploadBtn.state-paused {
+ background: #ffffff;
+ border: 1px solid #cfcfcf;
+ color: #565656;
+ padding: 0 18px;
+ display: inline-block;
+ border-radius: 3px;
+ margin-left: 10px;
+ cursor: pointer;
+ font-size: 14px;
+ float: left;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+#upload .statusBar .btns .webuploader-pick-hover,
+#upload .statusBar .btns .uploadBtn:hover,
+#upload .statusBar .btns .uploadBtn.state-uploading:hover,
+#upload .statusBar .btns .uploadBtn.state-paused:hover {
+ background: #f0f0f0;
+}
+
+#upload .statusBar .btns .uploadBtn,
+#upload .statusBar .btns .uploadBtn.state-paused{
+ background: #00b7ee;
+ color: #fff;
+ border-color: transparent;
+}
+#upload .statusBar .btns .uploadBtn:hover,
+#upload .statusBar .btns .uploadBtn.state-paused:hover{
+ background: #00a2d4;
+}
+
+#upload .statusBar .btns .uploadBtn.disabled {
+ pointer-events: none;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ -khtml-opacity: 0.6;
+ opacity: 0.6;
+}
+
+
+
+/* 图片管理样式 */
+#online {
+ width: 100%;
+ height: 336px;
+ padding: 10px 0 0 0;
+}
+#online #imageList{
+ width: 100%;
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ position: relative;
+}
+#online ul {
+ display: block;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+#online li {
+ float: left;
+ display: block;
+ list-style: none;
+ padding: 0;
+ width: 113px;
+ height: 113px;
+ margin: 0 0 9px 9px;
+ *margin: 0 0 6px 6px;
+ background-color: #eee;
+ overflow: hidden;
+ cursor: pointer;
+ position: relative;
+}
+#online li.clearFloat {
+ float: none;
+ clear: both;
+ display: block;
+ width:0;
+ height:0;
+ margin: 0;
+ padding: 0;
+}
+#online li img {
+ cursor: pointer;
+}
+#online li .icon {
+ cursor: pointer;
+ width: 113px;
+ height: 113px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ border: 0;
+ background-repeat: no-repeat;
+}
+#online li .icon:hover {
+ width: 107px;
+ height: 107px;
+ border: 3px solid #1094fa;
+}
+#online li.selected .icon {
+ background-image: url(images/success.png);
+ background-image: url(images/success.gif)\9;
+ background-position: 75px 75px;
+}
+#online li.selected .icon:hover {
+ width: 107px;
+ height: 107px;
+ border: 3px solid #1094fa;
+ background-position: 72px 72px;
+}
+
+
+/* 图片搜索样式 */
+#search .searchBar {
+ width: 100%;
+ height: 30px;
+ margin: 10px 0 5px 0;
+ padding: 0;
+}
+
+#search input.text{
+ width: 150px;
+ padding: 3px 6px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+#search input.text:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+}
+#search input.searchTxt {
+ margin-left:5px;
+ padding-left: 5px;
+ background: #FFF;
+ width: 300px;
+ *width: 260px;
+ height: 21px;
+ line-height: 21px;
+ float: left;
+ dislay: block;
+}
+
+#search .searchType {
+ width: 65px;
+ height: 28px;
+ padding:0;
+ line-height: 28px;
+ border: 1px solid #d7d7d7;
+ border-radius: 0;
+ vertical-align: top;
+ margin-left: 5px;
+ float: left;
+ dislay: block;
+}
+
+#search #searchBtn,
+#search #searchReset {
+ display: inline-block;
+ margin-bottom: 0;
+ margin-right: 5px;
+ padding: 4px 10px;
+ font-weight: 400;
+ text-align: center;
+ vertical-align: middle;
+ cursor: pointer;
+ background-image: none;
+ border: 1px solid transparent;
+ white-space: nowrap;
+ font-size: 14px;
+ border-radius: 4px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ vertical-align: top;
+ float: right;
+}
+
+#search #searchBtn {
+ color: white;
+ border-color: #285e8e;
+ background-color: #3b97d7;
+}
+#search #searchReset {
+ color: #333;
+ border-color: #ccc;
+ background-color: #fff;
+}
+#search #searchBtn:hover {
+ background-color: #3276b1;
+}
+#search #searchReset:hover {
+ background-color: #eee;
+}
+
+#search .msg {
+ margin-left: 5px;
+}
+
+#search .searchList{
+ width: 100%;
+ height: 300px;
+ overflow: hidden;
+ clear: both;
+}
+#search .searchList ul{
+ margin:0;
+ padding:0;
+ list-style:none;
+ clear: both;
+ width: 100%;
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ zoom: 1;
+ position: relative;
+}
+
+#search .searchList li {
+ list-style:none;
+ float: left;
+ display: block;
+ width: 115px;
+ margin: 5px 10px 5px 20px;
+ *margin: 5px 10px 5px 15px;
+ padding:0;
+ font-size: 12px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
+ position: relative;
+ vertical-align: top;
+ text-align: center;
+ overflow: hidden;
+ cursor: pointer;
+ filter: alpha(Opacity=100);
+ -moz-opacity: 1;
+ opacity: 1;
+ border: 2px solid #eee;
+}
+
+#search .searchList li.selected {
+ filter: alpha(Opacity=40);
+ -moz-opacity: 0.4;
+ opacity: 0.4;
+ border: 2px solid #00a0e9;
+}
+
+#search .searchList li p {
+ background-color: #eee;
+ margin: 0;
+ padding: 0;
+ position: relative;
+ width:100%;
+ height:115px;
+ overflow: hidden;
+}
+
+#search .searchList li p img {
+ cursor: pointer;
+ border: 0;
+}
+
+#search .searchList li a {
+ color: #999;
+ border-top: 1px solid #F2F2F2;
+ background: #FAFAFA;
+ text-align: center;
+ display: block;
+ padding: 0 5px;
+ width: 105px;
+ height:32px;
+ line-height:32px;
+ white-space:nowrap;
+ text-overflow:ellipsis;
+ text-decoration: none;
+ overflow: hidden;
+ word-break: break-all;
+}
+
+#search .searchList a:hover {
+ text-decoration: underline;
+ color: #333;
+}
+#search .searchList .clearFloat{
+ clear: both;
+}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.html
new file mode 100644
index 0000000..08ca022
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.html
@@ -0,0 +1,120 @@
+
+
+
+
+ ueditor图片对话框
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ px
+ px
+
+
+
+
+ px
+
+
+
+ px
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.js
new file mode 100644
index 0000000..dee16bb
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/image.js
@@ -0,0 +1,1142 @@
+/**
+ * User: Jinqn
+ * Date: 14-04-08
+ * Time: 下午16:34
+ * 上传图片对话框逻辑代码,包括tab: 远程图片/上传图片/在线图片/搜索图片
+ */
+
+(function () {
+
+ var remoteImage,
+ uploadImage,
+ onlineImage,
+ searchImage;
+
+ window.onload = function () {
+ initTabs();
+ initAlign();
+ initButtons();
+ };
+
+ /* 初始化tab标签 */
+ function initTabs() {
+ var tabs = $G('tabhead').children;
+ for (var i = 0; i < tabs.length; i++) {
+ domUtils.on(tabs[i], "click", function (e) {
+ var target = e.target || e.srcElement;
+ setTabFocus(target.getAttribute('data-content-id'));
+ });
+ }
+
+ var img = editor.selection.getRange().getClosedNode();
+ if (img && img.tagName && img.tagName.toLowerCase() == 'img') {
+ setTabFocus('remote');
+ } else {
+ setTabFocus('upload');
+ }
+ }
+
+ /* 初始化tabbody */
+ function setTabFocus(id) {
+ if(!id) return;
+ var i, bodyId, tabs = $G('tabhead').children;
+ for (i = 0; i < tabs.length; i++) {
+ bodyId = tabs[i].getAttribute('data-content-id');
+ if (bodyId == id) {
+ domUtils.addClass(tabs[i], 'focus');
+ domUtils.addClass($G(bodyId), 'focus');
+ } else {
+ domUtils.removeClasses(tabs[i], 'focus');
+ domUtils.removeClasses($G(bodyId), 'focus');
+ }
+ }
+ switch (id) {
+ case 'remote':
+ remoteImage = remoteImage || new RemoteImage();
+ break;
+ case 'upload':
+ setAlign(editor.getOpt('imageInsertAlign'));
+ uploadImage = uploadImage || new UploadImage('queueList');
+ break;
+ case 'online':
+ setAlign(editor.getOpt('imageManagerInsertAlign'));
+ onlineImage = onlineImage || new OnlineImage('imageList');
+ onlineImage.reset();
+ break;
+ case 'search':
+ setAlign(editor.getOpt('imageManagerInsertAlign'));
+ searchImage = searchImage || new SearchImage();
+ break;
+ }
+ }
+
+ /* 初始化onok事件 */
+ function initButtons() {
+
+ dialog.onok = function () {
+ var remote = false, list = [], id, tabs = $G('tabhead').children;
+ for (var i = 0; i < tabs.length; i++) {
+ if (domUtils.hasClass(tabs[i], 'focus')) {
+ id = tabs[i].getAttribute('data-content-id');
+ break;
+ }
+ }
+
+ switch (id) {
+ case 'remote':
+ list = remoteImage.getInsertList();
+ break;
+ case 'upload':
+ list = uploadImage.getInsertList();
+ var count = uploadImage.getQueueCount();
+ if (count) {
+ $('.info', '#queueList').html('' + '还有2个未上传文件'.replace(/[\d]/, count) + '');
+ return false;
+ }
+ break;
+ case 'online':
+ list = onlineImage.getInsertList();
+ break;
+ case 'search':
+ list = searchImage.getInsertList();
+ remote = true;
+ break;
+ }
+
+ if(list) {
+ editor.execCommand('insertimage', list);
+ remote && editor.fireEvent("catchRemoteImage");
+ }
+ };
+ }
+
+
+ /* 初始化对其方式的点击事件 */
+ function initAlign(){
+ /* 点击align图标 */
+ domUtils.on($G("alignIcon"), 'click', function(e){
+ var target = e.target || e.srcElement;
+ if(target.className && target.className.indexOf('-align') != -1) {
+ setAlign(target.getAttribute('data-align'));
+ }
+ });
+ }
+
+ /* 设置对齐方式 */
+ function setAlign(align){
+ align = align || 'none';
+ var aligns = $G("alignIcon").children;
+ for(i = 0; i < aligns.length; i++){
+ if(aligns[i].getAttribute('data-align') == align) {
+ domUtils.addClass(aligns[i], 'focus');
+ $G("align").value = aligns[i].getAttribute('data-align');
+ } else {
+ domUtils.removeClasses(aligns[i], 'focus');
+ }
+ }
+ }
+ /* 获取对齐方式 */
+ function getAlign(){
+ var align = $G("align").value || 'none';
+ return align == 'none' ? '':align;
+ }
+
+
+ /* 在线图片 */
+ function RemoteImage(target) {
+ this.container = utils.isString(target) ? document.getElementById(target) : target;
+ this.init();
+ }
+ RemoteImage.prototype = {
+ init: function () {
+ this.initContainer();
+ this.initEvents();
+ },
+ initContainer: function () {
+ this.dom = {
+ 'url': $G('url'),
+ 'width': $G('width'),
+ 'height': $G('height'),
+ 'border': $G('border'),
+ 'vhSpace': $G('vhSpace'),
+ 'title': $G('title'),
+ 'align': $G('align')
+ };
+ var img = editor.selection.getRange().getClosedNode();
+ if (img) {
+ this.setImage(img);
+ }
+ },
+ initEvents: function () {
+ var _this = this,
+ locker = $G('lock');
+
+ /* 改变url */
+ domUtils.on($G("url"), 'keyup', updatePreview);
+ domUtils.on($G("border"), 'keyup', updatePreview);
+ domUtils.on($G("title"), 'keyup', updatePreview);
+
+ domUtils.on($G("width"), 'keyup', function(){
+ updatePreview();
+ if(locker.checked) {
+ var proportion =locker.getAttribute('data-proportion');
+ $G('height').value = Math.round(this.value / proportion);
+ } else {
+ _this.updateLocker();
+ }
+ });
+ domUtils.on($G("height"), 'keyup', function(){
+ updatePreview();
+ if(locker.checked) {
+ var proportion =locker.getAttribute('data-proportion');
+ $G('width').value = Math.round(this.value * proportion);
+ } else {
+ _this.updateLocker();
+ }
+ });
+ domUtils.on($G("lock"), 'change', function(){
+ var proportion = parseInt($G("width").value) /parseInt($G("height").value);
+ locker.setAttribute('data-proportion', proportion);
+ });
+
+ function updatePreview(){
+ _this.setPreview();
+ }
+ },
+ updateLocker: function(){
+ var width = $G('width').value,
+ height = $G('height').value,
+ locker = $G('lock');
+ if(width && height && width == parseInt(width) && height == parseInt(height)) {
+ locker.disabled = false;
+ locker.title = '';
+ } else {
+ locker.checked = false;
+ locker.disabled = 'disabled';
+ locker.title = lang.remoteLockError;
+ }
+ },
+ setImage: function(img){
+ /* 不是正常的图片 */
+ if (!img.tagName || img.tagName.toLowerCase() != 'img' && !img.getAttribute("src") || !img.src) return;
+
+ var wordImgFlag = img.getAttribute("word_img"),
+ src = wordImgFlag ? wordImgFlag.replace("&", "&") : (img.getAttribute('_src') || img.getAttribute("src", 2).replace("&", "&")),
+ align = editor.queryCommandValue("imageFloat");
+
+ /* 防止onchange事件循环调用 */
+ if (src !== $G("url").value) $G("url").value = src;
+ if(src) {
+ /* 设置表单内容 */
+ $G("width").value = img.width || '';
+ $G("height").value = img.height || '';
+ $G("border").value = img.getAttribute("border") || '0';
+ $G("vhSpace").value = img.getAttribute("vspace") || '0';
+ $G("title").value = img.title || img.alt || '';
+ setAlign(align);
+ this.setPreview();
+ this.updateLocker();
+ }
+ },
+ getData: function(){
+ var data = {};
+ for(var k in this.dom){
+ data[k] = this.dom[k].value;
+ }
+ return data;
+ },
+ setPreview: function(){
+ var url = $G('url').value,
+ ow = parseInt($G('width').value, 10) || 0,
+ oh = parseInt($G('height').value, 10) || 0,
+ border = parseInt($G('border').value, 10) || 0,
+ title = $G('title').value,
+ preview = $G('preview'),
+ width,
+ height;
+
+ url = utils.unhtmlForUrl(url);
+ title = utils.unhtml(title);
+
+ width = ((!ow || !oh) ? preview.offsetWidth:Math.min(ow, preview.offsetWidth));
+ width = width+(border*2) > preview.offsetWidth ? width:(preview.offsetWidth - (border*2));
+ height = (!ow || !oh) ? '':width*oh/ow;
+
+ if(url) {
+ preview.innerHTML = '
';
+ }
+ },
+ getInsertList: function () {
+ var data = this.getData();
+ if(data['url']) {
+ return [{
+ src: data['url'],
+ _src: data['url'],
+ width: data['width'] || '',
+ height: data['height'] || '',
+ border: data['border'] || '',
+ floatStyle: data['align'] || '',
+ vspace: data['vhSpace'] || '',
+ title: data['title'] || '',
+ alt: data['title'] || '',
+ style: "width:" + data['width'] + "px;height:" + data['height'] + "px;"
+ }];
+ } else {
+ return [];
+ }
+ }
+ };
+
+
+
+ /* 上传图片 */
+ function UploadImage(target) {
+ this.$wrap = target.constructor == String ? $('#' + target) : $(target);
+ this.init();
+ }
+ UploadImage.prototype = {
+ init: function () {
+ this.imageList = [];
+ this.initContainer();
+ this.initUploader();
+ },
+ initContainer: function () {
+ this.$queue = this.$wrap.find('.filelist');
+ },
+ /* 初始化容器 */
+ initUploader: function () {
+ var _this = this,
+ $ = jQuery, // just in case. Make sure it's not an other libaray.
+ $wrap = _this.$wrap,
+ // 图片容器
+ $queue = $wrap.find('.filelist'),
+ // 状态栏,包括进度和控制按钮
+ $statusBar = $wrap.find('.statusBar'),
+ // 文件总体选择信息。
+ $info = $statusBar.find('.info'),
+ // 上传按钮
+ $upload = $wrap.find('.uploadBtn'),
+ // 上传按钮
+ $filePickerBtn = $wrap.find('.filePickerBtn'),
+ // 上传按钮
+ $filePickerBlock = $wrap.find('.filePickerBlock'),
+ // 没选择文件之前的内容。
+ $placeHolder = $wrap.find('.placeholder'),
+ // 总体进度条
+ $progress = $statusBar.find('.progress').hide(),
+ // 添加的文件数量
+ fileCount = 0,
+ // 添加的文件总大小
+ fileSize = 0,
+ // 优化retina, 在retina下这个值是2
+ ratio = window.devicePixelRatio || 1,
+ // 缩略图大小
+ thumbnailWidth = 113 * ratio,
+ thumbnailHeight = 113 * ratio,
+ // 可能有pedding, ready, uploading, confirm, done.
+ state = '',
+ // 所有文件的进度信息,key为file id
+ percentages = {},
+ supportTransition = (function () {
+ var s = document.createElement('p').style,
+ r = 'transition' in s ||
+ 'WebkitTransition' in s ||
+ 'MozTransition' in s ||
+ 'msTransition' in s ||
+ 'OTransition' in s;
+ s = null;
+ return r;
+ })(),
+ // WebUploader实例
+ uploader,
+ actionUrl = editor.getActionUrl(editor.getOpt('imageActionName')),
+ acceptExtensions = (editor.getOpt('imageAllowFiles') || []).join('').replace(/\./g, ',').replace(/^[,]/, ''),
+ imageMaxSize = editor.getOpt('imageMaxSize'),
+ imageCompressBorder = editor.getOpt('imageCompressBorder');
+
+ if (!WebUploader.Uploader.support()) {
+ $('#filePickerReady').after($('').html(lang.errorNotSupport)).hide();
+ return;
+ } else if (!editor.getOpt('imageActionName')) {
+ $('#filePickerReady').after($('').html(lang.errorLoadConfig)).hide();
+ return;
+ }
+
+ uploader = _this.uploader = WebUploader.create({
+ pick: {
+ id: '#filePickerReady',
+ label: lang.uploadSelectFile
+ },
+ accept: {
+ title: 'Images',
+ extensions: acceptExtensions,
+ mimeTypes: 'image/*'
+ },
+ swf: '../../third-party/webuploader/Uploader.swf',
+ server: actionUrl,
+ fileVal: editor.getOpt('imageFieldName'),
+ duplicate: true,
+ fileSingleSizeLimit: imageMaxSize, // 默认 2 M
+ compress: editor.getOpt('imageCompressEnable') ? {
+ width: imageCompressBorder,
+ height: imageCompressBorder,
+ // 图片质量,只有type为`image/jpeg`的时候才有效。
+ quality: 90,
+ // 是否允许放大,如果想要生成小图的时候不失真,此选项应该设置为false.
+ allowMagnify: false,
+ // 是否允许裁剪。
+ crop: false,
+ // 是否保留头部meta信息。
+ preserveHeaders: true
+ }:false
+ });
+ uploader.addButton({
+ id: '#filePickerBlock'
+ });
+ uploader.addButton({
+ id: '#filePickerBtn',
+ label: lang.uploadAddFile
+ });
+
+ setState('pedding');
+
+ // 当有文件添加进来时执行,负责view的创建
+ function addFile(file) {
+ var $li = $('' +
+ '' + file.name + '
' +
+ '' +
+ '
' +
+ ' '),
+
+ $btns = $('' +
+ '' + lang.uploadDelete + '' +
+ '' + lang.uploadTurnRight + '' +
+ '' + lang.uploadTurnLeft + '').appendTo($li),
+ $prgress = $li.find('p.progress span'),
+ $wrap = $li.find('p.imgWrap'),
+ $info = $('').hide().appendTo($li),
+
+ showError = function (code) {
+ switch (code) {
+ case 'exceed_size':
+ text = lang.errorExceedSize;
+ break;
+ case 'interrupt':
+ text = lang.errorInterrupt;
+ break;
+ case 'http':
+ text = lang.errorHttp;
+ break;
+ case 'not_allow_type':
+ text = lang.errorFileType;
+ break;
+ default:
+ text = lang.errorUploadRetry;
+ break;
+ }
+ $info.text(text).show();
+ };
+
+ if (file.getStatus() === 'invalid') {
+ showError(file.statusText);
+ } else {
+ $wrap.text(lang.uploadPreview);
+ if (browser.ie && browser.version <= 7) {
+ $wrap.text(lang.uploadNoPreview);
+ } else {
+ uploader.makeThumb(file, function (error, src) {
+ if (error || !src) {
+ $wrap.text(lang.uploadNoPreview);
+ } else {
+ var $img = $('
');
+ $wrap.empty().append($img);
+ $img.on('error', function () {
+ $wrap.text(lang.uploadNoPreview);
+ });
+ }
+ }, thumbnailWidth, thumbnailHeight);
+ }
+ percentages[ file.id ] = [ file.size, 0 ];
+ file.rotation = 0;
+
+ /* 检查文件格式 */
+ if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) {
+ showError('not_allow_type');
+ uploader.removeFile(file);
+ }
+ }
+
+ file.on('statuschange', function (cur, prev) {
+ if (prev === 'progress') {
+ $prgress.hide().width(0);
+ } else if (prev === 'queued') {
+ $li.off('mouseenter mouseleave');
+ $btns.remove();
+ }
+ // 成功
+ if (cur === 'error' || cur === 'invalid') {
+ showError(file.statusText);
+ percentages[ file.id ][ 1 ] = 1;
+ } else if (cur === 'interrupt') {
+ showError('interrupt');
+ } else if (cur === 'queued') {
+ percentages[ file.id ][ 1 ] = 0;
+ } else if (cur === 'progress') {
+ $info.hide();
+ $prgress.css('display', 'block');
+ } else if (cur === 'complete') {
+ }
+
+ $li.removeClass('state-' + prev).addClass('state-' + cur);
+ });
+
+ $li.on('mouseenter', function () {
+ $btns.stop().animate({height: 30});
+ });
+ $li.on('mouseleave', function () {
+ $btns.stop().animate({height: 0});
+ });
+
+ $btns.on('click', 'span', function () {
+ var index = $(this).index(),
+ deg;
+
+ switch (index) {
+ case 0:
+ uploader.removeFile(file);
+ return;
+ case 1:
+ file.rotation += 90;
+ break;
+ case 2:
+ file.rotation -= 90;
+ break;
+ }
+
+ if (supportTransition) {
+ deg = 'rotate(' + file.rotation + 'deg)';
+ $wrap.css({
+ '-webkit-transform': deg,
+ '-mos-transform': deg,
+ '-o-transform': deg,
+ 'transform': deg
+ });
+ } else {
+ $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');
+ }
+
+ });
+
+ $li.insertBefore($filePickerBlock);
+ }
+
+ // 负责view的销毁
+ function removeFile(file) {
+ var $li = $('#' + file.id);
+ delete percentages[ file.id ];
+ updateTotalProgress();
+ $li.off().find('.file-panel').off().end().remove();
+ }
+
+ function updateTotalProgress() {
+ var loaded = 0,
+ total = 0,
+ spans = $progress.children(),
+ percent;
+
+ $.each(percentages, function (k, v) {
+ total += v[ 0 ];
+ loaded += v[ 0 ] * v[ 1 ];
+ });
+
+ percent = total ? loaded / total : 0;
+
+ spans.eq(0).text(Math.round(percent * 100) + '%');
+ spans.eq(1).css('width', Math.round(percent * 100) + '%');
+ updateStatus();
+ }
+
+ function setState(val, files) {
+
+ if (val != state) {
+
+ var stats = uploader.getStats();
+
+ $upload.removeClass('state-' + state);
+ $upload.addClass('state-' + val);
+
+ switch (val) {
+
+ /* 未选择文件 */
+ case 'pedding':
+ $queue.addClass('element-invisible');
+ $statusBar.addClass('element-invisible');
+ $placeHolder.removeClass('element-invisible');
+ $progress.hide(); $info.hide();
+ uploader.refresh();
+ break;
+
+ /* 可以开始上传 */
+ case 'ready':
+ $placeHolder.addClass('element-invisible');
+ $queue.removeClass('element-invisible');
+ $statusBar.removeClass('element-invisible');
+ $progress.hide(); $info.show();
+ $upload.text(lang.uploadStart);
+ uploader.refresh();
+ break;
+
+ /* 上传中 */
+ case 'uploading':
+ $progress.show(); $info.hide();
+ $upload.text(lang.uploadPause);
+ break;
+
+ /* 暂停上传 */
+ case 'paused':
+ $progress.show(); $info.hide();
+ $upload.text(lang.uploadContinue);
+ break;
+
+ case 'confirm':
+ $progress.show(); $info.hide();
+ $upload.text(lang.uploadStart);
+
+ stats = uploader.getStats();
+ if (stats.successNum && !stats.uploadFailNum) {
+ setState('finish');
+ return;
+ }
+ break;
+
+ case 'finish':
+ $progress.hide(); $info.show();
+ if (stats.uploadFailNum) {
+ $upload.text(lang.uploadRetry);
+ } else {
+ $upload.text(lang.uploadStart);
+ }
+ break;
+ }
+
+ state = val;
+ updateStatus();
+
+ }
+
+ if (!_this.getQueueCount()) {
+ $upload.addClass('disabled')
+ } else {
+ $upload.removeClass('disabled')
+ }
+
+ }
+
+ function updateStatus() {
+ var text = '', stats;
+
+ if (state === 'ready') {
+ text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize));
+ } else if (state === 'confirm') {
+ stats = uploader.getStats();
+ if (stats.uploadFailNum) {
+ text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum);
+ }
+ } else {
+ stats = uploader.getStats();
+ text = lang.updateStatusFinish.replace('_', fileCount).
+ replace('_KB', WebUploader.formatSize(fileSize)).
+ replace('_', stats.successNum);
+
+ if (stats.uploadFailNum) {
+ text += lang.updateStatusError.replace('_', stats.uploadFailNum);
+ }
+ }
+
+ $info.html(text);
+ }
+
+ uploader.on('fileQueued', function (file) {
+ fileCount++;
+ fileSize += file.size;
+
+ if (fileCount === 1) {
+ $placeHolder.addClass('element-invisible');
+ $statusBar.show();
+ }
+
+ addFile(file);
+ });
+
+ uploader.on('fileDequeued', function (file) {
+ fileCount--;
+ fileSize -= file.size;
+
+ removeFile(file);
+ updateTotalProgress();
+ });
+
+ uploader.on('filesQueued', function (file) {
+ if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) {
+ setState('ready');
+ }
+ updateTotalProgress();
+ });
+
+ uploader.on('all', function (type, files) {
+ switch (type) {
+ case 'uploadFinished':
+ setState('confirm', files);
+ break;
+ case 'startUpload':
+ /* 添加额外的GET参数 */
+ var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '',
+ url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params);
+ uploader.option('server', url);
+ setState('uploading', files);
+ break;
+ case 'stopUpload':
+ setState('paused', files);
+ break;
+ }
+ });
+
+ uploader.on('uploadBeforeSend', function (file, data, header) {
+ //这里可以通过data对象添加POST参数
+ header['X_Requested_With'] = 'XMLHttpRequest';
+ });
+
+ uploader.on('uploadProgress', function (file, percentage) {
+ var $li = $('#' + file.id),
+ $percent = $li.find('.progress span');
+
+ $percent.css('width', percentage * 100 + '%');
+ percentages[ file.id ][ 1 ] = percentage;
+ updateTotalProgress();
+ });
+
+ uploader.on('uploadSuccess', function (file, ret) {
+ var $file = $('#' + file.id);
+ try {
+ var responseText = (ret._raw || ret),
+ json = utils.str2json(responseText);
+ if (json.state == 'SUCCESS') {
+ _this.imageList.push(json);
+ $file.append('');
+ } else {
+ $file.find('.error').text(json.state).show();
+ }
+ } catch (e) {
+ $file.find('.error').text(lang.errorServerUpload).show();
+ }
+ });
+
+ uploader.on('uploadError', function (file, code) {
+ });
+ uploader.on('error', function (code, file) {
+ if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') {
+ addFile(file);
+ }
+ });
+ uploader.on('uploadComplete', function (file, ret) {
+ });
+
+ $upload.on('click', function () {
+ if ($(this).hasClass('disabled')) {
+ return false;
+ }
+
+ if (state === 'ready') {
+ uploader.upload();
+ } else if (state === 'paused') {
+ uploader.upload();
+ } else if (state === 'uploading') {
+ uploader.stop();
+ }
+ });
+
+ $upload.addClass('state-' + state);
+ updateTotalProgress();
+ },
+ getQueueCount: function () {
+ var file, i, status, readyFile = 0, files = this.uploader.getFiles();
+ for (i = 0; file = files[i++]; ) {
+ status = file.getStatus();
+ if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++;
+ }
+ return readyFile;
+ },
+ destroy: function () {
+ this.$wrap.remove();
+ },
+ getInsertList: function () {
+ var i, data, list = [],
+ align = getAlign(),
+ prefix = editor.getOpt('imageUrlPrefix');
+ for (i = 0; i < this.imageList.length; i++) {
+ data = this.imageList[i];
+ list.push({
+ src: prefix + data.url,
+ _src: prefix + data.url,
+ title: data.title,
+ alt: data.original,
+ floatStyle: align
+ });
+ }
+ return list;
+ }
+ };
+
+
+ /* 在线图片 */
+ function OnlineImage(target) {
+ this.container = utils.isString(target) ? document.getElementById(target) : target;
+ this.init();
+ }
+ OnlineImage.prototype = {
+ init: function () {
+ this.reset();
+ this.initEvents();
+ },
+ /* 初始化容器 */
+ initContainer: function () {
+ this.container.innerHTML = '';
+ this.list = document.createElement('ul');
+ this.clearFloat = document.createElement('li');
+
+ domUtils.addClass(this.list, 'list');
+ domUtils.addClass(this.clearFloat, 'clearFloat');
+
+ this.list.appendChild(this.clearFloat);
+ this.container.appendChild(this.list);
+ },
+ /* 初始化滚动事件,滚动到地步自动拉取数据 */
+ initEvents: function () {
+ var _this = this;
+
+ /* 滚动拉取图片 */
+ domUtils.on($G('imageList'), 'scroll', function(e){
+ var panel = this;
+ if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) {
+ _this.getImageData();
+ }
+ });
+ /* 选中图片 */
+ domUtils.on(this.container, 'click', function (e) {
+ var target = e.target || e.srcElement,
+ li = target.parentNode;
+
+ if (li.tagName.toLowerCase() == 'li') {
+ if (domUtils.hasClass(li, 'selected')) {
+ domUtils.removeClasses(li, 'selected');
+ } else {
+ domUtils.addClass(li, 'selected');
+ }
+ }
+ });
+ },
+ /* 初始化第一次的数据 */
+ initData: function () {
+
+ /* 拉取数据需要使用的值 */
+ this.state = 0;
+ this.listSize = editor.getOpt('imageManagerListSize');
+ this.listIndex = 0;
+ this.listEnd = false;
+
+ /* 第一次拉取数据 */
+ this.getImageData();
+ },
+ /* 重置界面 */
+ reset: function() {
+ this.initContainer();
+ this.initData();
+ },
+ /* 向后台拉取图片列表数据 */
+ getImageData: function () {
+ var _this = this;
+
+ if(!_this.listEnd && !this.isLoadingData) {
+ this.isLoadingData = true;
+ var url = editor.getActionUrl(editor.getOpt('imageManagerActionName')),
+ isJsonp = utils.isCrossDomainUrl(url);
+ ajax.request(url, {
+ 'timeout': 100000,
+ 'dataType': isJsonp ? 'jsonp':'',
+ 'data': utils.extend({
+ start: this.listIndex,
+ size: this.listSize
+ }, editor.queryCommandValue('serverparam')),
+ 'method': 'get',
+ 'onsuccess': function (r) {
+ try {
+ var json = isJsonp ? r:eval('(' + r.responseText + ')');
+ if (json.state == 'SUCCESS') {
+ _this.pushData(json.list);
+ _this.listIndex = parseInt(json.start) + parseInt(json.list.length);
+ if(_this.listIndex >= json.total) {
+ _this.listEnd = true;
+ }
+ _this.isLoadingData = false;
+ }
+ } catch (e) {
+ if(r.responseText.indexOf('ue_separate_ue') != -1) {
+ var list = r.responseText.split(r.responseText);
+ _this.pushData(list);
+ _this.listIndex = parseInt(list.length);
+ _this.listEnd = true;
+ _this.isLoadingData = false;
+ }
+ }
+ },
+ 'onerror': function () {
+ _this.isLoadingData = false;
+ }
+ });
+ }
+ },
+ /* 添加图片到列表界面上 */
+ pushData: function (list) {
+ var i, item, img, icon, _this = this,
+ urlPrefix = editor.getOpt('imageManagerUrlPrefix');
+ for (i = 0; i < list.length; i++) {
+ if(list[i] && list[i].url) {
+ item = document.createElement('li');
+ img = document.createElement('img');
+ icon = document.createElement('span');
+
+ domUtils.on(img, 'load', (function(image){
+ return function(){
+ _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight);
+ }
+ })(img));
+ img.width = 113;
+ img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) );
+ img.setAttribute('_src', urlPrefix + list[i].url);
+ domUtils.addClass(icon, 'icon');
+
+ item.appendChild(img);
+ item.appendChild(icon);
+ this.list.insertBefore(item, this.clearFloat);
+ }
+ }
+ },
+ /* 改变图片大小 */
+ scale: function (img, w, h, type) {
+ var ow = img.width,
+ oh = img.height;
+
+ if (type == 'justify') {
+ if (ow >= oh) {
+ img.width = w;
+ img.height = h * oh / ow;
+ img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+ } else {
+ img.width = w * ow / oh;
+ img.height = h;
+ img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+ }
+ } else {
+ if (ow >= oh) {
+ img.width = w * ow / oh;
+ img.height = h;
+ img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+ } else {
+ img.width = w;
+ img.height = h * oh / ow;
+ img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+ }
+ }
+ },
+ getInsertList: function () {
+ var i, lis = this.list.children, list = [], align = getAlign();
+ for (i = 0; i < lis.length; i++) {
+ if (domUtils.hasClass(lis[i], 'selected')) {
+ var img = lis[i].firstChild,
+ src = img.getAttribute('_src');
+ list.push({
+ src: src,
+ _src: src,
+ alt: src.substr(src.lastIndexOf('/') + 1),
+ floatStyle: align
+ });
+ }
+
+ }
+ return list;
+ }
+ };
+
+ /*搜索图片 */
+ function SearchImage() {
+ this.init();
+ }
+ SearchImage.prototype = {
+ init: function () {
+ this.initEvents();
+ },
+ initEvents: function(){
+ var _this = this;
+
+ /* 点击搜索按钮 */
+ domUtils.on($G('searchBtn'), 'click', function(){
+ var key = $G('searchTxt').value;
+ if(key && key != lang.searchRemind) {
+ _this.getImageData();
+ }
+ });
+ /* 点击清除妞 */
+ domUtils.on($G('searchReset'), 'click', function(){
+ $G('searchTxt').value = lang.searchRemind;
+ $G('searchListUl').innerHTML = '';
+ $G('searchType').selectedIndex = 0;
+ });
+ /* 搜索框聚焦 */
+ domUtils.on($G('searchTxt'), 'focus', function(){
+ var key = $G('searchTxt').value;
+ if(key && key == lang.searchRemind) {
+ $G('searchTxt').value = '';
+ }
+ });
+ /* 搜索框回车键搜索 */
+ domUtils.on($G('searchTxt'), 'keydown', function(e){
+ var keyCode = e.keyCode || e.which;
+ if (keyCode == 13) {
+ $G('searchBtn').click();
+ }
+ });
+
+ /* 选中图片 */
+ domUtils.on($G('searchList'), 'click', function(e){
+ var target = e.target || e.srcElement,
+ li = target.parentNode.parentNode;
+
+ if (li.tagName.toLowerCase() == 'li') {
+ if (domUtils.hasClass(li, 'selected')) {
+ domUtils.removeClasses(li, 'selected');
+ } else {
+ domUtils.addClass(li, 'selected');
+ }
+ }
+ });
+ },
+ encodeToGb2312:function (str){
+ if(!str) return '';
+ var strOut = "",
+ z = 'D2BBB6A18140C6DF814181428143CDF2D5C9C8FDC9CFCFC2D8A2B2BBD3EB8144D8A4B3F38145D7A8C7D2D8A7CAC08146C7F0B1FBD2B5B4D4B6ABCBBFD8A9814781488149B6AA814AC1BDD1CF814BC9A5D8AD814CB8F6D1BEE3DCD6D0814D814EB7E1814FB4AE8150C1D98151D8BC8152CDE8B5A4CEAAD6F78153C0F6BED9D8AF815481558156C4CB8157BEC38158D8B1C3B4D2E58159D6AECEDAD5A7BAF5B7A6C0D6815AC6B9C5D2C7C7815BB9D4815CB3CBD2D2815D815ED8BFBEC5C6F2D2B2CFB0CFE7815F816081618162CAE981638164D8C081658166816781688169816AC2F2C2D2816BC8E9816C816D816E816F817081718172817381748175C7AC8176817781788179817A817B817CC1CB817DD3E8D5F9817ECAC2B6FED8A1D3DABFF78180D4C6BBA5D8C1CEE5BEAE81818182D8A88183D1C7D0A9818481858186D8BDD9EFCDF6BFBA8187BDBBBAA5D2E0B2FABAE0C4B68188CFEDBEA9CDA4C1C18189818A818BC7D7D9F1818CD9F4818D818E818F8190C8CBD8E9819181928193D2DACAB2C8CAD8ECD8EAD8C6BDF6C6CDB3F08194D8EBBDF1BDE98195C8D4B4D381968197C2D88198B2D6D7D0CACBCBFBD5CCB8B6CFC98199819A819BD9DAD8F0C7AA819CD8EE819DB4FAC1EED2D4819E819FD8ED81A0D2C7D8EFC3C781A181A281A3D1F681A4D6D9D8F281A5D8F5BCFEBCDB81A681A781A8C8CE81A9B7DD81AAB7C281ABC6F381AC81AD81AE81AF81B081B181B2D8F8D2C181B381B4CEE9BCBFB7FCB7A5D0DD81B581B681B781B881B9D6DAD3C5BBEFBBE1D8F181BA81BBC9A1CEB0B4AB81BCD8F381BDC9CBD8F6C2D7D8F781BE81BFCEB1D8F981C081C181C2B2AEB9C081C3D9A381C4B0E981C5C1E681C6C9EC81C7CBC581C8CBC6D9A481C981CA81CB81CC81CDB5E881CE81CFB5AB81D081D181D281D381D481D5CEBBB5CDD7A1D7F4D3D381D6CCE581D7BACE81D8D9A2D9DCD3E0D8FDB7F0D7F7D8FED8FAD9A1C4E381D981DAD3B6D8F4D9DD81DBD8FB81DCC5E581DD81DEC0D081DF81E0D1F0B0DB81E181E2BCD1D9A681E3D9A581E481E581E681E7D9ACD9AE81E8D9ABCAB981E981EA81EBD9A9D6B681EC81ED81EEB3DED9A881EFC0FD81F0CACC81F1D9AA81F2D9A781F381F4D9B081F581F6B6B181F781F881F9B9A981FAD2C081FB81FCCFC081FD81FEC2C28240BDC4D5ECB2E0C7C8BFEBD9AD8241D9AF8242CEEABAEE82438244824582468247C7D682488249824A824B824C824D824E824F8250B1E3825182528253B4D9B6EDD9B48254825582568257BFA182588259825AD9DEC7CEC0FED9B8825B825C825D825E825FCBD7B7FD8260D9B58261D9B7B1A3D3E1D9B98262D0C58263D9B682648265D9B18266D9B2C1A9D9B382678268BCF3D0DEB8A98269BEE3826AD9BD826B826C826D826ED9BA826FB0B3827082718272D9C28273827482758276827782788279827A827B827C827D827E8280D9C4B1B68281D9BF82828283B5B98284BEF3828582868287CCC8BAF2D2D08288D9C38289828ABDE8828BB3AB828C828D828ED9C5BEEB828FD9C6D9BBC4DF8290D9BED9C1D9C0829182928293829482958296829782988299829A829BD5AE829CD6B5829DC7E3829E829F82A082A1D9C882A282A382A4BCD9D9CA82A582A682A7D9BC82A8D9CBC6AB82A982AA82AB82AC82ADD9C982AE82AF82B082B1D7F682B2CDA382B382B482B582B682B782B882B982BABDA182BB82BC82BD82BE82BF82C0D9CC82C182C282C382C482C582C682C782C882C9C5BCCDB582CA82CB82CCD9CD82CD82CED9C7B3A5BFFE82CF82D082D182D2B8B582D382D4C0FC82D582D682D782D8B0F882D982DA82DB82DC82DD82DE82DF82E082E182E282E382E482E582E682E782E882E982EA82EB82EC82EDB4F682EED9CE82EFD9CFB4A2D9D082F082F1B4DF82F282F382F482F582F6B0C182F782F882F982FA82FB82FC82FDD9D1C9B582FE8340834183428343834483458346834783488349834A834B834C834D834E834F83508351CFF1835283538354835583568357D9D283588359835AC1C5835B835C835D835E835F836083618362836383648365D9D6C9AE8366836783688369D9D5D9D4D9D7836A836B836C836DCBDB836EBDA9836F8370837183728373C6A7837483758376837783788379837A837B837C837DD9D3D9D8837E83808381D9D9838283838384838583868387C8E583888389838A838B838C838D838E838F839083918392839383948395C0DC8396839783988399839A839B839C839D839E839F83A083A183A283A383A483A583A683A783A883A983AA83AB83AC83AD83AE83AF83B083B183B2B6F9D8A3D4CA83B3D4AAD0D6B3E4D5D783B4CFC8B9E283B5BFCB83B6C3E283B783B883B9B6D283BA83BBCDC3D9EED9F083BC83BD83BEB5B383BFB6B583C083C183C283C383C4BEA483C583C6C8EB83C783C8C8AB83C983CAB0CBB9ABC1F9D9E283CBC0BCB9B283CCB9D8D0CBB1F8C6E4BEDFB5E4D7C883CDD1F8BCE6CADE83CE83CFBCBDD9E6D8E783D083D1C4DA83D283D3B8D4C8BD83D483D5B2E1D4D983D683D783D883D9C3B083DA83DBC3E1DAA2C8DF83DCD0B483DDBEFCC5A983DE83DF83E0B9DA83E1DAA383E2D4A9DAA483E383E483E583E683E7D9FBB6AC83E883E9B7EBB1F9D9FCB3E5BEF683EABFF6D2B1C0E483EB83EC83EDB6B3D9FED9FD83EE83EFBEBB83F083F183F2C6E083F3D7BCDAA183F4C1B983F5B5F2C1E883F683F7BCF583F8B4D583F983FA83FB83FC83FD83FE844084418442C1DD8443C4FD84448445BCB8B7B284468447B7EF84488449844A844B844C844DD9EC844EC6BE844FBFADBBCB84508451B5CA8452DBC9D0D78453CDB9B0BCB3F6BBF7DBCABAAF8454D4E4B5B6B5F3D8D6C8D084558456B7D6C7D0D8D78457BFAF84588459DBBBD8D8845A845BD0CCBBAE845C845D845EEBBEC1D0C1F5D4F2B8D5B4B4845FB3F584608461C9BE846284638464C5D0846584668467C5D9C0FB8468B1F08469D8D9B9CE846AB5BD846B846CD8DA846D846ED6C6CBA2C8AFC9B2B4CCBFCC846FB9F48470D8DBD8DCB6E7BCC1CCEA847184728473847484758476CFF78477D8DDC7B084788479B9D0BDA3847A847BCCDE847CC6CA847D847E848084818482D8E08483D8DE84848485D8DF848684878488B0FE8489BEE7848ACAA3BCF4848B848C848D848EB8B1848F8490B8EE849184928493849484958496849784988499849AD8E2849BBDCB849CD8E4D8E3849D849E849F84A084A1C5FC84A284A384A484A584A684A784A8D8E584A984AAD8E684AB84AC84AD84AE84AF84B084B1C1A684B2C8B0B0ECB9A6BCD3CEF1DBBDC1D384B384B484B584B6B6AFD6FAC5ACBDD9DBBEDBBF84B784B884B9C0F8BEA2C0CD84BA84BB84BC84BD84BE84BF84C084C184C284C3DBC0CAC684C484C584C6B2AA84C784C884C9D3C284CAC3E384CBD1AB84CC84CD84CE84CFDBC284D0C0D584D184D284D3DBC384D4BFB184D584D684D784D884D984DAC4BC84DB84DC84DD84DEC7DA84DF84E084E184E284E384E484E584E684E784E884E9DBC484EA84EB84EC84ED84EE84EF84F084F1D9E8C9D784F284F384F4B9B4CEF0D4C884F584F684F784F8B0FCB4D284F9D0D984FA84FB84FC84FDD9E984FEDECBD9EB8540854185428543D8B0BBAFB1B18544B3D7D8CE85458546D4D185478548BDB3BFEF8549CFBB854A854BD8D0854C854D854EB7CB854F85508551D8D185528553855485558556855785588559855A855BC6A5C7F8D2BD855C855DD8D2C4E4855ECAAE855FC7A78560D8A68561C9FDCEE7BBDCB0EB856285638564BBAAD0AD8565B1B0D7E4D7BF8566B5A5C2F4C4CF85678568B2A98569B2B7856AB1E5DFB2D5BCBFA8C2ACD8D5C2B1856BD8D4CED4856CDAE0856DCEC0856E856FD8B4C3AED3A1CEA38570BCB4C8B4C2D18571BEEDD0B68572DAE18573857485758576C7E485778578B3A78579B6F2CCFCC0FA857A857BC0F7857CD1B9D1E1D8C7857D857E85808581858285838584B2DE85858586C0E58587BAF185888589D8C8858AD4AD858B858CCFE1D8C9858DD8CACFC3858EB3F8BEC7858F859085918592D8CB8593859485958596859785988599DBCC859A859B859C859DC8A5859E859F85A0CFD885A1C8FEB2CE85A285A385A485A585A6D3D6B2E6BCB0D3D1CBABB7B485A785A885A9B7A285AA85ABCAE585ACC8A1CADCB1E4D0F085ADC5D185AE85AF85B0DBC5B5FE85B185B2BFDAB9C5BEE4C1ED85B3DFB6DFB5D6BBBDD0D5D9B0C8B6A3BFC9CCA8DFB3CAB7D3D285B4D8CFD2B6BAC5CBBECCBE85B5DFB7B5F0DFB485B685B785B8D3F585B9B3D4B8F785BADFBA85BBBACFBCAAB5F585BCCDACC3FBBAF3C0F4CDC2CFF2DFB8CFC585BDC2C0DFB9C2F085BE85BF85C0BEFD85C1C1DFCDCCD2F7B7CDDFC185C2DFC485C385C4B7F1B0C9B6D6B7D485C5BAACCCFDBFD4CBB1C6F485C6D6A8DFC585C7CEE2B3B385C885C9CEFCB4B585CACEC7BAF085CBCEE185CCD1BD85CD85CEDFC085CF85D0B4F485D1B3CA85D2B8E6DFBB85D385D485D585D6C4C585D7DFBCDFBDDFBEC5BBDFBFDFC2D4B1DFC385D8C7BACED885D985DA85DB85DC85DDC4D885DEDFCA85DFDFCF85E0D6DC85E185E285E385E485E585E685E785E8DFC9DFDACEB685E9BAC7DFCEDFC8C5DE85EA85EBC9EBBAF4C3FC85EC85EDBED785EEDFC685EFDFCD85F0C5D885F185F285F385F4D5A6BACD85F5BECCD3BDB8C085F6D6E485F7DFC7B9BEBFA785F885F9C1FCDFCBDFCC85FADFD085FB85FC85FD85FE8640DFDBDFE58641DFD7DFD6D7C9DFE3DFE4E5EBD2A7DFD28642BFA98643D4DB8644BFC8DFD4864586468647CFCC86488649DFDD864AD1CA864BDFDEB0A7C6B7DFD3864CBAE5864DB6DFCDDBB9FED4D5864E864FDFDFCFECB0A5DFE7DFD1D1C6DFD5DFD8DFD9DFDC8650BBA98651DFE0DFE18652DFE2DFE6DFE8D3B486538654865586568657B8E7C5B6DFEAC9DAC1A8C4C486588659BFDECFF8865A865B865CD5DCDFEE865D865E865F866086618662B2B88663BADFDFEC8664DBC18665D1E48666866786688669CBF4B4BD866AB0A6866B866C866D866E866FDFF1CCC6DFF286708671DFED867286738674867586768677DFE986788679867A867BDFEB867CDFEFDFF0BBBD867D867EDFF386808681DFF48682BBA38683CADBCEA8E0A7B3AA8684E0A6868586868687E0A186888689868A868BDFFE868CCDD9DFFC868DDFFA868EBFD0D7C4868FC9CC86908691DFF8B0A186928693869486958696DFFD869786988699869ADFFBE0A2869B869C869D869E869FE0A886A086A186A286A3B7C886A486A5C6A1C9B6C0B2DFF586A686A7C5BE86A8D8C4DFF9C4F686A986AA86AB86AC86AD86AEE0A3E0A4E0A5D0A586AF86B0E0B4CCE486B1E0B186B2BFA6E0AFCEB9E0ABC9C686B386B4C0AEE0AEBAEDBAB0E0A986B586B686B7DFF686B8E0B386B986BAE0B886BB86BC86BDB4ADE0B986BE86BFCFB2BAC886C0E0B086C186C286C386C486C586C686C7D0FA86C886C986CA86CB86CC86CD86CE86CF86D0E0AC86D1D4FB86D2DFF786D3C5E786D4E0AD86D5D3F786D6E0B6E0B786D786D886D986DA86DBE0C4D0E186DC86DD86DEE0BC86DF86E0E0C9E0CA86E186E286E3E0BEE0AAC9A4E0C186E4E0B286E586E686E786E886E9CAC8E0C386EAE0B586EBCECB86ECCBC3E0CDE0C6E0C286EDE0CB86EEE0BAE0BFE0C086EF86F0E0C586F186F2E0C7E0C886F3E0CC86F4E0BB86F586F686F786F886F9CBD4E0D586FAE0D6E0D286FB86FC86FD86FE87408741E0D0BCCE87428743E0D18744B8C2D8C587458746874787488749874A874B874CD0EA874D874EC2EF874F8750E0CFE0BD875187528753E0D4E0D387548755E0D78756875787588759E0DCE0D8875A875B875CD6F6B3B0875DD7EC875ECBBB875F8760E0DA8761CEFB876287638764BAD987658766876787688769876A876B876C876D876E876F8770E0E1E0DDD2AD87718772877387748775E0E287768777E0DBE0D9E0DF87788779E0E0877A877B877C877D877EE0DE8780E0E4878187828783C6F7D8ACD4EBE0E6CAC98784878587868787E0E587888789878A878BB8C1878C878D878E878FE0E7E0E887908791879287938794879587968797E0E9E0E387988799879A879B879C879D879EBABFCCE7879F87A087A1E0EA87A287A387A487A587A687A787A887A987AA87AB87AC87AD87AE87AF87B0CFF987B187B287B387B487B587B687B787B887B987BA87BBE0EB87BC87BD87BE87BF87C087C187C2C8C287C387C487C587C6BDC087C787C887C987CA87CB87CC87CD87CE87CF87D087D187D287D3C4D287D487D587D687D787D887D987DA87DB87DCE0EC87DD87DEE0ED87DF87E0C7F4CBC487E1E0EEBBD8D8B6D2F2E0EFCDC587E2B6DA87E387E487E587E687E787E8E0F187E9D4B087EA87EBC0A7B4D187EC87EDCEA7E0F087EE87EF87F0E0F2B9CC87F187F2B9FACDBCE0F387F387F487F5C6D4E0F487F6D4B287F7C8A6E0F6E0F587F887F987FA87FB87FC87FD87FE8840884188428843884488458846884788488849E0F7884A884BCDC1884C884D884ECAA5884F885088518852D4DADBD7DBD98853DBD8B9E7DBDCDBDDB5D888548855DBDA8856885788588859885ADBDBB3A1DBDF885B885CBBF8885DD6B7885EDBE0885F886088618862BEF988638864B7BB8865DBD0CCAEBFB2BBB5D7F8BFD38866886788688869886ABFE9886B886CBCE1CCB3DBDEB0D3CEEBB7D8D7B9C6C2886D886EC0A4886FCCB98870DBE7DBE1C6BADBE38871DBE88872C5F7887388748875DBEA88768877DBE9BFC088788879887ADBE6DBE5887B887C887D887E8880B4B9C0ACC2A2DBE2DBE48881888288838884D0CDDBED88858886888788888889C0DDDBF2888A888B888C888D888E888F8890B6E28891889288938894DBF3DBD2B9B8D4ABDBEC8895BFD1DBF08896DBD18897B5E68898DBEBBFE58899889A889BDBEE889CDBF1889D889E889FDBF988A088A188A288A388A488A588A688A788A8B9A1B0A388A988AA88AB88AC88AD88AE88AFC2F188B088B1B3C7DBEF88B288B3DBF888B4C6D2DBF488B588B6DBF5DBF7DBF688B788B8DBFE88B9D3F2B2BA88BA88BB88BCDBFD88BD88BE88BF88C088C188C288C388C4DCA488C5DBFB88C688C788C888C9DBFA88CA88CB88CCDBFCC5E0BBF988CD88CEDCA388CF88D0DCA588D1CCC388D288D388D4B6D1DDC088D588D688D7DCA188D8DCA288D988DA88DBC7B588DC88DD88DEB6E988DF88E088E1DCA788E288E388E488E5DCA688E6DCA9B1A488E788E8B5CC88E988EA88EB88EC88EDBFB088EE88EF88F088F188F2D1DF88F388F488F588F6B6C288F788F888F988FA88FB88FC88FD88FE894089418942894389448945DCA88946894789488949894A894B894CCBFAEBF3894D894E894FCBDC89508951CBFE895289538954CCC189558956895789588959C8FB895A895B895C895D895E895FDCAA89608961896289638964CCEEDCAB89658966896789688969896A896B896C896D896E896F897089718972897389748975DBD38976DCAFDCAC8977BEB38978CAFB8979897A897BDCAD897C897D897E89808981898289838984C9CAC4B989858986898789888989C7BDDCAE898A898B898CD4F6D0E6898D898E898F89908991899289938994C4ABB6D589958996899789988999899A899B899C899D899E899F89A089A189A289A389A489A589A6DBD489A789A889A989AAB1DA89AB89AC89ADDBD589AE89AF89B089B189B289B389B489B589B689B789B8DBD689B989BA89BBBABE89BC89BD89BE89BF89C089C189C289C389C489C589C689C789C889C9C8C089CA89CB89CC89CD89CE89CFCABFC8C989D0D7B389D1C9F989D289D3BFC789D489D5BAF889D689D7D2BC89D889D989DA89DB89DC89DD89DE89DFE2BA89E0B4A689E189E2B1B889E389E489E589E689E7B8B489E8CFC489E989EA89EB89ECD9E7CFA6CDE289ED89EED9EDB6E089EFD2B989F089F1B9BB89F289F389F489F5E2B9E2B789F6B4F389F7CCECCCABB7F289F8D8B2D1EBBABB89F9CAA789FA89FBCDB789FC89FDD2C4BFE4BCD0B6E189FEDEC58A408A418A428A43DEC6DBBC8A44D1D98A458A46C6E6C4CEB7EE8A47B7DC8A488A49BFFCD7E08A4AC6F58A4B8A4CB1BCDEC8BDB1CCD7DECA8A4DDEC98A4E8A4F8A508A518A52B5EC8A53C9DD8A548A55B0C28A568A578A588A598A5A8A5B8A5C8A5D8A5E8A5F8A608A618A62C5AEC5AB8A63C4CC8A64BCE9CBFD8A658A668A67BAC38A688A698A6AE5F9C8E7E5FACDFD8A6BD7B1B8BEC2E88A6CC8D18A6D8A6EE5FB8A6F8A708A718A72B6CABCCB8A738A74D1FDE6A18A75C3EE8A768A778A788A79E6A48A7A8A7B8A7C8A7DE5FEE6A5CDD78A7E8A80B7C1E5FCE5FDE6A38A818A82C4DDE6A88A838A84E6A78A858A868A878A888A898A8AC3C38A8BC6DE8A8C8A8DE6AA8A8E8A8F8A908A918A928A938A94C4B78A958A968A97E6A2CABC8A988A998A9A8A9BBDE3B9C3E6A6D0D5CEAF8A9C8A9DE6A9E6B08A9ED2A68A9FBDAAE6AD8AA08AA18AA28AA38AA4E6AF8AA5C0D18AA68AA7D2CC8AA88AA98AAABCA78AAB8AAC8AAD8AAE8AAF8AB08AB18AB28AB38AB48AB58AB6E6B18AB7D2F68AB88AB98ABAD7CB8ABBCDFE8ABCCDDEC2A6E6ABE6ACBDBFE6AEE6B38ABD8ABEE6B28ABF8AC08AC18AC2E6B68AC3E6B88AC48AC58AC68AC7C4EF8AC88AC98ACAC4C88ACB8ACCBEEAC9EF8ACD8ACEE6B78ACFB6F08AD08AD18AD2C3E48AD38AD48AD58AD68AD78AD88AD9D3E9E6B48ADAE6B58ADBC8A28ADC8ADD8ADE8ADF8AE0E6BD8AE18AE28AE3E6B98AE48AE58AE68AE78AE8C6C58AE98AEACDF1E6BB8AEB8AEC8AED8AEE8AEF8AF08AF18AF28AF38AF4E6BC8AF58AF68AF78AF8BBE98AF98AFA8AFB8AFC8AFD8AFE8B40E6BE8B418B428B438B44E6BA8B458B46C0B78B478B488B498B4A8B4B8B4C8B4D8B4E8B4FD3A4E6BFC9F4E6C38B508B51E6C48B528B538B548B55D0F68B568B578B588B598B5A8B5B8B5C8B5D8B5E8B5F8B608B618B628B638B648B658B668B67C3BD8B688B698B6A8B6B8B6C8B6D8B6EC3C4E6C28B6F8B708B718B728B738B748B758B768B778B788B798B7A8B7B8B7CE6C18B7D8B7E8B808B818B828B838B84E6C7CFB18B85EBF48B868B87E6CA8B888B898B8A8B8B8B8CE6C58B8D8B8EBCDEC9A98B8F8B908B918B928B938B94BCB58B958B96CFD38B978B988B998B9A8B9BE6C88B9CE6C98B9DE6CE8B9EE6D08B9F8BA08BA1E6D18BA28BA38BA4E6CBB5D58BA5E6CC8BA68BA7E6CF8BA88BA9C4DB8BAAE6C68BAB8BAC8BAD8BAE8BAFE6CD8BB08BB18BB28BB38BB48BB58BB68BB78BB88BB98BBA8BBB8BBC8BBD8BBE8BBF8BC08BC18BC28BC38BC48BC58BC6E6D28BC78BC88BC98BCA8BCB8BCC8BCD8BCE8BCF8BD08BD18BD2E6D4E6D38BD38BD48BD58BD68BD78BD88BD98BDA8BDB8BDC8BDD8BDE8BDF8BE08BE18BE28BE38BE48BE58BE68BE78BE88BE98BEA8BEB8BECE6D58BEDD9F88BEE8BEFE6D68BF08BF18BF28BF38BF48BF58BF68BF7E6D78BF88BF98BFA8BFB8BFC8BFD8BFE8C408C418C428C438C448C458C468C47D7D3E6DD8C48E6DEBFD7D4D08C49D7D6B4E6CBEFE6DAD8C3D7CED0A28C4AC3CF8C4B8C4CE6DFBCBEB9C2E6DBD1A78C4D8C4EBAA2C2CF8C4FD8AB8C508C518C52CAEBE5EE8C53E6DC8C54B7F58C558C568C578C58C8E68C598C5AC4F58C5B8C5CE5B2C4FE8C5DCBFCE5B3D5AC8C5ED3EECAD8B0B28C5FCBCECDEA8C608C61BAEA8C628C638C64E5B58C65E5B48C66D7DAB9D9D6E6B6A8CDF0D2CBB1A6CAB58C67B3E8C9F3BFCDD0FBCAD2E5B6BBC28C688C698C6ACFDCB9AC8C6B8C6C8C6D8C6ED4D78C6F8C70BAA6D1E7CFFCBCD28C71E5B7C8DD8C728C738C74BFEDB1F6CBDE8C758C76BCC58C77BCC4D2FAC3DCBFDC8C788C798C7A8C7BB8BB8C7C8C7D8C7EC3C28C80BAAED4A28C818C828C838C848C858C868C878C888C89C7DEC4AFB2EC8C8AB9D18C8B8C8CE5BBC1C88C8D8C8ED5AF8C8F8C908C918C928C93E5BC8C94E5BE8C958C968C978C988C998C9A8C9BB4E7B6D4CBC2D1B0B5BC8C9C8C9DCAD98C9EB7E28C9F8CA0C9E48CA1BDAB8CA28CA3CEBED7F08CA48CA58CA68CA7D0A18CA8C9D98CA98CAAB6FBE6D8BCE28CABB3BE8CACC9D08CADE6D9B3A28CAE8CAF8CB08CB1DECC8CB2D3C8DECD8CB3D2A28CB48CB58CB68CB7DECE8CB88CB98CBA8CBBBECD8CBC8CBDDECF8CBE8CBF8CC0CAACD2FCB3DFE5EAC4E1BEA1CEB2C4F2BED6C6A8B2E38CC18CC2BED38CC38CC4C7FCCCEBBDECCEDD8CC58CC6CABAC6C1E5ECD0BC8CC78CC88CC9D5B98CCA8CCB8CCCE5ED8CCD8CCE8CCF8CD0CAF48CD1CDC0C2C58CD2E5EF8CD3C2C4E5F08CD48CD58CD68CD78CD88CD98CDAE5F8CDCD8CDBC9BD8CDC8CDD8CDE8CDF8CE08CE18CE2D2D9E1A88CE38CE48CE58CE6D3EC8CE7CBEAC6F18CE88CE98CEA8CEB8CECE1AC8CED8CEE8CEFE1A7E1A98CF08CF1E1AAE1AF8CF28CF3B2ED8CF4E1ABB8DAE1ADE1AEE1B0B5BAE1B18CF58CF68CF78CF88CF9E1B3E1B88CFA8CFB8CFC8CFD8CFED1D28D40E1B6E1B5C1EB8D418D428D43E1B78D44D4C08D45E1B28D46E1BAB0B68D478D488D498D4AE1B48D4BBFF98D4CE1B98D4D8D4EE1BB8D4F8D508D518D528D538D54E1BE8D558D568D578D588D598D5AE1BC8D5B8D5C8D5D8D5E8D5F8D60D6C58D618D628D638D648D658D668D67CFBF8D688D69E1BDE1BFC2CD8D6AB6EB8D6BD3F88D6C8D6DC7CD8D6E8D6FB7E58D708D718D728D738D748D758D768D778D788D79BEFE8D7A8D7B8D7C8D7D8D7E8D80E1C0E1C18D818D82E1C7B3E78D838D848D858D868D878D88C6E98D898D8A8D8B8D8C8D8DB4DE8D8ED1C28D8F8D908D918D92E1C88D938D94E1C68D958D968D978D988D99E1C58D9AE1C3E1C28D9BB1C08D9C8D9D8D9ED5B8E1C48D9F8DA08DA18DA28DA3E1CB8DA48DA58DA68DA78DA88DA98DAA8DABE1CCE1CA8DAC8DAD8DAE8DAF8DB08DB18DB28DB3EFFA8DB48DB5E1D3E1D2C7B68DB68DB78DB88DB98DBA8DBB8DBC8DBD8DBE8DBF8DC0E1C98DC18DC2E1CE8DC3E1D08DC48DC58DC68DC78DC88DC98DCA8DCB8DCC8DCD8DCEE1D48DCFE1D1E1CD8DD08DD1E1CF8DD28DD38DD48DD5E1D58DD68DD78DD88DD98DDA8DDB8DDC8DDD8DDE8DDF8DE08DE18DE2E1D68DE38DE48DE58DE68DE78DE88DE98DEA8DEB8DEC8DED8DEE8DEF8DF08DF18DF28DF38DF48DF58DF68DF78DF8E1D78DF98DFA8DFBE1D88DFC8DFD8DFE8E408E418E428E438E448E458E468E478E488E498E4A8E4B8E4C8E4D8E4E8E4F8E508E518E528E538E548E55E1DA8E568E578E588E598E5A8E5B8E5C8E5D8E5E8E5F8E608E618E62E1DB8E638E648E658E668E678E688E69CEA18E6A8E6B8E6C8E6D8E6E8E6F8E708E718E728E738E748E758E76E7DD8E77B4A8D6DD8E788E79D1B2B3B28E7A8E7BB9A4D7F3C7C9BEDEB9AE8E7CCED78E7D8E7EB2EEDBCF8E80BCBAD2D1CBC8B0CD8E818E82CFEF8E838E848E858E868E87D9E3BDED8E888E89B1D2CAD0B2BC8E8ACBA7B7AB8E8BCAA68E8C8E8D8E8ECFA38E8F8E90E0F8D5CAE0FB8E918E92E0FAC5C1CCFB8E93C1B1E0F9D6E3B2AFD6C4B5DB8E948E958E968E978E988E998E9A8E9BB4F8D6A18E9C8E9D8E9E8E9F8EA0CFAFB0EF8EA18EA2E0FC8EA38EA48EA58EA68EA7E1A1B3A38EA88EA9E0FDE0FEC3B18EAA8EAB8EAC8EADC3DD8EAEE1A2B7F98EAF8EB08EB18EB28EB38EB4BBCF8EB58EB68EB78EB88EB98EBA8EBBE1A3C4BB8EBC8EBD8EBE8EBF8EC0E1A48EC18EC2E1A58EC38EC4E1A6B4B18EC58EC68EC78EC88EC98ECA8ECB8ECC8ECD8ECE8ECF8ED08ED18ED28ED3B8C9C6BDC4EA8ED4B2A28ED5D0D28ED6E7DBBBC3D3D7D3C48ED7B9E3E2CF8ED88ED98EDAD7AF8EDBC7ECB1D38EDC8EDDB4B2E2D18EDE8EDF8EE0D0F2C2AEE2D08EE1BFE2D3A6B5D7E2D2B5EA8EE2C3EDB8FD8EE3B8AE8EE4C5D3B7CFE2D48EE58EE68EE78EE8E2D3B6C8D7F98EE98EEA8EEB8EEC8EEDCDA58EEE8EEF8EF08EF18EF2E2D88EF3E2D6CAFCBFB5D3B9E2D58EF48EF58EF68EF7E2D78EF88EF98EFA8EFB8EFC8EFD8EFE8F408F418F42C1AEC0C88F438F448F458F468F478F48E2DBE2DAC0AA8F498F4AC1CE8F4B8F4C8F4D8F4EE2DC8F4F8F508F518F528F538F548F558F568F578F588F598F5AE2DD8F5BE2DE8F5C8F5D8F5E8F5F8F608F618F628F638F64DBC88F65D1D3CDA28F668F67BDA88F688F698F6ADEC3D8A5BFAADBCDD2ECC6FAC5AA8F6B8F6C8F6DDEC48F6EB1D7DFAE8F6F8F708F71CABD8F72DFB18F73B9AD8F74D2FD8F75B8A5BAEB8F768F77B3DA8F788F798F7AB5DCD5C58F7B8F7C8F7D8F7EC3D6CFD2BBA18F80E5F3E5F28F818F82E5F48F83CDE48F84C8F58F858F868F878F888F898F8A8F8BB5AFC7BF8F8CE5F68F8D8F8E8F8FECB08F908F918F928F938F948F958F968F978F988F998F9A8F9B8F9C8F9D8F9EE5E68F9FB9E9B5B18FA0C2BCE5E8E5E7E5E98FA18FA28FA38FA4D2CD8FA58FA68FA7E1EAD0CE8FA8CDAE8FA9D1E58FAA8FABB2CAB1EB8FACB1F2C5ED8FAD8FAED5C3D3B08FAFE1DC8FB08FB18FB2E1DD8FB3D2DB8FB4B3B9B1CB8FB58FB68FB7CDF9D5F7E1DE8FB8BEB6B4FD8FB9E1DFBADCE1E0BBB2C2C9E1E18FBA8FBB8FBCD0EC8FBDCDBD8FBE8FBFE1E28FC0B5C3C5C7E1E38FC18FC2E1E48FC38FC48FC58FC6D3F98FC78FC88FC98FCA8FCB8FCCE1E58FCDD1AD8FCE8FCFE1E6CEA28FD08FD18FD28FD38FD48FD5E1E78FD6B5C28FD78FD88FD98FDAE1E8BBD58FDB8FDC8FDD8FDE8FDFD0C4E2E0B1D8D2E48FE08FE1E2E18FE28FE3BCC9C8CC8FE4E2E3ECFEECFDDFAF8FE58FE68FE7E2E2D6BECDFCC3A68FE88FE98FEAE3C38FEB8FECD6D2E2E78FED8FEEE2E88FEF8FF0D3C78FF18FF2E2ECBFEC8FF3E2EDE2E58FF48FF5B3C08FF68FF78FF8C4EE8FF98FFAE2EE8FFB8FFCD0C38FFDBAF6E2E9B7DEBBB3CCACCBCBE2E4E2E6E2EAE2EB8FFE90409041E2F790429043E2F4D4F5E2F390449045C5AD9046D5FAC5C2B2C090479048E2EF9049E2F2C1AFCBBC904A904BB5A1E2F9904C904D904EBCB1E2F1D0D4D4B9E2F5B9D6E2F6904F90509051C7D390529053905490559056E2F0905790589059905A905BD7DCEDA1905C905DE2F8905EEDA5E2FECAD1905F906090619062906390649065C1B59066BBD090679068BFD69069BAE3906A906BCBA1906C906D906EEDA6EDA3906F9070EDA29071907290739074BBD6EDA7D0F490759076EDA4BADEB6F7E3A1B6B2CCF1B9A79077CFA2C7A190789079BFD2907A907BB6F1907CE2FAE2FBE2FDE2FCC4D5E3A2907DD3C1907E90809081E3A7C7C49082908390849085CFA490869087E3A9BAB790889089908A908BE3A8908CBBDA908DE3A3908E908F9090E3A4E3AA9091E3A69092CEF2D3C690939094BBBC90959096D4C39097C4FA90989099EDA8D0FCE3A5909AC3F5909BE3ADB1AF909CE3B2909D909E909FBCC290A090A1E3ACB5BF90A290A390A490A590A690A790A890A9C7E9E3B090AA90AB90ACBEAACDEF90AD90AE90AF90B090B1BBF390B290B390B4CCE890B590B6E3AF90B7E3B190B8CFA7E3AE90B9CEA9BBDD90BA90BB90BC90BD90BEB5EBBEE5B2D2B3CD90BFB1B9E3ABB2D1B5ACB9DFB6E890C090C1CFEBE3B790C2BBCC90C390C4C8C7D0CA90C590C690C790C890C9E3B8B3EE90CA90CB90CC90CDEDA990CED3FAD3E490CF90D090D1EDAAE3B9D2E290D290D390D490D590D6E3B590D790D890D990DAD3DE90DB90DC90DD90DEB8D0E3B390DF90E0E3B6B7DF90E1E3B4C0A290E290E390E4E3BA90E590E690E790E890E990EA90EB90EC90ED90EE90EF90F090F190F290F390F490F590F690F7D4B890F890F990FA90FB90FC90FD90FE9140B4C89141E3BB9142BBC59143C9F791449145C9E5914691479148C4BD9149914A914B914C914D914E914FEDAB9150915191529153C2FD9154915591569157BBDBBFAE91589159915A915B915C915D915ECEBF915F916091619162E3BC9163BFB6916491659166916791689169916A916B916C916D916E916F9170917191729173917491759176B1EF91779178D4F79179917A917B917C917DE3BE917E9180918191829183918491859186EDAD918791889189918A918B918C918D918E918FE3BFBAA9EDAC91909191E3BD91929193919491959196919791989199919A919BE3C0919C919D919E919F91A091A1BAB691A291A391A4B6AE91A591A691A791A891A9D0B891AAB0C3EDAE91AB91AC91AD91AE91AFEDAFC0C191B0E3C191B191B291B391B491B591B691B791B891B991BA91BB91BC91BD91BE91BF91C091C1C5B391C291C391C491C591C691C791C891C991CA91CB91CC91CD91CE91CFE3C291D091D191D291D391D491D591D691D791D8DCB291D991DA91DB91DC91DD91DEEDB091DFB8EA91E0CEECEAA7D0E7CAF9C8D6CFB7B3C9CED2BDE491E191E2E3DEBBF2EAA8D5BD91E3C6DDEAA991E491E591E6EAAA91E7EAACEAAB91E8EAAEEAAD91E991EA91EB91ECBDD891EDEAAF91EEC2BE91EF91F091F191F2B4C1B4F791F391F4BBA791F591F691F791F891F9ECE6ECE5B7BFCBF9B1E291FAECE791FB91FC91FDC9C8ECE8ECE991FECAD6DED0B2C5D4FA92409241C6CBB0C7B4F2C8D3924292439244CDD092459246BFB8924792489249924A924B924C924DBFDB924E924FC7A4D6B49250C0A9DED1C9A8D1EFC5A4B0E7B3B6C8C592519252B0E292539254B7F692559256C5FA92579258B6F39259D5D2B3D0BCBC925A925B925CB3AD925D925E925F9260BEF1B0D1926192629263926492659266D2D6CAE3D7A59267CDB6B6B6BFB9D5DB9268B8A7C5D79269926A926BDED2BFD9C2D5C7C0926CBBA4B1A8926D926EC5EA926F9270C5FBCCA79271927292739274B1A7927592769277B5D692789279927AC4A8927BDED3D1BAB3E9927CC3F2927D927EB7F79280D6F4B5A3B2F0C4B4C4E9C0ADDED49281B0E8C5C4C1E09282B9D59283BEDCCDD8B0CE9284CDCFDED6BED0D7BEDED5D5D0B0DD92859286C4E292879288C2A3BCF09289D3B5C0B9C5A1B2A6D4F1928A928BC0A8CAC3DED7D5FC928CB9B0928DC8ADCBA9928EDED9BFBD928F929092919292C6B4D7A7CAB0C4C39293B3D6B9D29294929592969297D6B8EAFCB0B492989299929A929BBFE6929C929DCCF4929E929F92A092A1CDDA92A292A392A4D6BFC2CE92A5CECECCA2D0AEC4D3B5B2DED8D5F5BCB7BBD392A692A7B0A492A8C5B2B4EC92A992AA92ABD5F192AC92ADEAFD92AE92AF92B092B192B292B3DEDACDA692B492B5CDEC92B692B792B892B9CEE6DEDC92BACDB1C0A692BB92BCD7BD92BDDEDBB0C6BAB4C9D3C4F3BEE892BE92BF92C092C1B2B692C292C392C492C592C692C792C892C9C0CCCBF092CABCF1BBBBB5B792CB92CC92CDC5F592CEDEE692CF92D092D1DEE3BEDD92D292D3DEDF92D492D592D692D7B4B7BDDD92D892D9DEE0C4ED92DA92DB92DC92DDCFC692DEB5E092DF92E092E192E2B6DECADAB5F4DEE592E3D5C692E4DEE1CCCDC6FE92E5C5C592E692E792E8D2B492E9BEF292EA92EB92EC92ED92EE92EF92F0C2D392F1CCBDB3B892F2BDD392F3BFD8CDC6D1DAB4EB92F4DEE4DEDDDEE792F5EAFE92F692F7C2B0DEE292F892F9D6C0B5A792FAB2F492FBDEE892FCDEF292FD92FE934093419342DEED9343DEF193449345C8E0934693479348D7E1DEEFC3E8CCE19349B2E5934A934B934CD2BE934D934E934F9350935193529353DEEE9354DEEBCED59355B4A79356935793589359935ABFABBEBE935B935CBDD2935D935E935F9360DEE99361D4AE9362DEDE9363DEEA9364936593669367C0BF9368DEECB2F3B8E9C2A79369936ABDC1936B936C936D936E936FDEF5DEF893709371B2ABB4A493729373B4EAC9A6937493759376937793789379DEF6CBD1937AB8E3937BDEF7DEFA937C937D937E9380DEF9938193829383CCC29384B0E1B4EE93859386938793889389938AE5BA938B938C938D938E938FD0AF93909391B2EB9392EBA19393DEF493949395C9E3DEF3B0DAD2A1B1F79396CCAF939793989399939A939B939C939DDEF0939ECBA4939F93A093A1D5AA93A293A393A493A593A6DEFB93A793A893A993AA93AB93AC93AD93AEB4DD93AFC4A693B093B193B2DEFD93B393B493B593B693B793B893B993BA93BB93BCC3FEC4A1DFA193BD93BE93BF93C093C193C293C3C1CC93C4DEFCBEEF93C5C6B293C693C793C893C993CA93CB93CC93CD93CEB3C5C8F693CF93D0CBBADEFE93D193D2DFA493D393D493D593D6D7B293D793D893D993DA93DBB3B793DC93DD93DE93DFC1C393E093E1C7CBB2A5B4E993E2D7AB93E393E493E593E6C4EC93E7DFA2DFA393E8DFA593E9BAB393EA93EB93ECDFA693EDC0DE93EE93EFC9C393F093F193F293F393F493F593F6B2D9C7E693F7DFA793F8C7DC93F993FA93FB93FCDFA8EBA293FD93FE944094419442CBD3944394449445DFAA9446DFA99447B2C194489449944A944B944C944D944E944F9450945194529453945494559456945794589459945A945B945C945D945E945F9460C5CA94619462946394649465946694679468DFAB9469946A946B946C946D946E946F9470D4DC94719472947394749475C8C19476947794789479947A947B947C947D947E948094819482DFAC94839484948594869487BEF094889489DFADD6A7948A948B948C948DEAB7EBB6CAD5948ED8FCB8C4948FB9A594909491B7C5D5FE94929493949494959496B9CA94979498D0A7F4CD9499949AB5D0949B949CC3F4949DBEC8949E949F94A0EBB7B0BD94A194A2BDCC94A3C1B294A4B1D6B3A894A594A694A7B8D2C9A294A894A9B6D894AA94AB94AC94ADEBB8BEB494AE94AF94B0CAFD94B1C7C394B2D5FB94B394B4B7F394B594B694B794B894B994BA94BB94BC94BD94BE94BF94C094C194C294C3CEC494C494C594C6D5ABB1F394C794C894C9ECB3B0DF94CAECB594CB94CC94CDB6B794CEC1CF94CFF5FAD0B194D094D1D5E594D2CED394D394D4BDEFB3E294D5B8AB94D6D5B694D7EDBD94D8B6CF94D9CBB9D0C294DA94DB94DC94DD94DE94DF94E094E1B7BD94E294E3ECB6CAA994E494E594E6C5D494E7ECB9ECB8C2C3ECB794E894E994EA94EBD0FDECBA94ECECBBD7E594ED94EEECBC94EF94F094F1ECBDC6EC94F294F394F494F594F694F794F894F9CEDE94FABCC894FB94FCC8D5B5A9BEC9D6BCD4E794FD94FED1AED0F1EAB8EAB9EABABAB59540954195429543CAB1BFF595449545CDFA9546954795489549954AEAC0954BB0BAEABE954C954DC0A5954E954F9550EABB9551B2FD9552C3F7BBE8955395549555D2D7CEF4EABF955695579558EABC9559955A955BEAC3955CD0C7D3B3955D955E955F9560B4BA9561C3C1D7F29562956395649565D5D19566CAC79567EAC595689569EAC4EAC7EAC6956A956B956C956D956ED6E7956FCFD495709571EACB9572BBCE9573957495759576957795789579BDFAC9CE957A957BEACC957C957DC9B9CFFEEACAD4CEEACDEACF957E9580CDED9581958295839584EAC99585EACE95869587CEEE9588BBDE9589B3BF958A958B958C958D958EC6D5BEB0CEFA958F95909591C7E79592BEA7EAD095939594D6C7959595969597C1C095989599959AD4DD959BEAD1959C959DCFBE959E959F95A095A1EAD295A295A395A495A5CAEE95A695A795A895A9C5AFB0B595AA95AB95AC95AD95AEEAD495AF95B095B195B295B395B495B595B695B7EAD3F4DF95B895B995BA95BB95BCC4BA95BD95BE95BF95C095C1B1A995C295C395C495C5E5DF95C695C795C895C9EAD595CA95CB95CC95CD95CE95CF95D095D195D295D395D495D595D695D795D895D995DA95DB95DC95DD95DE95DF95E095E195E295E3CAEF95E4EAD6EAD7C6D895E595E695E795E895E995EA95EB95ECEAD895ED95EEEAD995EF95F095F195F295F395F4D4BB95F5C7FAD2B7B8FC95F695F7EAC295F8B2DC95F995FAC2FC95FBD4F8CCE6D7EE95FC95FD95FE9640964196429643D4C2D3D0EBC3C5F39644B7FE96459646EBD4964796489649CBB7EBDE964AC0CA964B964C964DCDFB964EB3AF964FC6DA965096519652965396549655EBFC9656C4BE9657CEB4C4A9B1BED4FD9658CAF59659D6EC965A965BC6D3B6E4965C965D965E965FBBFA96609661D0E096629663C9B19664D4D3C8A896659666B8CB9667E8BEC9BC96689669E8BB966AC0EED0D3B2C4B4E5966BE8BC966C966DD5C8966E966F967096719672B6C59673E8BDCAF8B8DCCCF5967496759676C0B496779678D1EEE8BFE8C29679967ABABC967BB1ADBDDC967CEABDE8C3967DE8C6967EE8CB9680968196829683E8CC9684CBC9B0E59685BCAB96869687B9B996889689E8C1968ACDF7968BE8CA968C968D968E968FCEF69690969196929693D5ED9694C1D6E8C49695C3B69696B9FBD6A6E8C8969796989699CAE0D4E6969AE8C0969BE8C5E8C7969CC7B9B7E3969DE8C9969EBFDDE8D2969F96A0E8D796A1E8D5BCDCBCCFE8DB96A296A396A496A596A696A796A896A9E8DE96AAE8DAB1FA96AB96AC96AD96AE96AF96B096B196B296B396B4B0D8C4B3B8CCC6E2C8BEC8E196B596B696B7E8CFE8D4E8D696B8B9F1E8D8D7F596B9C4FB96BAE8DC96BB96BCB2E996BD96BE96BFE8D196C096C1BCED96C296C3BFC2E8CDD6F996C4C1F8B2F196C596C696C796C896C996CA96CB96CCE8DF96CDCAC1E8D996CE96CF96D096D1D5A496D2B1EAD5BBE8CEE8D0B6B0E8D396D3E8DDC0B896D4CAF796D5CBA896D696D7C6DCC0F596D896D996DA96DB96DCE8E996DD96DE96DFD0A396E096E196E296E396E496E596E6E8F2D6EA96E796E896E996EA96EB96EC96EDE8E0E8E196EE96EF96F0D1F9BACBB8F996F196F2B8F1D4D4E8EF96F3E8EEE8ECB9F0CCD2E8E6CEA6BFF296F4B0B8E8F1E8F096F5D7C096F6E8E496F7CDA9C9A396F8BBB8BDDBE8EA96F996FA96FB96FC96FD96FE9740974197429743E8E2E8E3E8E5B5B5E8E7C7C5E8EBE8EDBDB0D7AE9744E8F897459746974797489749974A974B974CE8F5974DCDB0E8F6974E974F9750975197529753975497559756C1BA9757E8E89758C3B7B0F09759975A975B975C975D975E975F9760E8F4976197629763E8F7976497659766B9A3976797689769976A976B976C976D976E976F9770C9D2977197729773C3CECEE0C0E69774977597769777CBF39778CCDDD0B59779977ACAE1977BE8F3977C977D977E9780978197829783978497859786BCEC9787E8F997889789978A978B978C978DC3DE978EC6E5978FB9F79790979197929793B0F497949795D7D897969797BCAC9798C5EF9799979A979B979C979DCCC4979E979FE9A697A097A197A297A397A497A597A697A797A897A9C9AD97AAE9A2C0E297AB97AC97ADBFC397AE97AF97B0E8FEB9D797B1E8FB97B297B397B497B5E9A497B697B797B8D2CE97B997BA97BB97BC97BDE9A397BED6B2D7B597BFE9A797C0BDB797C197C297C397C497C597C697C797C897C997CA97CB97CCE8FCE8FD97CD97CE97CFE9A197D097D197D297D397D497D597D697D7CDD697D897D9D2AC97DA97DB97DCE9B297DD97DE97DF97E0E9A997E197E297E3B4AA97E4B4BB97E597E6E9AB97E797E897E997EA97EB97EC97ED97EE97EF97F097F197F297F397F497F597F697F7D0A897F897F9E9A597FA97FBB3FE97FC97FDE9ACC0E397FEE9AA98409841E9B998429843E9B89844984598469847E9AE98489849E8FA984A984BE9A8984C984D984E984F9850BFACE9B1E9BA98519852C2A5985398549855E9AF9856B8C59857E9AD9858D3DCE9B4E9B5E9B79859985A985BE9C7985C985D985E985F98609861C0C6E9C598629863E9B098649865E9BBB0F19866986798689869986A986B986C986D986E986FE9BCD5A598709871E9BE9872E9BF987398749875E9C198769877C1F198789879C8B6987A987B987CE9BD987D987E988098819882E9C29883988498859886988798889889988AE9C3988BE9B3988CE9B6988DBBB1988E988F9890E9C0989198929893989498959896BCF7989798989899E9C4E9C6989A989B989C989D989E989F98A098A198A298A398A498A5E9CA98A698A798A898A9E9CE98AA98AB98AC98AD98AE98AF98B098B198B298B3B2DB98B4E9C898B598B698B798B898B998BA98BB98BC98BD98BEB7AE98BF98C098C198C298C398C498C598C698C798C898C998CAE9CBE9CC98CB98CC98CD98CE98CF98D0D5C198D1C4A398D298D398D498D598D698D7E9D898D8BAE198D998DA98DB98DCE9C998DDD3A398DE98DF98E0E9D498E198E298E398E498E598E698E7E9D7E9D098E898E998EA98EB98ECE9CF98ED98EEC7C198EF98F098F198F298F398F498F598F6E9D298F798F898F998FA98FB98FC98FDE9D9B3C898FEE9D399409941994299439944CFF0994599469947E9CD99489949994A994B994C994D994E994F995099519952B3F79953995499559956995799589959E9D6995A995BE9DA995C995D995ECCB4995F99609961CFAD99629963996499659966996799689969996AE9D5996BE9DCE9DB996C996D996E996F9970E9DE99719972997399749975997699779978E9D19979997A997B997C997D997E99809981E9DD9982E9DFC3CA9983998499859986998799889989998A998B998C998D998E998F9990999199929993999499959996999799989999999A999B999C999D999E999F99A099A199A299A399A499A599A699A799A899A999AA99AB99AC99AD99AE99AF99B099B199B299B399B499B599B699B799B899B999BA99BB99BC99BD99BE99BF99C099C199C299C399C499C599C699C799C899C999CA99CB99CC99CD99CE99CF99D099D199D299D399D499D599D699D799D899D999DA99DB99DC99DD99DE99DF99E099E199E299E399E499E599E699E799E899E999EA99EB99EC99ED99EE99EF99F099F199F299F399F499F5C7B7B4CEBBB6D0C0ECA399F699F7C5B799F899F999FA99FB99FC99FD99FE9A409A419A42D3FB9A439A449A459A46ECA49A47ECA5C6DB9A489A499A4ABFEE9A4B9A4C9A4D9A4EECA69A4F9A50ECA7D0AA9A51C7B89A529A53B8E89A549A559A569A579A589A599A5A9A5B9A5C9A5D9A5E9A5FECA89A609A619A629A639A649A659A669A67D6B9D5FDB4CBB2BDCEE4C6E79A689A69CDE19A6A9A6B9A6C9A6D9A6E9A6F9A709A719A729A739A749A759A769A77B4F59A78CBC0BCDF9A799A7A9A7B9A7CE9E2E9E3D1EAE9E59A7DB4F9E9E49A7ED1B3CAE2B2D09A80E9E89A819A829A839A84E9E6E9E79A859A86D6B39A879A889A89E9E9E9EA9A8A9A8B9A8C9A8D9A8EE9EB9A8F9A909A919A929A939A949A959A96E9EC9A979A989A999A9A9A9B9A9C9A9D9A9EECAFC5B9B6CE9A9FD2F39AA09AA19AA29AA39AA49AA59AA6B5EE9AA7BBD9ECB19AA89AA9D2E39AAA9AAB9AAC9AAD9AAECEE39AAFC4B89AB0C3BF9AB19AB2B6BED8B9B1C8B1CFB1D1C5FE9AB3B1D09AB4C3AB9AB59AB69AB79AB89AB9D5B19ABA9ABB9ABC9ABD9ABE9ABF9AC09AC1EBA4BAC19AC29AC39AC4CCBA9AC59AC69AC7EBA59AC8EBA79AC99ACA9ACBEBA89ACC9ACD9ACEEBA69ACF9AD09AD19AD29AD39AD49AD5EBA9EBABEBAA9AD69AD79AD89AD99ADAEBAC9ADBCACFD8B5C3F19ADCC3A5C6F8EBADC4CA9ADDEBAEEBAFEBB0B7D59ADE9ADF9AE0B7FA9AE1EBB1C7E29AE2EBB39AE3BAA4D1F5B0B1EBB2EBB49AE49AE59AE6B5AAC2C8C7E89AE7EBB59AE8CBAEE3DF9AE99AEAD3C09AEB9AEC9AED9AEED9DB9AEF9AF0CDA1D6ADC7F39AF19AF29AF3D9E0BBE39AF4BABAE3E29AF59AF69AF79AF89AF9CFAB9AFA9AFB9AFCE3E0C9C79AFDBAB99AFE9B409B41D1B4E3E1C8EAB9AFBDADB3D8CEDB9B429B43CCC09B449B459B46E3E8E3E9CDF49B479B489B499B4A9B4BCCAD9B4CBCB39B4DE3EA9B4EE3EB9B4F9B50D0DA9B519B529B53C6FBB7DA9B549B55C7DFD2CACED69B56E3E4E3EC9B57C9F2B3C19B589B59E3E79B5A9B5BC6E3E3E59B5C9B5DEDB3E3E69B5E9B5F9B609B61C9B39B62C5E69B639B649B65B9B59B66C3BB9B67E3E3C5BDC1A4C2D9B2D79B68E3EDBBA6C4AD9B69E3F0BEDA9B6A9B6BE3FBE3F5BAD39B6C9B6D9B6E9B6FB7D0D3CD9B70D6CED5D3B9C1D5B4D1D89B719B729B739B74D0B9C7F69B759B769B77C8AAB2B49B78C3DA9B799B7A9B7BE3EE9B7C9B7DE3FCE3EFB7A8E3F7E3F49B7E9B809B81B7BA9B829B83C5A29B84E3F6C5DDB2A8C6FC9B85C4E09B869B87D7A29B88C0E1E3F99B899B8AE3FAE3FDCCA9E3F39B8BD3BE9B8CB1C3EDB4E3F1E3F29B8DE3F8D0BAC6C3D4F3E3FE9B8E9B8FBDE09B909B91E4A79B929B93E4A69B949B959B96D1F3E4A39B97E4A99B989B999B9AC8F79B9B9B9C9B9D9B9ECFB49B9FE4A8E4AEC2E59BA09BA1B6B49BA29BA39BA49BA59BA69BA7BDF29BA8E4A29BA99BAABAE9E4AA9BAB9BACE4AC9BAD9BAEB6FDD6DEE4B29BAFE4AD9BB09BB19BB2E4A19BB3BBEECDDDC7A2C5C99BB49BB5C1F79BB6E4A49BB7C7B3BDACBDBDE4A59BB8D7C7B2E29BB9E4ABBCC3E4AF9BBABBEBE4B0C5A8E4B19BBB9BBC9BBD9BBED5E3BFA39BBFE4BA9BC0E4B79BC1E4BB9BC29BC3E4BD9BC49BC5C6D69BC69BC7BAC6C0CB9BC89BC99BCAB8A1E4B49BCB9BCC9BCD9BCED4A19BCF9BD0BAA3BDFE9BD19BD29BD3E4BC9BD49BD59BD69BD79BD8CDBF9BD99BDAC4F99BDB9BDCCFFBC9E69BDD9BDED3BF9BDFCFD19BE09BE1E4B39BE2E4B8E4B9CCE99BE39BE49BE59BE69BE7CCCE9BE8C0D4E4B5C1B0E4B6CED09BE9BBC1B5D39BEAC8F3BDA7D5C7C9ACB8A2E4CA9BEB9BECE4CCD1C49BED9BEED2BA9BEF9BF0BAAD9BF19BF2BAD49BF39BF49BF59BF69BF79BF8E4C3B5ED9BF99BFA9BFBD7CDE4C0CFFDE4BF9BFC9BFD9BFEC1DCCCCA9C409C419C429C43CAE79C449C459C469C47C4D79C48CCD4E4C89C499C4A9C4BE4C7E4C19C4CE4C4B5AD9C4D9C4ED3D99C4FE4C69C509C519C529C53D2F9B4E39C54BBB49C559C56C9EE9C57B4BE9C589C599C5ABBEC9C5BD1CD9C5CCCEDEDB59C5D9C5E9C5F9C609C619C629C639C64C7E59C659C669C679C68D4A89C69E4CBD7D5E4C29C6ABDA5E4C59C6B9C6CD3E69C6DE4C9C9F89C6E9C6FE4BE9C709C71D3E59C729C73C7FEB6C99C74D4FCB2B3E4D79C759C769C77CEC29C78E4CD9C79CEBC9C7AB8DB9C7B9C7CE4D69C7DBFCA9C7E9C809C81D3CE9C82C3EC9C839C849C859C869C879C889C899C8AC5C8E4D89C8B9C8C9C8D9C8E9C8F9C909C919C92CDC4E4CF9C939C949C959C96E4D4E4D59C97BAFE9C98CFE69C999C9AD5BF9C9B9C9C9C9DE4D29C9E9C9F9CA09CA19CA29CA39CA49CA59CA69CA79CA8E4D09CA99CAAE4CE9CAB9CAC9CAD9CAE9CAF9CB09CB19CB29CB39CB49CB59CB69CB79CB89CB9CDE5CAAA9CBA9CBB9CBCC0A39CBDBDA6E4D39CBE9CBFB8C89CC09CC19CC29CC39CC4E4E7D4B49CC59CC69CC79CC89CC99CCA9CCBE4DB9CCC9CCD9CCEC1EF9CCF9CD0E4E99CD19CD2D2E79CD39CD4E4DF9CD5E4E09CD69CD7CFAA9CD89CD99CDA9CDBCBDD9CDCE4DAE4D19CDDE4E59CDEC8DCE4E39CDF9CE0C4E7E4E29CE1E4E19CE29CE39CE4B3FCE4E89CE59CE69CE79CE8B5E19CE99CEA9CEBD7CC9CEC9CED9CEEE4E69CEFBBAC9CF0D7D2CCCFEBF89CF1E4E49CF29CF3B9F69CF49CF59CF6D6CDE4D9E4DCC2FAE4DE9CF7C2CBC0C4C2D09CF8B1F5CCB29CF99CFA9CFB9CFC9CFD9CFE9D409D419D429D43B5CE9D449D459D469D47E4EF9D489D499D4A9D4B9D4C9D4D9D4E9D4FC6AF9D509D519D52C6E19D539D54E4F59D559D569D579D589D59C2A99D5A9D5B9D5CC0ECD1DDE4EE9D5D9D5E9D5F9D609D619D629D639D649D659D66C4AE9D679D689D69E4ED9D6A9D6B9D6C9D6DE4F6E4F4C2FE9D6EE4DD9D6FE4F09D70CAFE9D71D5C49D729D73E4F19D749D759D769D779D789D799D7AD1FA9D7B9D7C9D7D9D7E9D809D819D82E4EBE4EC9D839D849D85E4F29D86CEAB9D879D889D899D8A9D8B9D8C9D8D9D8E9D8F9D90C5CB9D919D929D93C7B19D94C2BA9D959D969D97E4EA9D989D999D9AC1CA9D9B9D9C9D9D9D9E9D9F9DA0CCB6B3B19DA19DA29DA3E4FB9DA4E4F39DA59DA69DA7E4FA9DA8E4FD9DA9E4FC9DAA9DAB9DAC9DAD9DAE9DAF9DB0B3CE9DB19DB29DB3B3BAE4F79DB49DB5E4F9E4F8C5EC9DB69DB79DB89DB99DBA9DBB9DBC9DBD9DBE9DBF9DC09DC19DC2C0BD9DC39DC49DC59DC6D4E89DC79DC89DC99DCA9DCBE5A29DCC9DCD9DCE9DCF9DD09DD19DD29DD39DD49DD59DD6B0C49DD79DD8E5A49DD99DDAE5A39DDB9DDC9DDD9DDE9DDF9DE0BCA49DE1E5A59DE29DE39DE49DE59DE69DE7E5A19DE89DE99DEA9DEB9DEC9DED9DEEE4FEB1F49DEF9DF09DF19DF29DF39DF49DF59DF69DF79DF89DF9E5A89DFAE5A9E5A69DFB9DFC9DFD9DFE9E409E419E429E439E449E459E469E47E5A7E5AA9E489E499E4A9E4B9E4C9E4D9E4E9E4F9E509E519E529E539E549E559E569E579E589E599E5A9E5B9E5C9E5D9E5E9E5F9E609E619E629E639E649E659E669E679E68C6D99E699E6A9E6B9E6C9E6D9E6E9E6F9E70E5ABE5AD9E719E729E739E749E759E769E77E5AC9E789E799E7A9E7B9E7C9E7D9E7E9E809E819E829E839E849E859E869E879E889E89E5AF9E8A9E8B9E8CE5AE9E8D9E8E9E8F9E909E919E929E939E949E959E969E979E989E999E9A9E9B9E9C9E9D9E9EB9E09E9F9EA0E5B09EA19EA29EA39EA49EA59EA69EA79EA89EA99EAA9EAB9EAC9EAD9EAEE5B19EAF9EB09EB19EB29EB39EB49EB59EB69EB79EB89EB99EBABBF0ECE1C3F09EBBB5C6BBD29EBC9EBD9EBE9EBFC1E9D4EE9EC0BEC49EC19EC29EC3D7C69EC4D4D6B2D3ECBE9EC59EC69EC79EC8EAC19EC99ECA9ECBC2AFB4B69ECC9ECD9ECED1D79ECF9ED09ED1B3B49ED2C8B2BFBBECC09ED39ED4D6CB9ED59ED6ECBFECC19ED79ED89ED99EDA9EDB9EDC9EDD9EDE9EDF9EE09EE19EE29EE3ECC5BEE6CCBFC5DABEBC9EE4ECC69EE5B1FE9EE69EE79EE8ECC4D5A8B5E39EE9ECC2C1B6B3E39EEA9EEBECC3CBB8C0C3CCFE9EEC9EED9EEE9EEFC1D29EF0ECC89EF19EF29EF39EF49EF59EF69EF79EF89EF99EFA9EFB9EFC9EFDBAE6C0D39EFED6F29F409F419F42D1CC9F439F449F459F46BFBE9F47B7B3C9D5ECC7BBE29F48CCCCBDFDC8C89F49CFA99F4A9F4B9F4C9F4D9F4E9F4F9F50CDE99F51C5EB9F529F539F54B7E99F559F569F579F589F599F5A9F5B9F5C9F5D9F5E9F5FD1C9BAB89F609F619F629F639F64ECC99F659F66ECCA9F67BBC0ECCB9F68ECE2B1BAB7D99F699F6A9F6B9F6C9F6D9F6E9F6F9F709F719F729F73BDB99F749F759F769F779F789F799F7A9F7BECCCD1E6ECCD9F7C9F7D9F7E9F80C8BB9F819F829F839F849F859F869F879F889F899F8A9F8B9F8C9F8D9F8EECD19F8F9F909F919F92ECD39F93BBCD9F94BCE59F959F969F979F989F999F9A9F9B9F9C9F9D9F9E9F9F9FA09FA1ECCF9FA2C9B79FA39FA49FA59FA69FA7C3BA9FA8ECE3D5D5ECD09FA99FAA9FAB9FAC9FADD6F39FAE9FAF9FB0ECD2ECCE9FB19FB29FB39FB4ECD49FB5ECD59FB69FB7C9BF9FB89FB99FBA9FBB9FBC9FBDCFA89FBE9FBF9FC09FC19FC2D0DC9FC39FC49FC59FC6D1AC9FC79FC89FC99FCAC8DB9FCB9FCC9FCDECD6CEF59FCE9FCF9FD09FD19FD2CAECECDA9FD39FD49FD59FD69FD79FD89FD9ECD99FDA9FDB9FDCB0BE9FDD9FDE9FDF9FE09FE19FE2ECD79FE3ECD89FE49FE59FE6ECE49FE79FE89FE99FEA9FEB9FEC9FED9FEE9FEFC8BC9FF09FF19FF29FF39FF49FF59FF69FF79FF89FF9C1C79FFA9FFB9FFC9FFD9FFEECDCD1E0A040A041A042A043A044A045A046A047A048A049ECDBA04AA04BA04CA04DD4EFA04EECDDA04FA050A051A052A053A054DBC6A055A056A057A058A059A05AA05BA05CA05DA05EECDEA05FA060A061A062A063A064A065A066A067A068A069A06AB1ACA06BA06CA06DA06EA06FA070A071A072A073A074A075A076A077A078A079A07AA07BA07CA07DA07EA080A081ECDFA082A083A084A085A086A087A088A089A08AA08BECE0A08CD7A6A08DC5C0A08EA08FA090EBBCB0AEA091A092A093BEF4B8B8D2AFB0D6B5F9A094D8B3A095CBACA096E3DDA097A098A099A09AA09BA09CA09DC6ACB0E6A09EA09FA0A0C5C6EBB9A0A1A0A2A0A3A0A4EBBAA0A5A0A6A0A7EBBBA0A8A0A9D1C0A0AAC5A3A0ABEAF2A0ACC4B2A0ADC4B5C0CEA0AEA0AFA0B0EAF3C4C1A0B1CEEFA0B2A0B3A0B4A0B5EAF0EAF4A0B6A0B7C9FCA0B8A0B9C7A3A0BAA0BBA0BCCCD8CEFEA0BDA0BEA0BFEAF5EAF6CFACC0E7A0C0A0C1EAF7A0C2A0C3A0C4A0C5A0C6B6BFEAF8A0C7EAF9A0C8EAFAA0C9A0CAEAFBA0CBA0CCA0CDA0CEA0CFA0D0A0D1A0D2A0D3A0D4A0D5A0D6EAF1A0D7A0D8A0D9A0DAA0DBA0DCA0DDA0DEA0DFA0E0A0E1A0E2C8AEE1EBA0E3B7B8E1ECA0E4A0E5A0E6E1EDA0E7D7B4E1EEE1EFD3CCA0E8A0E9A0EAA0EBA0ECA0EDA0EEE1F1BFF1E1F0B5D2A0EFA0F0A0F1B1B7A0F2A0F3A0F4A0F5E1F3E1F2A0F6BAFCA0F7E1F4A0F8A0F9A0FAA0FBB9B7A0FCBED1A0FDA0FEAA40AA41C4FCAA42BADDBDC6AA43AA44AA45AA46AA47AA48E1F5E1F7AA49AA4AB6C0CFC1CAA8E1F6D5F8D3FCE1F8E1FCE1F9AA4BAA4CE1FAC0EAAA4DE1FEE2A1C0C7AA4EAA4FAA50AA51E1FBAA52E1FDAA53AA54AA55AA56AA57AA58E2A5AA59AA5AAA5BC1D4AA5CAA5DAA5EAA5FE2A3AA60E2A8B2FEE2A2AA61AA62AA63C3CDB2C2E2A7E2A6AA64AA65E2A4E2A9AA66AA67E2ABAA68AA69AA6AD0C9D6EDC3A8E2ACAA6BCFD7AA6CAA6DE2AEAA6EAA6FBAEFAA70AA71E9E0E2ADE2AAAA72AA73AA74AA75BBABD4B3AA76AA77AA78AA79AA7AAA7BAA7CAA7DAA7EAA80AA81AA82AA83E2B0AA84AA85E2AFAA86E9E1AA87AA88AA89AA8AE2B1AA8BAA8CAA8DAA8EAA8FAA90AA91AA92E2B2AA93AA94AA95AA96AA97AA98AA99AA9AAA9BAA9CAA9DE2B3CCA1AA9EE2B4AA9FAAA0AB40AB41AB42AB43AB44AB45AB46AB47AB48AB49AB4AAB4BE2B5AB4CAB4DAB4EAB4FAB50D0FEAB51AB52C2CAAB53D3F1AB54CDF5AB55AB56E7E0AB57AB58E7E1AB59AB5AAB5BAB5CBEC1AB5DAB5EAB5FAB60C2EAAB61AB62AB63E7E4AB64AB65E7E3AB66AB67AB68AB69AB6AAB6BCDE6AB6CC3B5AB6DAB6EE7E2BBB7CFD6AB6FC1E1E7E9AB70AB71AB72E7E8AB73AB74E7F4B2A3AB75AB76AB77AB78E7EAAB79E7E6AB7AAB7BAB7CAB7DAB7EE7ECE7EBC9BAAB80AB81D5E4AB82E7E5B7A9E7E7AB83AB84AB85AB86AB87AB88AB89E7EEAB8AAB8BAB8CAB8DE7F3AB8ED6E9AB8FAB90AB91AB92E7EDAB93E7F2AB94E7F1AB95AB96AB97B0E0AB98AB99AB9AAB9BE7F5AB9CAB9DAB9EAB9FABA0AC40AC41AC42AC43AC44AC45AC46AC47AC48AC49AC4AC7F2AC4BC0C5C0EDAC4CAC4DC1F0E7F0AC4EAC4FAC50AC51E7F6CBF6AC52AC53AC54AC55AC56AC57AC58AC59AC5AE8A2E8A1AC5BAC5CAC5DAC5EAC5FAC60D7C1AC61AC62E7FAE7F9AC63E7FBAC64E7F7AC65E7FEAC66E7FDAC67E7FCAC68AC69C1D5C7D9C5FDC5C3AC6AAC6BAC6CAC6DAC6EC7EDAC6FAC70AC71AC72E8A3AC73AC74AC75AC76AC77AC78AC79AC7AAC7BAC7CAC7DAC7EAC80AC81AC82AC83AC84AC85AC86E8A6AC87E8A5AC88E8A7BAF7E7F8E8A4AC89C8F0C9AAAC8AAC8BAC8CAC8DAC8EAC8FAC90AC91AC92AC93AC94AC95AC96E8A9AC97AC98B9E5AC99AC9AAC9BAC9CAC9DD1FEE8A8AC9EAC9FACA0AD40AD41AD42E8AAAD43E8ADE8AEAD44C1A7AD45AD46AD47E8AFAD48AD49AD4AE8B0AD4BAD4CE8ACAD4DE8B4AD4EAD4FAD50AD51AD52AD53AD54AD55AD56AD57AD58E8ABAD59E8B1AD5AAD5BAD5CAD5DAD5EAD5FAD60AD61E8B5E8B2E8B3AD62AD63AD64AD65AD66AD67AD68AD69AD6AAD6BAD6CAD6DAD6EAD6FAD70AD71E8B7AD72AD73AD74AD75AD76AD77AD78AD79AD7AAD7BAD7CAD7DAD7EAD80AD81AD82AD83AD84AD85AD86AD87AD88AD89E8B6AD8AAD8BAD8CAD8DAD8EAD8FAD90AD91AD92B9CFAD93F0ACAD94F0ADAD95C6B0B0EAC8BFAD96CDDFAD97AD98AD99AD9AAD9BAD9CAD9DCECDEAB1AD9EAD9FADA0AE40EAB2AE41C6BFB4C9AE42AE43AE44AE45AE46AE47AE48EAB3AE49AE4AAE4BAE4CD5E7AE4DAE4EAE4FAE50AE51AE52AE53AE54DDF9AE55EAB4AE56EAB5AE57EAB6AE58AE59AE5AAE5BB8CADFB0C9F5AE5CCCF0AE5DAE5EC9FAAE5FAE60AE61AE62AE63C9FBAE64AE65D3C3CBA6AE66B8A6F0AEB1C2AE67E5B8CCEFD3C9BCD7C9EAAE68B5E7AE69C4D0B5E9AE6AEEAEBBADAE6BAE6CE7DEAE6DEEAFAE6EAE6FAE70AE71B3A9AE72AE73EEB2AE74AE75EEB1BDE7AE76EEB0CEB7AE77AE78AE79AE7AC5CFAE7BAE7CAE7DAE7EC1F4DBCEEEB3D0F3AE80AE81AE82AE83AE84AE85AE86AE87C2D4C6E8AE88AE89AE8AB7ACAE8BAE8CAE8DAE8EAE8FAE90AE91EEB4AE92B3EBAE93AE94AE95BBFBEEB5AE96AE97AE98AE99AE9AE7DCAE9BAE9CAE9DEEB6AE9EAE9FBDAEAEA0AF40AF41AF42F1E2AF43AF44AF45CAE8AF46D2C9F0DAAF47F0DBAF48F0DCC1C6AF49B8EDBECEAF4AAF4BF0DEAF4CC5B1F0DDD1F1AF4DF0E0B0CCBDEAAF4EAF4FAF50AF51AF52D2DFF0DFAF53B4AFB7E8F0E6F0E5C6A3F0E1F0E2B4C3AF54AF55F0E3D5EEAF56AF57CCDBBED2BCB2AF58AF59AF5AF0E8F0E7F0E4B2A1AF5BD6A2D3B8BEB7C8ACAF5CAF5DF0EAAF5EAF5FAF60AF61D1F7AF62D6CCBADBF0E9AF63B6BBAF64AF65CDB4AF66AF67C6A6AF68AF69AF6AC1A1F0EBF0EEAF6BF0EDF0F0F0ECAF6CBBBEF0EFAF6DAF6EAF6FAF70CCB5F0F2AF71AF72B3D5AF73AF74AF75AF76B1D4AF77AF78F0F3AF79AF7AF0F4F0F6B4E1AF7BF0F1AF7CF0F7AF7DAF7EAF80AF81F0FAAF82F0F8AF83AF84AF85F0F5AF86AF87AF88AF89F0FDAF8AF0F9F0FCF0FEAF8BF1A1AF8CAF8DAF8ECEC1F1A4AF8FF1A3AF90C1F6F0FBCADDAF91AF92B4F1B1F1CCB1AF93F1A6AF94AF95F1A7AF96AF97F1ACD5CEF1A9AF98AF99C8B3AF9AAF9BAF9CF1A2AF9DF1ABF1A8F1A5AF9EAF9FF1AAAFA0B040B041B042B043B044B045B046B0A9F1ADB047B048B049B04AB04BB04CF1AFB04DF1B1B04EB04FB050B051B052F1B0B053F1AEB054B055B056B057D1A2B058B059B05AB05BB05CB05DB05EF1B2B05FB060B061F1B3B062B063B064B065B066B067B068B069B9EFB06AB06BB5C7B06CB0D7B0D9B06DB06EB06FD4EDB070B5C4B071BDD4BBCAF0A7B072B073B8DEB074B075F0A8B076B077B0A8B078F0A9B079B07ACDEEB07BB07CF0AAB07DB07EB080B081B082B083B084B085B086B087F0ABB088B089B08AB08BB08CB08DB08EB08FB090C6A4B091B092D6E5F1E4B093F1E5B094B095B096B097B098B099B09AB09BB09CB09DC3F3B09EB09FD3DBB0A0B140D6D1C5E8B141D3AFB142D2E6B143B144EEC1B0BBD5B5D1CEBCE0BAD0B145BFF8B146B8C7B5C1C5CCB147B148CAA2B149B14AB14BC3CBB14CB14DB14EB14FB150EEC2B151B152B153B154B155B156B157B158C4BFB6A2B159EDECC3A4B15AD6B1B15BB15CB15DCFE0EDEFB15EB15FC5CEB160B6DCB161B162CAA1B163B164EDEDB165B166EDF0EDF1C3BCB167BFB4B168EDEEB169B16AB16BB16CB16DB16EB16FB170B171B172B173EDF4EDF2B174B175B176B177D5E6C3DFB178EDF3B179B17AB17BEDF6B17CD5A3D1A3B17DB17EB180EDF5B181C3D0B182B183B184B185B186EDF7BFF4BEECEDF8B187CCF7B188D1DBB189B18AB18BD7C5D5F6B18CEDFCB18DB18EB18FEDFBB190B191B192B193B194B195B196B197EDF9EDFAB198B199B19AB19BB19CB19DB19EB19FEDFDBEA6B1A0B240B241B242B243CBAFEEA1B6BDB244EEA2C4C0B245EDFEB246B247BDDEB2C7B248B249B24AB24BB24CB24DB24EB24FB250B251B252B253B6C3B254B255B256EEA5D8BAEEA3EEA6B257B258B259C3E9B3F2B25AB25BB25CB25DB25EB25FEEA7EEA4CFB9B260B261EEA8C2F7B262B263B264B265B266B267B268B269B26AB26BB26CB26DEEA9EEAAB26EDEABB26FB270C6B3B271C7C6B272D6F5B5C9B273CBB2B274B275B276EEABB277B278CDABB279EEACB27AB27BB27CB27DB27ED5B0B280EEADB281F6C4B282B283B284B285B286B287B288B289B28AB28BB28CB28DB28EDBC7B28FB290B291B292B293B294B295B296B297B4A3B298B299B29AC3ACF1E6B29BB29CB29DB29EB29FCAB8D2D3B2A0D6AAB340EFF2B341BED8B342BDC3EFF3B6CCB0ABB343B344B345B346CAAFB347B348EDB6B349EDB7B34AB34BB34CB34DCEF9B7AFBFF3EDB8C2EBC9B0B34EB34FB350B351B352B353EDB9B354B355C6F6BFB3B356B357B358EDBCC5F8B359D1D0B35AD7A9EDBAEDBBB35BD1E2B35CEDBFEDC0B35DEDC4B35EB35FB360EDC8B361EDC6EDCED5E8B362EDC9B363B364EDC7EDBEB365B366C5E9B367B368B369C6C6B36AB36BC9E9D4D2EDC1EDC2EDC3EDC5B36CC0F9B36DB4A1B36EB36FB370B371B9E8B372EDD0B373B374B375B376EDD1B377EDCAB378EDCFB379CEF8B37AB37BCBB6EDCCEDCDB37CB37DB37EB380B381CFF5B382B383B384B385B386B387B388B389B38AB38BB38CB38DEDD2C1F2D3B2EDCBC8B7B38EB38FB390B391B392B393B394B395BCEFB396B397B398B399C5F0B39AB39BB39CB39DB39EB39FB3A0B440B441B442EDD6B443B5EFB444B445C2B5B0ADCBE9B446B447B1AEB448EDD4B449B44AB44BCDEBB5E2B44CEDD5EDD3EDD7B44DB44EB5FAB44FEDD8B450EDD9B451EDDCB452B1CCB453B454B455B456B457B458B459B45AC5F6BCEEEDDACCBCB2EAB45BB45CB45DB45EEDDBB45FB460B461B462C4EBB463B464B4C5B465B466B467B0F5B468B469B46AEDDFC0DAB4E8B46BB46CB46DB46EC5CDB46FB470B471EDDDBFC4B472B473B474EDDEB475B476B477B478B479B47AB47BB47CB47DB47EB480B481B482B483C4A5B484B485B486EDE0B487B488B489B48AB48BEDE1B48CEDE3B48DB48EC1D7B48FB490BBC7B491B492B493B494B495B496BDB8B497B498B499EDE2B49AB49BB49CB49DB49EB49FB4A0B540B541B542B543B544B545EDE4B546B547B548B549B54AB54BB54CB54DB54EB54FEDE6B550B551B552B553B554EDE5B555B556B557B558B559B55AB55BB55CB55DB55EB55FB560B561B562B563EDE7B564B565B566B567B568CABEECEAC0F1B569C9E7B56AECEBC6EEB56BB56CB56DB56EECECB56FC6EDECEDB570B571B572B573B574B575B576B577B578ECF0B579B57AD7E6ECF3B57BB57CECF1ECEEECEFD7A3C9F1CBEEECF4B57DECF2B57EB580CFE9B581ECF6C6B1B582B583B584B585BCC0B586ECF5B587B588B589B58AB58BB58CB58DB5BBBBF6B58EECF7B58FB590B591B592B593D9F7BDFBB594B595C2BBECF8B596B597B598B599ECF9B59AB59BB59CB59DB8A3B59EB59FB5A0B640B641B642B643B644B645B646ECFAB647B648B649B64AB64BB64CB64DB64EB64FB650B651B652ECFBB653B654B655B656B657B658B659B65AB65BB65CB65DECFCB65EB65FB660B661B662D3EDD8AEC0EBB663C7DDBACCB664D0E3CBBDB665CDBAB666B667B8D1B668B669B1FCB66AC7EFB66BD6D6B66CB66DB66EBFC6C3EBB66FB670EFF5B671B672C3D8B673B674B675B676B677B678D7E2B679B67AB67BEFF7B3D3B67CC7D8D1EDB67DD6C8B67EEFF8B680EFF6B681BBFDB3C6B682B683B684B685B686B687B688BDD5B689B68AD2C6B68BBBE0B68CB68DCFA1B68EEFFCEFFBB68FB690EFF9B691B692B693B694B3CCB695C9D4CBB0B696B697B698B699B69AEFFEB69BB69CB0DEB69DB69ED6C9B69FB6A0B740EFFDB741B3EDB742B743F6D5B744B745B746B747B748B749B74AB74BB74CB74DB74EB74FB750B751B752CEC8B753B754B755F0A2B756F0A1B757B5BEBCDABBFCB758B8E5B759B75AB75BB75CB75DB75EC4C2B75FB760B761B762B763B764B765B766B767B768F0A3B769B76AB76BB76CB76DCBEBB76EB76FB770B771B772B773B774B775B776B777B778B779B77AB77BB77CB77DB77EB780B781B782B783B784B785B786F0A6B787B788B789D1A8B78ABEBFC7EEF1B6F1B7BFD5B78BB78CB78DB78EB4A9F1B8CDBBB78FC7D4D5ADB790F1B9B791F1BAB792B793B794B795C7CFB796B797B798D2A4D6CFB799B79AF1BBBDD1B4B0BEBDB79BB79CB79DB4DCCED1B79EBFDFF1BDB79FB7A0B840B841BFFAF1BCB842F1BFB843B844B845F1BEF1C0B846B847B848B849B84AF1C1B84BB84CB84DB84EB84FB850B851B852B853B854B855C1FEB856B857B858B859B85AB85BB85CB85DB85EB85FB860C1A2B861B862B863B864B865B866B867B868B869B86ACAFAB86BB86CD5BEB86DB86EB86FB870BEBABEB9D5C2B871B872BFA2B873CDAFF1B5B874B875B876B877B878B879BDDFB87AB6CBB87BB87CB87DB87EB880B881B882B883B884D6F1F3C3B885B886F3C4B887B8CDB888B889B88AF3C6F3C7B88BB0CAB88CF3C5B88DF3C9CBF1B88EB88FB890F3CBB891D0A6B892B893B1CAF3C8B894B895B896F3CFB897B5D1B898B899F3D7B89AF3D2B89BB89CB89DF3D4F3D3B7FBB89EB1BFB89FF3CEF3CAB5DAB8A0F3D0B940B941F3D1B942F3D5B943B944B945B946F3CDB947BCE3B948C1FDB949F3D6B94AB94BB94CB94DB94EB94FF3DAB950F3CCB951B5C8B952BDEEF3DCB953B954B7A4BFF0D6FECDB2B955B4F0B956B2DFB957F3D8B958F3D9C9B8B959F3DDB95AB95BF3DEB95CF3E1B95DB95EB95FB960B961B962B963B964B965B966B967F3DFB968B969F3E3F3E2B96AB96BF3DBB96CBFEAB96DB3EFB96EF3E0B96FB970C7A9B971BCF2B972B973B974B975F3EBB976B977B978B979B97AB97BB97CB9BFB97DB97EF3E4B980B981B982B2ADBBFEB983CBE3B984B985B986B987F3EDF3E9B988B989B98AB9DCF3EEB98BB98CB98DF3E5F3E6F3EAC2E1F3ECF3EFF3E8BCFDB98EB98FB990CFE4B991B992F3F0B993B994B995F3E7B996B997B998B999B99AB99BB99CB99DF3F2B99EB99FB9A0BA40D7ADC6AABA41BA42BA43BA44F3F3BA45BA46BA47BA48F3F1BA49C2A8BA4ABA4BBA4CBA4DBA4EB8DDF3F5BA4FBA50F3F4BA51BA52BA53B4DBBA54BA55BA56F3F6F3F7BA57BA58BA59F3F8BA5ABA5BBA5CC0BABA5DBA5EC0E9BA5FBA60BA61BA62BA63C5F1BA64BA65BA66BA67F3FBBA68F3FABA69BA6ABA6BBA6CBA6DBA6EBA6FBA70B4D8BA71BA72BA73F3FEF3F9BA74BA75F3FCBA76BA77BA78BA79BA7ABA7BF3FDBA7CBA7DBA7EBA80BA81BA82BA83BA84F4A1BA85BA86BA87BA88BA89BA8AF4A3BBC9BA8BBA8CF4A2BA8DBA8EBA8FBA90BA91BA92BA93BA94BA95BA96BA97BA98BA99F4A4BA9ABA9BBA9CBA9DBA9EBA9FB2BEF4A6F4A5BAA0BB40BB41BB42BB43BB44BB45BB46BB47BB48BB49BCAEBB4ABB4BBB4CBB4DBB4EBB4FBB50BB51BB52BB53BB54BB55BB56BB57BB58BB59BB5ABB5BBB5CBB5DBB5EBB5FBB60BB61BB62BB63BB64BB65BB66BB67BB68BB69BB6ABB6BBB6CBB6DBB6EC3D7D9E1BB6FBB70BB71BB72BB73BB74C0E0F4CCD7D1BB75BB76BB77BB78BB79BB7ABB7BBB7CBB7DBB7EBB80B7DBBB81BB82BB83BB84BB85BB86BB87F4CEC1A3BB88BB89C6C9BB8AB4D6D5B3BB8BBB8CBB8DF4D0F4CFF4D1CBDABB8EBB8FF4D2BB90D4C1D6E0BB91BB92BB93BB94B7E0BB95BB96BB97C1B8BB98BB99C1BBF4D3BEACBB9ABB9BBB9CBB9DBB9EB4E2BB9FBBA0F4D4F4D5BEABBC40BC41F4D6BC42BC43BC44F4DBBC45F4D7F4DABC46BAFDBC47F4D8F4D9BC48BC49BC4ABC4BBC4CBC4DBC4EB8E2CCC7F4DCBC4FB2DABC50BC51C3D3BC52BC53D4E3BFB7BC54BC55BC56BC57BC58BC59BC5AF4DDBC5BBC5CBC5DBC5EBC5FBC60C5B4BC61BC62BC63BC64BC65BC66BC67BC68F4E9BC69BC6ACFB5BC6BBC6CBC6DBC6EBC6FBC70BC71BC72BC73BC74BC75BC76BC77BC78CEC9BC79BC7ABC7BBC7CBC7DBC7EBC80BC81BC82BC83BC84BC85BC86BC87BC88BC89BC8ABC8BBC8CBC8DBC8ECBD8BC8FCBF7BC90BC91BC92BC93BDF4BC94BC95BC96D7CFBC97BC98BC99C0DBBC9ABC9BBC9CBC9DBC9EBC9FBCA0BD40BD41BD42BD43BD44BD45BD46BD47BD48BD49BD4ABD4BBD4CBD4DBD4EBD4FBD50BD51BD52BD53BD54BD55BD56BD57BD58BD59BD5ABD5BBD5CBD5DBD5EBD5FBD60BD61BD62BD63BD64BD65BD66BD67BD68BD69BD6ABD6BBD6CBD6DBD6EBD6FBD70BD71BD72BD73BD74BD75BD76D0F5BD77BD78BD79BD7ABD7BBD7CBD7DBD7EF4EABD80BD81BD82BD83BD84BD85BD86BD87BD88BD89BD8ABD8BBD8CBD8DBD8EBD8FBD90BD91BD92BD93BD94BD95BD96BD97BD98BD99BD9ABD9BBD9CBD9DBD9EBD9FBDA0BE40BE41BE42BE43BE44BE45BE46BE47BE48BE49BE4ABE4BBE4CF4EBBE4DBE4EBE4FBE50BE51BE52BE53F4ECBE54BE55BE56BE57BE58BE59BE5ABE5BBE5CBE5DBE5EBE5FBE60BE61BE62BE63BE64BE65BE66BE67BE68BE69BE6ABE6BBE6CBE6DBE6EBE6FBE70BE71BE72BE73BE74BE75BE76BE77BE78BE79BE7ABE7BBE7CBE7DBE7EBE80BE81BE82BE83BE84BE85BE86BE87BE88BE89BE8ABE8BBE8CBE8DBE8EBE8FBE90BE91BE92BE93BE94BE95BE96BE97BE98BE99BE9ABE9BBE9CBE9DBE9EBE9FBEA0BF40BF41BF42BF43BF44BF45BF46BF47BF48BF49BF4ABF4BBF4CBF4DBF4EBF4FBF50BF51BF52BF53BF54BF55BF56BF57BF58BF59BF5ABF5BBF5CBF5DBF5EBF5FBF60BF61BF62BF63BF64BF65BF66BF67BF68BF69BF6ABF6BBF6CBF6DBF6EBF6FBF70BF71BF72BF73BF74BF75BF76BF77BF78BF79BF7ABF7BBF7CBF7DBF7EBF80F7E3BF81BF82BF83BF84BF85B7B1BF86BF87BF88BF89BF8AF4EDBF8BBF8CBF8DBF8EBF8FBF90BF91BF92BF93BF94BF95BF96BF97BF98BF99BF9ABF9BBF9CBF9DBF9EBF9FBFA0C040C041C042C043C044C045C046C047C048C049C04AC04BC04CC04DC04EC04FC050C051C052C053C054C055C056C057C058C059C05AC05BC05CC05DC05EC05FC060C061C062C063D7EBC064C065C066C067C068C069C06AC06BC06CC06DC06EC06FC070C071C072C073C074C075C076C077C078C079C07AC07BF4EEC07CC07DC07EE6F9BEC0E6FABAECE6FBCFCBE6FCD4BCBCB6E6FDE6FEBCCDC8D2CEB3E7A1C080B4BFE7A2C9B4B8D9C4C9C081D7DDC2DAB7D7D6BDCEC6B7C4C082C083C5A6E7A3CFDFE7A4E7A5E7A6C1B7D7E9C9F0CFB8D6AFD6D5E7A7B0EDE7A8E7A9C9DCD2EFBEADE7AAB0F3C8DEBDE1E7ABC8C6C084E7ACBBE6B8F8D1A4E7ADC2E7BEF8BDCACDB3E7AEE7AFBEEED0E5C085CBE7CCD0BCCCE7B0BCA8D0F7E7B1C086D0F8E7B2E7B3B4C2E7B4E7B5C9FECEACC3E0E7B7B1C1B3F1C087E7B8E7B9D7DBD5C0E7BAC2CCD7BAE7BBE7BCE7BDBCEAC3E5C0C2E7BEE7BFBCA9C088E7C0E7C1E7B6B6D0E7C2C089E7C3E7C4BBBAB5DEC2C6B1E0E7C5D4B5E7C6B8BFE7C8E7C7B7ECC08AE7C9B2F8E7CAE7CBE7CCE7CDE7CEE7CFE7D0D3A7CBF5E7D1E7D2E7D3E7D4C9C9E7D5E7D6E7D7E7D8E7D9BDC9E7DAF3BEC08BB8D7C08CC8B1C08DC08EC08FC090C091C092C093F3BFC094F3C0F3C1C095C096C097C098C099C09AC09BC09CC09DC09EB9DECDF8C09FC0A0D8E8BAB1C140C2DEEEB7C141B7A3C142C143C144C145EEB9C146EEB8B0D5C147C148C149C14AC14BEEBBD5D6D7EFC14CC14DC14ED6C3C14FC150EEBDCAF0C151EEBCC152C153C154C155EEBEC156C157C158C159EEC0C15AC15BEEBFC15CC15DC15EC15FC160C161C162C163D1F2C164C7BCC165C3C0C166C167C168C169C16AB8E1C16BC16CC16DC16EC16FC1E7C170C171F4C6D0DFF4C7C172CFDBC173C174C8BAC175C176F4C8C177C178C179C17AC17BC17CC17DF4C9F4CAC17EF4CBC180C181C182C183C184D9FAB8FEC185C186E5F1D3F0C187F4E0C188CECCC189C18AC18BB3E1C18CC18DC18EC18FF1B4C190D2EEC191F4E1C192C193C194C195C196CFE8F4E2C197C198C7CCC199C19AC19BC19CC19DC19EB5D4B4E4F4E4C19FC1A0C240F4E3F4E5C241C242F4E6C243C244C245C246F4E7C247BAB2B0BFC248F4E8C249C24AC24BC24CC24DC24EC24FB7ADD2EDC250C251C252D2ABC0CFC253BFBCEBA3D5DFEAC8C254C255C256C257F1F3B6F8CBA3C258C259C4CDC25AF1E7C25BF1E8B8FBF1E9BAC4D4C5B0D2C25CC25DF1EAC25EC25FC260F1EBC261F1ECC262C263F1EDF1EEF1EFF1F1F1F0C5D5C264C265C266C267C268C269F1F2C26AB6FAC26BF1F4D2AEDEC7CBCAC26CC26DB3DCC26EB5A2C26FB9A2C270C271C4F4F1F5C272C273F1F6C274C275C276C1C4C1FBD6B0F1F7C277C278C279C27AF1F8C27BC1AAC27CC27DC27EC6B8C280BEDBC281C282C283C284C285C286C287C288C289C28AC28BC28CC28DC28EF1F9B4CFC28FC290C291C292C293C294F1FAC295C296C297C298C299C29AC29BC29CC29DC29EC29FC2A0C340EDB2EDB1C341C342CBE0D2DEC343CBC1D5D8C344C8E2C345C0DFBCA1C346C347C348C349C34AC34BEBC1C34CC34DD0A4C34ED6E2C34FB6C7B8D8EBC0B8CEC350EBBFB3A6B9C9D6ABC351B7F4B7CAC352C353C354BCE7B7BEEBC6C355EBC7B0B9BFCFC356EBC5D3FDC357EBC8C358C359EBC9C35AC35BB7CEC35CEBC2EBC4C9F6D6D7D5CDD0B2EBCFCEB8EBD0C35DB5A8C35EC35FC360C361C362B1B3EBD2CCA5C363C364C365C366C367C368C369C5D6EBD3C36AEBD1C5DFEBCECAA4EBD5B0FBC36BC36CBAFAC36DC36ED8B7F1E3C36FEBCAEBCBEBCCEBCDEBD6E6C0EBD9C370BFE8D2C8EBD7EBDCB8ECEBD8C371BDBAC372D0D8C373B0B7C374EBDDC4DCC375C376C377C378D6ACC379C37AC37BB4E0C37CC37DC2F6BCB9C37EC380EBDAEBDBD4E0C6EAC4D4EBDFC5A7D9F5C381B2B1C382EBE4C383BDC5C384C385C386EBE2C387C388C389C38AC38BC38CC38DC38EC38FC390C391C392C393EBE3C394C395B8ACC396CDD1EBE5C397C398C399EBE1C39AC1B3C39BC39CC39DC39EC39FC6A2C3A0C440C441C442C443C444C445CCF3C446EBE6C447C0B0D2B8EBE7C448C449C44AB8AFB8ADC44BEBE8C7BBCDF3C44CC44DC44EEBEAEBEBC44FC450C451C452C453EBEDC454C455C456C457D0C8C458EBF2C459EBEEC45AC45BC45CEBF1C8F9C45DD1FCEBECC45EC45FEBE9C460C461C462C463B8B9CFD9C4E5EBEFEBF0CCDACDC8B0F2C464EBF6C465C466C467C468C469EBF5C46AB2B2C46BC46CC46DC46EB8E0C46FEBF7C470C471C472C473C474C475B1ECC476C477CCC5C4A4CFA5C478C479C47AC47BC47CEBF9C47DC47EECA2C480C5F2C481EBFAC482C483C484C485C486C487C488C489C9C5C48AC48BC48CC48DC48EC48FE2DFEBFEC490C491C492C493CDCEECA1B1DBD3B7C494C495D2DCC496C497C498EBFDC499EBFBC49AC49BC49CC49DC49EC49FC4A0C540C541C542C543C544C545C546C547C548C549C54AC54BC54CC54DC54EB3BCC54FC550C551EAB0C552C553D7D4C554F4ABB3F4C555C556C557C558C559D6C1D6C2C55AC55BC55CC55DC55EC55FD5E9BECAC560F4A7C561D2A8F4A8F4A9C562F4AABECBD3DFC563C564C565C566C567C9E0C9E1C568C569F3C2C56ACAE6C56BCCF2C56CC56DC56EC56FC570C571E2B6CBB4C572CEE8D6DBC573F4ADF4AEF4AFC574C575C576C577F4B2C578BABDF4B3B0E3F4B0C579F4B1BDA2B2D5C57AF4B6F4B7B6E6B2B0CFCFF4B4B4ACC57BF4B5C57CC57DF4B8C57EC580C581C582C583F4B9C584C585CDA7C586F4BAC587F4BBC588C589C58AF4BCC58BC58CC58DC58EC58FC590C591C592CBD2C593F4BDC594C595C596C597F4BEC598C599C59AC59BC59CC59DC59EC59FF4BFC5A0C640C641C642C643F4DEC1BCBCE8C644C9ABD1DEE5F5C645C646C647C648DCB3D2D5C649C64ADCB4B0ACDCB5C64BC64CBDDAC64DDCB9C64EC64FC650D8C2C651DCB7D3F3C652C9D6DCBADCB6C653DCBBC3A2C654C655C656C657DCBCDCC5DCBDC658C659CEDFD6A5C65ADCCFC65BDCCDC65CC65DDCD2BDE6C2ABC65EDCB8DCCBDCCEDCBEB7D2B0C5DCC7D0BEDCC1BBA8C65FB7BCDCCCC660C661DCC6DCBFC7DBC662C663C664D1BFDCC0C665C666DCCAC667C668DCD0C669C66ACEADDCC2C66BDCC3DCC8DCC9B2D4DCD1CBD5C66CD4B7DCDBDCDFCCA6DCE6C66DC3E7DCDCC66EC66FBFC1DCD9C670B0FAB9B6DCE5DCD3C671DCC4DCD6C8F4BFE0C672C673C674C675C9BBC676C677C678B1BDC679D3A2C67AC67BDCDAC67CC67DDCD5C67EC6BBC680DCDEC681C682C683C684C685D7C2C3AFB7B6C7D1C3A9DCE2DCD8DCEBDCD4C686C687DCDDC688BEA5DCD7C689DCE0C68AC68BDCE3DCE4C68CDCF8C68DC68EDCE1DDA2DCE7C68FC690C691C692C693C694C695C696C697C698BCEBB4C4C699C69AC3A3B2E7DCFAC69BDCF2C69CDCEFC69DDCFCDCEED2F0B2E8C69EC8D7C8E3DCFBC69FDCEDC6A0C740C741DCF7C742C743DCF5C744C745BEA3DCF4C746B2DDC747C748C749C74AC74BDCF3BCF6DCE8BBC4C74CC0F3C74DC74EC74FC750C751BCD4DCE9DCEAC752DCF1DCF6DCF9B5B4C753C8D9BBE7DCFEDCFDD3ABDDA1DDA3DDA5D2F1DDA4DDA6DDA7D2A9C754C755C756C757C758C759C75ABAC9DDA9C75BC75CDDB6DDB1DDB4C75DC75EC75FC760C761C762C763DDB0C6CEC764C765C0F2C766C767C768C769C9AFC76AC76BC76CDCECDDAEC76DC76EC76FC770DDB7C771C772DCF0DDAFC773DDB8C774DDACC775C776C777C778C779C77AC77BDDB9DDB3DDADC4AAC77CC77DC77EC780DDA8C0B3C1ABDDAADDABC781DDB2BBF1DDB5D3A8DDBAC782DDBBC3A7C783C784DDD2DDBCC785C786C787DDD1C788B9BDC789C78ABED5C78BBEFAC78CC78DBACAC78EC78FC790C791DDCAC792DDC5C793DDBFC794C795C796B2CBDDC3C797DDCBB2A4DDD5C798C799C79ADDBEC79BC79CC79DC6D0DDD0C79EC79FC7A0C840C841DDD4C1E2B7C6C842C843C844C845C846DDCEDDCFC847C848C849DDC4C84AC84BC84CDDBDC84DDDCDCCD1C84EDDC9C84FC850C851C852DDC2C3C8C6BCCEAEDDCCC853DDC8C854C855C856C857C858C859DDC1C85AC85BC85CDDC6C2DCC85DC85EC85FC860C861C862D3A9D3AADDD3CFF4C8F8C863C864C865C866C867C868C869C86ADDE6C86BC86CC86DC86EC86FC870DDC7C871C872C873DDE0C2E4C874C875C876C877C878C879C87AC87BDDE1C87CC87DC87EC880C881C882C883C884C885C886DDD7C887C888C889C88AC88BD6F8C88CDDD9DDD8B8F0DDD6C88DC88EC88FC890C6CFC891B6ADC892C893C894C895C896DDE2C897BAF9D4E1DDE7C898C899C89AB4D0C89BDDDAC89CBFFBDDE3C89DDDDFC89EDDDDC89FC8A0C940C941C942C943C944B5D9C945C946C947C948DDDBDDDCDDDEC949BDAFDDE4C94ADDE5C94BC94CC94DC94EC94FC950C951C952DDF5C953C3C9C954C955CBE2C956C957C958C959DDF2C95AC95BC95CC95DC95EC95FC960C961C962C963C964C965C966D8E1C967C968C6D1C969DDF4C96AC96BC96CD5F4DDF3DDF0C96DC96EDDECC96FDDEFC970DDE8C971C972D0EEC973C974C975C976C8D8DDEEC977C978DDE9C979C97ADDEACBF2C97BDDEDC97CC97DB1CDC97EC980C981C982C983C984C0B6C985BCBBDDF1C986C987DDF7C988DDF6DDEBC989C98AC98BC98CC98DC5EEC98EC98FC990DDFBC991C992C993C994C995C996C997C998C999C99AC99BDEA4C99CC99DDEA3C99EC99FC9A0CA40CA41CA42CA43CA44CA45CA46CA47CA48DDF8CA49CA4ACA4BCA4CC3EFCA4DC2FBCA4ECA4FCA50D5E1CA51CA52CEB5CA53CA54CA55CA56DDFDCA57B2CCCA58CA59CA5ACA5BCA5CCA5DCA5ECA5FCA60C4E8CADFCA61CA62CA63CA64CA65CA66CA67CA68CA69CA6AC7BEDDFADDFCDDFEDEA2B0AAB1CECA6BCA6CCA6DCA6ECA6FDEACCA70CA71CA72CA73DEA6BDB6C8EFCA74CA75CA76CA77CA78CA79CA7ACA7BCA7CCA7DCA7EDEA1CA80CA81DEA5CA82CA83CA84CA85DEA9CA86CA87CA88CA89CA8ADEA8CA8BCA8CCA8DDEA7CA8ECA8FCA90CA91CA92CA93CA94CA95CA96DEADCA97D4CCCA98CA99CA9ACA9BDEB3DEAADEAECA9CCA9DC0D9CA9ECA9FCAA0CB40CB41B1A1DEB6CB42DEB1CB43CB44CB45CB46CB47CB48CB49DEB2CB4ACB4BCB4CCB4DCB4ECB4FCB50CB51CB52CB53CB54D1A6DEB5CB55CB56CB57CB58CB59CB5ACB5BDEAFCB5CCB5DCB5EDEB0CB5FD0BDCB60CB61CB62DEB4CAEDDEB9CB63CB64CB65CB66CB67CB68DEB8CB69DEB7CB6ACB6BCB6CCB6DCB6ECB6FCB70DEBBCB71CB72CB73CB74CB75CB76CB77BDE5CB78CB79CB7ACB7BCB7CB2D8C3EACB7DCB7EDEBACB80C5BACB81CB82CB83CB84CB85CB86DEBCCB87CB88CB89CB8ACB8BCB8CCB8DCCD9CB8ECB8FCB90CB91B7AACB92CB93CB94CB95CB96CB97CB98CB99CB9ACB9BCB9CCB9DCB9ECB9FCBA0CC40CC41D4E5CC42CC43CC44DEBDCC45CC46CC47CC48CC49DEBFCC4ACC4BCC4CCC4DCC4ECC4FCC50CC51CC52CC53CC54C4A2CC55CC56CC57CC58DEC1CC59CC5ACC5BCC5CCC5DCC5ECC5FCC60CC61CC62CC63CC64CC65CC66CC67CC68DEBECC69DEC0CC6ACC6BCC6CCC6DCC6ECC6FCC70CC71CC72CC73CC74CC75CC76CC77D5BACC78CC79CC7ADEC2CC7BCC7CCC7DCC7ECC80CC81CC82CC83CC84CC85CC86CC87CC88CC89CC8ACC8BF2AEBBA2C2B2C5B0C2C7CC8CCC8DF2AFCC8ECC8FCC90CC91CC92D0E9CC93CC94CC95D3DDCC96CC97CC98EBBDCC99CC9ACC9BCC9CCC9DCC9ECC9FCCA0B3E6F2B0CD40F2B1CD41CD42CAADCD43CD44CD45CD46CD47CD48CD49BAE7F2B3F2B5F2B4CBE4CFBAF2B2CAB4D2CFC2ECCD4ACD4BCD4CCD4DCD4ECD4FCD50CEC3F2B8B0F6F2B7CD51CD52CD53CD54CD55F2BECD56B2CFCD57CD58CD59CD5ACD5BCD5CD1C1F2BACD5DCD5ECD5FCD60CD61F2BCD4E9CD62CD63F2BBF2B6F2BFF2BDCD64F2B9CD65CD66F2C7F2C4F2C6CD67CD68F2CAF2C2F2C0CD69CD6ACD6BF2C5CD6CCD6DCD6ECD6FCD70D6FBCD71CD72CD73F2C1CD74C7F9C9DFCD75F2C8B9C6B5B0CD76CD77F2C3F2C9F2D0F2D6CD78CD79BBD7CD7ACD7BCD7CF2D5CDDCCD7DD6EBCD7ECD80F2D2F2D4CD81CD82CD83CD84B8F2CD85CD86CD87CD88F2CBCD89CD8ACD8BF2CEC2F9CD8CD5DDF2CCF2CDF2CFF2D3CD8DCD8ECD8FF2D9D3BCCD90CD91CD92CD93B6EACD94CAF1CD95B7E4F2D7CD96CD97CD98F2D8F2DAF2DDF2DBCD99CD9AF2DCCD9BCD9CCD9DCD9ED1D1F2D1CD9FCDC9CDA0CECFD6A9CE40F2E3CE41C3DBCE42F2E0CE43CE44C0AFF2ECF2DECE45F2E1CE46CE47CE48F2E8CE49CE4ACE4BCE4CF2E2CE4DCE4EF2E7CE4FCE50F2E6CE51CE52F2E9CE53CE54CE55F2DFCE56CE57F2E4F2EACE58CE59CE5ACE5BCE5CCE5DCE5ED3ACF2E5B2F5CE5FCE60F2F2CE61D0ABCE62CE63CE64CE65F2F5CE66CE67CE68BBC8CE69F2F9CE6ACE6BCE6CCE6DCE6ECE6FF2F0CE70CE71F2F6F2F8F2FACE72CE73CE74CE75CE76CE77CE78CE79F2F3CE7AF2F1CE7BCE7CCE7DBAFBCE7EB5FBCE80CE81CE82CE83F2EFF2F7F2EDF2EECE84CE85CE86F2EBF3A6CE87F3A3CE88CE89F3A2CE8ACE8BF2F4CE8CC8DACE8DCE8ECE8FCE90CE91F2FBCE92CE93CE94F3A5CE95CE96CE97CE98CE99CE9ACE9BC3F8CE9CCE9DCE9ECE9FCEA0CF40CF41CF42F2FDCF43CF44F3A7F3A9F3A4CF45F2FCCF46CF47CF48F3ABCF49F3AACF4ACF4BCF4CCF4DC2DDCF4ECF4FF3AECF50CF51F3B0CF52CF53CF54CF55CF56F3A1CF57CF58CF59F3B1F3ACCF5ACF5BCF5CCF5DCF5EF3AFF2FEF3ADCF5FCF60CF61CF62CF63CF64CF65F3B2CF66CF67CF68CF69F3B4CF6ACF6BCF6CCF6DF3A8CF6ECF6FCF70CF71F3B3CF72CF73CF74F3B5CF75CF76CF77CF78CF79CF7ACF7BCF7CCF7DCF7ED0B7CF80CF81CF82CF83F3B8CF84CF85CF86CF87D9F9CF88CF89CF8ACF8BCF8CCF8DF3B9CF8ECF8FCF90CF91CF92CF93CF94CF95F3B7CF96C8E4F3B6CF97CF98CF99CF9AF3BACF9BCF9CCF9DCF9ECF9FF3BBB4C0CFA0D040D041D042D043D044D045D046D047D048D049D04AD04BD04CD04DEEC3D04ED04FD050D051D052D053F3BCD054D055F3BDD056D057D058D1AAD059D05AD05BF4ACD0C6D05CD05DD05ED05FD060D061D0D0D1DCD062D063D064D065D066D067CFCED068D069BDD6D06AD1C3D06BD06CD06DD06ED06FD070D071BAE2E1E9D2C2F1C2B2B9D072D073B1EDF1C3D074C9C0B3C4D075D9F2D076CBA5D077F1C4D078D079D07AD07BD6D4D07CD07DD07ED080D081F1C5F4C0F1C6D082D4ACF1C7D083B0C0F4C1D084D085F4C2D086D087B4FCD088C5DBD089D08AD08BD08CCCBBD08DD08ED08FD0E4D090D091D092D093D094CDE0D095D096D097D098D099F1C8D09AD9F3D09BD09CD09DD09ED09FD0A0B1BBD140CFAED141D142D143B8A4D144D145D146D147D148F1CAD149D14AD14BD14CF1CBD14DD14ED14FD150B2C3C1D1D151D152D7B0F1C9D153D154F1CCD155D156D157D158F1CED159D15AD15BD9F6D15CD2E1D4A3D15DD15EF4C3C8B9D15FD160D161D162D163F4C4D164D165F1CDF1CFBFE3F1D0D166D167F1D4D168D169D16AD16BD16CD16DD16EF1D6F1D1D16FC9D1C5E1D170D171D172C2E3B9FCD173D174F1D3D175F1D5D176D177D178B9D3D179D17AD17BD17CD17DD17ED180F1DBD181D182D183D184D185BAD6D186B0FDF1D9D187D188D189D18AD18BF1D8F1D2F1DAD18CD18DD18ED18FD190F1D7D191D192D193C8ECD194D195D196D197CDCAF1DDD198D199D19AD19BE5BDD19CD19DD19EF1DCD19FF1DED1A0D240D241D242D243D244D245D246D247D248F1DFD249D24ACFE5D24BD24CD24DD24ED24FD250D251D252D253D254D255D256D257D258D259D25AD25BD25CD25DD25ED25FD260D261D262D263F4C5BDF3D264D265D266D267D268D269F1E0D26AD26BD26CD26DD26ED26FD270D271D272D273D274D275D276D277D278D279D27AD27BD27CD27DF1E1D27ED280D281CEF7D282D2AAD283F1FBD284D285B8B2D286D287D288D289D28AD28BD28CD28DD28ED28FD290D291D292D293D294D295D296D297D298D299D29AD29BD29CD29DD29ED29FD2A0D340D341D342D343D344D345D346D347D348D349D34AD34BD34CD34DD34ED34FD350D351D352D353D354D355D356D357D358D359D35AD35BD35CD35DD35EBCFBB9DBD35FB9E6C3D9CAD3EAE8C0C0BEF5EAE9EAEAEAEBD360EAECEAEDEAEEEAEFBDC7D361D362D363F5FBD364D365D366F5FDD367F5FED368F5FCD369D36AD36BD36CBDE2D36DF6A1B4A5D36ED36FD370D371F6A2D372D373D374F6A3D375D376D377ECB2D378D379D37AD37BD37CD37DD37ED380D381D382D383D384D1D4D385D386D387D388D389D38AD9EAD38BD38CD38DD38ED38FD390D391D392D393D394D395D396D397D398D399D39AD39BD39CD39DD39ED39FD3A0D440D441D442D443D444D445D446D447D448D449D44AD44BD44CD44DD44ED44FD450D451D452D453D454D455D456D457D458D459D45AD45BD45CD45DD45ED45FF6A4D460D461D462D463D464D465D466D467D468EEBAD469D46AD46BD46CD46DD46ED46FD470D471D472D473D474D475D476D477D478D479D47AD47BD47CD47DD47ED480D481D482D483D484D485D486D487D488D489D48AD48BD48CD48DD48ED48FD490D491D492D493D494D495D496D497D498D499D5B2D49AD49BD49CD49DD49ED49FD4A0D540D541D542D543D544D545D546D547D3FECCDCD548D549D54AD54BD54CD54DD54ED54FCAC4D550D551D552D553D554D555D556D557D558D559D55AD55BD55CD55DD55ED55FD560D561D562D563D564D565D566D567D568D569D56AD56BD56CD56DD56ED56FD570D571D572D573D574D575D576D577D578D579D57AD57BD57CD57DD57ED580D581D582D583D584D585D586D587D588D589D58AD58BD58CD58DD58ED58FD590D591D592D593D594D595D596D597D598D599D59AD59BD59CD59DD59ED59FD5A0D640D641D642D643D644D645D646D647D648D649D64AD64BD64CD64DD64ED64FD650D651D652D653D654D655D656D657D658D659D65AD65BD65CD65DD65ED65FD660D661D662E5C0D663D664D665D666D667D668D669D66AD66BD66CD66DD66ED66FD670D671D672D673D674D675D676D677D678D679D67AD67BD67CD67DD67ED680D681F6A5D682D683D684D685D686D687D688D689D68AD68BD68CD68DD68ED68FD690D691D692D693D694D695D696D697D698D699D69AD69BD69CD69DD69ED69FD6A0D740D741D742D743D744D745D746D747D748D749D74AD74BD74CD74DD74ED74FD750D751D752D753D754D755D756D757D758D759D75AD75BD75CD75DD75ED75FBEAFD760D761D762D763D764C6A9D765D766D767D768D769D76AD76BD76CD76DD76ED76FD770D771D772D773D774D775D776D777D778D779D77AD77BD77CD77DD77ED780D781D782D783D784D785D786D787D788D789D78AD78BD78CD78DD78ED78FD790D791D792D793D794D795D796D797D798DAA5BCC6B6A9B8BCC8CFBCA5DAA6DAA7CCD6C8C3DAA8C6FDD799D1B5D2E9D1B6BCC7D79ABDB2BBE4DAA9DAAAD1C8DAABD0EDB6EFC2DBD79BCBCFB7EDC9E8B7C3BEF7D6A4DAACDAADC6C0D7E7CAB6D79CD5A9CBDFD5EFDAAED6DFB4CADAB0DAAFD79DD2EBDAB1DAB2DAB3CAD4DAB4CAABDAB5DAB6B3CFD6EFDAB7BBB0B5AEDAB8DAB9B9EED1AFD2E8DABAB8C3CFEAB2EFDABBDABCD79EBDEBCEDCD3EFDABDCEF3DABED3D5BBE5DABFCBB5CBD0DAC0C7EBD6EEDAC1C5B5B6C1DAC2B7CCBFCEDAC3DAC4CBADDAC5B5F7DAC6C1C2D7BBDAC7CCB8D79FD2EAC4B1DAC8B5FDBBD1DAC9D0B3DACADACBCEBDDACCDACDDACEB2F7DAD1DACFD1E8DAD0C3D5DAD2D7A0DAD3DAD4DAD5D0BBD2A5B0F9DAD6C7ABDAD7BDF7C3A1DAD8DAD9C3FDCCB7DADADADBC0BEC6D7DADCDADDC7B4DADEDADFB9C8D840D841D842D843D844D845D846D847D848BBEDD849D84AD84BD84CB6B9F4F8D84DF4F9D84ED84FCDE3D850D851D852D853D854D855D856D857F5B9D858D859D85AD85BEBE0D85CD85DD85ED85FD860D861CFF3BBBFD862D863D864D865D866D867D868BAC0D4A5D869D86AD86BD86CD86DD86ED86FE1D9D870D871D872D873F5F4B1AAB2F2D874D875D876D877D878D879D87AF5F5D87BD87CF5F7D87DD87ED880BAD1F5F6D881C3B2D882D883D884D885D886D887D888F5F9D889D88AD88BF5F8D88CD88DD88ED88FD890D891D892D893D894D895D896D897D898D899D89AD89BD89CD89DD89ED89FD8A0D940D941D942D943D944D945D946D947D948D949D94AD94BD94CD94DD94ED94FD950D951D952D953D954D955D956D957D958D959D95AD95BD95CD95DD95ED95FD960D961D962D963D964D965D966D967D968D969D96AD96BD96CD96DD96ED96FD970D971D972D973D974D975D976D977D978D979D97AD97BD97CD97DD97ED980D981D982D983D984D985D986D987D988D989D98AD98BD98CD98DD98ED98FD990D991D992D993D994D995D996D997D998D999D99AD99BD99CD99DD99ED99FD9A0DA40DA41DA42DA43DA44DA45DA46DA47DA48DA49DA4ADA4BDA4CDA4DDA4EB1B4D5EAB8BADA4FB9B1B2C6D4F0CFCDB0DCD5CBBBF5D6CAB7B7CCB0C6B6B1E1B9BAD6FCB9E1B7A1BCFAEADAEADBCCF9B9F3EADCB4FBC3B3B7D1BAD8EADDD4F4EADEBCD6BBDFEADFC1DEC2B8D4DFD7CAEAE0EAE1EAE4EAE2EAE3C9DEB8B3B6C4EAE5CAEAC9CDB4CDDA50DA51E2D9C5E2EAE6C0B5DA52D7B8EAE7D7ACC8FCD8D3D8CDD4DEDA53D4F9C9C4D3AEB8D3B3E0DA54C9E2F4F6DA55DA56DA57BAD5DA58F4F7DA59DA5AD7DFDA5BDA5CF4F1B8B0D5D4B8CFC6F0DA5DDA5EDA5FDA60DA61DA62DA63DA64DA65B3C3DA66DA67F4F2B3ACDA68DA69DA6ADA6BD4BDC7F7DA6CDA6DDA6EDA6FDA70F4F4DA71DA72F4F3DA73DA74DA75DA76DA77DA78DA79DA7ADA7BDA7CCCCBDA7DDA7EDA80C8A4DA81DA82DA83DA84DA85DA86DA87DA88DA89DA8ADA8BDA8CDA8DF4F5DA8ED7E3C5BFF5C0DA8FDA90F5BBDA91F5C3DA92F5C2DA93D6BAF5C1DA94DA95DA96D4BEF5C4DA97F5CCDA98DA99DA9ADA9BB0CFB5F8DA9CF5C9F5CADA9DC5DCDA9EDA9FDAA0DB40F5C5F5C6DB41DB42F5C7F5CBDB43BEE0F5C8B8FADB44DB45DB46F5D0F5D3DB47DB48DB49BFE7DB4AB9F2F5BCF5CDDB4BDB4CC2B7DB4DDB4EDB4FCCF8DB50BCF9DB51F5CEF5CFF5D1B6E5F5D2DB52F5D5DB53DB54DB55DB56DB57DB58DB59F5BDDB5ADB5BDB5CF5D4D3BBDB5DB3ECDB5EDB5FCCA4DB60DB61DB62DB63F5D6DB64DB65DB66DB67DB68DB69DB6ADB6BF5D7BEE1F5D8DB6CDB6DCCDFF5DBDB6EDB6FDB70DB71DB72B2C8D7D9DB73F5D9DB74F5DAF5DCDB75F5E2DB76DB77DB78F5E0DB79DB7ADB7BF5DFF5DDDB7CDB7DF5E1DB7EDB80F5DEF5E4F5E5DB81CCE3DB82DB83E5BFB5B8F5E3F5E8CCA3DB84DB85DB86DB87DB88F5E6F5E7DB89DB8ADB8BDB8CDB8DDB8EF5BEDB8FDB90DB91DB92DB93DB94DB95DB96DB97DB98DB99DB9AB1C4DB9BDB9CF5BFDB9DDB9EB5C5B2E4DB9FF5ECF5E9DBA0B6D7DC40F5EDDC41F5EADC42DC43DC44DC45DC46F5EBDC47DC48B4DADC49D4EADC4ADC4BDC4CF5EEDC4DB3F9DC4EDC4FDC50DC51DC52DC53DC54F5EFF5F1DC55DC56DC57F5F0DC58DC59DC5ADC5BDC5CDC5DDC5EF5F2DC5FF5F3DC60DC61DC62DC63DC64DC65DC66DC67DC68DC69DC6ADC6BC9EDB9AADC6CDC6DC7FBDC6EDC6FB6E3DC70DC71DC72DC73DC74DC75DC76CCC9DC77DC78DC79DC7ADC7BDC7CDC7DDC7EDC80DC81DC82DC83DC84DC85DC86DC87DC88DC89DC8AEAA6DC8BDC8CDC8DDC8EDC8FDC90DC91DC92DC93DC94DC95DC96DC97DC98DC99DC9ADC9BDC9CDC9DDC9EDC9FDCA0DD40DD41DD42DD43DD44DD45DD46DD47DD48DD49DD4ADD4BDD4CDD4DDD4EDD4FDD50DD51DD52DD53DD54DD55DD56DD57DD58DD59DD5ADD5BDD5CDD5DDD5EDD5FDD60DD61DD62DD63DD64DD65DD66DD67DD68DD69DD6ADD6BDD6CDD6DDD6EDD6FDD70DD71DD72DD73DD74DD75DD76DD77DD78DD79DD7ADD7BDD7CDD7DDD7EDD80DD81DD82DD83DD84DD85DD86DD87DD88DD89DD8ADD8BDD8CDD8DDD8EDD8FDD90DD91DD92DD93DD94DD95DD96DD97DD98DD99DD9ADD9BDD9CDD9DDD9EDD9FDDA0DE40DE41DE42DE43DE44DE45DE46DE47DE48DE49DE4ADE4BDE4CDE4DDE4EDE4FDE50DE51DE52DE53DE54DE55DE56DE57DE58DE59DE5ADE5BDE5CDE5DDE5EDE5FDE60B3B5D4FEB9ECD0F9DE61E9EDD7AAE9EEC2D6C8EDBAE4E9EFE9F0E9F1D6E1E9F2E9F3E9F5E9F4E9F6E9F7C7E1E9F8D4D8E9F9BDCEDE62E9FAE9FBBDCFE9FCB8A8C1BEE9FDB1B2BBD4B9F5E9FEDE63EAA1EAA2EAA3B7F8BCADDE64CAE4E0CED4AFCFBDD5B7EAA4D5DEEAA5D0C1B9BCDE65B4C7B1D9DE66DE67DE68C0B1DE69DE6ADE6BDE6CB1E6B1E7DE6DB1E8DE6EDE6FDE70DE71B3BDC8E8DE72DE73DE74DE75E5C1DE76DE77B1DFDE78DE79DE7AC1C9B4EFDE7BDE7CC7A8D3D8DE7DC6F9D1B8DE7EB9FDC2F5DE80DE81DE82DE83DE84D3ADDE85D4CBBDFCDE86E5C2B7B5E5C3DE87DE88BBB9D5E2DE89BDF8D4B6CEA5C1ACB3D9DE8ADE8BCCF6DE8CE5C6E5C4E5C8DE8DE5CAE5C7B5CFC6C8DE8EB5FCE5C5DE8FCAF6DE90DE91E5C9DE92DE93DE94C3D4B1C5BCA3DE95DE96DE97D7B7DE98DE99CDCBCBCDCACACCD3E5CCE5CBC4E6DE9ADE9BD1A1D1B7E5CDDE9CE5D0DE9DCDB8D6F0E5CFB5DDDE9ECDBEDE9FE5D1B6BADEA0DF40CDA8B9E4DF41CAC5B3D1CBD9D4ECE5D2B7EADF42DF43DF44E5CEDF45DF46DF47DF48DF49DF4AE5D5B4FEE5D6DF4BDF4CDF4DDF4EDF4FE5D3E5D4DF50D2DDDF51DF52C2DFB1C6DF53D3E2DF54DF55B6DDCBECDF56E5D7DF57DF58D3F6DF59DF5ADF5BDF5CDF5DB1E9DF5EB6F4E5DAE5D8E5D9B5C0DF5FDF60DF61D2C5E5DCDF62DF63E5DEDF64DF65DF66DF67DF68DF69E5DDC7B2DF6AD2A3DF6BDF6CE5DBDF6DDF6EDF6FDF70D4E2D5DADF71DF72DF73DF74DF75E5E0D7F1DF76DF77DF78DF79DF7ADF7BDF7CE5E1DF7DB1DCD1FBDF7EE5E2E5E4DF80DF81DF82DF83E5E3DF84DF85E5E5DF86DF87DF88DF89DF8AD2D8DF8BB5CBDF8CE7DFDF8DDAF5DF8EDAF8DF8FDAF6DF90DAF7DF91DF92DF93DAFAD0CFC4C7DF94DF95B0EEDF96DF97DF98D0B0DF99DAF9DF9AD3CABAAADBA2C7F1DF9BDAFCDAFBC9DBDAFDDF9CDBA1D7DEDAFEC1DADF9DDF9EDBA5DF9FDFA0D3F4E040E041DBA7DBA4E042DBA8E043E044BDBCE045E046E047C0C9DBA3DBA6D6A3E048DBA9E049E04AE04BDBADE04CE04DE04EDBAEDBACBAC2E04FE050E051BFA4DBABE052E053E054DBAAD4C7B2BFE055E056DBAFE057B9F9E058DBB0E059E05AE05BE05CB3BBE05DE05EE05FB5A6E060E061E062E063B6BCDBB1E064E065E066B6F5E067DBB2E068E069E06AE06BE06CE06DE06EE06FE070E071E072E073E074E075E076E077E078E079E07AE07BB1C9E07CE07DE07EE080DBB4E081E082E083DBB3DBB5E084E085E086E087E088E089E08AE08BE08CE08DE08EDBB7E08FDBB6E090E091E092E093E094E095E096DBB8E097E098E099E09AE09BE09CE09DE09EE09FDBB9E0A0E140DBBAE141E142D3CFF4FAC7F5D7C3C5E4F4FCF4FDF4FBE143BEC6E144E145E146E147D0EFE148E149B7D3E14AE14BD4CDCCAAE14CE14DF5A2F5A1BAA8F4FECBD6E14EE14FE150F5A4C0D2E151B3EAE152CDAAF5A5F5A3BDB4F5A8E153F5A9BDCDC3B8BFE1CBE1F5AAE154E155E156F5A6F5A7C4F0E157E158E159E15AE15BF5ACE15CB4BCE15DD7EDE15EB4D7F5ABF5AEE15FE160F5ADF5AFD0D1E161E162E163E164E165E166E167C3D1C8A9E168E169E16AE16BE16CE16DF5B0F5B1E16EE16FE170E171E172E173F5B2E174E175F5B3F5B4F5B5E176E177E178E179F5B7F5B6E17AE17BE17CE17DF5B8E17EE180E181E182E183E184E185E186E187E188E189E18AB2C9E18BD3D4CACDE18CC0EFD6D8D2B0C1BFE18DBDF0E18EE18FE190E191E192E193E194E195E196E197B8AAE198E199E19AE19BE19CE19DE19EE19FE1A0E240E241E242E243E244E245E246E247E248E249E24AE24BE24CE24DE24EE24FE250E251E252E253E254E255E256E257E258E259E25AE25BE25CE25DE25EE25FE260E261E262E263E264E265E266E267E268E269E26AE26BE26CE26DE26EE26FE270E271E272E273E274E275E276E277E278E279E27AE27BE27CE27DE27EE280E281E282E283E284E285E286E287E288E289E28AE28BE28CE28DE28EE28FE290E291E292E293E294E295E296E297E298E299E29AE29BE29CE29DE29EE29FE2A0E340E341E342E343E344E345E346E347E348E349E34AE34BE34CE34DE34EE34FE350E351E352E353E354E355E356E357E358E359E35AE35BE35CE35DE35EE35FE360E361E362E363E364E365E366E367E368E369E36AE36BE36CE36DBCF8E36EE36FE370E371E372E373E374E375E376E377E378E379E37AE37BE37CE37DE37EE380E381E382E383E384E385E386E387F6C6E388E389E38AE38BE38CE38DE38EE38FE390E391E392E393E394E395E396E397E398E399E39AE39BE39CE39DE39EE39FE3A0E440E441E442E443E444E445F6C7E446E447E448E449E44AE44BE44CE44DE44EE44FE450E451E452E453E454E455E456E457E458E459E45AE45BE45CE45DE45EF6C8E45FE460E461E462E463E464E465E466E467E468E469E46AE46BE46CE46DE46EE46FE470E471E472E473E474E475E476E477E478E479E47AE47BE47CE47DE47EE480E481E482E483E484E485E486E487E488E489E48AE48BE48CE48DE48EE48FE490E491E492E493E494E495E496E497E498E499E49AE49BE49CE49DE49EE49FE4A0E540E541E542E543E544E545E546E547E548E549E54AE54BE54CE54DE54EE54FE550E551E552E553E554E555E556E557E558E559E55AE55BE55CE55DE55EE55FE560E561E562E563E564E565E566E567E568E569E56AE56BE56CE56DE56EE56FE570E571E572E573F6C9E574E575E576E577E578E579E57AE57BE57CE57DE57EE580E581E582E583E584E585E586E587E588E589E58AE58BE58CE58DE58EE58FE590E591E592E593E594E595E596E597E598E599E59AE59BE59CE59DE59EE59FF6CAE5A0E640E641E642E643E644E645E646E647E648E649E64AE64BE64CE64DE64EE64FE650E651E652E653E654E655E656E657E658E659E65AE65BE65CE65DE65EE65FE660E661E662F6CCE663E664E665E666E667E668E669E66AE66BE66CE66DE66EE66FE670E671E672E673E674E675E676E677E678E679E67AE67BE67CE67DE67EE680E681E682E683E684E685E686E687E688E689E68AE68BE68CE68DE68EE68FE690E691E692E693E694E695E696E697E698E699E69AE69BE69CE69DF6CBE69EE69FE6A0E740E741E742E743E744E745E746E747F7E9E748E749E74AE74BE74CE74DE74EE74FE750E751E752E753E754E755E756E757E758E759E75AE75BE75CE75DE75EE75FE760E761E762E763E764E765E766E767E768E769E76AE76BE76CE76DE76EE76FE770E771E772E773E774E775E776E777E778E779E77AE77BE77CE77DE77EE780E781E782E783E784E785E786E787E788E789E78AE78BE78CE78DE78EE78FE790E791E792E793E794E795E796E797E798E799E79AE79BE79CE79DE79EE79FE7A0E840E841E842E843E844E845E846E847E848E849E84AE84BE84CE84DE84EF6CDE84FE850E851E852E853E854E855E856E857E858E859E85AE85BE85CE85DE85EE85FE860E861E862E863E864E865E866E867E868E869E86AE86BE86CE86DE86EE86FE870E871E872E873E874E875E876E877E878E879E87AF6CEE87BE87CE87DE87EE880E881E882E883E884E885E886E887E888E889E88AE88BE88CE88DE88EE88FE890E891E892E893E894EEC4EEC5EEC6D5EBB6A4EEC8EEC7EEC9EECAC7A5EECBEECCE895B7B0B5F6EECDEECFE896EECEE897B8C6EED0EED1EED2B6DBB3AED6D3C4C6B1B5B8D6EED3EED4D4BFC7D5BEFBCED9B9B3EED6EED5EED8EED7C5A5EED9EEDAC7AEEEDBC7AFEEDCB2A7EEDDEEDEEEDFEEE0EEE1D7EAEEE2EEE3BCD8EEE4D3CBCCFAB2ACC1E5EEE5C7A6C3ADE898EEE6EEE7EEE8EEE9EEEAEEEBEEECE899EEEDEEEEEEEFE89AE89BEEF0EEF1EEF2EEF4EEF3E89CEEF5CDADC2C1EEF6EEF7EEF8D5A1EEF9CFB3EEFAEEFBE89DEEFCEEFDEFA1EEFEEFA2B8F5C3FAEFA3EFA4BDC2D2BFB2F9EFA5EFA6EFA7D2F8EFA8D6FDEFA9C6CCE89EEFAAEFABC1B4EFACCFFACBF8EFAEEFADB3FAB9F8EFAFEFB0D0E2EFB1EFB2B7E6D0BFEFB3EFB4EFB5C8F1CCE0EFB6EFB7EFB8EFB9EFBAD5E0EFBBB4EDC3AAEFBCE89FEFBDEFBEEFBFE8A0CEFDEFC0C2E0B4B8D7B6BDF5E940CFC7EFC3EFC1EFC2EFC4B6A7BCFCBEE2C3CCEFC5EFC6E941EFC7EFCFEFC8EFC9EFCAC7C2EFF1B6CDEFCBE942EFCCEFCDB6C6C3BEEFCEE943EFD0EFD1EFD2D5F2E944EFD3C4F7E945EFD4C4F8EFD5EFD6B8E4B0F7EFD7EFD8EFD9E946EFDAEFDBEFDCEFDDE947EFDEBEB5EFE1EFDFEFE0E948EFE2EFE3C1CDEFE4EFE5EFE6EFE7EFE8EFE9EFEAEFEBEFECC0D8E949EFEDC1ADEFEEEFEFEFF0E94AE94BCFE2E94CE94DE94EE94FE950E951E952E953B3A4E954E955E956E957E958E959E95AE95BE95CE95DE95EE95FE960E961E962E963E964E965E966E967E968E969E96AE96BE96CE96DE96EE96FE970E971E972E973E974E975E976E977E978E979E97AE97BE97CE97DE97EE980E981E982E983E984E985E986E987E988E989E98AE98BE98CE98DE98EE98FE990E991E992E993E994E995E996E997E998E999E99AE99BE99CE99DE99EE99FE9A0EA40EA41EA42EA43EA44EA45EA46EA47EA48EA49EA4AEA4BEA4CEA4DEA4EEA4FEA50EA51EA52EA53EA54EA55EA56EA57EA58EA59EA5AEA5BC3C5E3C5C9C1E3C6EA5CB1D5CECAB4B3C8F2E3C7CFD0E3C8BCE4E3C9E3CAC3C6D5A2C4D6B9EBCEC5E3CBC3F6E3CCEA5DB7A7B8F3BAD2E3CDE3CED4C4E3CFEA5EE3D0D1CBE3D1E3D2E3D3E3D4D1D6E3D5B2FBC0BBE3D6EA5FC0ABE3D7E3D8E3D9EA60E3DAE3DBEA61B8B7DAE2EA62B6D3EA63DAE4DAE3EA64EA65EA66EA67EA68EA69EA6ADAE6EA6BEA6CEA6DC8EEEA6EEA6FDAE5B7C0D1F4D2F5D5F3BDD7EA70EA71EA72EA73D7E8DAE8DAE7EA74B0A2CDD3EA75DAE9EA76B8BDBCCAC2BDC2A4B3C2DAEAEA77C2AAC4B0BDB5EA78EA79CFDEEA7AEA7BEA7CDAEBC9C2EA7DEA7EEA80EA81EA82B1DDEA83EA84EA85DAECEA86B6B8D4BAEA87B3FDEA88EA89DAEDD4C9CFD5C5E3EA8ADAEEEA8BEA8CEA8DEA8EEA8FDAEFEA90DAF0C1EACCD5CFDDEA91EA92EA93EA94EA95EA96EA97EA98EA99EA9AEA9BEA9CEA9DD3E7C2A1EA9EDAF1EA9FEAA0CBE5EB40DAF2EB41CBE6D2FEEB42EB43EB44B8F4EB45EB46DAF3B0AFCFB6EB47EB48D5CFEB49EB4AEB4BEB4CEB4DEB4EEB4FEB50EB51EB52CBEDEB53EB54EB55EB56EB57EB58EB59EB5ADAF4EB5BEB5CE3C4EB5DEB5EC1A5EB5FEB60F6BFEB61EB62F6C0F6C1C4D1EB63C8B8D1E3EB64EB65D0DBD1C5BCAFB9CDEB66EFF4EB67EB68B4C6D3BAF6C2B3FBEB69EB6AF6C3EB6BEB6CB5F1EB6DEB6EEB6FEB70EB71EB72EB73EB74EB75EB76F6C5EB77EB78EB79EB7AEB7BEB7CEB7DD3EAF6A7D1A9EB7EEB80EB81EB82F6A9EB83EB84EB85F6A8EB86EB87C1E3C0D7EB88B1A2EB89EB8AEB8BEB8CCEEDEB8DD0E8F6ABEB8EEB8FCFF6EB90F6AAD5F0F6ACC3B9EB91EB92EB93BBF4F6AEF6ADEB94EB95EB96C4DEEB97EB98C1D8EB99EB9AEB9BEB9CEB9DCBAAEB9ECFBCEB9FEBA0EC40EC41EC42EC43EC44EC45EC46EC47EC48F6AFEC49EC4AF6B0EC4BEC4CF6B1EC4DC2B6EC4EEC4FEC50EC51EC52B0D4C5F9EC53EC54EC55EC56F6B2EC57EC58EC59EC5AEC5BEC5CEC5DEC5EEC5FEC60EC61EC62EC63EC64EC65EC66EC67EC68EC69C7E0F6A6EC6AEC6BBEB8EC6CEC6DBEB2EC6EB5E5EC6FEC70B7C7EC71BFBFC3D2C3E6EC72EC73D8CCEC74EC75EC76B8EFEC77EC78EC79EC7AEC7BEC7CEC7DEC7EEC80BDF9D1A5EC81B0D0EC82EC83EC84EC85EC86F7B0EC87EC88EC89EC8AEC8BEC8CEC8DEC8EF7B1EC8FEC90EC91EC92EC93D0ACEC94B0B0EC95EC96EC97F7B2F7B3EC98F7B4EC99EC9AEC9BC7CAEC9CEC9DEC9EEC9FECA0ED40ED41BECFED42ED43F7B7ED44ED45ED46ED47ED48ED49ED4AF7B6ED4BB1DEED4CF7B5ED4DED4EF7B8ED4FF7B9ED50ED51ED52ED53ED54ED55ED56ED57ED58ED59ED5AED5BED5CED5DED5EED5FED60ED61ED62ED63ED64ED65ED66ED67ED68ED69ED6AED6BED6CED6DED6EED6FED70ED71ED72ED73ED74ED75ED76ED77ED78ED79ED7AED7BED7CED7DED7EED80ED81CEA4C8CDED82BAABE8B8E8B9E8BABEC2ED83ED84ED85ED86ED87D2F4ED88D4CFC9D8ED89ED8AED8BED8CED8DED8EED8FED90ED91ED92ED93ED94ED95ED96ED97ED98ED99ED9AED9BED9CED9DED9EED9FEDA0EE40EE41EE42EE43EE44EE45EE46EE47EE48EE49EE4AEE4BEE4CEE4DEE4EEE4FEE50EE51EE52EE53EE54EE55EE56EE57EE58EE59EE5AEE5BEE5CEE5DEE5EEE5FEE60EE61EE62EE63EE64EE65EE66EE67EE68EE69EE6AEE6BEE6CEE6DEE6EEE6FEE70EE71EE72EE73EE74EE75EE76EE77EE78EE79EE7AEE7BEE7CEE7DEE7EEE80EE81EE82EE83EE84EE85EE86EE87EE88EE89EE8AEE8BEE8CEE8DEE8EEE8FEE90EE91EE92EE93EE94EE95EE96EE97EE98EE99EE9AEE9BEE9CEE9DEE9EEE9FEEA0EF40EF41EF42EF43EF44EF45D2B3B6A5C7EAF1FCCFEECBB3D0EBE7EFCDE7B9CBB6D9F1FDB0E4CBCCF1FED4A4C2ADC1ECC6C4BEB1F2A1BCD5EF46F2A2F2A3EF47F2A4D2C3C6B5EF48CDC7F2A5EF49D3B1BFC5CCE2EF4AF2A6F2A7D1D5B6EEF2A8F2A9B5DFF2AAF2ABEF4BB2FCF2ACF2ADC8A7EF4CEF4DEF4EEF4FEF50EF51EF52EF53EF54EF55EF56EF57EF58EF59EF5AEF5BEF5CEF5DEF5EEF5FEF60EF61EF62EF63EF64EF65EF66EF67EF68EF69EF6AEF6BEF6CEF6DEF6EEF6FEF70EF71B7E7EF72EF73ECA9ECAAECABEF74ECACEF75EF76C6AEECADECAEEF77EF78EF79B7C9CAB3EF7AEF7BEF7CEF7DEF7EEF80EF81E2B8F7CFEF82EF83EF84EF85EF86EF87EF88EF89EF8AEF8BEF8CEF8DEF8EEF8FEF90EF91EF92EF93EF94EF95EF96EF97EF98EF99EF9AEF9BEF9CEF9DEF9EEF9FEFA0F040F041F042F043F044F7D0F045F046B2CDF047F048F049F04AF04BF04CF04DF04EF04FF050F051F052F053F054F055F056F057F058F059F05AF05BF05CF05DF05EF05FF060F061F062F063F7D1F064F065F066F067F068F069F06AF06BF06CF06DF06EF06FF070F071F072F073F074F075F076F077F078F079F07AF07BF07CF07DF07EF080F081F082F083F084F085F086F087F088F089F7D3F7D2F08AF08BF08CF08DF08EF08FF090F091F092F093F094F095F096E2BBF097BCA2F098E2BCE2BDE2BEE2BFE2C0E2C1B7B9D2FBBDA4CACEB1A5CBC7F099E2C2B6FCC8C4E2C3F09AF09BBDC8F09CB1FDE2C4F09DB6F6E2C5C4D9F09EF09FE2C6CFDAB9DDE2C7C0A1F0A0E2C8B2F6F140E2C9F141C1F3E2CAE2CBC2F8E2CCE2CDE2CECAD7D8B8D9E5CFE3F142F143F144F145F146F147F148F149F14AF14BF14CF0A5F14DF14EDCB0F14FF150F151F152F153F154F155F156F157F158F159F15AF15BF15CF15DF15EF15FF160F161F162F163F164F165F166F167F168F169F16AF16BF16CF16DF16EF16FF170F171F172F173F174F175F176F177F178F179F17AF17BF17CF17DF17EF180F181F182F183F184F185F186F187F188F189F18AF18BF18CF18DF18EF18FF190F191F192F193F194F195F196F197F198F199F19AF19BF19CF19DF19EF19FF1A0F240F241F242F243F244F245F246F247F248F249F24AF24BF24CF24DF24EF24FF250F251F252F253F254F255F256F257F258F259F25AF25BF25CF25DF25EF25FF260F261F262F263F264F265F266F267F268F269F26AF26BF26CF26DF26EF26FF270F271F272F273F274F275F276F277F278F279F27AF27BF27CF27DF27EF280F281F282F283F284F285F286F287F288F289F28AF28BF28CF28DF28EF28FF290F291F292F293F294F295F296F297F298F299F29AF29BF29CF29DF29EF29FF2A0F340F341F342F343F344F345F346F347F348F349F34AF34BF34CF34DF34EF34FF350F351C2EDD4A6CDD4D1B1B3DBC7FDF352B2B5C2BFE6E0CABBE6E1E6E2BED4E6E3D7A4CDD5E6E5BCDDE6E4E6E6E6E7C2EEF353BDBEE6E8C2E6BAA7E6E9F354E6EAB3D2D1E9F355F356BFA5E6EBC6EFE6ECE6EDF357F358E6EEC6ADE6EFF359C9A7E6F0E6F1E6F2E5B9E6F3E6F4C2E2E6F5E6F6D6E8E6F7F35AE6F8B9C7F35BF35CF35DF35EF35FF360F361F7BBF7BAF362F363F364F365F7BEF7BCBAA1F366F7BFF367F7C0F368F369F36AF7C2F7C1F7C4F36BF36CF7C3F36DF36EF36FF370F371F7C5F7C6F372F373F374F375F7C7F376CBE8F377F378F379F37AB8DFF37BF37CF37DF37EF380F381F7D4F382F7D5F383F384F385F386F7D6F387F388F389F38AF7D8F38BF7DAF38CF7D7F38DF38EF38FF390F391F392F393F394F395F7DBF396F7D9F397F398F399F39AF39BF39CF39DD7D7F39EF39FF3A0F440F7DCF441F442F443F444F445F446F7DDF447F448F449F7DEF44AF44BF44CF44DF44EF44FF450F451F452F453F454F7DFF455F456F457F7E0F458F459F45AF45BF45CF45DF45EF45FF460F461F462DBCBF463F464D8AAF465F466F467F468F469F46AF46BF46CE5F7B9EDF46DF46EF46FF470BFFDBBEAF7C9C6C7F7C8F471F7CAF7CCF7CBF472F473F474F7CDF475CEBAF476F7CEF477F478C4A7F479F47AF47BF47CF47DF47EF480F481F482F483F484F485F486F487F488F489F48AF48BF48CF48DF48EF48FF490F491F492F493F494F495F496F497F498F499F49AF49BF49CF49DF49EF49FF4A0F540F541F542F543F544F545F546F547F548F549F54AF54BF54CF54DF54EF54FF550F551F552F553F554F555F556F557F558F559F55AF55BF55CF55DF55EF55FF560F561F562F563F564F565F566F567F568F569F56AF56BF56CF56DF56EF56FF570F571F572F573F574F575F576F577F578F579F57AF57BF57CF57DF57EF580F581F582F583F584F585F586F587F588F589F58AF58BF58CF58DF58EF58FF590F591F592F593F594F595F596F597F598F599F59AF59BF59CF59DF59EF59FF5A0F640F641F642F643F644F645F646F647F648F649F64AF64BF64CF64DF64EF64FF650F651F652F653F654F655F656F657F658F659F65AF65BF65CF65DF65EF65FF660F661F662F663F664F665F666F667F668F669F66AF66BF66CF66DF66EF66FF670F671F672F673F674F675F676F677F678F679F67AF67BF67CF67DF67EF680F681F682F683F684F685F686F687F688F689F68AF68BF68CF68DF68EF68FF690F691F692F693F694F695F696F697F698F699F69AF69BF69CF69DF69EF69FF6A0F740F741F742F743F744F745F746F747F748F749F74AF74BF74CF74DF74EF74FF750F751F752F753F754F755F756F757F758F759F75AF75BF75CF75DF75EF75FF760F761F762F763F764F765F766F767F768F769F76AF76BF76CF76DF76EF76FF770F771F772F773F774F775F776F777F778F779F77AF77BF77CF77DF77EF780D3E3F781F782F6CFF783C2B3F6D0F784F785F6D1F6D2F6D3F6D4F786F787F6D6F788B1ABF6D7F789F6D8F6D9F6DAF78AF6DBF6DCF78BF78CF78DF78EF6DDF6DECFCAF78FF6DFF6E0F6E1F6E2F6E3F6E4C0F0F6E5F6E6F6E7F6E8F6E9F790F6EAF791F6EBF6ECF792F6EDF6EEF6EFF6F0F6F1F6F2F6F3F6F4BEA8F793F6F5F6F6F6F7F6F8F794F795F796F797F798C8FAF6F9F6FAF6FBF6FCF799F79AF6FDF6FEF7A1F7A2F7A3F7A4F7A5F79BF79CF7A6F7A7F7A8B1EEF7A9F7AAF7ABF79DF79EF7ACF7ADC1DBF7AEF79FF7A0F7AFF840F841F842F843F844F845F846F847F848F849F84AF84BF84CF84DF84EF84FF850F851F852F853F854F855F856F857F858F859F85AF85BF85CF85DF85EF85FF860F861F862F863F864F865F866F867F868F869F86AF86BF86CF86DF86EF86FF870F871F872F873F874F875F876F877F878F879F87AF87BF87CF87DF87EF880F881F882F883F884F885F886F887F888F889F88AF88BF88CF88DF88EF88FF890F891F892F893F894F895F896F897F898F899F89AF89BF89CF89DF89EF89FF8A0F940F941F942F943F944F945F946F947F948F949F94AF94BF94CF94DF94EF94FF950F951F952F953F954F955F956F957F958F959F95AF95BF95CF95DF95EF95FF960F961F962F963F964F965F966F967F968F969F96AF96BF96CF96DF96EF96FF970F971F972F973F974F975F976F977F978F979F97AF97BF97CF97DF97EF980F981F982F983F984F985F986F987F988F989F98AF98BF98CF98DF98EF98FF990F991F992F993F994F995F996F997F998F999F99AF99BF99CF99DF99EF99FF9A0FA40FA41FA42FA43FA44FA45FA46FA47FA48FA49FA4AFA4BFA4CFA4DFA4EFA4FFA50FA51FA52FA53FA54FA55FA56FA57FA58FA59FA5AFA5BFA5CFA5DFA5EFA5FFA60FA61FA62FA63FA64FA65FA66FA67FA68FA69FA6AFA6BFA6CFA6DFA6EFA6FFA70FA71FA72FA73FA74FA75FA76FA77FA78FA79FA7AFA7BFA7CFA7DFA7EFA80FA81FA82FA83FA84FA85FA86FA87FA88FA89FA8AFA8BFA8CFA8DFA8EFA8FFA90FA91FA92FA93FA94FA95FA96FA97FA98FA99FA9AFA9BFA9CFA9DFA9EFA9FFAA0FB40FB41FB42FB43FB44FB45FB46FB47FB48FB49FB4AFB4BFB4CFB4DFB4EFB4FFB50FB51FB52FB53FB54FB55FB56FB57FB58FB59FB5AFB5BC4F1F0AFBCA6F0B0C3F9FB5CC5B8D1BBFB5DF0B1F0B2F0B3F0B4F0B5D1BCFB5ED1ECFB5FF0B7F0B6D4A7FB60CDD2F0B8F0BAF0B9F0BBF0BCFB61FB62B8EBF0BDBAE8FB63F0BEF0BFBEE9F0C0B6ECF0C1F0C2F0C3F0C4C8B5F0C5F0C6FB64F0C7C5F4FB65F0C8FB66FB67FB68F0C9FB69F0CAF7BDFB6AF0CBF0CCF0CDFB6BF0CEFB6CFB6DFB6EFB6FF0CFBAD7FB70F0D0F0D1F0D2F0D3F0D4F0D5F0D6F0D8FB71FB72D3A5F0D7FB73F0D9FB74FB75FB76FB77FB78FB79FB7AFB7BFB7CFB7DF5BAC2B9FB7EFB80F7E4FB81FB82FB83FB84F7E5F7E6FB85FB86F7E7FB87FB88FB89FB8AFB8BFB8CF7E8C2B4FB8DFB8EFB8FFB90FB91FB92FB93FB94FB95F7EAFB96F7EBFB97FB98FB99FB9AFB9BFB9CC2F3FB9DFB9EFB9FFBA0FC40FC41FC42FC43FC44FC45FC46FC47FC48F4F0FC49FC4AFC4BF4EFFC4CFC4DC2E9FC4EF7E1F7E2FC4FFC50FC51FC52FC53BBC6FC54FC55FC56FC57D9E4FC58FC59FC5ACAF2C0E8F0A4FC5BBADAFC5CFC5DC7ADFC5EFC5FFC60C4ACFC61FC62F7ECF7EDF7EEFC63F7F0F7EFFC64F7F1FC65FC66F7F4FC67F7F3FC68F7F2F7F5FC69FC6AFC6BFC6CF7F6FC6DFC6EFC6FFC70FC71FC72FC73FC74FC75EDE9FC76EDEAEDEBFC77F6BCFC78FC79FC7AFC7BFC7CFC7DFC7EFC80FC81FC82FC83FC84F6BDFC85F6BEB6A6FC86D8BEFC87FC88B9C4FC89FC8AFC8BD8BBFC8CDCB1FC8DFC8EFC8FFC90FC91FC92CAF3FC93F7F7FC94FC95FC96FC97FC98FC99FC9AFC9BFC9CF7F8FC9DFC9EF7F9FC9FFCA0FD40FD41FD42FD43FD44F7FBFD45F7FAFD46B1C7FD47F7FCF7FDFD48FD49FD4AFD4BFD4CF7FEFD4DFD4EFD4FFD50FD51FD52FD53FD54FD55FD56FD57C6EBECB4FD58FD59FD5AFD5BFD5CFD5DFD5EFD5FFD60FD61FD62FD63FD64FD65FD66FD67FD68FD69FD6AFD6BFD6CFD6DFD6EFD6FFD70FD71FD72FD73FD74FD75FD76FD77FD78FD79FD7AFD7BFD7CFD7DFD7EFD80FD81FD82FD83FD84FD85B3DDF6B3FD86FD87F6B4C1E4F6B5F6B6F6B7F6B8F6B9F6BAC8A3F6BBFD88FD89FD8AFD8BFD8CFD8DFD8EFD8FFD90FD91FD92FD93C1FAB9A8EDE8FD94FD95FD96B9EAD9DFFD97FD98FD99FD9AFD9';
+
+ for (var i = 0; i < str.length; i++) {
+ var c = str.charAt(i),
+ code = str.charCodeAt(i);
+ if (c == " ") strOut += "+";
+ else if (code >= 19968 && code <= 40869) {
+ var index = code - 19968;
+ strOut += "%" + z.substr(index * 4, 2) + "%" + z.substr(index * 4 + 2, 2);
+ } else {
+ strOut += "%" + str.charCodeAt(i).toString(16);
+ }
+ }
+ return strOut;
+ },
+ /* 改变图片大小 */
+ scale: function (img, w, h) {
+ var ow = img.width,
+ oh = img.height;
+
+ if (ow >= oh) {
+ img.width = w * ow / oh;
+ img.height = h;
+ img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+ } else {
+ img.width = w;
+ img.height = h * oh / ow;
+ img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+ }
+ },
+ getImageData: function(){
+ var _this = this,
+ key = $G('searchTxt').value,
+ type = $G('searchType').value,
+ keepOriginName = editor.options.keepOriginName ? "1" : "0",
+ url = "http://image.baidu.com/i?ct=201326592&cl=2&lm=-1&st=-1&tn=baiduimagejson&istype=2&rn=32&fm=index&pv=&word=" + _this.encodeToGb2312(key) + type + "&keeporiginname=" + keepOriginName + "&" + +new Date;
+
+ $G('searchListUl').innerHTML = lang.searchLoading;
+ ajax.request(url, {
+ 'dataType': 'jsonp',
+ 'charset': 'GB18030',
+ 'onsuccess':function(json){
+ var list = [];
+ if(json && json.data) {
+ for(var i = 0; i < json.data.length; i++) {
+ if(json.data[i].objURL) {
+ list.push({
+ title: json.data[i].fromPageTitleEnc,
+ src: json.data[i].objURL,
+ url: json.data[i].fromURL
+ });
+ }
+ }
+ }
+ _this.setList(list);
+ },
+ 'onerror':function(){
+ $G('searchListUl').innerHTML = lang.searchRetry;
+ }
+ });
+ },
+ /* 添加图片到列表界面上 */
+ setList: function (list) {
+ var i, item, p, img, link, _this = this,
+ listUl = $G('searchListUl');
+
+ listUl.innerHTML = '';
+ if(list.length) {
+ for (i = 0; i < list.length; i++) {
+ item = document.createElement('li');
+ p = document.createElement('p');
+ img = document.createElement('img');
+ link = document.createElement('a');
+
+ img.onload = function () {
+ _this.scale(this, 113, 113);
+ };
+ img.width = 113;
+ img.setAttribute('src', list[i].src);
+
+ link.href = list[i].url;
+ link.target = '_blank';
+ link.title = list[i].title;
+ link.innerHTML = list[i].title;
+
+ p.appendChild(img);
+ item.appendChild(p);
+ item.appendChild(link);
+ listUl.appendChild(item);
+ }
+ } else {
+ listUl.innerHTML = lang.searchRetry;
+ }
+ },
+ getInsertList: function () {
+ var child,
+ src,
+ align = getAlign(),
+ list = [],
+ items = $G('searchListUl').children;
+ for(var i = 0; i < items.length; i++) {
+ child = items[i].firstChild && items[i].firstChild.firstChild;
+ if(child.tagName && child.tagName.toLowerCase() == 'img' && domUtils.hasClass(items[i], 'selected')) {
+ src = child.src;
+ list.push({
+ src: src,
+ _src: src,
+ alt: src.substr(src.lastIndexOf('/') + 1),
+ floatStyle: align
+ });
+ }
+ }
+ return list;
+ }
+ };
+
+})();
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/alignicon.jpg b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/alignicon.jpg
new file mode 100644
index 0000000..754755b
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/alignicon.jpg differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/bg.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/bg.png
new file mode 100644
index 0000000..580be0a
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/bg.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/icons.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/icons.gif
new file mode 100644
index 0000000..78459de
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/icons.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/icons.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/icons.png
new file mode 100644
index 0000000..12e4700
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/icons.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/image.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/image.png
new file mode 100644
index 0000000..19699f6
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/image.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/progress.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/progress.png
new file mode 100644
index 0000000..717c486
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/progress.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/success.gif b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/success.gif
new file mode 100644
index 0000000..8d4f311
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/success.gif differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/success.png b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/success.png
new file mode 100644
index 0000000..94f968d
Binary files /dev/null and b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/image/images/success.png differ
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/insertframe/insertframe.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/insertframe/insertframe.html
new file mode 100644
index 0000000..7f1f3e9
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/insertframe/insertframe.html
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ px
+
+
+
+ px
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/internal.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/internal.js
new file mode 100644
index 0000000..44dc17f
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/internal.js
@@ -0,0 +1,81 @@
+(function () {
+ var parent = window.parent;
+ //dialog对象
+ dialog = parent.$EDITORUI[window.frameElement.id.replace( /_iframe$/, '' )];
+ //当前打开dialog的编辑器实例
+ editor = dialog.editor;
+
+ UE = parent.UE;
+
+ domUtils = UE.dom.domUtils;
+
+ utils = UE.utils;
+
+ browser = UE.browser;
+
+ ajax = UE.ajax;
+
+ $G = function ( id ) {
+ return document.getElementById( id )
+ };
+ //focus元素
+ $focus = function ( node ) {
+ setTimeout( function () {
+ if ( browser.ie ) {
+ var r = node.createTextRange();
+ r.collapse( false );
+ r.select();
+ } else {
+ node.focus()
+ }
+ }, 0 )
+ };
+ utils.loadFile(document,{
+ href:editor.options.themePath + editor.options.theme + "/dialogbase.css?cache="+Math.random(),
+ tag:"link",
+ type:"text/css",
+ rel:"stylesheet"
+ });
+ lang = editor.getLang(dialog.className.split( "-" )[2]);
+ if(lang){
+ domUtils.on(window,'load',function () {
+
+ var langImgPath = editor.options.langPath + editor.options.lang + "/images/";
+ //针对静态资源
+ for ( var i in lang["static"] ) {
+ var dom = $G( i );
+ if(!dom) continue;
+ var tagName = dom.tagName,
+ content = lang["static"][i];
+ if(content.src){
+ //clone
+ content = utils.extend({},content,false);
+ content.src = langImgPath + content.src;
+ }
+ if(content.style){
+ content = utils.extend({},content,false);
+ content.style = content.style.replace(/url\s*\(/g,"url(" + langImgPath)
+ }
+ switch ( tagName.toLowerCase() ) {
+ case "var":
+ dom.parentNode.replaceChild( document.createTextNode( content ), dom );
+ break;
+ case "select":
+ var ops = dom.options;
+ for ( var j = 0, oj; oj = ops[j]; ) {
+ oj.innerHTML = content.options[j++];
+ }
+ for ( var p in content ) {
+ p != "options" && dom.setAttribute( p, content[p] );
+ }
+ break;
+ default :
+ domUtils.setAttributes( dom, content);
+ }
+ }
+ } );
+ }
+
+
+})();
+
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/link/link.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/link/link.html
new file mode 100644
index 0000000..55ab4d1
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/link/link.html
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/map/map.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/map/map.html
new file mode 100644
index 0000000..e763b8e
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/map/map.html
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/map/show.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/map/show.html
new file mode 100644
index 0000000..329cfeb
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/map/show.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+ 百度地图API自定义地图
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.css b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.css
new file mode 100644
index 0000000..8fb7a94
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.css
@@ -0,0 +1,30 @@
+.wrapper{margin: 5px 10px;}
+
+.searchBar{height:30px;padding:7px 0 3px;text-align:center;}
+.searchBtn{font-size:13px;height:24px;}
+
+.resultBar{width:460px;margin:5px auto;border: 1px solid #CCC;border-radius: 5px;box-shadow: 2px 2px 5px #D3D6DA;overflow: hidden;}
+
+.listPanel{overflow: hidden;}
+.panelon{display:block;}
+.paneloff{display:none}
+
+.page{width:220px;margin:20px auto;overflow: hidden;}
+.pageon{float:right;width:24px;line-height:24px;height:24px;margin-right: 5px;background: none;border: none;color: #000;font-weight: bold;text-align:center}
+.pageoff{float:right;width:24px;line-height:24px;height:24px;cursor:pointer;background-color: #fff;
+ border: 1px solid #E7ECF0;color: #2D64B3;margin-right: 5px;text-decoration: none;text-align:center;}
+
+.m-box{width:460px;}
+.m-m{float: left;line-height: 20px;height: 20px;}
+.m-h{height:24px;line-height:24px;padding-left: 46px;background-color:#FAFAFA;border-bottom: 1px solid #DAD8D8;font-weight: bold;font-size: 12px;color: #333;}
+.m-l{float:left;width:40px; }
+.m-t{float:left;width:140px;}
+.m-s{float:left;width:110px;}
+.m-z{float:left;width:100px;}
+.m-try-t{float: left;width: 60px;;}
+
+.m-try{float:left;width:20px;height:20px;background:url('http://static.tieba.baidu.com/tb/editor/images/try_music.gif') no-repeat ;}
+.m-trying{float:left;width:20px;height:20px;background:url('http://static.tieba.baidu.com/tb/editor/images/stop_music.gif') no-repeat ;}
+
+.loading{width:95px;height:7px;font-size:7px;margin:60px auto;background:url(http://static.tieba.baidu.com/tb/editor/images/loading.gif) no-repeat}
+.empty{width:300px;height:40px;padding:2px;margin:50px auto;line-height:40px; color:#006699;text-align:center;}
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.html b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.html
new file mode 100644
index 0000000..e7ef04f
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.html
@@ -0,0 +1,32 @@
+
+
+
+
+ 插入音乐
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.js b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.js
new file mode 100644
index 0000000..1c538bf
--- /dev/null
+++ b/app/Admin/Extensions/dcat-admin-extension/ueditor/resources/assets/dialogs/music/music.js
@@ -0,0 +1,192 @@
+function Music() {
+ this.init();
+}
+(function () {
+ var pages = [],
+ panels = [],
+ selectedItem = null;
+ Music.prototype = {
+ total:70,
+ pageSize:10,
+ dataUrl:"http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.common",
+ playerUrl:"http://box.baidu.com/widget/flash/bdspacesong.swf",
+
+ init:function () {
+ var me = this;
+ domUtils.on($G("J_searchName"), "keyup", function (event) {
+ var e = window.event || event;
+ if (e.keyCode == 13) {
+ me.dosearch();
+ }
+ });
+ domUtils.on($G("J_searchBtn"), "click", function () {
+ me.dosearch();
+ });
+ },
+ callback:function (data) {
+ var me = this;
+ me.data = data.song_list;
+ setTimeout(function () {
+ $G('J_resultBar').innerHTML = me._renderTemplate(data.song_list);
+ }, 300);
+ },
+ dosearch:function () {
+ var me = this;
+ selectedItem = null;
+ var key = $G('J_searchName').value;
+ if (utils.trim(key) == "")return false;
+ key = encodeURIComponent(key);
+ me._sent(key);
+ },
+ doselect:function (i) {
+ var me = this;
+ if (typeof i == 'object') {
+ selectedItem = i;
+ } else if (typeof i == 'number') {
+ selectedItem = me.data[i];
+ }
+ },
+ onpageclick:function (id) {
+ var me = this;
+ for (var i = 0; i < pages.length; i++) {
+ $G(pages[i]).className = 'pageoff';
+ $G(panels[i]).className = 'paneloff';
+ }
+ $G('page' + id).className = 'pageon';
+ $G('panel' + id).className = 'panelon';
+ },
+ listenTest:function (elem) {
+ var me = this,
+ view = $G('J_preview'),
+ is_play_action = (elem.className == 'm-try'),
+ old_trying = me._getTryingElem();
+
+ if (old_trying) {
+ old_trying.className = 'm-try';
+ view.innerHTML = '';
+ }
+ if (is_play_action) {
+ elem.className = 'm-trying';
+ view.innerHTML = me._buildMusicHtml(me._getUrl(true));
+ }
+ },
+ _sent:function (param) {
+ var me = this;
+ $G('J_resultBar').innerHTML = '';
+
+ utils.loadFile(document, {
+ src:me.dataUrl + '&query=' + param + '&page_size=' + me.total + '&callback=music.callback&.r=' + Math.random(),
+ tag:"script",
+ type:"text/javascript",
+ defer:"defer"
+ });
+ },
+ _removeHtml:function (str) {
+ var reg = /<\s*\/?\s*[^>]*\s*>/gi;
+ return str.replace(reg, "");
+ },
+ _getUrl:function (isTryListen) {
+ var me = this;
+ var param = 'from=tiebasongwidget&url=&name=' + encodeURIComponent(me._removeHtml(selectedItem.title)) + '&artist='
+ + encodeURIComponent(me._removeHtml(selectedItem.author)) + '&extra='
+ + encodeURIComponent(me._removeHtml(selectedItem.album_title))
+ + '&autoPlay='+isTryListen+'' + '&loop=true';
+ return me.playerUrl + "?" + param;
+ },
+ _getTryingElem:function () {
+ var s = $G('J_listPanel').getElementsByTagName('span');
+
+ for (var i = 0; i < s.length; i++) {
+ if (s[i].className == 'm-trying')
+ return s[i];
+ }
+ return null;
+ },
+ _buildMusicHtml:function (playerUrl) {
+ var html = '