From d4c3c9ef10be0e7c7c2127a6ebdb903ca53fda5a Mon Sep 17 00:00:00 2001 From: printempw Date: Sat, 19 Mar 2016 16:14:20 +0800 Subject: [PATCH] tweaked style of file input --- assets/css/user.style.css | 6 +- assets/js/upload.utils.js | 9 +- libs/bootstrap-fileinput/LICENSE.md | 28 + libs/bootstrap-fileinput/README.md | 96 + libs/bootstrap-fileinput/css/fileinput.css | 253 ++ .../bootstrap-fileinput/css/fileinput.min.css | 11 + libs/bootstrap-fileinput/img/loading-sm.gif | Bin 0 -> 2670 bytes libs/bootstrap-fileinput/img/loading.gif | Bin 0 -> 847 bytes libs/bootstrap-fileinput/js/fileinput.js | 2764 +++++++++++++++++ libs/bootstrap-fileinput/js/fileinput.min.js | 17 + .../js/fileinput_locale_zh.js | 61 + .../js/plugins/canvas-to-blob.js | 95 + .../js/plugins/canvas-to-blob.min.js | 1 + libs/iCheck/all.css | 61 + libs/iCheck/icheck.min.js | 10 + libs/iCheck/square/blue.css | 62 + libs/iCheck/square/blue.png | Bin 0 -> 2185 bytes libs/iCheck/square/blue@2x.png | Bin 0 -> 4485 bytes user/upload.php | 13 +- 19 files changed, 3481 insertions(+), 6 deletions(-) create mode 100644 libs/bootstrap-fileinput/LICENSE.md create mode 100644 libs/bootstrap-fileinput/README.md create mode 100644 libs/bootstrap-fileinput/css/fileinput.css create mode 100644 libs/bootstrap-fileinput/css/fileinput.min.css create mode 100644 libs/bootstrap-fileinput/img/loading-sm.gif create mode 100644 libs/bootstrap-fileinput/img/loading.gif create mode 100644 libs/bootstrap-fileinput/js/fileinput.js create mode 100644 libs/bootstrap-fileinput/js/fileinput.min.js create mode 100644 libs/bootstrap-fileinput/js/fileinput_locale_zh.js create mode 100644 libs/bootstrap-fileinput/js/plugins/canvas-to-blob.js create mode 100644 libs/bootstrap-fileinput/js/plugins/canvas-to-blob.min.js create mode 100644 libs/iCheck/all.css create mode 100644 libs/iCheck/icheck.min.js create mode 100644 libs/iCheck/square/blue.css create mode 100644 libs/iCheck/square/blue.png create mode 100644 libs/iCheck/square/blue@2x.png diff --git a/assets/css/user.style.css b/assets/css/user.style.css index e37b439b..3ed42cf0 100644 --- a/assets/css/user.style.css +++ b/assets/css/user.style.css @@ -2,7 +2,7 @@ * @Author: printempw * @Date: 2016-01-21 19:12:06 * @Last Modified by: printempw -* @Last Modified time: 2016-03-19 13:07:41 +* @Last Modified time: 2016-03-19 15:53:06 */ @import url(https://cdn.moefont.com/fonts/css?family=Ubuntu); @@ -49,3 +49,7 @@ body, .ply-layer { padding: 15px 30px 15px 15px; border-left: 5px solid #eee; } +.model-label { + font-weight: 500; + font-size: 15px; +} diff --git a/assets/js/upload.utils.js b/assets/js/upload.utils.js index 0c73550e..77fe706a 100644 --- a/assets/js/upload.utils.js +++ b/assets/js/upload.utils.js @@ -2,7 +2,7 @@ * @Author: printempw * @Date: 2016-03-18 21:58:09 * @Last Modified by: printempw -* @Last Modified time: 2016-03-19 10:03:32 +* @Last Modified time: 2016-03-19 16:12:11 */ 'use strict'; @@ -47,3 +47,10 @@ $("#upload").click(function(){ showCallout('callout-warning', '你还没有选择任何文件哦'); } }); + +$(document).ready(function() { + $('input[type=radio]').iCheck({ + radioClass: 'iradio_square-blue' + }); + $('input[type=file]').fileinput({'showUpload':false, 'language': 'zh'}); +}); diff --git a/libs/bootstrap-fileinput/LICENSE.md b/libs/bootstrap-fileinput/LICENSE.md new file mode 100644 index 00000000..fcde9550 --- /dev/null +++ b/libs/bootstrap-fileinput/LICENSE.md @@ -0,0 +1,28 @@ +Copyright (c) 2014 - 2015, Kartik Visweswaran +Krajee.com +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +* Neither the names of Kartik Visweswaran or Krajee nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/libs/bootstrap-fileinput/README.md b/libs/bootstrap-fileinput/README.md new file mode 100644 index 00000000..462082d9 --- /dev/null +++ b/libs/bootstrap-fileinput/README.md @@ -0,0 +1,96 @@ +bootstrap-fileinput +=================== + +[![Bower version](https://badge.fury.io/bo/bootstrap-fileinput.svg)](http://badge.fury.io/bo/bootstrap-fileinput) +[![Latest Stable Version](https://poser.pugx.org/kartik-v/bootstrap-fileinput/v/stable)](https://packagist.org/packages/kartik-v/bootstrap-fileinput) +[![License](https://poser.pugx.org/kartik-v/bootstrap-fileinput/license)](https://packagist.org/packages/kartik-v/bootstrap-fileinput) +[![Packagist Downloads](https://poser.pugx.org/kartik-v/bootstrap-fileinput/downloads)](https://packagist.org/packages/kartik-v/bootstrap-fileinput) +[![Monthly Downloads](https://poser.pugx.org/kartik-v/bootstrap-fileinput/d/monthly)](https://packagist.org/packages/kartik-v/bootstrap-fileinput) + +An enhanced HTML 5 file input for Bootstrap 3.x with file preview for various files, offers multiple selection, and more. The plugin allows you a simple way to setup an advanced file picker/upload control built to work specially with Bootstrap CSS3 styles. It enhances the file input functionality further, by offering support to preview a wide variety of files i.e. images, text, html, video, audio, flash, and objects. In addition, it includes AJAX based uploads, dragging & dropping files, viewing upload progress, and selectively previewing, adding, or deleting files. + +![File Input Screenshot](https://lh3.googleusercontent.com/-3FiEmc_okc4/VBw_d2LBAJI/AAAAAAAAAL8/KbVj5X9Dus0/w596-h454-no/FileInput.jpg) + +> NOTE: The latest version of the plugin is v4.3.1 (dev-master). Refer the [CHANGE LOG](https://github.com/kartik-v/bootstrap-fileinput/blob/master/CHANGE.md) for details. + +## Documentation and Demo + +View the [plugin documentation](http://plugins.krajee.com/file-input) and [plugin demos](http://plugins.krajee.com/file-input/demo) at Krajee JQuery plugins. + +## Pre-requisites + +1. [Bootstrap 3.x](http://getbootstrap.com/) +2. Latest [JQuery](http://jquery.com/) +3. Most modern browsers supporting HTML5 (inputs and FileReader API) including CSS3 & JQuery. For Internet Explorer, one must use IE versions 10 and above. IE9 and below will work as a normal file input, and will not support multiple file selection or the HTML 5 FileReader API. +4. With release 4.0, AJAX uploads are supported. AJAX uploads require that the browser support HTML5 FormData and XHR2 (XMLHttpRequest 2). Most modern browsers support FormData and XHR2. The plugin will automatically degrade to normal form based submission for browsers not supporting AJAX uploads. + +> NOTE: You can use the [sass branch](https://github.com/kartik-v/bootstrap-fileinput/tree/sass) for installation using `bootstrap-sass` dependency. +The [master branch](https://github.com/kartik-v/bootstrap-fileinput/tree/master) can be used for installation using plain `bootstrap` dependency. + +## Installation + +### Using Bower +You can use the `bower` package manager to install. Run: + + bower install bootstrap-fileinput + +### Using Composer +You can use the `composer` package manager to install. Either run: + + $ php composer.phar require kartik-v/bootstrap-fileinput "@dev" + +or add: + + "kartik-v/bootstrap-fileinput": "@dev" + +to your composer.json file + +### Manual Install + +You can also manually install the plugin easily to your project. Just download the source [ZIP](https://github.com/kartik-v/bootstrap-fileinput/zipball/master) or [TAR ball](https://github.com/kartik-v/bootstrap-fileinput/tarball/master) and extract the plugin assets (css and js folders) into your project. + +## Usage + +Step 1: Load the following assets in your header. + +```html + + + + + + + + + + +``` + +If you noticed, you need to load the `jquery.min.js` and `bootstrap.min.css` in addition to the `fileinput.min.css` and `fileinput.min.js`. The locale file `fileinput_locale_.js` can be optionally included for translating for your language if needed. + +NOTE: The `canvas-to-blob.min.js` file is the source for the [JavaScript-Canvas-to-Blob plugin by blueimp](https://github.com/blueimp/JavaScript-Canvas-to-Blob). It is required to be loaded before `fileinput.js` if you wish to use the image resize feature of the **bootstrap-fileinput** plugin. For ease of access, the plugin source for JavaScript-Canvas-to-Blob is included in the `js/plugins` folder of this project repository. + +Step 2: Initialize the plugin on your page. For example, + +```js +// initialize with defaults +$("#input-id").fileinput(); + +// with plugin options +$("#input-id").fileinput({'showUpload':false, 'previewFileType':'any'}); +``` + +The `#input-id` is the identifier for the input (e.g. `type = file`) on your page, which is hidden automatically by the plugin. + +Alternatively, you can directly call the plugin options by setting data attributes to your input field. + +```html + +``` + +## License + +**bootstrap-fileinput** is released under the BSD 3-Clause License. See the bundled `LICENSE.md` for details. diff --git a/libs/bootstrap-fileinput/css/fileinput.css b/libs/bootstrap-fileinput/css/fileinput.css new file mode 100644 index 00000000..ba4bba91 --- /dev/null +++ b/libs/bootstrap-fileinput/css/fileinput.css @@ -0,0 +1,253 @@ +/*! + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015 + * @package bootstrap-fileinput + * @version 4.3.1 + * + * File input styling for Bootstrap 3.0 + * Built for Yii Framework 2.0 + * Author: Kartik Visweswaran + * Year: 2015 + * For more Yii related demos visit http://demos.krajee.com + */ +.file-loading { + top: 0; + right: 0; + width: 25px; + height: 25px; + font-size: 999px; + text-align: right; + color: #fff; + background: transparent url('../img/loading.gif') top left no-repeat; + border: none; +} + +.file-object { + margin: 0 0 -5px 0; + padding: 0; +} + +.btn-file { + position: relative; + overflow: hidden; +} + +.btn-file input[type=file] { + position: absolute; + top: 0; + right: 0; + min-width: 100%; + min-height: 100%; + text-align: right; + opacity: 0; + background: none repeat scroll 0 0 transparent; + cursor: inherit; + display: block; +} + +.file-caption-name { + display: inline-block; + overflow: hidden; + height: 20px; + word-break: break-all; +} + +.input-group-lg .file-caption-name { + height: 25px; +} + +.file-preview-detail-modal { + text-align: left; +} + +.file-error-message { + color: #a94442; + background-color: #f2dede; + margin: 5px; + border: 1px solid #ebccd1; + border-radius: 4px; + padding: 15px; +} + +.file-error-message pre, .file-error-message ul { + margin: 0; + text-align: left; +} + +.file-error-message pre { + margin: 5px 0; +} + +.file-caption-disabled { + background-color: #EEEEEE; + cursor: not-allowed; + opacity: 1; +} + +.file-preview { + border-radius: 5px; + border: 1px solid #ddd; + padding: 5px; + width: 100%; + margin-bottom: 5px; +} + +.file-preview-frame { + display: table; + margin: 8px; + height: 160px; + border: 1px solid #ddd; + box-shadow: 1px 1px 5px 0 #a2958a; + padding: 6px; + float: left; + text-align: center; + vertical-align: middle; +} + +.file-preview-frame:not(.file-preview-error):hover { + box-shadow: 3px 3px 5px 0 #333; +} + +.file-preview-image { + height: 160px; + vertical-align: middle; +} + +.file-preview-text { + text-align: left; + width: 160px; + margin-bottom: 2px; + color: #428bca; + background: #fff; + overflow-x: hidden; +} + +.file-preview-other { + display: table-cell; + text-align: center; + vertical-align: middle; + width: 160px; + height: 160px; + border: 2px solid #999; + border-radius: 30px; +} + +.file-preview-other:hover { + opacity: 0.8; +} + +.file-actions, .file-other-error { + text-align: left; +} + +.file-icon-lg { + font-size: 1.2em; +} + +.file-icon-2x { + font-size: 2.4em; +} + +.file-icon-4x { + font-size: 4.8em; +} + +.file-input-new .file-preview, .file-input-new .close, .file-input-new .glyphicon-file, +.file-input-new .fileinput-remove-button, .file-input-new .fileinput-upload-button, +.file-input-ajax-new .fileinput-remove-button, .file-input-ajax-new .fileinput-upload-button { + display: none; +} + +.file-thumb-loading { + background: transparent url('../img/loading.gif') no-repeat scroll center center content-box !important; +} + +.file-actions { + margin-top: 15px; +} + +.file-footer-buttons { + float: right; +} + +.file-upload-indicator { + padding-top: 2px; + cursor: default; + opacity: 0.8; + width: 60%; +} + +.file-upload-indicator:hover { + font-weight: bold; + opacity: 1; +} + +.file-footer-caption { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 160px; + text-align: center; + padding-top: 4px; + font-size: 11px; + color: #777; + margin: 5px auto 10px auto; +} + +.file-preview-error { + opacity: 0.65; + box-shadow: none; +} + +.file-preview-frame:not(.file-preview-error) .file-footer-caption:hover { + color: #000; +} + +.file-drop-zone { + border: 1px dashed #aaa; + border-radius: 4px; + height: 100%; + text-align: center; + vertical-align: middle; + margin: 12px 15px 12px 12px; + padding: 5px; +} + +.file-drop-zone-title { + color: #aaa; + font-size: 40px; + padding: 85px 10px; +} + +.file-highlighted { + border: 2px dashed #999 !important; + background-color: #f0f0f0; +} + +.file-uploading { + background: url('../img/loading-sm.gif') no-repeat center bottom 10px; + opacity: 0.65; +} + +.file-thumb-progress .progress, .file-thumb-progress .progress-bar { + height: 10px; + font-size: 9px; + line-height: 10px; +} + +.file-thumbnail-footer { + position: relative; +} + +.file-thumb-progress { + position: absolute; + top: 22px; + left: 0; + right: 0; +} + +/* IE 10 fix */ +.btn-file ::-ms-browse { + width:100%; + height:100%; +} \ No newline at end of file diff --git a/libs/bootstrap-fileinput/css/fileinput.min.css b/libs/bootstrap-fileinput/css/fileinput.min.css new file mode 100644 index 00000000..fe406c80 --- /dev/null +++ b/libs/bootstrap-fileinput/css/fileinput.min.css @@ -0,0 +1,11 @@ +/*! + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015 + * @package bootstrap-fileinput + * @version 4.3.1 + * + * File input styling for Bootstrap 3.0 + * Built for Yii Framework 2.0 + * Author: Kartik Visweswaran + * Year: 2015 + * For more Yii related demos visit http://demos.krajee.com + */.file-preview-frame,.file-preview-image,.file-preview-other{height:160px;vertical-align:middle}.file-loading{top:0;right:0;width:25px;height:25px;font-size:999px;text-align:right;color:#fff;background:url(../img/loading.gif)top left no-repeat;border:none}.file-object{margin:0 0 -5px;padding:0}.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;text-align:right;opacity:0;background:0 0;cursor:inherit;display:block}.file-caption-name{display:inline-block;overflow:hidden;height:20px;word-break:break-all}.input-group-lg .file-caption-name{height:25px}.file-preview-detail-modal{text-align:left}.file-error-message{color:#a94442;background-color:#f2dede;margin:5px;border:1px solid #ebccd1;border-radius:4px;padding:15px}.file-error-message pre,.file-error-message ul{margin:0;text-align:left}.file-error-message pre{margin:5px 0}.file-caption-disabled{background-color:#EEE;cursor:not-allowed;opacity:1}.file-preview{border-radius:5px;border:1px solid #ddd;padding:5px;width:100%;margin-bottom:5px}.file-preview-frame{display:table;margin:8px;border:1px solid #ddd;box-shadow:1px 1px 5px 0 #a2958a;padding:6px;float:left;text-align:center}.file-preview-frame:not(.file-preview-error):hover{box-shadow:3px 3px 5px 0 #333}.file-preview-text{text-align:left;width:160px;margin-bottom:2px;color:#428bca;background:#fff;overflow-x:hidden}.file-preview-other{display:table-cell;text-align:center;width:160px;border:2px solid #999;border-radius:30px}.file-preview-other:hover{opacity:.8}.file-actions,.file-other-error{text-align:left}.file-icon-lg{font-size:1.2em}.file-icon-2x{font-size:2.4em}.file-icon-4x{font-size:4.8em}.file-input-ajax-new .fileinput-remove-button,.file-input-ajax-new .fileinput-upload-button,.file-input-new .close,.file-input-new .file-preview,.file-input-new .fileinput-remove-button,.file-input-new .fileinput-upload-button,.file-input-new .glyphicon-file{display:none}.file-thumb-loading{background:url(../img/loading.gif)center center no-repeat content-box!important}.file-actions{margin-top:15px}.file-footer-buttons{float:right}.file-upload-indicator{padding-top:2px;cursor:default;opacity:.8;width:60%}.file-upload-indicator:hover{font-weight:700;opacity:1}.file-footer-caption{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:160px;text-align:center;padding-top:4px;font-size:11px;color:#777;margin:5px auto 10px}.file-preview-error{opacity:.65;box-shadow:none}.file-preview-frame:not(.file-preview-error) .file-footer-caption:hover{color:#000}.file-drop-zone{border:1px dashed #aaa;border-radius:4px;height:100%;text-align:center;vertical-align:middle;margin:12px 15px 12px 12px;padding:5px}.file-drop-zone-title{color:#aaa;font-size:40px;padding:85px 10px}.file-highlighted{border:2px dashed #999!important;background-color:#f0f0f0}.file-uploading{background:url(../img/loading-sm.gif)center bottom 10px no-repeat;opacity:.65}.file-thumb-progress .progress,.file-thumb-progress .progress-bar{height:10px;font-size:9px;line-height:10px}.file-thumbnail-footer{position:relative}.file-thumb-progress{position:absolute;top:22px;left:0;right:0}.btn-file ::-ms-browse{width:100%;height:100%} \ No newline at end of file diff --git a/libs/bootstrap-fileinput/img/loading-sm.gif b/libs/bootstrap-fileinput/img/loading-sm.gif new file mode 100644 index 0000000000000000000000000000000000000000..44e3b7a0f702aa1d301468b1d6c1d74d45dfdfa4 GIT binary patch literal 2670 zcmb`Je@v5i9>LSr1(@@0hFth{;0&ijQR3npb})ArbBQ}PvxUrk9==i>-je&{`bYn0 zn)LJfykDR9({*{d^3^65#=>kEmYR~<(cUp}W8&ez9`;@Cv+TEYecW~T-rd+qu-ktq^cI?{N#Y-2bznz}@Wlou^?0COp;`YSDe?RQ|Tc54YcCq*3v~POu z=Q)qt<8AOhdGZ9Ce@UMNZ%`E#<|wqPl%!-T1wNGi6v$*^VoXMUfgA&)8H|&=avY{@ zJeN-^xjCUe&M)59EweXtoViM;a-1?pz|8ANLRhI=H=wp@r|+lJt@60`I1L>ikf9d z0~~r>SYAh`8ncKP#Y`em&991Ki+9$D<+Ah`h8ABLvp^+Tq&fmry95!A4*~{!r(W{r|twO<9E6hwX}% z)F~4zBCfrDD2L!G=moq=Ocm!kf(>!j#MWki`kE{G-BYoHbydNkr`YYfzkHJ}sdz&Z z8KyFYGObizP&mFNfL9$Pkl^BMW@H7Mj~&{~Y}&^@Em8az7i38?{{@hom-`@R{}EIl zuKr(+p!%I^SP+EozXRAQx&zv)Q;+jLkH^n1bF~-lxqi~zs6M>$2b`E?bDR1(oHROR zaB7GXUJ{zi)G5043^#qed;40J-ClCQog6(Hud5xphOP%&4#R>m7Bck%Y7iX-)s;GnT=AX8I6;x z*Ol?b-#BAm+c8m@;Zg6;uE=_2%jzUWr*x2ox8%paAn8qLY^bd(b;)ctlkU^fu=Vc3 zz;SN~k7AeP8RH2m;z z2CX1gkPsDhP~gugYVl&ptMm6Li~=Mu93%mmkyQ%qyHLgm8|ug3#{dSLkO}}pC4+2m z`Abd|+`DA@$4K%kR+rDRtj=pVseWU_SosF`XJ_(Mv(56PPTS5aAL87zteO7ON2zXW zXJVy1^(Mx0!G&0`_T@yc7N3_Iz0+VN*C^fuY4rdK8WyJhb56^W6%| zhv|@e@GJq}V9C%h00$|+q%bv<3=9s$WESlms9VW!FOl?MEbIgN3J@Vy2p1xL+O3%* z4%2yvY0~i3-n5pgHjU@SvC&L^4Rsa4mb2FHx-acsLminpiEGcb4^avWjB6bs?yxHv zFP>OoZm&@)|E$XG{cHFN;rjRP&k2G>fr0d>;EjE|0c(GfTT-1_oMa2pu0v=?C ziWR6(s{%i;LARh*1pqiF)TclTcn}}b?&(F5kHB?rd-LMljI3nO?V@)3zQ#dO-513t ztjcsEGqLW@n}vqVK-aY$rTULTyjJV(hyiVw^9O}%O%TO%-BuBoT7PVy_KKNUTkL36 z?~x1XsVjwnVnJz^Up>+9s|T|{G?2yf>OloQZy$sL`TErZnkDwpwn;{pv6^-mtgcw9 z_E@9A+pHJ039kOw(VR1!{Fzhc9qk-wO9+x3Qyrg@1UN60rpBE1jKy*kvzjY8GMB%rN zWSO@Pl7v*3SO+Q5wzobgsdpIf?Qr=duPeH-rgHWhu znosfxTsJ3QpXcCF1>~qGXs@ZJ zyw~IM73y!A^G>VZ8R)gNG&BU|KuYo)y+(NV^DdAFW5LeVJBBCMNfRtuR+y^ER&<(X zE7%B&e5#Z^`o7-@nEg_P~LI*N!rA^h{|;%@7gdIe0+9 zL6FPmK*NXRK=)=Qr!7yn1(?oIuvujqni9B8`-RfJ#pzQFR*0=zw6NbXTj0F1BLlZh zfVly?4JS*30beAWg%&SoyRsrS%M*Y;RQ^0c<0TpwHaFY zz6r{%O%_#7fe{VKyK@(naSJIeRCsx4aYAE48*ixFGRdMll6*@GUTc0%``>`o8j#V4 zg9*c-O~)LSJSTE&n6)s0!!ECt)zd(wL!wvC+k6wRhYtI}PTi7bt)^yIDG`AshjlL| qtmsHM!1PnVu#-b#!*qv!K4 "; + status = div.getElementsByTagName("i").length; + document.body.appendChild(div); + div.parentNode.removeChild(div); + return status; + }; + isEdge = function () { + return new RegExp('Edge\/[0-9]+', 'i').test(navigator.userAgent); + }; + handler = function ($el, event, callback, skipNS) { + var ev = skipNS ? event : event.split(' ').join(NAMESPACE + ' ') + NAMESPACE; + $el.off(ev).on(ev, callback); + }; + previewCache = { + data: {}, + init: function (obj) { + var content = obj.initialPreview, id = obj.id; + if (content.length > 0 && !isArray(content)) { + content = content.split(obj.initialPreviewDelimiter); + } + previewCache.data[id] = { + content: content, + config: obj.initialPreviewConfig, + tags: obj.initialPreviewThumbTags, + delimiter: obj.initialPreviewDelimiter, + template: obj.previewGenericTemplate, + msg: function (n) { + return obj._getMsgSelected(n); + }, + initId: obj.previewInitId, + footer: obj._getLayoutTemplate('footer').replace(/\{progress}/g, obj._renderThumbProgress()), + isDelete: obj.initialPreviewShowDelete, + caption: obj.initialCaption, + actions: function (showUpload, showDelete, disabled, url, key) { + return obj._renderFileActions(showUpload, showDelete, disabled, url, key); + } + }; + }, + fetch: function (id) { + return previewCache.data[id].content.filter(function (n) { + return n !== null; + }); + }, + count: function (id, all) { + return !!previewCache.data[id] && !!previewCache.data[id].content ? + (all ? previewCache.data[id].content.length : previewCache.fetch(id).length) : 0; + }, + get: function (id, i, isDisabled) { + var ind = 'init_' + i, data = previewCache.data[id], config = data.config[i], + previewId = data.initId + '-' + ind, out, $tmp, frameClass = ' file-preview-initial'; + /** @namespace config.frameClass */ + /** @namespace config.frameAttr */ + isDisabled = isDisabled === undefined ? true : isDisabled; + if (data.content[i] === null) { + return ''; + } + if (!isEmpty(config) && !isEmpty(config.frameClass)) { + frameClass += ' ' + config.frameClass; + } + out = data.template + .replace(/\{previewId}/g, previewId) + .replace(/\{frameClass}/g, frameClass) + .replace(/\{fileindex}/g, ind) + .replace(/\{content}/g, data.content[i]) + .replace(/\{footer}/g, previewCache.footer(id, i, isDisabled)); + if (data.tags.length && data.tags[i]) { + out = replaceTags(out, data.tags[i]); + } + if (!isEmpty(config) && !isEmpty(config.frameAttr)) { + $tmp = $(document.createElement('div')).html(out); + $tmp.find('.file-preview-initial').attr(config.frameAttr); + out = $tmp.html(); + $tmp.remove(); + } + return out; + }, + add: function (id, content, config, tags, append) { + var data = $.extend(true, {}, previewCache.data[id]), index; + if (!isArray(content)) { + content = content.split(data.delimiter); + } + if (append) { + index = data.content.push(content) - 1; + data.config[index] = config; + data.tags[index] = tags; + } else { + index = content.length; + data.content = content; + data.config = config; + data.tags = tags; + } + previewCache.data[id] = data; + return index; + }, + set: function (id, content, config, tags, append) { + var data = $.extend(true, {}, previewCache.data[id]), i, chk; + if (!content || !content.length) { + return; + } + if (!isArray(content)) { + content = content.split(data.delimiter); + } + chk = content.filter(function (n) { + return n !== null; + }); + if (!chk.length) { + return; + } + if (data.content === undefined) { + data.content = []; + } + if (data.config === undefined) { + data.config = []; + } + if (data.tags === undefined) { + data.tags = []; + } + if (append) { + for (i = 0; i < content.length; i++) { + if (content[i]) { + data.content.push(content[i]); + } + } + for (i = 0; i < config.length; i++) { + if (config[i]) { + data.config.push(config[i]); + } + } + for (i = 0; i < tags.length; i++) { + if (tags[i]) { + data.tags.push(tags[i]); + } + } + } else { + data.content = content; + data.config = config; + data.tags = tags; + } + previewCache.data[id] = data; + }, + unset: function (id, index) { + var chk = previewCache.count(id); + if (!chk) { + return; + } + if (chk === 1) { + previewCache.data[id].content = []; + previewCache.data[id].config = []; + return; + } + previewCache.data[id].content[index] = null; + previewCache.data[id].config[index] = null; + }, + out: function (id) { + var html = '', data = previewCache.data[id], caption, len = previewCache.count(id, true); + if (len === 0) { + return {content: '', caption: ''}; + } + for (var i = 0; i < len; i++) { + html += previewCache.get(id, i); + } + caption = data.msg(previewCache.count(id)); + return {content: html, caption: caption}; + }, + footer: function (id, i, isDisabled) { + var data = previewCache.data[id]; + isDisabled = isDisabled === undefined ? true : isDisabled; + if (data.config.length === 0 || isEmpty(data.config[i])) { + return ''; + } + var config = data.config[i], + caption = isSet('caption', config) ? config.caption : '', + width = isSet('width', config) ? config.width : 'auto', + url = isSet('url', config) ? config.url : false, + key = isSet('key', config) ? config.key : null, + disabled = (url === false) && isDisabled, + actions = data.isDelete ? data.actions(false, true, disabled, url, key) : '', + footer = data.footer.replace(/\{actions}/g, actions); + return footer.replace(/\{caption}/g, caption) + .replace(/\{width}/g, width) + .replace(/\{indicator}/g, '') + .replace(/\{indicatorTitle}/g, ''); + } + }; + getNum = function (num, def) { + def = def || 0; + if (typeof num === "number") { + return num; + } + if (typeof num === "string") { + num = parseFloat(num); + } + return isNaN(num) ? def : num; + }; + hasFileAPISupport = function () { + return !!(window.File && window.FileReader); + }; + hasDragDropSupport = function () { + var div = document.createElement('div'); + /** @namespace div.draggable */ + /** @namespace div.ondragstart */ + /** @namespace div.ondrop */ + return !isIE(9) && !isEdge() && // Fix for MS Edge drag & drop support bug + (div.draggable !== undefined || (div.ondragstart !== undefined && div.ondrop !== undefined)); + }; + hasFileUploadSupport = function () { + return hasFileAPISupport() && window.FormData; + }; + addCss = function ($el, css) { + $el.removeClass(css).addClass(css); + }; + STYLE_SETTING = 'style="width:{width};height:{height};"'; + OBJECT_PARAMS = ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n'; + DEFAULT_PREVIEW = '
\n' + + ' {previewFileIcon}\n' + + '
'; + defaultFileActionSettings = { + removeIcon: '', + removeClass: 'btn btn-xs btn-default', + removeTitle: 'Remove file', + uploadIcon: '', + uploadClass: 'btn btn-xs btn-default', + uploadTitle: 'Upload file', + indicatorNew: '', + indicatorSuccess: '', + indicatorError: '', + indicatorLoading: '', + indicatorNewTitle: 'Not uploaded yet', + indicatorSuccessTitle: 'Uploaded', + indicatorErrorTitle: 'Upload Error', + indicatorLoadingTitle: 'Uploading ...' + }; + tMain1 = '{preview}\n' + + '
\n' + + '
\n' + + ' {caption}\n' + + '
\n' + + ' {remove}\n' + + ' {cancel}\n' + + ' {upload}\n' + + ' {browse}\n' + + '
\n' + + '
'; + tMain2 = '{preview}\n
\n{remove}\n{cancel}\n{upload}\n{browse}\n'; + tPreview = '
\n' + + ' {close}' + + '
\n' + + '
\n' + + '
\n' + + '
' + + '
\n' + + '
\n' + + '
\n' + + '
'; + tClose = '
×
\n'; + tIcon = ''; + tCaption = '
\n' + + '
\n' + + '
\n'; + //noinspection HtmlUnknownAttribute + tBtnDefault = ''; + tBtnLink = '{icon}{label}'; + tBtnBrowse = '
{icon}{label}
'; + tModal = ''; + tProgress = '
\n' + + '
\n' + + ' {percent}%\n' + + '
\n' + + '
'; + tFooter = ''; + tActions = '
\n' + + ' \n' + + '
{indicator}
\n' + + '
\n' + + '
'; + tActionDelete = '\n'; + tActionUpload = '\n'; + tZoom = '\n'; + tGeneric = '
\n' + + ' {content}\n' + + ' {footer}\n' + + '
\n'; + tHtml = '
\n' + + ' \n' + + ' ' + DEFAULT_PREVIEW + '\n' + + ' \n' + + ' {footer}\n' + + '
'; + tImage = '
\n' + + ' {caption}\n' + + ' {footer}\n' + + '
\n'; + tText = '
\n' + + '
{data}
\n' + + ' {zoom}\n' + + ' {footer}\n' + + '
'; + tVideo = '
\n' + + ' \n' + + ' {footer}\n' + + '
\n'; + tAudio = '
\n' + + ' \n' + + ' {footer}\n' + + '
'; + tFlash = '
\n' + + ' \n' + + OBJECT_PARAMS + ' ' + DEFAULT_PREVIEW + '\n' + + ' \n' + + ' {footer}\n' + + '
\n'; + tObject = '
\n' + + ' \n' + + ' \n' + + OBJECT_PARAMS + ' ' + DEFAULT_PREVIEW + '\n' + + ' \n' + + ' {footer}\n' + + '
'; + tOther = '
\n' + + '
\n' + + ' ' + DEFAULT_PREVIEW + '\n' + + '
\n' + + ' \n' + + '
'; + defaultLayoutTemplates = { + main1: tMain1, + main2: tMain2, + preview: tPreview, + close: tClose, + zoom: tZoom, + icon: tIcon, + caption: tCaption, + modal: tModal, + progress: tProgress, + footer: tFooter, + actions: tActions, + actionDelete: tActionDelete, + actionUpload: tActionUpload, + btnDefault: tBtnDefault, + btnLink: tBtnLink, + btnBrowse: tBtnBrowse + }; + defaultPreviewTemplates = { + generic: tGeneric, + html: tHtml, + image: tImage, + text: tText, + video: tVideo, + audio: tAudio, + flash: tFlash, + object: tObject, + other: tOther + }; + defaultPreviewTypes = ['image', 'html', 'text', 'video', 'audio', 'flash', 'object']; + defaultPreviewSettings = { + image: {width: "auto", height: "160px"}, + html: {width: "213px", height: "160px"}, + text: {width: "160px", height: "136px"}, + video: {width: "213px", height: "160px"}, + audio: {width: "213px", height: "80px"}, + flash: {width: "213px", height: "160px"}, + object: {width: "160px", height: "160px"}, + other: {width: "160px", height: "160px"} + }; + defaultFileTypeSettings = { + image: function (vType, vName) { + return compare(vType, 'image.*') || compare(vName, /\.(gif|png|jpe?g)$/i); + }, + html: function (vType, vName) { + return compare(vType, 'text/html') || compare(vName, /\.(htm|html)$/i); + }, + text: function (vType, vName) { + return compare(vType, 'text.*') || compare(vType, /\.(xml|javascript)$/i) || + compare(vName, /\.(txt|md|csv|nfo|ini|json|php|js|css)$/i); + }, + video: function (vType, vName) { + return compare(vType, 'video.*') && (compare(vType, /(ogg|mp4|mp?g|webm|3gp)$/i) || + compare(vName, /\.(og?|mp4|webm|mp?g|3gp)$/i)); + }, + audio: function (vType, vName) { + return compare(vType, 'audio.*') && (compare(vType, /(ogg|mp3|mp?g|wav)$/i) || + compare(vName, /\.(og?|mp3|mp?g|wav)$/i)); + }, + flash: function (vType, vName) { + return compare(vType, 'application/x-shockwave-flash', true) || compare(vName, /\.(swf)$/i); + }, + object: function (vType, vName) { + return compare(vType, 'application/pdf', true) || compare(vName, /\.(pdf)$/i); + }, + other: function () { + return true; + } + }; + isEmpty = function (value, trim) { + return value === undefined || value === null || value.length === 0 || (trim && $.trim(value) === ''); + }; + isArray = function (a) { + return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]'; + }; + isSet = function (needle, haystack) { + return (typeof haystack === 'object' && needle in haystack); + }; + getElement = function (options, param, value) { + return (isEmpty(options) || isEmpty(options[param])) ? value : $(options[param]); + }; + uniqId = function () { + return Math.round(new Date().getTime() + (Math.random() * 100)); + }; + htmlEncode = function (str) { + return str.replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + }; + replaceTags = function (str, tags) { + var out = str; + if (!tags) { + return out; + } + $.each(tags, function (key, value) { + if (typeof value === "function") { + value = value(); + } + out = out.split(key).join(value); + }); + return out; + }; + cleanMemory = function ($thumb) { + var data = $thumb.is('img') ? $thumb.attr('src') : $thumb.find('source').attr('src'); + /** @namespace objUrl.revokeObjectURL */ + objUrl.revokeObjectURL(data); + }; + FileInput = function (element, options) { + var self = this; + self.$element = $(element); + if (!self._validate()) { + return; + } + self.isPreviewable = hasFileAPISupport(); + self.isIE9 = isIE(9); + self.isIE10 = isIE(10); + if (self.isPreviewable || self.isIE9) { + self._init(options); + self._listen(); + } else { + self.$element.removeClass('file-loading'); + } + }; + + FileInput.prototype = { + constructor: FileInput, + _init: function (options) { + var self = this, $el = self.$element, t; + $.each(options, function (key, value) { + switch (key) { + case 'minFileCount': + case 'maxFileCount': + case 'maxFileSize': + self[key] = getNum(value); + break; + default: + self[key] = value; + break; + } + }); + if (isEmpty(self.allowedPreviewTypes)) { + self.allowedPreviewTypes = defaultPreviewTypes; + } + self.fileInputCleared = false; + self.fileBatchCompleted = true; + if (!self.isPreviewable) { + self.showPreview = false; + } + self.uploadFileAttr = !isEmpty($el.attr('name')) ? $el.attr('name') : 'file_data'; + self.reader = null; + self.formdata = {}; + self.clearStack(); + self.uploadCount = 0; + self.uploadStatus = {}; + self.uploadLog = []; + self.uploadAsyncCount = 0; + self.loadedImages = []; + self.totalImagesCount = 0; + self.ajaxRequests = []; + self.isError = false; + self.ajaxAborted = false; + self.cancelling = false; + t = self._getLayoutTemplate('progress'); + self.progressTemplate = t.replace('{class}', self.progressClass); + self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass); + self.progressErrorTemplate = t.replace('{class}', self.progressErrorClass); + self.dropZoneEnabled = hasDragDropSupport() && self.dropZoneEnabled; + self.isDisabled = self.$element.attr('disabled') || self.$element.attr('readonly'); + self.isUploadable = hasFileUploadSupport() && !isEmpty(self.uploadUrl); + self.slug = typeof options.slugCallback === "function" ? options.slugCallback : self._slugDefault; + self.mainTemplate = self.showCaption ? self._getLayoutTemplate('main1') : self._getLayoutTemplate('main2'); + self.captionTemplate = self._getLayoutTemplate('caption'); + self.previewGenericTemplate = self._getPreviewTemplate('generic'); + if (self.resizeImage && (self.maxImageWidth || self.maxImageHeight)) { + self.imageCanvas = document.createElement('canvas'); + self.imageCanvasContext = self.imageCanvas.getContext('2d'); + } + if (isEmpty(self.$element.attr('id'))) { + self.$element.attr('id', uniqId()); + } + if (self.$container === undefined) { + self.$container = self._createContainer(); + } else { + self._refreshContainer(); + } + self.$dropZone = self.$container.find('.file-drop-zone'); + self.$progress = self.$container.find('.kv-upload-progress'); + self.$btnUpload = self.$container.find('.fileinput-upload'); + self.$captionContainer = getElement(options, 'elCaptionContainer', self.$container.find('.file-caption')); + self.$caption = getElement(options, 'elCaptionText', self.$container.find('.file-caption-name')); + self.$previewContainer = getElement(options, 'elPreviewContainer', self.$container.find('.file-preview')); + self.$preview = getElement(options, 'elPreviewImage', self.$container.find('.file-preview-thumbnails')); + self.$previewStatus = getElement(options, 'elPreviewStatus', self.$container.find('.file-preview-status')); + self.$errorContainer = getElement(options, 'elErrorContainer', + self.$previewContainer.find('.kv-fileinput-error')); + if (!isEmpty(self.msgErrorClass)) { + addCss(self.$errorContainer, self.msgErrorClass); + } + self.$errorContainer.hide(); + self.fileActionSettings = $.extend(true, defaultFileActionSettings, options.fileActionSettings); + self.previewInitId = "preview-" + uniqId(); + self.id = self.$element.attr('id'); + previewCache.init(self); + self._initPreview(true); + self._initPreviewDeletes(); + self.options = options; + self._setFileDropZoneTitle(); + self.$element.removeClass('file-loading'); + if (self.$element.attr('disabled')) { + self.disable(); + } + }, + _validate: function () { + var self = this, $exception; + if (self.$element.attr('type') === 'file') { + return true; + } + $exception = '
' + + '

Invalid Input Type

' + + 'You must set an input type = file for bootstrap-fileinput plugin to initialize.' + + '
'; + self.$element.after($exception); + return false; + }, + _errorsExist: function () { + var self = this, $err; + if (self.$errorContainer.find('li').length) { + return true; + } + $err = $(document.createElement('div')).html(self.$errorContainer.html()); + $err.find('span.kv-error-close').remove(); + $err.find('ul').remove(); + return $.trim($err.text()).length ? true : false; + }, + _errorHandler: function (evt, caption) { + var self = this, err = evt.target.error; + /** @namespace err.NOT_FOUND_ERR */ + /** @namespace err.SECURITY_ERR */ + /** @namespace err.NOT_READABLE_ERR */ + if (err.code === err.NOT_FOUND_ERR) { + self._showError(self.msgFileNotFound.replace('{name}', caption)); + } else if (err.code === err.SECURITY_ERR) { + self._showError(self.msgFileSecured.replace('{name}', caption)); + } else if (err.code === err.NOT_READABLE_ERR) { + self._showError(self.msgFileNotReadable.replace('{name}', caption)); + } else if (err.code === err.ABORT_ERR) { + self._showError(self.msgFilePreviewAborted.replace('{name}', caption)); + } else { + self._showError(self.msgFilePreviewError.replace('{name}', caption)); + } + }, + _addError: function (msg) { + var self = this, $error = self.$errorContainer; + if (msg && $error.length) { + $error.html(self.errorCloseButton + msg); + handler($error.find('.kv-error-close'), 'click', function () { + $error.fadeOut('slow'); + }); + } + }, + _resetErrors: function (fade) { + var self = this, $error = self.$errorContainer; + self.isError = false; + self.$container.removeClass('has-error'); + $error.html(''); + if (fade) { + $error.fadeOut('slow'); + } else { + $error.hide(); + } + }, + _showFolderError: function (folders) { + var self = this, $error = self.$errorContainer, msg; + if (!folders) { + return; + } + msg = self.msgFoldersNotAllowed.replace(/\{n}/g, folders); + self._addError(msg); + addCss(self.$container, 'has-error'); + $error.fadeIn(800); + self._raise('filefoldererror', [folders, msg]); + }, + _showUploadError: function (msg, params, event) { + var self = this, $error = self.$errorContainer, ev = event || 'fileuploaderror', e = params && params.id ? + '
  • ' + msg + '
  • ' : '
  • ' + msg + '
  • '; + if ($error.find('ul').length === 0) { + self._addError('
      ' + e + '
    '); + } else { + $error.find('ul').append(e); + } + $error.fadeIn(800); + self._raise(ev, [params, msg]); + self.$container.removeClass('file-input-new'); + addCss(self.$container, 'has-error'); + return true; + }, + _showError: function (msg, params, event) { + var self = this, $error = self.$errorContainer, ev = event || 'fileerror'; + params = params || {}; + params.reader = self.reader; + self._addError(msg); + $error.fadeIn(800); + self._raise(ev, [params, msg]); + if (!self.isUploadable) { + self._clearFileInput(); + } + self.$container.removeClass('file-input-new'); + addCss(self.$container, 'has-error'); + self.$btnUpload.attr('disabled', true); + return true; + }, + _noFilesError: function (params) { + var self = this, label = self.minFileCount > 1 ? self.filePlural : self.fileSingle, + msg = self.msgFilesTooLess.replace('{n}', self.minFileCount).replace('{files}', label), + $error = self.$errorContainer; + self._addError(msg); + self.isError = true; + self._updateFileDetails(0); + $error.fadeIn(800); + self._raise('fileerror', [params, msg]); + self._clearFileInput(); + addCss(self.$container, 'has-error'); + }, + _parseError: function (jqXHR, errorThrown, fileName) { + /** @namespace jqXHR.responseJSON */ + var self = this, errMsg = $.trim(errorThrown + ''), + dot = errMsg.slice(-1) === '.' ? '' : '.', + text = jqXHR.responseJSON !== undefined && jqXHR.responseJSON.error !== undefined ? + jqXHR.responseJSON.error : jqXHR.responseText; + if (self.cancelling && self.msgUploadAborted) { + errMsg = self.msgUploadAborted; + } + if (self.showAjaxErrorDetails && text) { + text = $.trim(text.replace(/\n\s*\n/g, '\n')); + text = text.length > 0 ? '
    ' + text + '
    ' : ''; + errMsg += dot + text; + } else { + errMsg += dot; + } + self.cancelling = false; + return fileName ? '' + fileName + ': ' + errMsg : errMsg; + }, + _parseFileType: function (file) { + var self = this, isValid, vType, cat, i; + for (i = 0; i < defaultPreviewTypes.length; i += 1) { + cat = defaultPreviewTypes[i]; + isValid = isSet(cat, self.fileTypeSettings) ? self.fileTypeSettings[cat] : defaultFileTypeSettings[cat]; + vType = isValid(file.type, file.name) ? cat : ''; + if (!isEmpty(vType)) { + return vType; + } + } + return 'other'; + }, + _parseFilePreviewIcon: function (content, fname) { + var self = this, ext, icn = self.previewFileIcon; + if (fname && fname.indexOf('.') > -1) { + ext = fname.split('.').pop(); + if (self.previewFileIconSettings && self.previewFileIconSettings[ext]) { + icn = self.previewFileIconSettings[ext]; + } + if (self.previewFileExtSettings) { + $.each(self.previewFileExtSettings, function (key, func) { + if (self.previewFileIconSettings[key] && func(ext)) { + icn = self.previewFileIconSettings[key]; + } + }); + } + } + if (content.indexOf('{previewFileIcon}') > -1) { + return content.replace(/\{previewFileIconClass}/g, self.previewFileIconClass).replace( + /\{previewFileIcon}/g, icn); + } + return content; + }, + _raise: function (event, params) { + var self = this, e = $.Event(event); + if (params !== undefined) { + self.$element.trigger(e, params); + } else { + self.$element.trigger(e); + } + if (e.isDefaultPrevented()) { + return false; + } + if (!e.result) { + return e.result; + } + switch (event) { + // ignore these events + case 'filebatchuploadcomplete': + case 'filebatchuploadsuccess': + case 'fileuploaded': + case 'fileclear': + case 'filecleared': + case 'filereset': + case 'fileerror': + case 'filefoldererror': + case 'fileuploaderror': + case 'filebatchuploaderror': + case 'filedeleteerror': + case 'filecustomerror': + case 'filesuccessremove': + break; + // receive data response via `filecustomerror` event` + default: + self.ajaxAborted = e.result; + break; + } + return true; + }, + _listen: function () { + var self = this, $el = self.$element, $form = $el.closest('form'), $cont = self.$container; + handler($el, 'change', $.proxy(self._change, self)); + handler(self.$btnFile, 'click', $.proxy(self._browse, self)); + handler($form, 'reset', $.proxy(self.reset, self)); + handler($cont.find('.fileinput-remove:not([disabled])'), 'click', $.proxy(self.clear, self)); + handler($cont.find('.fileinput-cancel'), 'click', $.proxy(self.cancel, self)); + self._initDragDrop(); + if (!self.isUploadable) { + handler($form, 'submit', $.proxy(self._submitForm, self)); + } + handler(self.$container.find('.fileinput-upload'), 'click', $.proxy(self._uploadClick, self)); + }, + _initDragDrop: function () { + var self = this, $zone = self.$dropZone; + if (self.isUploadable && self.dropZoneEnabled && self.showPreview) { + handler($zone, 'dragenter dragover', $.proxy(self._zoneDragEnter, self)); + handler($zone, 'dragleave', $.proxy(self._zoneDragLeave, self)); + handler($zone, 'drop', $.proxy(self._zoneDrop, self)); + handler($(document), 'dragenter dragover drop', self._zoneDragDropInit); + } + }, + _zoneDragDropInit: function (e) { + e.stopPropagation(); + e.preventDefault(); + }, + _zoneDragEnter: function (e) { + var self = this, hasFiles = $.inArray('Files', e.originalEvent.dataTransfer.types) > -1; + self._zoneDragDropInit(e); + if (self.isDisabled || !hasFiles) { + e.originalEvent.dataTransfer.effectAllowed = 'none'; + e.originalEvent.dataTransfer.dropEffect = 'none'; + return; + } + addCss(self.$dropZone, 'file-highlighted'); + }, + _zoneDragLeave: function (e) { + var self = this; + self._zoneDragDropInit(e); + if (self.isDisabled) { + return; + } + self.$dropZone.removeClass('file-highlighted'); + }, + _zoneDrop: function (e) { + var self = this; + e.preventDefault(); + /** @namespace e.originalEvent.dataTransfer */ + if (self.isDisabled || isEmpty(e.originalEvent.dataTransfer.files)) { + return; + } + self._change(e, 'dragdrop'); + self.$dropZone.removeClass('file-highlighted'); + }, + _uploadClick: function (e) { + var self = this, $btn = self.$container.find('.fileinput-upload'), $form, + isEnabled = !$btn.hasClass('disabled') && isEmpty($btn.attr('disabled')); + if (e && e.isDefaultPrevented()) { + return; + } + if (!self.isUploadable) { + if (isEnabled && $btn.attr('type') !== 'submit') { + $form = $btn.closest('form'); + // downgrade to normal form submit if possible + if ($form.length) { + $form.trigger('submit'); + } + e.preventDefault(); + } + return; + } + e.preventDefault(); + if (isEnabled) { + self.upload(); + } + }, + _submitForm: function () { + var self = this, $el = self.$element, files = $el.get(0).files; + if (files && self.minFileCount > 0 && self._getFileCount(files.length) < self.minFileCount) { + self._noFilesError({}); + return false; + } + return !self._abort({}); + }, + _clearPreview: function () { + var self = this, $thumbs = !self.showUploadedThumbs ? self.$preview.find('.file-preview-frame') : + self.$preview.find('.file-preview-frame:not(.file-preview-success)'); + $thumbs.remove(); + if (!self.$preview.find('.file-preview-frame').length || !self.showPreview) { + self._resetUpload(); + } + self._validateDefaultPreview(); + }, + _initPreview: function (isInit) { + var self = this, cap = self.initialCaption || '', out; + if (!previewCache.count(self.id)) { + self._clearPreview(); + if (isInit) { + self._setCaption(cap); + } else { + self._initCaption(); + } + return; + } + out = previewCache.out(self.id); + cap = isInit && self.initialCaption ? self.initialCaption : out.caption; + self.$preview.html(out.content); + self._setCaption(cap); + if (!isEmpty(out.content)) { + self.$container.removeClass('file-input-new'); + } + }, + _initPreviewDeletes: function () { + var self = this, deleteExtraData = self.deleteExtraData || {}, + resetProgress = function () { + var hasFiles = self.isUploadable ? previewCache.count(self.id) : self.$element.get(0).files.length; + if (self.$preview.find('.kv-file-remove').length === 0 && !hasFiles) { + self.reset(); + self.initialCaption = ''; + } + }; + + self.$preview.find('.kv-file-remove').each(function () { + var $el = $(this), vUrl = $el.data('url') || self.deleteUrl, vKey = $el.data('key'); + if (isEmpty(vUrl) || vKey === undefined) { + return; + } + var $frame = $el.closest('.file-preview-frame'), cache = previewCache.data[self.id], + settings, params, index = $frame.data('fileindex'), config, extraData; + index = parseInt(index.replace('init_', '')); + config = isEmpty(cache.config) && isEmpty(cache.config[index]) ? null : cache.config[index]; + extraData = isEmpty(config) || isEmpty(config.extra) ? deleteExtraData : config.extra; + if (typeof extraData === "function") { + extraData = extraData(); + } + params = {id: $el.attr('id'), key: vKey, extra: extraData}; + settings = $.extend(true, {}, { + url: vUrl, + type: 'POST', + dataType: 'json', + data: $.extend(true, {}, {key: vKey}, extraData), + beforeSend: function (jqXHR) { + self.ajaxAborted = false; + self._raise('filepredelete', [vKey, jqXHR, extraData]); + if (self.ajaxAborted) { + jqXHR.abort(); + } else { + addCss($frame, 'file-uploading'); + addCss($el, 'disabled'); + } + }, + success: function (data, textStatus, jqXHR) { + var n, cap; + if (isEmpty(data) || isEmpty(data.error)) { + previewCache.unset(self.id, index); + n = previewCache.count(self.id); + cap = n > 0 ? self._getMsgSelected(n) : ''; + self._raise('filedeleted', [vKey, jqXHR, extraData]); + self._setCaption(cap); + } else { + params.jqXHR = jqXHR; + params.response = data; + self._showError(data.error, params, 'filedeleteerror'); + $frame.removeClass('file-uploading'); + $el.removeClass('disabled'); + resetProgress(); + return; + } + $frame.removeClass('file-uploading').addClass('file-deleted'); + $frame.fadeOut('slow', function () { + self._clearObjects($frame); + $frame.remove(); + resetProgress(); + if (!n && self.getFileStack().length === 0) { + self._setCaption(''); + self.reset(); + } + }); + }, + error: function (jqXHR, textStatus, errorThrown) { + var errMsg = self._parseError(jqXHR, errorThrown); + params.jqXHR = jqXHR; + params.response = {}; + self._showError(errMsg, params, 'filedeleteerror'); + $frame.removeClass('file-uploading'); + resetProgress(); + } + }, self.ajaxDeleteSettings); + handler($el, 'click', function () { + if (!self._validateMinCount()) { + return false; + } + $.ajax(settings); + }); + }); + }, + _clearObjects: function ($el) { + $el.find('video audio').each(function () { + this.pause(); + $(this).remove(); + }); + $el.find('img object div').each(function () { + $(this).remove(); + }); + }, + _clearFileInput: function () { + var self = this, $el = self.$element, $srcFrm, $tmpFrm, $tmpEl; + if (isEmpty($el.val())) { + return; + } + // Fix for IE ver < 11, that does not clear file inputs. Requires a sequence of steps to prevent IE + // crashing but still allow clearing of the file input. + if (self.isIE9 || self.isIE10) { + $srcFrm = $el.closest('form'); + $tmpFrm = $(document.createElement('form')); + $tmpEl = $(document.createElement('div')); + $el.before($tmpEl); + if ($srcFrm.length) { + $srcFrm.after($tmpFrm); + } else { + $tmpEl.after($tmpFrm); + } + $tmpFrm.append($el).trigger('reset'); + $tmpEl.before($el).remove(); + $tmpFrm.remove(); + } else { // normal input clear behavior for other sane browsers + $el.val(''); + } + self.fileInputCleared = true; + }, + _resetUpload: function () { + var self = this; + self.uploadCache = {content: [], config: [], tags: [], append: true}; + self.uploadCount = 0; + self.uploadStatus = {}; + self.uploadLog = []; + self.uploadAsyncCount = 0; + self.loadedImages = []; + self.totalImagesCount = 0; + self.$btnUpload.removeAttr('disabled'); + self._setProgress(0); + addCss(self.$progress, 'hide'); + self._resetErrors(false); + self.ajaxAborted = false; + self.ajaxRequests = []; + self._resetCanvas(); + }, + _resetCanvas: function () { + var self = this; + if (self.canvas && self.imageCanvasContext) { + self.imageCanvasContext.clearRect(0, 0, self.canvas.width, self.canvas.height); + } + }, + _hasInitialPreview: function () { + var self = this; + return !self.overwriteInitial && previewCache.count(self.id); + }, + _resetPreview: function () { + var self = this, out, cap; + if (previewCache.count(self.id)) { + out = previewCache.out(self.id); + self.$preview.html(out.content); + cap = self.initialCaption ? self.initialCaption : out.caption; + self._setCaption(cap); + } else { + self._clearPreview(); + self._initCaption(); + } + }, + _clearDefaultPreview: function () { + var self = this; + self.$preview.find('.file-default-preview').remove(); + }, + _validateDefaultPreview: function () { + var self = this; + if (!self.showPreview || isEmpty(self.defaultPreviewContent)) { + return; + } + self.$preview.html('
    ' + self.defaultPreviewContent + '
    '); + self.$container.removeClass('file-input-new'); + }, + _resetPreviewThumbs: function (isAjax) { + var self = this, out; + if (isAjax) { + self._clearPreview(); + self.clearStack(); + return; + } + if (self._hasInitialPreview()) { + out = previewCache.out(self.id); + self.$preview.html(out.content); + self._setCaption(out.caption); + self._initPreviewDeletes(); + } else { + self._clearPreview(); + } + }, + _getLayoutTemplate: function (t) { + var self = this, + template = isSet(t, self.layoutTemplates) ? self.layoutTemplates[t] : defaultLayoutTemplates[t]; + if (isEmpty(self.customLayoutTags)) { + return template; + } + return replaceTags(template, self.customLayoutTags); + }, + _getPreviewTemplate: function (t) { + var self = this, + template = isSet(t, self.previewTemplates) ? self.previewTemplates[t] : defaultPreviewTemplates[t]; + if (isEmpty(self.customPreviewTags)) { + return template; + } + return replaceTags(template, self.customPreviewTags); + }, + _getOutData: function (jqXHR, responseData, filesData) { + var self = this; + jqXHR = jqXHR || {}; + responseData = responseData || {}; + filesData = filesData || self.filestack.slice(0) || {}; + return { + form: self.formdata, + files: filesData, + filenames: self.filenames, + extra: self._getExtraData(), + response: responseData, + reader: self.reader, + jqXHR: jqXHR + }; + }, + _getMsgSelected: function (n) { + var self = this, strFiles = n === 1 ? self.fileSingle : self.filePlural; + return self.msgSelected.replace('{n}', n).replace('{files}', strFiles); + }, + _getThumbs: function (css) { + css = css || ''; + return this.$preview.find('.file-preview-frame:not(.file-preview-initial)' + css); + }, + _getExtraData: function (previewId, index) { + var self = this, data = self.uploadExtraData; + if (typeof self.uploadExtraData === "function") { + data = self.uploadExtraData(previewId, index); + } + return data; + }, + _initXhr: function (xhrobj, previewId, fileCount) { + var self = this; + if (xhrobj.upload) { + xhrobj.upload.addEventListener('progress', function (event) { + var pct = 0, position = event.loaded || event.position, total = event.total; + /** @namespace event.lengthComputable */ + if (event.lengthComputable) { + pct = Math.ceil(position / total * 100); + } + if (previewId) { + self._setAsyncUploadStatus(previewId, pct, fileCount); + } else { + self._setProgress(Math.ceil(pct)); + } + }, false); + } + return xhrobj; + }, + _ajaxSubmit: function (fnBefore, fnSuccess, fnComplete, fnError, previewId, index) { + var self = this, settings; + self._raise('filepreajax', [previewId, index]); + self._uploadExtra(previewId, index); + settings = $.extend(true, {}, { + xhr: function () { + var xhrobj = $.ajaxSettings.xhr(); + return self._initXhr(xhrobj, previewId, self.getFileStack().length); + }, + url: self.uploadUrl, + type: 'POST', + dataType: 'json', + data: self.formdata, + cache: false, + processData: false, + contentType: false, + beforeSend: fnBefore, + success: fnSuccess, + complete: fnComplete, + error: fnError + }, self.ajaxSettings); + self.ajaxRequests.push($.ajax(settings)); + }, + _initUploadSuccess: function (out, $thumb, allFiles) { + var self = this, append, data, index, $newThumb, content, config, tags, i; + if (!self.showPreview || typeof out !== 'object' || $.isEmptyObject(out)) { + return; + } + if (out.initialPreview !== undefined && out.initialPreview.length > 0) { + self.hasInitData = true; + content = out.initialPreview || []; + config = out.initialPreviewConfig || []; + tags = out.initialPreviewThumbTags || []; + append = out.append === undefined || out.append ? true : false; + self.overwriteInitial = false; + if ($thumb !== undefined) { + if (!allFiles) { + index = previewCache.add(self.id, content, config[0], tags[0], append); + data = previewCache.get(self.id, index, false); + $newThumb = $(data).hide(); + $thumb.after($newThumb).fadeOut('slow', function () { + $newThumb.fadeIn('slow').css('display:inline-block'); + self._initPreviewDeletes(); + self._clearFileInput(); + $thumb.remove(); + }); + } else { + i = $thumb.attr('data-fileindex'); + self.uploadCache.content[i] = content[0]; + self.uploadCache.config[i] = config[0]; + self.uploadCache.tags[i] = tags[0]; + self.uploadCache.append = append; + } + } else { + previewCache.set(self.id, content, config, tags, append); + self._initPreview(); + self._initPreviewDeletes(); + } + } + }, + _initSuccessThumbs: function () { + var self = this; + if (!self.showPreview) { + return; + } + self._getThumbs('.file-preview-success').each(function () { + var $thumb = $(this), $remove = $thumb.find('.kv-file-remove'); + $remove.removeAttr('disabled'); + handler($remove, 'click', function () { + var out = self._raise('filesuccessremove', [$thumb.attr('id'), $thumb.data('fileindex')]); + cleanMemory($thumb); + if (out === false) { + return; + } + $thumb.fadeOut('slow', function () { + $thumb.remove(); + if (!self.$preview.find('.file-preview-frame').length) { + self.reset(); + } + }); + }); + }); + }, + _checkAsyncComplete: function () { + var self = this, previewId, i; + for (i = 0; i < self.filestack.length; i++) { + if (self.filestack[i]) { + previewId = self.previewInitId + "-" + i; + if ($.inArray(previewId, self.uploadLog) === -1) { + return false; + } + } + } + return (self.uploadAsyncCount === self.uploadLog.length); + }, + _uploadExtra: function (previewId, index) { + var self = this, data = self._getExtraData(previewId, index); + if (data.length === 0) { + return; + } + $.each(data, function (key, value) { + self.formdata.append(key, value); + }); + }, + _uploadSingle: function (i, files, allFiles) { + var self = this, total = self.getFileStack().length, formdata = new FormData(), outData, + previewId = self.previewInitId + "-" + i, $thumb, chkComplete, $btnUpload, $btnDelete, + hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData), + fnBefore, fnSuccess, fnComplete, fnError, updateUploadLog, params = {id: previewId, index: i}; + self.formdata = formdata; + if (self.showPreview) { + $thumb = $('#' + previewId + ':not(.file-preview-initial)'); + $btnUpload = $thumb.find('.kv-file-upload'); + $btnDelete = $thumb.find('.kv-file-remove'); + $('#' + previewId).find('.file-thumb-progress').removeClass('hide'); + } + if (total === 0 || !hasPostData || ($btnUpload && $btnUpload.hasClass('disabled')) || self._abort(params)) { + return; + } + updateUploadLog = function (i, previewId) { + self.updateStack(i, undefined); + self.uploadLog.push(previewId); + if (self._checkAsyncComplete()) { + self.fileBatchCompleted = true; + } + }; + chkComplete = function () { + if (!self.fileBatchCompleted) { + return; + } + setTimeout(function () { + if (self.showPreview) { + previewCache.set( + self.id, + self.uploadCache.content, + self.uploadCache.config, + self.uploadCache.tags, + self.uploadCache.append + ); + if (self.hasInitData) { + self._initPreview(); + self._initPreviewDeletes(); + } + } + self.unlock(); + self._clearFileInput(); + self._raise('filebatchuploadcomplete', [self.filestack, self._getExtraData()]); + self.uploadCount = 0; + self.uploadStatus = {}; + self.uploadLog = []; + self._setProgress(100); + }, 100); + }; + fnBefore = function (jqXHR) { + outData = self._getOutData(jqXHR); + self.fileBatchCompleted = false; + if (self.showPreview) { + if (!$thumb.hasClass('file-preview-success')) { + self._setThumbStatus($thumb, 'Loading'); + addCss($thumb, 'file-uploading'); + } + $btnUpload.attr('disabled', true); + $btnDelete.attr('disabled', true); + } + if (!allFiles) { + self.lock(); + } + self._raise('filepreupload', [outData, previewId, i]); + $.extend(true, params, outData); + if (self._abort(params)) { + jqXHR.abort(); + self._setProgressCancelled(); + } + }; + fnSuccess = function (data, textStatus, jqXHR) { + outData = self._getOutData(jqXHR, data); + $.extend(true, params, outData); + setTimeout(function () { + if (isEmpty(data) || isEmpty(data.error)) { + if (self.showPreview) { + self._setThumbStatus($thumb, 'Success'); + $btnUpload.hide(); + self._initUploadSuccess(data, $thumb, allFiles); + } + self._raise('fileuploaded', [outData, previewId, i]); + if (!allFiles) { + self.updateStack(i, undefined); + } else { + updateUploadLog(i, previewId); + } + } else { + self._showUploadError(data.error, params); + self._setPreviewError($thumb, i); + if (allFiles) { + updateUploadLog(i, previewId); + } + } + }, 100); + }; + fnComplete = function () { + setTimeout(function () { + if (self.showPreview) { + $btnUpload.removeAttr('disabled'); + $btnDelete.removeAttr('disabled'); + $thumb.removeClass('file-uploading'); + } + if (!allFiles) { + self.unlock(false); + self._clearFileInput(); + } else { + chkComplete(); + } + self._initSuccessThumbs(); + }, 100); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var errMsg = self._parseError(jqXHR, errorThrown, (allFiles ? files[i].name : null)); + setTimeout(function () { + if (allFiles) { + updateUploadLog(i, previewId); + } + self.uploadStatus[previewId] = 100; + self._setPreviewError($thumb, i); + $.extend(true, params, self._getOutData(jqXHR)); + self._showUploadError(errMsg, params); + }, 100); + }; + formdata.append(self.uploadFileAttr, files[i], self.filenames[i]); + formdata.append('file_id', i); + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, previewId, i); + }, + _uploadBatch: function () { + var self = this, files = self.filestack, total = files.length, params = {}, fnBefore, fnSuccess, fnError, + fnComplete, hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData), + setAllUploaded; + self.formdata = new FormData(); + if (total === 0 || !hasPostData || self._abort(params)) { + return; + } + setAllUploaded = function () { + $.each(files, function (key) { + self.updateStack(key, undefined); + }); + self._clearFileInput(); + }; + fnBefore = function (jqXHR) { + self.lock(); + var outData = self._getOutData(jqXHR); + if (self.showPreview) { + self._getThumbs().each(function () { + var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'), + $btnDelete = $thumb.find('.kv-file-remove'); + if (!$thumb.hasClass('file-preview-success')) { + self._setThumbStatus($thumb, 'Loading'); + addCss($thumb, 'file-uploading'); + } + $btnUpload.attr('disabled', true); + $btnDelete.attr('disabled', true); + }); + } + self._raise('filebatchpreupload', [outData]); + if (self._abort(outData)) { + jqXHR.abort(); + self._setProgressCancelled(); + } + }; + fnSuccess = function (data, textStatus, jqXHR) { + /** @namespace data.errorkeys */ + var outData = self._getOutData(jqXHR, data), $thumbs = self._getThumbs(), key = 0, + keys = isEmpty(data) || isEmpty(data.errorkeys) ? [] : data.errorkeys; + if (isEmpty(data) || isEmpty(data.error)) { + self._raise('filebatchuploadsuccess', [outData]); + setAllUploaded(); + if (self.showPreview) { + $thumbs.each(function () { + var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'); + $thumb.find('.kv-file-upload').hide(); + self._setThumbStatus($thumb, 'Success'); + $thumb.removeClass('file-uploading'); + $btnUpload.removeAttr('disabled'); + }); + self._initUploadSuccess(data); + } else { + self.reset(); + } + } else { + if (self.showPreview) { + $thumbs.each(function () { + var $thumb = $(this), $btnDelete = $thumb.find('.kv-file-remove'), + $btnUpload = $thumb.find('.kv-file-upload'); + $thumb.removeClass('file-uploading'); + $btnUpload.removeAttr('disabled'); + $btnDelete.removeAttr('disabled'); + if (keys.length === 0) { + self._setPreviewError($thumb); + return; + } + if ($.inArray(key, keys) !== -1) { + self._setPreviewError($thumb); + } else { + $thumb.find('.kv-file-upload').hide(); + self._setThumbStatus($thumb, 'Success'); + self.updateStack(key, undefined); + } + key++; + }); + self._initUploadSuccess(data); + } + self._showUploadError(data.error, outData, 'filebatchuploaderror'); + } + }; + fnComplete = function () { + self._setProgress(100); + self.unlock(); + self._initSuccessThumbs(); + self._clearFileInput(); + self._raise('filebatchuploadcomplete', [self.filestack, self._getExtraData()]); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var outData = self._getOutData(jqXHR), errMsg = self._parseError(jqXHR, errorThrown); + self._showUploadError(errMsg, outData, 'filebatchuploaderror'); + self.uploadFileCount = total - 1; + if (!self.showPreview) { + return; + } + self._getThumbs().each(function () { + var $thumb = $(this), key = $thumb.attr('data-fileindex'); + $thumb.removeClass('file-uploading'); + if (self.filestack[key] !== undefined) { + self._setPreviewError($thumb); + } + }); + self._getThumbs().removeClass('file-uploading'); + self._getThumbs(' .kv-file-upload').removeAttr('disabled'); + self._getThumbs(' .kv-file-delete').removeAttr('disabled'); + }; + $.each(files, function (key, data) { + if (!isEmpty(files[key])) { + self.formdata.append(self.uploadFileAttr, data, self.filenames[key]); + } + }); + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError); + }, + _uploadExtraOnly: function () { + var self = this, params = {}, fnBefore, fnSuccess, fnComplete, fnError; + self.formdata = new FormData(); + if (self._abort(params)) { + return; + } + fnBefore = function (jqXHR) { + self.lock(); + var outData = self._getOutData(jqXHR); + self._raise('filebatchpreupload', [outData]); + self._setProgress(50); + params.data = outData; + params.xhr = jqXHR; + if (self._abort(params)) { + jqXHR.abort(); + self._setProgressCancelled(); + } + }; + fnSuccess = function (data, textStatus, jqXHR) { + var outData = self._getOutData(jqXHR, data); + if (isEmpty(data) || isEmpty(data.error)) { + self._raise('filebatchuploadsuccess', [outData]); + self._clearFileInput(); + self._initUploadSuccess(data); + } else { + self._showUploadError(data.error, outData, 'filebatchuploaderror'); + } + }; + fnComplete = function () { + self._setProgress(100); + self.unlock(); + self._clearFileInput(); + self._raise('filebatchuploadcomplete', [self.filestack, self._getExtraData()]); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var outData = self._getOutData(jqXHR), errMsg = self._parseError(jqXHR, errorThrown); + params.data = outData; + self._showUploadError(errMsg, outData, 'filebatchuploaderror'); + }; + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError); + }, + _initFileActions: function () { + var self = this; + if (!self.showPreview) { + return; + } + self.$preview.find('.kv-file-remove').each(function () { + var $el = $(this), $frame = $el.closest('.file-preview-frame'), hasError, + id = $frame.attr('id'), ind = $frame.attr('data-fileindex'), n, cap, status; + handler($el, 'click', function () { + status = self._raise('filepreremove', [id, ind]); + if (status === false || !self._validateMinCount()) { + return false; + } + hasError = $frame.hasClass('file-preview-error'); + cleanMemory($frame); + $frame.fadeOut('slow', function () { + self.updateStack(ind, undefined); + self._clearObjects($frame); + $frame.remove(); + if (id && hasError) { + self.$errorContainer.find('li[data-file-id="' + id + '"]').fadeOut('fast', function () { + $(this).remove(); + if (!self._errorsExist()) { + self._resetErrors(); + } + }); + } + var filestack = self.getFileStack(true), len = filestack.length, chk = previewCache.count( + self.id), + hasThumb = self.showPreview && self.$preview.find('.file-preview-frame').length; + self._clearFileInput(); + if (len === 0 && chk === 0 && !hasThumb) { + self.reset(); + } else { + n = chk + len; + cap = n > 1 ? self._getMsgSelected(n) : (filestack[0] ? self._getFileNames()[0] : ''); + self._setCaption(cap); + } + self._raise('fileremoved', [id, ind]); + }); + }); + }); + self.$preview.find('.kv-file-upload').each(function () { + var $el = $(this); + handler($el, 'click', function () { + var $frame = $el.closest('.file-preview-frame'), + ind = $frame.attr('data-fileindex'); + if (!$frame.hasClass('file-preview-error')) { + self._uploadSingle(ind, self.filestack, false); + } + }); + }); + }, + _hideFileIcon: function () { + if (this.overwriteInitial) { + this.$captionContainer.find('.kv-caption-icon').hide(); + } + }, + _showFileIcon: function () { + this.$captionContainer.find('.kv-caption-icon').show(); + }, + _previewDefault: function (file, previewId, isDisabled) { + if (!this.showPreview) { + return; + } + var self = this, frameClass = '', fname = file ? file.name : '', + /** @namespace objUrl.createObjectURL */ + data = objUrl.createObjectURL(file), ind = previewId.slice(previewId.lastIndexOf('-') + 1), + config = self.previewSettings.other || defaultPreviewSettings.other, + footer = self._renderFileFooter(file.name, config.width), + previewOtherTemplate = self._parseFilePreviewIcon(self._getPreviewTemplate('other'), fname); + if (isDisabled === true) { + if (!self.isUploadable) { + footer += '
    ' + self.fileActionSettings.indicatorError + '
    '; + } + } + self._clearDefaultPreview(); + self.$preview.append("\n" + previewOtherTemplate + .replace(/\{previewId}/g, previewId) + .replace(/\{frameClass}/g, frameClass) + .replace(/\{fileindex}/g, ind) + .replace(/\{caption}/g, self.slug(file.name)) + .replace(/\{width}/g, config.width) + .replace(/\{height}/g, config.height) + .replace(/\{type}/g, file.type) + .replace(/\{data}/g, data) + .replace(/\{footer}/g, footer)); + if (isDisabled === true && self.isUploadable) { + self._setThumbStatus($('#' + previewId), 'Error'); + } + }, + _previewFile: function (i, file, theFile, previewId, data) { + if (!this.showPreview) { + return; + } + var self = this, cat = self._parseFileType(file), fname = file ? file.name : '', caption = self.slug(fname), + content, strText, types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes, + tmplt = self._getPreviewTemplate(cat), chkTypes = types && types.indexOf(cat) >= 0, id, + config = isSet(cat, self.previewSettings) ? self.previewSettings[cat] : defaultPreviewSettings[cat], + chkMimes = mimes && mimes.indexOf(file.type) !== -1, + footer = self._renderFileFooter(caption, config.width), modal = '', + ind = previewId.slice(previewId.lastIndexOf('-') + 1); + if (chkTypes || chkMimes) { + tmplt = self._parseFilePreviewIcon(tmplt, fname.split('.').pop()); + if (cat === 'text') { + strText = htmlEncode(theFile.target.result); + id = 'text-' + uniqId(); + content = tmplt.replace(/\{zoom}/g, self._getLayoutTemplate('zoom')); + modal = self._getLayoutTemplate('modal').replace('{id}', id) + .replace(/\{title}/g, caption) + .replace(/\{body}/g, strText).replace(/\{heading}/g, self.msgZoomModalHeading); + content = content.replace(/\{previewId}/g, previewId).replace(/\{caption}/g, caption) + .replace(/\{width}/g, config.width).replace(/\{height}/g, config.height) + .replace(/\{frameClass}/g, '').replace(/\{zoomInd}/g, self.zoomIndicator) + .replace(/\{footer}/g, footer).replace(/\{fileindex}/g, ind) + .replace(/\{type}/g, file.type).replace(/\{zoomTitle}/g, self.msgZoomTitle) + .replace(/\{dialog}/g, "$('#" + id + "').modal('show')") + .replace(/\{data}/g, strText) + modal; + } else { + content = tmplt.replace(/\{previewId}/g, previewId).replace(/\{caption}/g, caption) + .replace(/\{frameClass}/g, '').replace(/\{type}/g, file.type).replace(/\{fileindex}/g, ind) + .replace(/\{width}/g, config.width).replace(/\{height}/g, config.height) + .replace(/\{footer}/g, footer).replace(/\{data}/g, data); + } + self._clearDefaultPreview(); + self.$preview.append("\n" + content); + self._validateImage(i, previewId, caption, file.type); + } else { + self._previewDefault(file, previewId); + } + }, + _slugDefault: function (text) { + return isEmpty(text) ? '' : String(text).replace(/[\-\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, '_'); + }, + _readFiles: function (files) { + this.reader = new FileReader(); + var self = this, $el = self.$element, $preview = self.$preview, reader = self.reader, + $container = self.$previewContainer, $status = self.$previewStatus, msgLoading = self.msgLoading, + msgProgress = self.msgProgress, previewInitId = self.previewInitId, numFiles = files.length, + settings = self.fileTypeSettings, ctr = self.filestack.length, readFile, + throwError = function (msg, file, previewId, index) { + var p1 = $.extend(true, {}, self._getOutData({}, {}, files), {id: previewId, index: index}), + p2 = {id: previewId, index: index, file: file, files: files}; + self._previewDefault(file, previewId, true); + if (self.isUploadable) { + self.addToStack(undefined); + } + setTimeout(readFile(index + 1), 100); + self._initFileActions(); + if (self.removeFromPreviewOnError) { + $('#' + previewId).remove(); + } + return self.isUploadable ? self._showUploadError(msg, p1) : self._showError(msg, p2); + }; + + self.loadedImages = []; + self.totalImagesCount = 0; + + $.each(files, function (key, file) { + var func = self.fileTypeSettings.image || defaultFileTypeSettings.image; + if (func && func(file.type)) { + self.totalImagesCount++; + } + }); + + readFile = function (i) { + if (isEmpty($el.attr('multiple'))) { + numFiles = 1; + } + if (i >= numFiles) { + if (self.isUploadable && self.filestack.length > 0) { + self._raise('filebatchselected', [self.getFileStack()]); + } else { + self._raise('filebatchselected', [files]); + } + $container.removeClass('file-thumb-loading'); + $status.html(''); + return; + } + var node = ctr + i, previewId = previewInitId + "-" + node, isText, file = files[i], + caption = self.slug(file.name), fileSize = (file.size || 0) / 1000, checkFile, fileExtExpr = '', + previewData = objUrl.createObjectURL(file), fileCount = 0, j, msg, typ, chk, + fileTypes = self.allowedFileTypes, strTypes = isEmpty(fileTypes) ? '' : fileTypes.join(', '), + fileExt = self.allowedFileExtensions, strExt = isEmpty(fileExt) ? '' : fileExt.join(', '); + if (!isEmpty(fileExt)) { + fileExtExpr = new RegExp('\\.(' + fileExt.join('|') + ')$', 'i'); + } + fileSize = fileSize.toFixed(2); + if (self.maxFileSize > 0 && fileSize > self.maxFileSize) { + msg = self.msgSizeTooLarge.replace('{name}', caption) + .replace('{size}', fileSize) + .replace('{maxSize}', self.maxFileSize); + self.isError = throwError(msg, file, previewId, i); + return; + } + if (!isEmpty(fileTypes) && isArray(fileTypes)) { + for (j = 0; j < fileTypes.length; j += 1) { + typ = fileTypes[j]; + checkFile = settings[typ]; + chk = (checkFile !== undefined && checkFile(file.type, caption)); + fileCount += isEmpty(chk) ? 0 : chk.length; + } + if (fileCount === 0) { + msg = self.msgInvalidFileType.replace('{name}', caption).replace('{types}', strTypes); + self.isError = throwError(msg, file, previewId, i); + return; + } + } + if (fileCount === 0 && !isEmpty(fileExt) && isArray(fileExt) && !isEmpty(fileExtExpr)) { + chk = compare(caption, fileExtExpr); + fileCount += isEmpty(chk) ? 0 : chk.length; + if (fileCount === 0) { + msg = self.msgInvalidFileExtension.replace('{name}', caption).replace('{extensions}', + strExt); + self.isError = throwError(msg, file, previewId, i); + return; + } + } + if (!self.showPreview) { + self.addToStack(file); + setTimeout(readFile(i + 1), 100); + self._raise('fileloaded', [file, previewId, i, reader]); + return; + } + if ($preview.length > 0 && FileReader !== undefined) { + $status.html(msgLoading.replace('{index}', i + 1).replace('{files}', numFiles)); + $container.addClass('file-thumb-loading'); + reader.onerror = function (evt) { + self._errorHandler(evt, caption); + }; + reader.onload = function (theFile) { + self._previewFile(i, file, theFile, previewId, previewData); + self._initFileActions(); + }; + reader.onloadend = function () { + msg = msgProgress + .replace('{index}', i + 1).replace('{files}', numFiles) + .replace('{percent}', 50).replace('{name}', caption); + setTimeout(function () { + $status.html(msg); + self._updateFileDetails(numFiles); + readFile(i + 1); + }, 100); + self._raise('fileloaded', [file, previewId, i, reader]); + }; + reader.onprogress = function (data) { + if (data.lengthComputable) { + var fact = (data.loaded / data.total) * 100, progress = Math.ceil(fact); + msg = msgProgress.replace('{index}', i + 1).replace('{files}', numFiles) + .replace('{percent}', progress).replace('{name}', caption); + setTimeout(function () { + $status.html(msg); + }, 100); + } + }; + isText = isSet('text', settings) ? settings.text : defaultFileTypeSettings.text; + if (isText(file.type, caption)) { + reader.readAsText(file, self.textEncoding); + } else { + reader.readAsArrayBuffer(file); + } + } else { + self._previewDefault(file, previewId); + setTimeout(function () { + readFile(i + 1); + self._updateFileDetails(numFiles); + }, 100); + self._raise('fileloaded', [file, previewId, i, reader]); + } + self.addToStack(file); + }; + + readFile(0); + self._updateFileDetails(numFiles, false); + }, + _updateFileDetails: function (numFiles) { + var self = this, $el = self.$element, fileStack = self.getFileStack(), + name = ($el[0].files[0] && $el[0].files[0].name) || (fileStack.length && fileStack[0].name) || '', + label = self.slug(name), n = self.isUploadable ? fileStack.length : numFiles, + nFiles = previewCache.count(self.id) + n, log = n > 1 ? self._getMsgSelected(nFiles) : label; + if (self.isError) { + self.$previewContainer.removeClass('file-thumb-loading'); + self.$previewStatus.html(''); + self.$captionContainer.find('.kv-caption-icon').hide(); + } else { + self._showFileIcon(); + } + self._setCaption(log, self.isError); + self.$container.removeClass('file-input-new file-input-ajax-new'); + if (arguments.length === 1) { + self._raise('fileselect', [numFiles, label]); + } + if (previewCache.count(self.id)) { + self._initPreviewDeletes(); + } + }, + _setThumbStatus: function ($thumb, status) { + var self = this; + if (!self.showPreview) { + return; + } + var icon = 'indicator' + status, msg = icon + 'Title', + css = 'file-preview-' + status.toLowerCase(), + $indicator = $thumb.find('.file-upload-indicator'), + config = self.fileActionSettings; + $thumb.removeClass('file-preview-success file-preview-error file-preview-loading'); + if (status === 'Error') { + $thumb.find('.kv-file-upload').attr('disabled', true); + } + $indicator.html(config[icon]); + $indicator.attr('title', config[msg]); + $thumb.addClass(css); + }, + _setProgressCancelled: function () { + var self = this; + self._setProgress(100, self.$progress, self.msgCancelled); + }, + _setProgress: function (p, $el, error) { + var self = this, pct = Math.min(p, 100), template = pct < 100 ? self.progressTemplate : + (error ? self.progressErrorTemplate : self.progressCompleteTemplate); + $el = $el || self.$progress; + if (!isEmpty(template)) { + $el.html(template.replace(/\{percent}/g, pct)); + if (error) { + $el.find('[role="progressbar"]').html(error); + } + } + }, + _setFileDropZoneTitle: function () { + var self = this, $zone = self.$container.find('.file-drop-zone'); + $zone.find('.' + self.dropZoneTitleClass).remove(); + if (!self.isUploadable || !self.showPreview || $zone.length === 0 || self.getFileStack().length > 0 || !self.dropZoneEnabled) { + return; + } + if ($zone.find('.file-preview-frame').length === 0 && isEmpty(self.defaultPreviewContent)) { + $zone.prepend('
    ' + self.dropZoneTitle + '
    '); + } + self.$container.removeClass('file-input-new'); + addCss(self.$container, 'file-input-ajax-new'); + }, + _setAsyncUploadStatus: function (previewId, pct, total) { + var self = this, sum = 0; + self._setProgress(pct, $('#' + previewId).find('.file-thumb-progress')); + self.uploadStatus[previewId] = pct; + $.each(self.uploadStatus, function (key, value) { + sum += value; + }); + self._setProgress(Math.ceil(sum / total)); + + }, + _validateMinCount: function () { + var self = this, len = self.isUploadable ? self.getFileStack().length : self.$element.get(0).files.length; + if (self.validateInitialCount && self.minFileCount > 0 && self._getFileCount( + len - 1) < self.minFileCount) { + self._noFilesError({}); + return false; + } + return true; + }, + _getFileCount: function (fileCount) { + var self = this, addCount = 0; + if (self.validateInitialCount && !self.overwriteInitial) { + addCount = previewCache.count(self.id); + fileCount += addCount; + } + return fileCount; + }, + _getFileName: function (file) { + return file && file.name ? this.slug(file.name) : undefined; + }, + _getFileNames: function (skipNull) { + var self = this; + return self.filenames.filter(function (n) { + return (skipNull ? n !== undefined : n !== undefined && n !== null); + }); + }, + _setPreviewError: function ($thumb, i, val) { + var self = this; + if (i) { + self.updateStack(i, val); + } + if (self.removeFromPreviewOnError) { + $thumb.remove(); + } else { + self._setThumbStatus($thumb, 'Error'); + } + }, + _checkDimensions: function (i, chk, $img, $thumb, fname, type, params) { + var self = this, msg, dim, tag = chk === 'Small' ? 'min' : 'max', limit = self[tag + 'Image' + type], + $imgEl, isValid; + if (isEmpty(limit) || !$img.length) { + return; + } + $imgEl = $img[0]; + dim = (type === 'Width') ? $imgEl.naturalWidth || $imgEl.width : $imgEl.naturalHeight || $imgEl.height; + isValid = chk === 'Small' ? dim >= limit : dim <= limit; + if (isValid) { + return; + } + msg = self['msgImage' + type + chk].replace('{name}', fname).replace('{size}', limit); + self._showUploadError(msg, params); + self._setPreviewError($thumb, i, null); + }, + _validateImage: function (i, previewId, fname, ftype) { + var self = this, $preview = self.$preview, params, w1, w2, + $thumb = $preview.find("#" + previewId), $img = $thumb.find('img'); + fname = fname || 'Untitled'; + if (!$img.length) { + return; + } + handler($img, 'load', function () { + w1 = $thumb.width(); + w2 = $preview.width(); + if (w1 > w2) { + $img.css('width', '100%'); + $thumb.css('width', '97%'); + } + params = {ind: i, id: previewId}; + self._checkDimensions(i, 'Small', $img, $thumb, fname, 'Width', params); + self._checkDimensions(i, 'Small', $img, $thumb, fname, 'Height', params); + if (!self.resizeImage) { + self._checkDimensions(i, 'Large', $img, $thumb, fname, 'Width', params); + self._checkDimensions(i, 'Large', $img, $thumb, fname, 'Height', params); + } + self._raise('fileimageloaded', [previewId]); + self.loadedImages.push({ind: i, img: $img, thumb: $thumb, pid: previewId, typ: ftype}); + self._validateAllImages(); + objUrl.revokeObjectURL($img.attr('src')); + }); + }, + _validateAllImages: function () { + var self = this, i, config, $img, $thumb, pid, ind, params = {}, errFunc; + if (self.loadedImages.length !== self.totalImagesCount) { + return; + } + self._raise('fileimagesloaded'); + if (!self.resizeImage) { + return; + } + errFunc = self.isUploadable ? self._showUploadError : self._showError; + for (i = 0; i < self.loadedImages.length; i++) { + config = self.loadedImages[i]; + $img = config.img; + $thumb = config.thumb; + pid = config.pid; + ind = config.ind; + params = {id: pid, 'index': ind}; + if (!self._getResizedImage($img[0], config.typ, pid, ind)) { + errFunc(self.msgImageResizeError, params, 'fileimageresizeerror'); + self._setPreviewError($thumb, ind); + } + } + self._raise('fileimagesresized'); + }, + _getResizedImage: function (image, type, pid, ind) { + var self = this, width = image.naturalWidth, height = image.naturalHeight, ratio = 1, + maxWidth = self.maxImageWidth || width, maxHeight = self.maxImageHeight || height, + isValidImage = (width && height), chkWidth, chkHeight, + canvas = self.imageCanvas, context = self.imageCanvasContext; + if (!isValidImage) { + return false; + } + if (width === maxWidth && height === maxHeight) { + return true; + } + type = type || self.resizeDefaultImageType; + chkWidth = width > maxWidth; + chkHeight = height > maxHeight; + if (self.resizePreference === 'width') { + ratio = chkWidth ? maxWidth / width : (chkHeight ? maxHeight / height : 1); + } else { + ratio = chkHeight ? maxHeight / height : (chkWidth ? maxWidth / width : 1); + } + self._resetCanvas(); + width *= ratio; + height *= ratio; + canvas.width = width; + canvas.height = height; + try { + context.drawImage(image, 0, 0, width, height); + canvas.toBlob(function (blob) { + self._raise('fileimageresized', [pid, ind]); + self.filestack[ind] = blob; + }, type, self.resizeQuality); + return true; + } + catch (err) { + return false; + } + }, + _initBrowse: function ($container) { + var self = this; + self.$btnFile = $container.find('.btn-file'); + self.$btnFile.append(self.$element); + }, + _initCaption: function () { + var self = this, cap = self.initialCaption || ''; + if (self.overwriteInitial || isEmpty(cap)) { + self.$caption.html(''); + return false; + } + self._setCaption(cap); + return true; + }, + _setCaption: function (content, isError) { + var self = this, title, out, n, cap, stack = self.getFileStack(); + if (!self.$caption.length) { + return; + } + if (isError) { + title = $('
    ' + self.msgValidationError + '
    ').text(); + n = stack.length; + if (n) { + cap = n === 1 && stack[0] ? self._getFileNames()[0] : self._getMsgSelected(n); + } else { + cap = self._getMsgSelected(self.msgNo); + } + out = '' + self.msgValidationErrorIcon + + (isEmpty(content) ? cap : content) + ''; + } else { + if (isEmpty(content)) { + return; + } + title = $('
    ' + content + '
    ').text(); + out = self._getLayoutTemplate('icon') + title; + } + self.$caption.html(out); + self.$caption.attr('title', title); + self.$captionContainer.find('.file-caption-ellipsis').attr('title', title); + }, + _createContainer: function () { + var self = this, + $container = $(document.createElement("div")) + .attr({"class": 'file-input file-input-new'}) + .html(self._renderMain()); + self.$element.before($container); + self._initBrowse($container); + return $container; + }, + _refreshContainer: function () { + var self = this, $container = self.$container; + $container.before(self.$element); + $container.html(self._renderMain()); + self._initBrowse($container); + }, + _renderMain: function () { + var self = this, dropCss = (self.isUploadable && self.dropZoneEnabled) ? ' file-drop-zone' : 'file-drop-disabled', + close = !self.showClose ? '' : self._getLayoutTemplate('close'), + preview = !self.showPreview ? '' : self._getLayoutTemplate('preview') + .replace(/\{class}/g, self.previewClass) + .replace(/\{dropClass}/g, dropCss), + css = self.isDisabled ? self.captionClass + ' file-caption-disabled' : self.captionClass, + caption = self.captionTemplate.replace(/\{class}/g, css + ' kv-fileinput-caption'); + return self.mainTemplate.replace(/\{class}/g, self.mainClass) + .replace(/\{preview}/g, preview) + .replace(/\{close}/g, close) + .replace(/\{caption}/g, caption) + .replace(/\{upload}/g, self._renderButton('upload')) + .replace(/\{remove}/g, self._renderButton('remove')) + .replace(/\{cancel}/g, self._renderButton('cancel')) + .replace(/\{browse}/g, self._renderButton('browse')); + }, + _renderButton: function (type) { + var self = this, tmplt = self._getLayoutTemplate('btnDefault'), css = self[type + 'Class'], + title = self[type + 'Title'], icon = self[type + 'Icon'], label = self[type + 'Label'], + status = self.isDisabled ? ' disabled' : '', btnType = 'button'; + switch (type) { + case 'remove': + if (!self.showRemove) { + return ''; + } + break; + case 'cancel': + if (!self.showCancel) { + return ''; + } + css += ' hide'; + break; + case 'upload': + if (!self.showUpload) { + return ''; + } + if (self.isUploadable && !self.isDisabled) { + tmplt = self._getLayoutTemplate('btnLink').replace('{href}', self.uploadUrl); + } else { + btnType = 'submit'; + } + break; + case 'browse': + tmplt = self._getLayoutTemplate('btnBrowse'); + break; + default: + return ''; + } + css += type === 'browse' ? ' btn-file' : ' fileinput-' + type + ' fileinput-' + type + '-button'; + if (!isEmpty(label)) { + label = ' ' + label + ''; + } + return tmplt.replace('{type}', btnType) + .replace('{css}', css) + .replace('{title}', title) + .replace('{status}', status) + .replace('{icon}', icon) + .replace('{label}', label); + }, + _renderThumbProgress: function () { + return '
    ' + this.progressTemplate.replace(/\{percent}/g, + '0') + '
    '; + }, + _renderFileFooter: function (caption, width) { + var self = this, config = self.fileActionSettings, footer, out, template = self._getLayoutTemplate( + 'footer'); + if (self.isUploadable) { + footer = template.replace(/\{actions}/g, self._renderFileActions(true, true, false, false, false)); + out = footer.replace(/\{caption}/g, caption) + .replace(/\{width}/g, width) + .replace(/\{progress}/g, self._renderThumbProgress()) + .replace(/\{indicator}/g, config.indicatorNew) + .replace(/\{indicatorTitle}/g, config.indicatorNewTitle); + } else { + out = template.replace(/\{actions}/g, '') + .replace(/\{caption}/g, caption) + .replace(/\{progress}/g, '') + .replace(/\{width}/g, width) + .replace(/\{indicator}/g, '') + .replace(/\{indicatorTitle}/g, ''); + } + out = replaceTags(out, self.previewThumbTags); + return out; + }, + _renderFileActions: function (showUpload, showDelete, disabled, url, key) { + if (!showUpload && !showDelete) { + return ''; + } + var self = this, + vUrl = url === false ? '' : ' data-url="' + url + '"', + vKey = key === false ? '' : ' data-key="' + key + '"', + btnDelete = self._getLayoutTemplate('actionDelete'), + btnUpload = '', + template = self._getLayoutTemplate('actions'), + otherButtons = self.otherActionButtons.replace(/\{dataKey}/g, vKey), + config = self.fileActionSettings, + removeClass = disabled ? config.removeClass + ' disabled' : config.removeClass; + btnDelete = btnDelete + .replace(/\{removeClass}/g, removeClass) + .replace(/\{removeIcon}/g, config.removeIcon) + .replace(/\{removeTitle}/g, config.removeTitle) + .replace(/\{dataUrl}/g, vUrl) + .replace(/\{dataKey}/g, vKey); + if (showUpload) { + btnUpload = self._getLayoutTemplate('actionUpload') + .replace(/\{uploadClass}/g, config.uploadClass) + .replace(/\{uploadIcon}/g, config.uploadIcon) + .replace(/\{uploadTitle}/g, config.uploadTitle); + } + return template + .replace(/\{delete}/g, btnDelete) + .replace(/\{upload}/g, btnUpload) + .replace(/\{other}/g, otherButtons); + }, + _browse: function (e) { + var self = this; + self._raise('filebrowse'); + if (e && e.isDefaultPrevented()) { + return; + } + if (self.isError && !self.isUploadable) { + self.clear(); + } + self.$captionContainer.focus(); + }, + _change: function (e) { + var self = this, $el = self.$element; + if (!self.isUploadable && isEmpty($el.val()) && self.fileInputCleared) { // IE 11 fix + self.fileInputCleared = false; + return; + } + self.fileInputCleared = false; + var tfiles, msg, total, isDragDrop = arguments.length > 1, isAjaxUpload = self.isUploadable, i = 0, f, n, len, + files = isDragDrop ? e.originalEvent.dataTransfer.files : $el.get(0).files, ctr = self.filestack.length, + isSingleUpload = isEmpty($el.attr('multiple')), flagSingle = (isSingleUpload && ctr > 0), folders = 0, + throwError = function (mesg, file, previewId, index) { + var p1 = $.extend(true, {}, self._getOutData({}, {}, files), {id: previewId, index: index}), + p2 = {id: previewId, index: index, file: file, files: files}; + return self.isUploadable ? self._showUploadError(mesg, p1) : self._showError(mesg, p2); + }; + self.reader = null; + self._resetUpload(); + self._hideFileIcon(); + if (self.isUploadable) { + self.$container.find('.file-drop-zone .' + self.dropZoneTitleClass).remove(); + } + if (isDragDrop) { + tfiles = []; + while (files[i]) { + f = files[i]; + if (!f.type && f.size % 4096 === 0) { + folders++; + } else { + tfiles.push(f); + } + i++; + } + } else { + if (e.target.files === undefined) { + tfiles = e.target && e.target.value ? [ + {name: e.target.value.replace(/^.+\\/, '')} + ] : []; + } else { + tfiles = e.target.files; + } + } + if (isEmpty(tfiles) || tfiles.length === 0) { + if (!isAjaxUpload) { + self.clear(); + } + self._showFolderError(folders); + self._raise('fileselectnone'); + return; + } + self._resetErrors(); + len = tfiles.length; + total = self._getFileCount(self.isUploadable ? (self.getFileStack().length + len) : len); + if (self.maxFileCount > 0 && total > self.maxFileCount) { + if (!self.autoReplace || len > self.maxFileCount) { + n = (self.autoReplace && len > self.maxFileCount) ? len : total; + msg = self.msgFilesTooMany.replace('{m}', self.maxFileCount).replace('{n}', n); + self.isError = throwError(msg, null, null, null); + self.$captionContainer.find('.kv-caption-icon').hide(); + self._setCaption('', true); + self.$container.removeClass('file-input-new file-input-ajax-new'); + return; + } + if (total > self.maxFileCount) { + self._resetPreviewThumbs(isAjaxUpload); + } + } else { + if (!isAjaxUpload || flagSingle) { + self._resetPreviewThumbs(false); + if (flagSingle) { + self.clearStack(); + } + } else { + if (isAjaxUpload && ctr === 0 && (!previewCache.count(self.id) || self.overwriteInitial)) { + self._resetPreviewThumbs(true); + } + } + } + if (self.isPreviewable) { + self._readFiles(tfiles); + } else { + self._updateFileDetails(1); + } + self._showFolderError(folders); + }, + _abort: function (params) { + var self = this, data; + if (self.ajaxAborted && typeof self.ajaxAborted === "object" && self.ajaxAborted.message !== undefined) { + data = $.extend(true, {}, self._getOutData(), params); + data.abortData = self.ajaxAborted.data || {}; + data.abortMessage = self.ajaxAborted.message; + self.cancel(); + self._setProgress(100, self.$progress, self.msgCancelled); + self._showUploadError(self.ajaxAborted.message, data, 'filecustomerror'); + return true; + } + return false; + }, + _resetFileStack: function () { + var self = this, i = 0, newstack = [], newnames = []; + self._getThumbs().each(function () { + var $thumb = $(this), ind = $thumb.attr('data-fileindex'), + file = self.filestack[ind]; + if (ind === -1) { + return; + } + if (file !== undefined) { + newstack[i] = file; + newnames[i] = self._getFileName(file); + $thumb.attr({ + 'id': self.previewInitId + '-' + i, + 'data-fileindex': i + }); + i++; + } else { + $thumb.attr({ + 'id': 'uploaded-' + uniqId(), + 'data-fileindex': '-1' + }); + } + }); + self.filestack = newstack; + self.filenames = newnames; + }, + clearStack: function () { + var self = this; + self.filestack = []; + self.filenames = []; + return self.$element; + }, + updateStack: function (i, file) { + var self = this; + self.filestack[i] = file; + self.filenames[i] = self._getFileName(file); + return self.$element; + }, + addToStack: function (file) { + var self = this; + self.filestack.push(file); + self.filenames.push(self._getFileName(file)); + return self.$element; + }, + getFileStack: function (skipNull) { + var self = this; + return self.filestack.filter(function (n) { + return (skipNull ? n !== undefined : n !== undefined && n !== null); + }); + }, + lock: function () { + var self = this; + self._resetErrors(); + self.disable(); + if (self.showRemove) { + addCss(self.$container.find('.fileinput-remove'), 'hide'); + } + if (self.showCancel) { + self.$container.find('.fileinput-cancel').removeClass('hide'); + } + self._raise('filelock', [self.filestack, self._getExtraData()]); + return self.$element; + }, + unlock: function (reset) { + var self = this; + if (reset === undefined) { + reset = true; + } + self.enable(); + if (self.showCancel) { + addCss(self.$container.find('.fileinput-cancel'), 'hide'); + } + if (self.showRemove) { + self.$container.find('.fileinput-remove').removeClass('hide'); + } + if (reset) { + self._resetFileStack(); + } + self._raise('fileunlock', [self.filestack, self._getExtraData()]); + return self.$element; + }, + cancel: function () { + var self = this, xhr = self.ajaxRequests, len = xhr.length, i; + if (len > 0) { + for (i = 0; i < len; i += 1) { + self.cancelling = true; + xhr[i].abort(); + } + } + self._setProgressCancelled(); + self._getThumbs().each(function () { + var $thumb = $(this), ind = $thumb.attr('data-fileindex'); + $thumb.removeClass('file-uploading'); + if (self.filestack[ind] !== undefined) { + $thumb.find('.kv-file-upload').removeClass('disabled').removeAttr('disabled'); + $thumb.find('.kv-file-remove').removeClass('disabled').removeAttr('disabled'); + } + self.unlock(); + }); + return self.$element; + }, + clear: function () { + var self = this, cap; + self.$btnUpload.removeAttr('disabled'); + self._getThumbs().find('video,audio,img').each(function () { + cleanMemory($(this)); + }); + self._resetUpload(); + self.clearStack(); + self._clearFileInput(); + self._resetErrors(true); + self._raise('fileclear'); + if (self._hasInitialPreview()) { + self._showFileIcon(); + self._resetPreview(); + self._initPreviewDeletes(); + self.$container.removeClass('file-input-new'); + } else { + self._getThumbs().each(function () { + self._clearObjects($(this)); + }); + if (self.isUploadable) { + previewCache.data[self.id] = {}; + } + self.$preview.html(''); + cap = (!self.overwriteInitial && self.initialCaption.length > 0) ? self.initialCaption : ''; + self._setCaption(cap); + self.$caption.attr('title', ''); + addCss(self.$container, 'file-input-new'); + self._validateDefaultPreview(); + } + if (self.$container.find('.file-preview-frame').length === 0) { + if (!self._initCaption()) { + self.$captionContainer.find('.kv-caption-icon').hide(); + } + } + self._hideFileIcon(); + self._raise('filecleared'); + self.$captionContainer.focus(); + self._setFileDropZoneTitle(); + return self.$element; + }, + reset: function () { + var self = this; + self._resetPreview(); + self.$container.find('.fileinput-filename').text(''); + self._raise('filereset'); + addCss(self.$container, 'file-input-new'); + if (self.$preview.find('.file-preview-frame').length || self.isUploadable && self.dropZoneEnabled) { + self.$container.removeClass('file-input-new'); + } + self._setFileDropZoneTitle(); + self.clearStack(); + self.formdata = {}; + return self.$element; + }, + disable: function () { + var self = this; + self.isDisabled = true; + self._raise('filedisabled'); + self.$element.attr('disabled', 'disabled'); + self.$container.find(".kv-fileinput-caption").addClass("file-caption-disabled"); + self.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").attr( + "disabled", + true); + self._initDragDrop(); + return self.$element; + }, + enable: function () { + var self = this; + self.isDisabled = false; + self._raise('fileenabled'); + self.$element.removeAttr('disabled'); + self.$container.find(".kv-fileinput-caption").removeClass("file-caption-disabled"); + self.$container.find( + ".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").removeAttr("disabled"); + self._initDragDrop(); + return self.$element; + }, + upload: function () { + var self = this, totLen = self.getFileStack().length, params = {}, + i, outData, len, hasExtraData = !$.isEmptyObject(self._getExtraData()); + if (self.minFileCount > 0 && self._getFileCount(totLen) < self.minFileCount) { + self._noFilesError(params); + return; + } + if (!self.isUploadable || self.isDisabled || (totLen === 0 && !hasExtraData)) { + return; + } + self._resetUpload(); + self.$progress.removeClass('hide'); + self.uploadCount = 0; + self.uploadStatus = {}; + self.uploadLog = []; + self.lock(); + self._setProgress(2); + if (totLen === 0 && hasExtraData) { + self._uploadExtraOnly(); + return; + } + len = self.filestack.length; + self.hasInitData = false; + if (self.uploadAsync) { + outData = self._getOutData(); + self._raise('filebatchpreupload', [outData]); + self.fileBatchCompleted = false; + self.uploadCache = {content: [], config: [], tags: [], append: true}; + self.uploadAsyncCount = self.getFileStack().length; + for (i = 0; i < len; i++) { + self.uploadCache.content[i] = null; + self.uploadCache.config[i] = null; + self.uploadCache.tags[i] = null; + } + for (i = 0; i < len; i++) { + if (self.filestack[i] !== undefined) { + self._uploadSingle(i, self.filestack, true); + } + } + return; + } + self._uploadBatch(); + return self.$element; + }, + destroy: function () { + var self = this, $cont = self.$container; + $cont.find('.file-drop-zone').off(); + self.$element.insertBefore($cont).off(NAMESPACE).removeData(); + $cont.off().remove(); + return self.$element; + }, + refresh: function (options) { + var self = this, $el = self.$element; + options = options ? $.extend(true, {}, self.options, options) : self.options; + self.destroy(); + $el.fileinput(options); + if ($el.val()) { + $el.trigger('change.fileinput'); + } + return $el; + } + }; + + $.fn.fileinput = function (option) { + if (!hasFileAPISupport() && !isIE(9)) { + return; + } + var args = Array.apply(null, arguments), retvals = []; + args.shift(); + this.each(function () { + var self = $(this), data = self.data('fileinput'), options = typeof option === 'object' && option, + lang = options.language || self.data('language') || 'en', loc = {}, opts; + + if (!data) { + if (lang !== 'en' && !isEmpty($.fn.fileinputLocales[lang])) { + loc = $.fn.fileinputLocales[lang]; + } + opts = $.extend(true, {}, $.fn.fileinput.defaults, $.fn.fileinputLocales.en, loc, options, self.data()); + data = new FileInput(this, opts); + self.data('fileinput', data); + } + + if (typeof option === 'string') { + retvals.push(data[option].apply(data, args)); + } + }); + switch (retvals.length) { + case 0: + return this; + case 1: + return retvals[0]; + default: + return retvals; + } + }; + + $.fn.fileinput.defaults = { + language: 'en', + showCaption: true, + showPreview: true, + showRemove: true, + showUpload: true, + showCancel: true, + showClose: true, + showUploadedThumbs: true, + autoReplace: false, + mainClass: '', + previewClass: '', + captionClass: '', + mainTemplate: null, + initialCaption: '', + initialPreview: [], + initialPreviewDelimiter: '*$$*', + initialPreviewConfig: [], + initialPreviewThumbTags: [], + previewThumbTags: {}, + initialPreviewShowDelete: true, + removeFromPreviewOnError: false, + deleteUrl: '', + deleteExtraData: {}, + overwriteInitial: true, + layoutTemplates: defaultLayoutTemplates, + previewTemplates: defaultPreviewTemplates, + allowedPreviewTypes: null, + allowedPreviewMimeTypes: null, + allowedFileTypes: null, + allowedFileExtensions: null, + defaultPreviewContent: null, + customLayoutTags: {}, + customPreviewTags: {}, + previewSettings: defaultPreviewSettings, + fileTypeSettings: defaultFileTypeSettings, + previewFileIcon: '', + previewFileIconClass: 'file-icon-4x', + previewFileIconSettings: {}, + previewFileExtSettings: {}, + buttonLabelClass: 'hidden-xs', + browseIcon: ' ', + browseClass: 'btn btn-primary', + removeIcon: '', + removeClass: 'btn btn-default', + cancelIcon: '', + cancelClass: 'btn btn-default', + uploadIcon: '', + uploadClass: 'btn btn-default', + uploadUrl: null, + uploadAsync: true, + uploadExtraData: {}, + minImageWidth: null, + minImageHeight: null, + maxImageWidth: null, + maxImageHeight: null, + resizeImage: false, + resizePreference: 'width', + resizeQuality: 0.92, + resizeDefaultImageType: 'image/jpeg', + maxFileSize: 0, + minFileCount: 0, + maxFileCount: 0, + validateInitialCount: false, + msgValidationErrorClass: 'text-danger', + msgValidationErrorIcon: ' ', + msgErrorClass: 'file-error-message', + progressThumbClass: "progress-bar progress-bar-success progress-bar-striped active", + progressClass: "progress-bar progress-bar-success progress-bar-striped active", + progressCompleteClass: "progress-bar progress-bar-success", + progressErrorClass: "progress-bar progress-bar-danger", + previewFileType: 'image', + zoomIndicator: '', + elCaptionContainer: null, + elCaptionText: null, + elPreviewContainer: null, + elPreviewImage: null, + elPreviewStatus: null, + elErrorContainer: null, + errorCloseButton: '×', + slugCallback: null, + dropZoneEnabled: true, + dropZoneTitleClass: 'file-drop-zone-title', + fileActionSettings: {}, + otherActionButtons: '', + textEncoding: 'UTF-8', + ajaxSettings: {}, + ajaxDeleteSettings: {}, + showAjaxErrorDetails: true + }; + + $.fn.fileinputLocales.en = { + fileSingle: 'file', + filePlural: 'files', + browseLabel: 'Browse …', + removeLabel: 'Remove', + removeTitle: 'Clear selected files', + cancelLabel: 'Cancel', + cancelTitle: 'Abort ongoing upload', + uploadLabel: 'Upload', + uploadTitle: 'Upload selected files', + msgNo: 'No', + msgCancelled: 'Cancelled', + msgZoomTitle: 'View details', + msgZoomModalHeading: 'Detailed Preview', + msgSizeTooLarge: 'File "{name}" ({size} KB) exceeds maximum allowed upload size of {maxSize} KB.', + msgFilesTooLess: 'You must select at least {n} {files} to upload.', + msgFilesTooMany: 'Number of files selected for upload ({n}) exceeds maximum allowed limit of {m}.', + msgFileNotFound: 'File "{name}" not found!', + msgFileSecured: 'Security restrictions prevent reading the file "{name}".', + msgFileNotReadable: 'File "{name}" is not readable.', + msgFilePreviewAborted: 'File preview aborted for "{name}".', + msgFilePreviewError: 'An error occurred while reading the file "{name}".', + msgInvalidFileType: 'Invalid type for file "{name}". Only "{types}" files are supported.', + msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.', + msgUploadAborted: 'The file upload was aborted', + msgValidationError: 'Validation Error', + msgLoading: 'Loading file {index} of {files} …', + msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.', + msgSelected: '{n} {files} selected', + msgFoldersNotAllowed: 'Drag & drop files only! {n} folder(s) dropped were skipped.', + msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.', + msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.', + msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.', + msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.', + msgImageResizeError: 'Could not get the image dimensions to resize.', + msgImageResizeException: 'Error while resizing the image.
    {errors}
    ', + dropZoneTitle: 'Drag & drop files here …' + }; + + $.fn.fileinput.Constructor = FileInput; + + /** + * Convert automatically file inputs with class 'file' into a bootstrap fileinput control. + */ + $(document).ready(function () { + var $input = $('input.file[type=file]'); + if ($input.length) { + $input.fileinput(); + } + }); +})); \ No newline at end of file diff --git a/libs/bootstrap-fileinput/js/fileinput.min.js b/libs/bootstrap-fileinput/js/fileinput.min.js new file mode 100644 index 00000000..3961d5c7 --- /dev/null +++ b/libs/bootstrap-fileinput/js/fileinput.min.js @@ -0,0 +1,17 @@ +/*! + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015 + * @version 4.3.1 + * + * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced features including the FileReader API. + * + * The plugin drastically enhances the HTML file input to preview multiple files on the client before upload. In + * addition it provides the ability to preview content of images, text, videos, audio, html, flash and other objects. + * It also offers the ability to upload and delete files using AJAX, and add files in batches (i.e. preview, append, + * or remove before upload). + * + * Author: Kartik Visweswaran + * Copyright: 2015, Kartik Visweswaran, Krajee.com + * For more JQuery plugins visit http://plugins.krajee.com + * For more Yii related demos visit http://demos.krajee.com + */!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery")):e(window.jQuery)}(function(e){"use strict";e.fn.fileinputLocales={};var i,t,a,r,n,l,o,s,d,c,p,u,f,v,g,m,h,w,_,b,C,x,y,T,F,E,I,$,k,P,S,D,U,A,j,L,z,O,R,N,B,M,Z,H,W,q,V,K,X,J,Q,Y,G,ee,ie;i=".fileinput",t=window.URL||window.webkitURL,a=function(e,i,t){return void 0!==e&&(t?e===i:e.match(i))},r=function(e){if("Microsoft Internet Explorer"!==navigator.appName)return!1;if(10===e)return new RegExp("msie\\s"+e,"i").test(navigator.userAgent);var i,t=document.createElement("div");return t.innerHTML="",i=t.getElementsByTagName("i").length,document.body.appendChild(t),t.parentNode.removeChild(t),i},n=function(){return new RegExp("Edge/[0-9]+","i").test(navigator.userAgent)},l=function(e,t,a,r){var n=r?t:t.split(" ").join(i+" ")+i;e.off(n).on(n,a)},o={data:{},init:function(e){var i=e.initialPreview,t=e.id;i.length>0&&!X(i)&&(i=i.split(e.initialPreviewDelimiter)),o.data[t]={content:i,config:e.initialPreviewConfig,tags:e.initialPreviewThumbTags,delimiter:e.initialPreviewDelimiter,template:e.previewGenericTemplate,msg:function(i){return e._getMsgSelected(i)},initId:e.previewInitId,footer:e._getLayoutTemplate("footer").replace(/\{progress}/g,e._renderThumbProgress()),isDelete:e.initialPreviewShowDelete,caption:e.initialCaption,actions:function(i,t,a,r,n){return e._renderFileActions(i,t,a,r,n)}}},fetch:function(e){return o.data[e].content.filter(function(e){return null!==e})},count:function(e,i){return o.data[e]&&o.data[e].content?i?o.data[e].content.length:o.fetch(e).length:0},get:function(i,t,a){var r,n,l="init_"+t,s=o.data[i],d=s.config[t],c=s.initId+"-"+l,p=" file-preview-initial";return a=void 0===a?!0:a,null===s.content[t]?"":(K(d)||K(d.frameClass)||(p+=" "+d.frameClass),r=s.template.replace(/\{previewId}/g,c).replace(/\{frameClass}/g,p).replace(/\{fileindex}/g,l).replace(/\{content}/g,s.content[t]).replace(/\{footer}/g,o.footer(i,t,a)),s.tags.length&&s.tags[t]&&(r=ee(r,s.tags[t])),K(d)||K(d.frameAttr)||(n=e(document.createElement("div")).html(r),n.find(".file-preview-initial").attr(d.frameAttr),r=n.html(),n.remove()),r)},add:function(i,t,a,r,n){var l,s=e.extend(!0,{},o.data[i]);return X(t)||(t=t.split(s.delimiter)),n?(l=s.content.push(t)-1,s.config[l]=a,s.tags[l]=r):(l=t.length,s.content=t,s.config=a,s.tags=r),o.data[i]=s,l},set:function(i,t,a,r,n){var l,s,d=e.extend(!0,{},o.data[i]);if(t&&t.length&&(X(t)||(t=t.split(d.delimiter)),s=t.filter(function(e){return null!==e}),s.length)){if(void 0===d.content&&(d.content=[]),void 0===d.config&&(d.config=[]),void 0===d.tags&&(d.tags=[]),n){for(l=0;ln;n++)t+=o.get(e,n);return i=a.msg(o.count(e)),{content:t,caption:i}},footer:function(e,i,t){var a=o.data[e];if(t=void 0===t?!0:t,0===a.config.length||K(a.config[i]))return"";var r=a.config[i],n=J("caption",r)?r.caption:"",l=J("width",r)?r.width:"auto",s=J("url",r)?r.url:!1,d=J("key",r)?r.key:null,c=s===!1&&t,p=a.isDelete?a.actions(!1,!0,c,s,d):"",u=a.footer.replace(/\{actions}/g,p);return u.replace(/\{caption}/g,n).replace(/\{width}/g,l).replace(/\{indicator}/g,"").replace(/\{indicatorTitle}/g,"")}},s=function(e,i){return i=i||0,"number"==typeof e?e:("string"==typeof e&&(e=parseFloat(e)),isNaN(e)?i:e)},d=function(){return!(!window.File||!window.FileReader)},c=function(){var e=document.createElement("div");return!r(9)&&!n()&&(void 0!==e.draggable||void 0!==e.ondragstart&&void 0!==e.ondrop)},p=function(){return d()&&window.FormData},u=function(e,i){e.removeClass(i).addClass(i)},f='style="width:{width};height:{height};"',v=' \n \n \n \n \n \n',g='
    \n {previewFileIcon}\n
    ',m={removeIcon:'',removeClass:"btn btn-xs btn-default",removeTitle:"Remove file",uploadIcon:'',uploadClass:"btn btn-xs btn-default",uploadTitle:"Upload file",indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorNewTitle:"Not uploaded yet",indicatorSuccessTitle:"Uploaded",indicatorErrorTitle:"Upload Error",indicatorLoadingTitle:"Uploading ..."},h='{preview}\n
    \n
    \n {caption}\n
    \n {remove}\n {cancel}\n {upload}\n {browse}\n
    \n
    ',w='{preview}\n
    \n{remove}\n{cancel}\n{upload}\n{browse}\n',_='
    \n {close}
    \n
    \n
    \n
    \n
    \n
    \n
    ',C='
    ×
    \n',b='',x='
    \n
    \n
    \n',y='',T='{icon}{label}',F='
    {icon}{label}
    ',E='',I='
    \n
    \n {percent}%\n
    \n
    ',$='',k='
    \n \n
    {indicator}
    \n
    \n
    ',P='\n',S='\n',D='\n',U='
    \n {content}\n {footer}\n
    \n',A='
    \n \n '+g+"\n \n {footer}\n
    ",j='
    \n {caption}\n {footer}\n
    \n",L='
    \n
    {data}
    \n {zoom}\n {footer}\n
    ",z='
    \n \n {footer}\n
    \n",O='
    \n \n {footer}\n
    ",R='
    \n \n'+v+" "+g+"\n \n {footer}\n
    \n",N='
    \n \n \n'+v+" "+g+"\n \n {footer}\n
    ",B='
    \n
    \n '+g+'\n
    \n \n
    ',M={main1:h,main2:w,preview:_,close:C,zoom:D,icon:b,caption:x,modal:E,progress:I,footer:$,actions:k,actionDelete:P,actionUpload:S,btnDefault:y,btnLink:T,btnBrowse:F},Z={generic:U,html:A,image:j,text:L,video:z,audio:O,flash:R,object:N,other:B},H=["image","html","text","video","audio","flash","object"],W={image:{width:"auto",height:"160px"},html:{width:"213px",height:"160px"},text:{width:"160px",height:"136px"},video:{width:"213px",height:"160px"},audio:{width:"213px",height:"80px"},flash:{width:"213px",height:"160px"},object:{width:"160px",height:"160px"},other:{width:"160px",height:"160px"}},V={image:function(e,i){return a(e,"image.*")||a(i,/\.(gif|png|jpe?g)$/i)},html:function(e,i){return a(e,"text/html")||a(i,/\.(htm|html)$/i)},text:function(e,i){return a(e,"text.*")||a(e,/\.(xml|javascript)$/i)||a(i,/\.(txt|md|csv|nfo|ini|json|php|js|css)$/i)},video:function(e,i){return a(e,"video.*")&&(a(e,/(ogg|mp4|mp?g|webm|3gp)$/i)||a(i,/\.(og?|mp4|webm|mp?g|3gp)$/i))},audio:function(e,i){return a(e,"audio.*")&&(a(e,/(ogg|mp3|mp?g|wav)$/i)||a(i,/\.(og?|mp3|mp?g|wav)$/i))},flash:function(e,i){return a(e,"application/x-shockwave-flash",!0)||a(i,/\.(swf)$/i)},object:function(e,i){return a(e,"application/pdf",!0)||a(i,/\.(pdf)$/i)},other:function(){return!0}},K=function(i,t){return void 0===i||null===i||0===i.length||t&&""===e.trim(i)},X=function(e){return Array.isArray(e)||"[object Array]"===Object.prototype.toString.call(e)},J=function(e,i){return"object"==typeof i&&e in i},Q=function(i,t,a){return K(i)||K(i[t])?a:e(i[t])},Y=function(){return Math.round((new Date).getTime()+100*Math.random())},G=function(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},ee=function(i,t){var a=i;return t?(e.each(t,function(e,i){"function"==typeof i&&(i=i()),a=a.split(e).join(i)}),a):a},ie=function(e){var i=e.is("img")?e.attr("src"):e.find("source").attr("src");t.revokeObjectURL(i)},q=function(i,t){var a=this;a.$element=e(i),a._validate()&&(a.isPreviewable=d(),a.isIE9=r(9),a.isIE10=r(10),a.isPreviewable||a.isIE9?(a._init(t),a._listen()):a.$element.removeClass("file-loading"))},q.prototype={constructor:q,_init:function(i){var t,a=this,r=a.$element;e.each(i,function(e,i){switch(e){case"minFileCount":case"maxFileCount":case"maxFileSize":a[e]=s(i);break;default:a[e]=i}}),K(a.allowedPreviewTypes)&&(a.allowedPreviewTypes=H),a.fileInputCleared=!1,a.fileBatchCompleted=!0,a.isPreviewable||(a.showPreview=!1),a.uploadFileAttr=K(r.attr("name"))?"file_data":r.attr("name"),a.reader=null,a.formdata={},a.clearStack(),a.uploadCount=0,a.uploadStatus={},a.uploadLog=[],a.uploadAsyncCount=0,a.loadedImages=[],a.totalImagesCount=0,a.ajaxRequests=[],a.isError=!1,a.ajaxAborted=!1,a.cancelling=!1,t=a._getLayoutTemplate("progress"),a.progressTemplate=t.replace("{class}",a.progressClass),a.progressCompleteTemplate=t.replace("{class}",a.progressCompleteClass),a.progressErrorTemplate=t.replace("{class}",a.progressErrorClass),a.dropZoneEnabled=c()&&a.dropZoneEnabled,a.isDisabled=a.$element.attr("disabled")||a.$element.attr("readonly"),a.isUploadable=p()&&!K(a.uploadUrl),a.slug="function"==typeof i.slugCallback?i.slugCallback:a._slugDefault,a.mainTemplate=a.showCaption?a._getLayoutTemplate("main1"):a._getLayoutTemplate("main2"),a.captionTemplate=a._getLayoutTemplate("caption"),a.previewGenericTemplate=a._getPreviewTemplate("generic"),a.resizeImage&&(a.maxImageWidth||a.maxImageHeight)&&(a.imageCanvas=document.createElement("canvas"),a.imageCanvasContext=a.imageCanvas.getContext("2d")),K(a.$element.attr("id"))&&a.$element.attr("id",Y()),void 0===a.$container?a.$container=a._createContainer():a._refreshContainer(),a.$dropZone=a.$container.find(".file-drop-zone"),a.$progress=a.$container.find(".kv-upload-progress"),a.$btnUpload=a.$container.find(".fileinput-upload"),a.$captionContainer=Q(i,"elCaptionContainer",a.$container.find(".file-caption")),a.$caption=Q(i,"elCaptionText",a.$container.find(".file-caption-name")),a.$previewContainer=Q(i,"elPreviewContainer",a.$container.find(".file-preview")),a.$preview=Q(i,"elPreviewImage",a.$container.find(".file-preview-thumbnails")),a.$previewStatus=Q(i,"elPreviewStatus",a.$container.find(".file-preview-status")),a.$errorContainer=Q(i,"elErrorContainer",a.$previewContainer.find(".kv-fileinput-error")),K(a.msgErrorClass)||u(a.$errorContainer,a.msgErrorClass),a.$errorContainer.hide(),a.fileActionSettings=e.extend(!0,m,i.fileActionSettings),a.previewInitId="preview-"+Y(),a.id=a.$element.attr("id"),o.init(a),a._initPreview(!0),a._initPreviewDeletes(),a.options=i,a._setFileDropZoneTitle(),a.$element.removeClass("file-loading"),a.$element.attr("disabled")&&a.disable()},_validate:function(){var e,i=this;return"file"===i.$element.attr("type")?!0:(e='

    Invalid Input Type

    You must set an input type = file for bootstrap-fileinput plugin to initialize.
    ',i.$element.after(e),!1)},_errorsExist:function(){var i,t=this;return t.$errorContainer.find("li").length?!0:(i=e(document.createElement("div")).html(t.$errorContainer.html()),i.find("span.kv-error-close").remove(),i.find("ul").remove(),e.trim(i.text()).length?!0:!1)},_errorHandler:function(e,i){var t=this,a=e.target.error;a.code===a.NOT_FOUND_ERR?t._showError(t.msgFileNotFound.replace("{name}",i)):a.code===a.SECURITY_ERR?t._showError(t.msgFileSecured.replace("{name}",i)):a.code===a.NOT_READABLE_ERR?t._showError(t.msgFileNotReadable.replace("{name}",i)):a.code===a.ABORT_ERR?t._showError(t.msgFilePreviewAborted.replace("{name}",i)):t._showError(t.msgFilePreviewError.replace("{name}",i))},_addError:function(e){var i=this,t=i.$errorContainer;e&&t.length&&(t.html(i.errorCloseButton+e),l(t.find(".kv-error-close"),"click",function(){t.fadeOut("slow")}))},_resetErrors:function(e){var i=this,t=i.$errorContainer;i.isError=!1,i.$container.removeClass("has-error"),t.html(""),e?t.fadeOut("slow"):t.hide()},_showFolderError:function(e){var i,t=this,a=t.$errorContainer;e&&(i=t.msgFoldersNotAllowed.replace(/\{n}/g,e),t._addError(i),u(t.$container,"has-error"),a.fadeIn(800),t._raise("filefoldererror",[e,i]))},_showUploadError:function(e,i,t){var a=this,r=a.$errorContainer,n=t||"fileuploaderror",l=i&&i.id?'
  • '+e+"
  • ":"
  • "+e+"
  • ";return 0===r.find("ul").length?a._addError("
      "+l+"
    "):r.find("ul").append(l),r.fadeIn(800),a._raise(n,[i,e]),a.$container.removeClass("file-input-new"),u(a.$container,"has-error"),!0},_showError:function(e,i,t){var a=this,r=a.$errorContainer,n=t||"fileerror";return i=i||{},i.reader=a.reader,a._addError(e),r.fadeIn(800),a._raise(n,[i,e]),a.isUploadable||a._clearFileInput(),a.$container.removeClass("file-input-new"),u(a.$container,"has-error"),a.$btnUpload.attr("disabled",!0),!0},_noFilesError:function(e){var i=this,t=i.minFileCount>1?i.filePlural:i.fileSingle,a=i.msgFilesTooLess.replace("{n}",i.minFileCount).replace("{files}",t),r=i.$errorContainer;i._addError(a),i.isError=!0,i._updateFileDetails(0),r.fadeIn(800),i._raise("fileerror",[e,a]),i._clearFileInput(),u(i.$container,"has-error")},_parseError:function(i,t,a){var r=this,n=e.trim(t+""),l="."===n.slice(-1)?"":".",o=void 0!==i.responseJSON&&void 0!==i.responseJSON.error?i.responseJSON.error:i.responseText;return r.cancelling&&r.msgUploadAborted&&(n=r.msgUploadAborted),r.showAjaxErrorDetails&&o?(o=e.trim(o.replace(/\n\s*\n/g,"\n")),o=o.length>0?"
    "+o+"
    ":"",n+=l+o):n+=l,r.cancelling=!1,a?""+a+": "+n:n},_parseFileType:function(e){var i,t,a,r,n=this;for(r=0;r-1&&(a=t.split(".").pop(),r.previewFileIconSettings&&r.previewFileIconSettings[a]&&(n=r.previewFileIconSettings[a]),r.previewFileExtSettings&&e.each(r.previewFileExtSettings,function(e,i){r.previewFileIconSettings[e]&&i(a)&&(n=r.previewFileIconSettings[e])})),i.indexOf("{previewFileIcon}")>-1?i.replace(/\{previewFileIconClass}/g,r.previewFileIconClass).replace(/\{previewFileIcon}/g,n):i},_raise:function(i,t){var a=this,r=e.Event(i);if(void 0!==t?a.$element.trigger(r,t):a.$element.trigger(r),r.isDefaultPrevented())return!1;if(!r.result)return r.result;switch(i){case"filebatchuploadcomplete":case"filebatchuploadsuccess":case"fileuploaded":case"fileclear":case"filecleared":case"filereset":case"fileerror":case"filefoldererror":case"fileuploaderror":case"filebatchuploaderror":case"filedeleteerror":case"filecustomerror":case"filesuccessremove":break;default:a.ajaxAborted=r.result}return!0},_listen:function(){var i=this,t=i.$element,a=t.closest("form"),r=i.$container;l(t,"change",e.proxy(i._change,i)),l(i.$btnFile,"click",e.proxy(i._browse,i)),l(a,"reset",e.proxy(i.reset,i)),l(r.find(".fileinput-remove:not([disabled])"),"click",e.proxy(i.clear,i)),l(r.find(".fileinput-cancel"),"click",e.proxy(i.cancel,i)),i._initDragDrop(),i.isUploadable||l(a,"submit",e.proxy(i._submitForm,i)),l(i.$container.find(".fileinput-upload"),"click",e.proxy(i._uploadClick,i))},_initDragDrop:function(){var i=this,t=i.$dropZone;i.isUploadable&&i.dropZoneEnabled&&i.showPreview&&(l(t,"dragenter dragover",e.proxy(i._zoneDragEnter,i)),l(t,"dragleave",e.proxy(i._zoneDragLeave,i)),l(t,"drop",e.proxy(i._zoneDrop,i)),l(e(document),"dragenter dragover drop",i._zoneDragDropInit))},_zoneDragDropInit:function(e){e.stopPropagation(),e.preventDefault()},_zoneDragEnter:function(i){var t=this,a=e.inArray("Files",i.originalEvent.dataTransfer.types)>-1;return t._zoneDragDropInit(i),t.isDisabled||!a?(i.originalEvent.dataTransfer.effectAllowed="none",void(i.originalEvent.dataTransfer.dropEffect="none")):void u(t.$dropZone,"file-highlighted")},_zoneDragLeave:function(e){var i=this;i._zoneDragDropInit(e),i.isDisabled||i.$dropZone.removeClass("file-highlighted")},_zoneDrop:function(e){var i=this;e.preventDefault(),i.isDisabled||K(e.originalEvent.dataTransfer.files)||(i._change(e,"dragdrop"),i.$dropZone.removeClass("file-highlighted"))},_uploadClick:function(e){var i,t=this,a=t.$container.find(".fileinput-upload"),r=!a.hasClass("disabled")&&K(a.attr("disabled"));if(!e||!e.isDefaultPrevented()){if(!t.isUploadable)return void(r&&"submit"!==a.attr("type")&&(i=a.closest("form"),i.length&&i.trigger("submit"),e.preventDefault()));e.preventDefault(),r&&t.upload()}},_submitForm:function(){var e=this,i=e.$element,t=i.get(0).files;return t&&e.minFileCount>0&&e._getFileCount(t.length)0?i._getMsgSelected(l):"",i._raise("filedeleted",[s,n,f]),i._setCaption(d),v.removeClass("file-uploading").addClass("file-deleted"),void v.fadeOut("slow",function(){i._clearObjects(v),v.remove(),a(),l||0!==i.getFileStack().length||(i._setCaption(""),i.reset())})):(c.jqXHR=n,c.response=e,i._showError(e.error,c,"filedeleteerror"),v.removeClass("file-uploading"),r.removeClass("disabled"),void a())},error:function(e,t,r){var n=i._parseError(e,r);c.jqXHR=e,c.response={},i._showError(n,c,"filedeleteerror"),v.removeClass("file-uploading"),a()}},i.ajaxDeleteSettings),l(r,"click",function(){return i._validateMinCount()?void e.ajax(d):!1})}})},_clearObjects:function(i){i.find("video audio").each(function(){this.pause(),e(this).remove()}),i.find("img object div").each(function(){e(this).remove()})},_clearFileInput:function(){var i,t,a,r=this,n=r.$element;K(n.val())||(r.isIE9||r.isIE10?(i=n.closest("form"),t=e(document.createElement("form")),a=e(document.createElement("div")),n.before(a),i.length?i.after(t):a.after(t),t.append(n).trigger("reset"),a.before(n).remove(),t.remove()):n.val(""),r.fileInputCleared=!0)},_resetUpload:function(){var e=this;e.uploadCache={content:[],config:[],tags:[],append:!0},e.uploadCount=0,e.uploadStatus={},e.uploadLog=[],e.uploadAsyncCount=0,e.loadedImages=[],e.totalImagesCount=0,e.$btnUpload.removeAttr("disabled"),e._setProgress(0),u(e.$progress,"hide"),e._resetErrors(!1),e.ajaxAborted=!1,e.ajaxRequests=[],e._resetCanvas()},_resetCanvas:function(){var e=this;e.canvas&&e.imageCanvasContext&&e.imageCanvasContext.clearRect(0,0,e.canvas.width,e.canvas.height)},_hasInitialPreview:function(){var e=this;return!e.overwriteInitial&&o.count(e.id)},_resetPreview:function(){var e,i,t=this;o.count(t.id)?(e=o.out(t.id),t.$preview.html(e.content),i=t.initialCaption?t.initialCaption:e.caption,t._setCaption(i)):(t._clearPreview(),t._initCaption())},_clearDefaultPreview:function(){var e=this;e.$preview.find(".file-default-preview").remove()},_validateDefaultPreview:function(){var e=this;e.showPreview&&!K(e.defaultPreviewContent)&&(e.$preview.html('
    '+e.defaultPreviewContent+"
    "),e.$container.removeClass("file-input-new"))},_resetPreviewThumbs:function(e){var i,t=this;return e?(t._clearPreview(),void t.clearStack()):void(t._hasInitialPreview()?(i=o.out(t.id),t.$preview.html(i.content),t._setCaption(i.caption),t._initPreviewDeletes()):t._clearPreview())},_getLayoutTemplate:function(e){var i=this,t=J(e,i.layoutTemplates)?i.layoutTemplates[e]:M[e];return K(i.customLayoutTags)?t:ee(t,i.customLayoutTags)},_getPreviewTemplate:function(e){var i=this,t=J(e,i.previewTemplates)?i.previewTemplates[e]:Z[e];return K(i.customPreviewTags)?t:ee(t,i.customPreviewTags)},_getOutData:function(e,i,t){var a=this;return e=e||{},i=i||{},t=t||a.filestack.slice(0)||{},{form:a.formdata,files:t,filenames:a.filenames,extra:a._getExtraData(),response:i,reader:a.reader,jqXHR:e}},_getMsgSelected:function(e){var i=this,t=1===e?i.fileSingle:i.filePlural;return i.msgSelected.replace("{n}",e).replace("{files}",t)},_getThumbs:function(e){return e=e||"",this.$preview.find(".file-preview-frame:not(.file-preview-initial)"+e)},_getExtraData:function(e,i){var t=this,a=t.uploadExtraData;return"function"==typeof t.uploadExtraData&&(a=t.uploadExtraData(e,i)),a},_initXhr:function(e,i,t){var a=this;return e.upload&&e.upload.addEventListener("progress",function(e){var r=0,n=e.loaded||e.position,l=e.total;e.lengthComputable&&(r=Math.ceil(n/l*100)),i?a._setAsyncUploadStatus(i,r,t):a._setProgress(Math.ceil(r))},!1),e},_ajaxSubmit:function(i,t,a,r,n,l){var o,s=this;s._raise("filepreajax",[n,l]),s._uploadExtra(n,l),o=e.extend(!0,{},{xhr:function(){var i=e.ajaxSettings.xhr();return s._initXhr(i,n,s.getFileStack().length)},url:s.uploadUrl,type:"POST",dataType:"json",data:s.formdata,cache:!1,processData:!1,contentType:!1,beforeSend:i,success:t,complete:a,error:r},s.ajaxSettings),s.ajaxRequests.push(e.ajax(o))},_initUploadSuccess:function(i,t,a){var r,n,l,s,d,c,p,u,f=this;f.showPreview&&"object"==typeof i&&!e.isEmptyObject(i)&&void 0!==i.initialPreview&&i.initialPreview.length>0&&(f.hasInitData=!0,d=i.initialPreview||[],c=i.initialPreviewConfig||[],p=i.initialPreviewThumbTags||[],r=void 0===i.append||i.append?!0:!1,f.overwriteInitial=!1,void 0!==t?a?(u=t.attr("data-fileindex"),f.uploadCache.content[u]=d[0],f.uploadCache.config[u]=c[0],f.uploadCache.tags[u]=p[0],f.uploadCache.append=r):(l=o.add(f.id,d,c[0],p[0],r),n=o.get(f.id,l,!1),s=e(n).hide(),t.after(s).fadeOut("slow",function(){s.fadeIn("slow").css("display:inline-block"),f._initPreviewDeletes(),f._clearFileInput(),t.remove()})):(o.set(f.id,d,c,p,r),f._initPreview(),f._initPreviewDeletes()))},_initSuccessThumbs:function(){var i=this;i.showPreview&&i._getThumbs(".file-preview-success").each(function(){var t=e(this),a=t.find(".kv-file-remove");a.removeAttr("disabled"),l(a,"click",function(){var e=i._raise("filesuccessremove",[t.attr("id"),t.data("fileindex")]);ie(t),e!==!1&&t.fadeOut("slow",function(){t.remove(),i.$preview.find(".file-preview-frame").length||i.reset()})})})},_checkAsyncComplete:function(){var i,t,a=this;for(t=0;t0||!e.isEmptyObject(m.uploadExtraData),C={id:_,index:i};m.formdata=w,m.showPreview&&(n=e("#"+_+":not(.file-preview-initial)"),s=n.find(".kv-file-upload"),d=n.find(".kv-file-remove"),e("#"+_).find(".file-thumb-progress").removeClass("hide")),0===h||!b||s&&s.hasClass("disabled")||m._abort(C)||(g=function(e,i){m.updateStack(e,void 0),m.uploadLog.push(i),m._checkAsyncComplete()&&(m.fileBatchCompleted=!0)},l=function(){m.fileBatchCompleted&&setTimeout(function(){m.showPreview&&(o.set(m.id,m.uploadCache.content,m.uploadCache.config,m.uploadCache.tags,m.uploadCache.append),m.hasInitData&&(m._initPreview(),m._initPreviewDeletes())),m.unlock(),m._clearFileInput(),m._raise("filebatchuploadcomplete",[m.filestack,m._getExtraData()]),m.uploadCount=0,m.uploadStatus={},m.uploadLog=[],m._setProgress(100)},100)},c=function(t){r=m._getOutData(t),m.fileBatchCompleted=!1,m.showPreview&&(n.hasClass("file-preview-success")||(m._setThumbStatus(n,"Loading"),u(n,"file-uploading")),s.attr("disabled",!0),d.attr("disabled",!0)),a||m.lock(),m._raise("filepreupload",[r,_,i]),e.extend(!0,C,r),m._abort(C)&&(t.abort(),m._setProgressCancelled())},p=function(t,l,o){r=m._getOutData(o,t),e.extend(!0,C,r),setTimeout(function(){K(t)||K(t.error)?(m.showPreview&&(m._setThumbStatus(n,"Success"),s.hide(),m._initUploadSuccess(t,n,a)),m._raise("fileuploaded",[r,_,i]),a?g(i,_):m.updateStack(i,void 0)):(m._showUploadError(t.error,C),m._setPreviewError(n,i),a&&g(i,_))},100)},f=function(){setTimeout(function(){m.showPreview&&(s.removeAttr("disabled"),d.removeAttr("disabled"),n.removeClass("file-uploading")),a?l():(m.unlock(!1),m._clearFileInput()),m._initSuccessThumbs()},100)},v=function(r,l,o){var s=m._parseError(r,o,a?t[i].name:null);setTimeout(function(){a&&g(i,_),m.uploadStatus[_]=100,m._setPreviewError(n,i),e.extend(!0,C,m._getOutData(r)),m._showUploadError(s,C)},100)},w.append(m.uploadFileAttr,t[i],m.filenames[i]),w.append("file_id",i),m._ajaxSubmit(c,p,f,v,_,i))},_uploadBatch:function(){var i,t,a,r,n,l=this,o=l.filestack,s=o.length,d={},c=l.filestack.length>0||!e.isEmptyObject(l.uploadExtraData);l.formdata=new FormData,0!==s&&c&&!l._abort(d)&&(n=function(){e.each(o,function(e){l.updateStack(e,void 0)}),l._clearFileInput()},i=function(i){l.lock();var t=l._getOutData(i);l.showPreview&&l._getThumbs().each(function(){var i=e(this),t=i.find(".kv-file-upload"),a=i.find(".kv-file-remove");i.hasClass("file-preview-success")||(l._setThumbStatus(i,"Loading"),u(i,"file-uploading")),t.attr("disabled",!0),a.attr("disabled",!0)}),l._raise("filebatchpreupload",[t]),l._abort(t)&&(i.abort(),l._setProgressCancelled())},t=function(i,t,a){var r=l._getOutData(a,i),o=l._getThumbs(),s=0,d=K(i)||K(i.errorkeys)?[]:i.errorkeys;K(i)||K(i.error)?(l._raise("filebatchuploadsuccess",[r]),n(),l.showPreview?(o.each(function(){var i=e(this),t=i.find(".kv-file-upload");i.find(".kv-file-upload").hide(),l._setThumbStatus(i,"Success"),i.removeClass("file-uploading"),t.removeAttr("disabled")}),l._initUploadSuccess(i)):l.reset()):(l.showPreview&&(o.each(function(){var i=e(this),t=i.find(".kv-file-remove"),a=i.find(".kv-file-upload");return i.removeClass("file-uploading"),a.removeAttr("disabled"),t.removeAttr("disabled"),0===d.length?void l._setPreviewError(i):(-1!==e.inArray(s,d)?l._setPreviewError(i):(i.find(".kv-file-upload").hide(),l._setThumbStatus(i,"Success"),l.updateStack(s,void 0)),void s++)}),l._initUploadSuccess(i)),l._showUploadError(i.error,r,"filebatchuploaderror"))},r=function(){l._setProgress(100),l.unlock(),l._initSuccessThumbs(),l._clearFileInput(),l._raise("filebatchuploadcomplete",[l.filestack,l._getExtraData()])},a=function(i,t,a){var r=l._getOutData(i),n=l._parseError(i,a);l._showUploadError(n,r,"filebatchuploaderror"),l.uploadFileCount=s-1,l.showPreview&&(l._getThumbs().each(function(){var i=e(this),t=i.attr("data-fileindex");i.removeClass("file-uploading"),void 0!==l.filestack[t]&&l._setPreviewError(i)}),l._getThumbs().removeClass("file-uploading"),l._getThumbs(" .kv-file-upload").removeAttr("disabled"),l._getThumbs(" .kv-file-delete").removeAttr("disabled"))},e.each(o,function(e,i){K(o[e])||l.formdata.append(l.uploadFileAttr,i,l.filenames[e])}),l._ajaxSubmit(i,t,r,a))},_uploadExtraOnly:function(){var e,i,t,a,r=this,n={};r.formdata=new FormData,r._abort(n)||(e=function(e){r.lock(); +var i=r._getOutData(e);r._raise("filebatchpreupload",[i]),r._setProgress(50),n.data=i,n.xhr=e,r._abort(n)&&(e.abort(),r._setProgressCancelled())},i=function(e,i,t){var a=r._getOutData(t,e);K(e)||K(e.error)?(r._raise("filebatchuploadsuccess",[a]),r._clearFileInput(),r._initUploadSuccess(e)):r._showUploadError(e.error,a,"filebatchuploaderror")},t=function(){r._setProgress(100),r.unlock(),r._clearFileInput(),r._raise("filebatchuploadcomplete",[r.filestack,r._getExtraData()])},a=function(e,i,t){var a=r._getOutData(e),l=r._parseError(e,t);n.data=a,r._showUploadError(l,a,"filebatchuploaderror")},r._ajaxSubmit(e,i,t,a))},_initFileActions:function(){var i=this;i.showPreview&&(i.$preview.find(".kv-file-remove").each(function(){var t,a,r,n,s=e(this),d=s.closest(".file-preview-frame"),c=d.attr("id"),p=d.attr("data-fileindex");l(s,"click",function(){return n=i._raise("filepreremove",[c,p]),n!==!1&&i._validateMinCount()?(t=d.hasClass("file-preview-error"),ie(d),void d.fadeOut("slow",function(){i.updateStack(p,void 0),i._clearObjects(d),d.remove(),c&&t&&i.$errorContainer.find('li[data-file-id="'+c+'"]').fadeOut("fast",function(){e(this).remove(),i._errorsExist()||i._resetErrors()});var n=i.getFileStack(!0),l=n.length,s=o.count(i.id),u=i.showPreview&&i.$preview.find(".file-preview-frame").length;i._clearFileInput(),0!==l||0!==s||u?(a=s+l,r=a>1?i._getMsgSelected(a):n[0]?i._getFileNames()[0]:"",i._setCaption(r)):i.reset(),i._raise("fileremoved",[c,p])})):!1})}),i.$preview.find(".kv-file-upload").each(function(){var t=e(this);l(t,"click",function(){var e=t.closest(".file-preview-frame"),a=e.attr("data-fileindex");e.hasClass("file-preview-error")||i._uploadSingle(a,i.filestack,!1)})}))},_hideFileIcon:function(){this.overwriteInitial&&this.$captionContainer.find(".kv-caption-icon").hide()},_showFileIcon:function(){this.$captionContainer.find(".kv-caption-icon").show()},_previewDefault:function(i,a,r){if(this.showPreview){var n=this,l="",o=i?i.name:"",s=t.createObjectURL(i),d=a.slice(a.lastIndexOf("-")+1),c=n.previewSettings.other||W.other,p=n._renderFileFooter(i.name,c.width),u=n._parseFilePreviewIcon(n._getPreviewTemplate("other"),o);r===!0&&(n.isUploadable||(p+='
    '+n.fileActionSettings.indicatorError+"
    ")),n._clearDefaultPreview(),n.$preview.append("\n"+u.replace(/\{previewId}/g,a).replace(/\{frameClass}/g,l).replace(/\{fileindex}/g,d).replace(/\{caption}/g,n.slug(i.name)).replace(/\{width}/g,c.width).replace(/\{height}/g,c.height).replace(/\{type}/g,i.type).replace(/\{data}/g,s).replace(/\{footer}/g,p)),r===!0&&n.isUploadable&&n._setThumbStatus(e("#"+a),"Error")}},_previewFile:function(e,i,t,a,r){if(this.showPreview){var n,l,o,s=this,d=s._parseFileType(i),c=i?i.name:"",p=s.slug(c),u=s.allowedPreviewTypes,f=s.allowedPreviewMimeTypes,v=s._getPreviewTemplate(d),g=u&&u.indexOf(d)>=0,m=J(d,s.previewSettings)?s.previewSettings[d]:W[d],h=f&&-1!==f.indexOf(i.type),w=s._renderFileFooter(p,m.width),_="",b=a.slice(a.lastIndexOf("-")+1);g||h?(v=s._parseFilePreviewIcon(v,c.split(".").pop()),"text"===d?(l=G(t.target.result),o="text-"+Y(),n=v.replace(/\{zoom}/g,s._getLayoutTemplate("zoom")),_=s._getLayoutTemplate("modal").replace("{id}",o).replace(/\{title}/g,p).replace(/\{body}/g,l).replace(/\{heading}/g,s.msgZoomModalHeading),n=n.replace(/\{previewId}/g,a).replace(/\{caption}/g,p).replace(/\{width}/g,m.width).replace(/\{height}/g,m.height).replace(/\{frameClass}/g,"").replace(/\{zoomInd}/g,s.zoomIndicator).replace(/\{footer}/g,w).replace(/\{fileindex}/g,b).replace(/\{type}/g,i.type).replace(/\{zoomTitle}/g,s.msgZoomTitle).replace(/\{dialog}/g,"$('#"+o+"').modal('show')").replace(/\{data}/g,l)+_):n=v.replace(/\{previewId}/g,a).replace(/\{caption}/g,p).replace(/\{frameClass}/g,"").replace(/\{type}/g,i.type).replace(/\{fileindex}/g,b).replace(/\{width}/g,m.width).replace(/\{height}/g,m.height).replace(/\{footer}/g,w).replace(/\{data}/g,r),s._clearDefaultPreview(),s.$preview.append("\n"+n),s._validateImage(e,a,p,i.type)):s._previewDefault(i,a)}},_slugDefault:function(e){return K(e)?"":String(e).replace(/[\-\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g,"_")},_readFiles:function(i){this.reader=new FileReader;var r,n=this,l=n.$element,o=n.$preview,s=n.reader,d=n.$previewContainer,c=n.$previewStatus,p=n.msgLoading,u=n.msgProgress,f=n.previewInitId,v=i.length,g=n.fileTypeSettings,m=n.filestack.length,h=function(t,a,l,o){var s=e.extend(!0,{},n._getOutData({},{},i),{id:l,index:o}),d={id:l,index:o,file:a,files:i};return n._previewDefault(a,l,!0),n.isUploadable&&n.addToStack(void 0),setTimeout(r(o+1),100),n._initFileActions(),n.removeFromPreviewOnError&&e("#"+l).remove(),n.isUploadable?n._showUploadError(t,s):n._showError(t,d)};n.loadedImages=[],n.totalImagesCount=0,e.each(i,function(e,i){var t=n.fileTypeSettings.image||V.image;t&&t(i.type)&&n.totalImagesCount++}),r=function(e){if(K(l.attr("multiple"))&&(v=1),e>=v)return n.isUploadable&&n.filestack.length>0?n._raise("filebatchselected",[n.getFileStack()]):n._raise("filebatchselected",[i]),d.removeClass("file-thumb-loading"),void c.html("");var w,_,b,C,x,y,T=m+e,F=f+"-"+T,E=i[e],I=n.slug(E.name),$=(E.size||0)/1e3,k="",P=t.createObjectURL(E),S=0,D=n.allowedFileTypes,U=K(D)?"":D.join(", "),A=n.allowedFileExtensions,j=K(A)?"":A.join(", ");if(K(A)||(k=new RegExp("\\.("+A.join("|")+")$","i")),$=$.toFixed(2),n.maxFileSize>0&&$>n.maxFileSize)return C=n.msgSizeTooLarge.replace("{name}",I).replace("{size}",$).replace("{maxSize}",n.maxFileSize),void(n.isError=h(C,E,F,e));if(!K(D)&&X(D)){for(b=0;b0&&void 0!==FileReader?(c.html(p.replace("{index}",e+1).replace("{files}",v)),d.addClass("file-thumb-loading"),s.onerror=function(e){n._errorHandler(e,I)},s.onload=function(i){n._previewFile(e,E,i,F,P),n._initFileActions()},s.onloadend=function(){C=u.replace("{index}",e+1).replace("{files}",v).replace("{percent}",50).replace("{name}",I),setTimeout(function(){c.html(C),n._updateFileDetails(v),r(e+1)},100),n._raise("fileloaded",[E,F,e,s])},s.onprogress=function(i){if(i.lengthComputable){var t=i.loaded/i.total*100,a=Math.ceil(t);C=u.replace("{index}",e+1).replace("{files}",v).replace("{percent}",a).replace("{name}",I),setTimeout(function(){c.html(C)},100)}},w=J("text",g)?g.text:V.text,w(E.type,I)?s.readAsText(E,n.textEncoding):s.readAsArrayBuffer(E)):(n._previewDefault(E,F),setTimeout(function(){r(e+1),n._updateFileDetails(v)},100),n._raise("fileloaded",[E,F,e,s])),void n.addToStack(E)):(n.addToStack(E),setTimeout(r(e+1),100),void n._raise("fileloaded",[E,F,e,s])):(C=n.msgInvalidFileExtension.replace("{name}",I).replace("{extensions}",j),void(n.isError=h(C,E,F,e)))},r(0),n._updateFileDetails(v,!1)},_updateFileDetails:function(e){var i=this,t=i.$element,a=i.getFileStack(),r=t[0].files[0]&&t[0].files[0].name||a.length&&a[0].name||"",n=i.slug(r),l=i.isUploadable?a.length:e,s=o.count(i.id)+l,d=l>1?i._getMsgSelected(s):n;i.isError?(i.$previewContainer.removeClass("file-thumb-loading"),i.$previewStatus.html(""),i.$captionContainer.find(".kv-caption-icon").hide()):i._showFileIcon(),i._setCaption(d,i.isError),i.$container.removeClass("file-input-new file-input-ajax-new"),1===arguments.length&&i._raise("fileselect",[e,n]),o.count(i.id)&&i._initPreviewDeletes()},_setThumbStatus:function(e,i){var t=this;if(t.showPreview){var a="indicator"+i,r=a+"Title",n="file-preview-"+i.toLowerCase(),l=e.find(".file-upload-indicator"),o=t.fileActionSettings;e.removeClass("file-preview-success file-preview-error file-preview-loading"),"Error"===i&&e.find(".kv-file-upload").attr("disabled",!0),l.html(o[a]),l.attr("title",o[r]),e.addClass(n)}},_setProgressCancelled:function(){var e=this;e._setProgress(100,e.$progress,e.msgCancelled)},_setProgress:function(e,i,t){var a=this,r=Math.min(e,100),n=100>r?a.progressTemplate:t?a.progressErrorTemplate:a.progressCompleteTemplate;i=i||a.$progress,K(n)||(i.html(n.replace(/\{percent}/g,r)),t&&i.find('[role="progressbar"]').html(t))},_setFileDropZoneTitle:function(){var e=this,i=e.$container.find(".file-drop-zone");i.find("."+e.dropZoneTitleClass).remove(),e.isUploadable&&e.showPreview&&0!==i.length&&!(e.getFileStack().length>0)&&e.dropZoneEnabled&&(0===i.find(".file-preview-frame").length&&K(e.defaultPreviewContent)&&i.prepend('
    '+e.dropZoneTitle+"
    "),e.$container.removeClass("file-input-new"),u(e.$container,"file-input-ajax-new"))},_setAsyncUploadStatus:function(i,t,a){var r=this,n=0;r._setProgress(t,e("#"+i).find(".file-thumb-progress")),r.uploadStatus[i]=t,e.each(r.uploadStatus,function(e,i){n+=i}),r._setProgress(Math.ceil(n/a))},_validateMinCount:function(){var e=this,i=e.isUploadable?e.getFileStack().length:e.$element.get(0).files.length;return e.validateInitialCount&&e.minFileCount>0&&e._getFileCount(i-1)=f:f>=s,c||(o=p["msgImage"+n+i].replace("{name}",r).replace("{size}",f),p._showUploadError(o,l),p._setPreviewError(a,e,null)))},_validateImage:function(e,i,a,r){var n,o,s,d=this,c=d.$preview,p=c.find("#"+i),u=p.find("img");a=a||"Untitled",u.length&&l(u,"load",function(){o=p.width(),s=c.width(),o>s&&(u.css("width","100%"),p.css("width","97%")),n={ind:e,id:i},d._checkDimensions(e,"Small",u,p,a,"Width",n),d._checkDimensions(e,"Small",u,p,a,"Height",n),d.resizeImage||(d._checkDimensions(e,"Large",u,p,a,"Width",n),d._checkDimensions(e,"Large",u,p,a,"Height",n)),d._raise("fileimageloaded",[i]),d.loadedImages.push({ind:e,img:u,thumb:p,pid:i,typ:r}),d._validateAllImages(),t.revokeObjectURL(u.attr("src"))})},_validateAllImages:function(){var e,i,t,a,r,n,l,o=this,s={};if(o.loadedImages.length===o.totalImagesCount&&(o._raise("fileimagesloaded"),o.resizeImage)){for(l=o.isUploadable?o._showUploadError:o._showError,e=0;ec,n=s>p,d="width"===l.resizePreference?r?c/o:n?p/s:1:n?p/s:r?c/o:1,l._resetCanvas(),o*=d,s*=d,f.width=o,f.height=s;try{return v.drawImage(e,0,0,o,s),f.toBlob(function(e){l._raise("fileimageresized",[t,a]),l.filestack[a]=e},i,l.resizeQuality),!0}catch(g){return!1}},_initBrowse:function(e){var i=this;i.$btnFile=e.find(".btn-file"),i.$btnFile.append(i.$element)},_initCaption:function(){var e=this,i=e.initialCaption||"";return e.overwriteInitial||K(i)?(e.$caption.html(""),!1):(e._setCaption(i),!0)},_setCaption:function(i,t){var a,r,n,l,o=this,s=o.getFileStack();if(o.$caption.length){if(t)a=e("
    "+o.msgValidationError+"
    ").text(),n=s.length,l=n?1===n&&s[0]?o._getFileNames()[0]:o._getMsgSelected(n):o._getMsgSelected(o.msgNo),r=''+o.msgValidationErrorIcon+(K(i)?l:i)+"";else{if(K(i))return;a=e("
    "+i+"
    ").text(),r=o._getLayoutTemplate("icon")+a}o.$caption.html(r),o.$caption.attr("title",a),o.$captionContainer.find(".file-caption-ellipsis").attr("title",a)}},_createContainer:function(){var i=this,t=e(document.createElement("div")).attr({"class":"file-input file-input-new"}).html(i._renderMain());return i.$element.before(t),i._initBrowse(t),t},_refreshContainer:function(){var e=this,i=e.$container;i.before(e.$element),i.html(e._renderMain()),e._initBrowse(i)},_renderMain:function(){var e=this,i=e.isUploadable&&e.dropZoneEnabled?" file-drop-zone":"file-drop-disabled",t=e.showClose?e._getLayoutTemplate("close"):"",a=e.showPreview?e._getLayoutTemplate("preview").replace(/\{class}/g,e.previewClass).replace(/\{dropClass}/g,i):"",r=e.isDisabled?e.captionClass+" file-caption-disabled":e.captionClass,n=e.captionTemplate.replace(/\{class}/g,r+" kv-fileinput-caption");return e.mainTemplate.replace(/\{class}/g,e.mainClass).replace(/\{preview}/g,a).replace(/\{close}/g,t).replace(/\{caption}/g,n).replace(/\{upload}/g,e._renderButton("upload")).replace(/\{remove}/g,e._renderButton("remove")).replace(/\{cancel}/g,e._renderButton("cancel")).replace(/\{browse}/g,e._renderButton("browse"))},_renderButton:function(e){var i=this,t=i._getLayoutTemplate("btnDefault"),a=i[e+"Class"],r=i[e+"Title"],n=i[e+"Icon"],l=i[e+"Label"],o=i.isDisabled?" disabled":"",s="button";switch(e){case"remove":if(!i.showRemove)return"";break;case"cancel":if(!i.showCancel)return"";a+=" hide";break;case"upload":if(!i.showUpload)return"";i.isUploadable&&!i.isDisabled?t=i._getLayoutTemplate("btnLink").replace("{href}",i.uploadUrl):s="submit";break;case"browse":t=i._getLayoutTemplate("btnBrowse");break;default:return""}return a+="browse"===e?" btn-file":" fileinput-"+e+" fileinput-"+e+"-button",K(l)||(l=' '+l+""),t.replace("{type}",s).replace("{css}",a).replace("{title}",r).replace("{status}",o).replace("{icon}",n).replace("{label}",l)},_renderThumbProgress:function(){return'
    '+this.progressTemplate.replace(/\{percent}/g,"0")+"
    "},_renderFileFooter:function(e,i){var t,a,r=this,n=r.fileActionSettings,l=r._getLayoutTemplate("footer");return r.isUploadable?(t=l.replace(/\{actions}/g,r._renderFileActions(!0,!0,!1,!1,!1)),a=t.replace(/\{caption}/g,e).replace(/\{width}/g,i).replace(/\{progress}/g,r._renderThumbProgress()).replace(/\{indicator}/g,n.indicatorNew).replace(/\{indicatorTitle}/g,n.indicatorNewTitle)):a=l.replace(/\{actions}/g,"").replace(/\{caption}/g,e).replace(/\{progress}/g,"").replace(/\{width}/g,i).replace(/\{indicator}/g,"").replace(/\{indicatorTitle}/g,""),a=ee(a,r.previewThumbTags)},_renderFileActions:function(e,i,t,a,r){if(!e&&!i)return"";var n=this,l=a===!1?"":' data-url="'+a+'"',o=r===!1?"":' data-key="'+r+'"',s=n._getLayoutTemplate("actionDelete"),d="",c=n._getLayoutTemplate("actions"),p=n.otherActionButtons.replace(/\{dataKey}/g,o),u=n.fileActionSettings,f=t?u.removeClass+" disabled":u.removeClass;return s=s.replace(/\{removeClass}/g,f).replace(/\{removeIcon}/g,u.removeIcon).replace(/\{removeTitle}/g,u.removeTitle).replace(/\{dataUrl}/g,l).replace(/\{dataKey}/g,o),e&&(d=n._getLayoutTemplate("actionUpload").replace(/\{uploadClass}/g,u.uploadClass).replace(/\{uploadIcon}/g,u.uploadIcon).replace(/\{uploadTitle}/g,u.uploadTitle)),c.replace(/\{delete}/g,s).replace(/\{upload}/g,d).replace(/\{other}/g,p)},_browse:function(e){var i=this;i._raise("filebrowse"),e&&e.isDefaultPrevented()||(i.isError&&!i.isUploadable&&i.clear(),i.$captionContainer.focus())},_change:function(i){var t=this,a=t.$element;if(!t.isUploadable&&K(a.val())&&t.fileInputCleared)return void(t.fileInputCleared=!1);t.fileInputCleared=!1;var r,n,l,s,d,c,p=arguments.length>1,u=t.isUploadable,f=0,v=p?i.originalEvent.dataTransfer.files:a.get(0).files,g=t.filestack.length,m=K(a.attr("multiple")),h=m&&g>0,w=0,_=function(i,a,r,n){var l=e.extend(!0,{},t._getOutData({},{},v),{id:r,index:n}),o={id:r,index:n,file:a,files:v};return t.isUploadable?t._showUploadError(i,l):t._showError(i,o)};if(t.reader=null,t._resetUpload(),t._hideFileIcon(),t.isUploadable&&t.$container.find(".file-drop-zone ."+t.dropZoneTitleClass).remove(),p)for(r=[];v[f];)s=v[f],s.type||s.size%4096!==0?r.push(s):w++,f++;else r=void 0===i.target.files?i.target&&i.target.value?[{name:i.target.value.replace(/^.+\\/,"")}]:[]:i.target.files;if(K(r)||0===r.length)return u||t.clear(),t._showFolderError(w),void t._raise("fileselectnone");if(t._resetErrors(),c=r.length,l=t._getFileCount(t.isUploadable?t.getFileStack().length+c:c),t.maxFileCount>0&&l>t.maxFileCount){if(!t.autoReplace||c>t.maxFileCount)return d=t.autoReplace&&c>t.maxFileCount?c:l,n=t.msgFilesTooMany.replace("{m}",t.maxFileCount).replace("{n}",d),t.isError=_(n,null,null,null),t.$captionContainer.find(".kv-caption-icon").hide(),t._setCaption("",!0),void t.$container.removeClass("file-input-new file-input-ajax-new");l>t.maxFileCount&&t._resetPreviewThumbs(u)}else!u||h?(t._resetPreviewThumbs(!1),h&&t.clearStack()):!u||0!==g||o.count(t.id)&&!t.overwriteInitial||t._resetPreviewThumbs(!0);t.isPreviewable?t._readFiles(r):t._updateFileDetails(1),t._showFolderError(w)},_abort:function(i){var t,a=this;return a.ajaxAborted&&"object"==typeof a.ajaxAborted&&void 0!==a.ajaxAborted.message?(t=e.extend(!0,{},a._getOutData(),i),t.abortData=a.ajaxAborted.data||{},t.abortMessage=a.ajaxAborted.message,a.cancel(),a._setProgress(100,a.$progress,a.msgCancelled),a._showUploadError(a.ajaxAborted.message,t,"filecustomerror"),!0):!1},_resetFileStack:function(){var i=this,t=0,a=[],r=[];i._getThumbs().each(function(){var n=e(this),l=n.attr("data-fileindex"),o=i.filestack[l];-1!==l&&(void 0!==o?(a[t]=o,r[t]=i._getFileName(o),n.attr({id:i.previewInitId+"-"+t,"data-fileindex":t}),t++):n.attr({id:"uploaded-"+Y(),"data-fileindex":"-1"}))}),i.filestack=a,i.filenames=r},clearStack:function(){var e=this;return e.filestack=[],e.filenames=[],e.$element},updateStack:function(e,i){var t=this;return t.filestack[e]=i,t.filenames[e]=t._getFileName(i),t.$element},addToStack:function(e){var i=this;return i.filestack.push(e),i.filenames.push(i._getFileName(e)),i.$element},getFileStack:function(e){var i=this;return i.filestack.filter(function(i){return e?void 0!==i:void 0!==i&&null!==i})},lock:function(){var e=this;return e._resetErrors(),e.disable(),e.showRemove&&u(e.$container.find(".fileinput-remove"),"hide"),e.showCancel&&e.$container.find(".fileinput-cancel").removeClass("hide"),e._raise("filelock",[e.filestack,e._getExtraData()]),e.$element},unlock:function(e){var i=this;return void 0===e&&(e=!0),i.enable(),i.showCancel&&u(i.$container.find(".fileinput-cancel"),"hide"),i.showRemove&&i.$container.find(".fileinput-remove").removeClass("hide"),e&&i._resetFileStack(),i._raise("fileunlock",[i.filestack,i._getExtraData()]),i.$element},cancel:function(){var i,t=this,a=t.ajaxRequests,r=a.length;if(r>0)for(i=0;r>i;i+=1)t.cancelling=!0,a[i].abort();return t._setProgressCancelled(),t._getThumbs().each(function(){var i=e(this),a=i.attr("data-fileindex");i.removeClass("file-uploading"),void 0!==t.filestack[a]&&(i.find(".kv-file-upload").removeClass("disabled").removeAttr("disabled"),i.find(".kv-file-remove").removeClass("disabled").removeAttr("disabled")),t.unlock()}),t.$element},clear:function(){var i,t=this;return t.$btnUpload.removeAttr("disabled"),t._getThumbs().find("video,audio,img").each(function(){ie(e(this))}),t._resetUpload(),t.clearStack(),t._clearFileInput(),t._resetErrors(!0),t._raise("fileclear"),t._hasInitialPreview()?(t._showFileIcon(),t._resetPreview(),t._initPreviewDeletes(),t.$container.removeClass("file-input-new")):(t._getThumbs().each(function(){t._clearObjects(e(this))}),t.isUploadable&&(o.data[t.id]={}),t.$preview.html(""),i=!t.overwriteInitial&&t.initialCaption.length>0?t.initialCaption:"",t._setCaption(i),t.$caption.attr("title",""),u(t.$container,"file-input-new"),t._validateDefaultPreview()),0===t.$container.find(".file-preview-frame").length&&(t._initCaption()||t.$captionContainer.find(".kv-caption-icon").hide()),t._hideFileIcon(),t._raise("filecleared"),t.$captionContainer.focus(),t._setFileDropZoneTitle(),t.$element},reset:function(){var e=this;return e._resetPreview(),e.$container.find(".fileinput-filename").text(""),e._raise("filereset"),u(e.$container,"file-input-new"),(e.$preview.find(".file-preview-frame").length||e.isUploadable&&e.dropZoneEnabled)&&e.$container.removeClass("file-input-new"),e._setFileDropZoneTitle(),e.clearStack(),e.formdata={},e.$element},disable:function(){var e=this;return e.isDisabled=!0,e._raise("filedisabled"),e.$element.attr("disabled","disabled"),e.$container.find(".kv-fileinput-caption").addClass("file-caption-disabled"),e.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").attr("disabled",!0),e._initDragDrop(),e.$element},enable:function(){var e=this;return e.isDisabled=!1,e._raise("fileenabled"),e.$element.removeAttr("disabled"),e.$container.find(".kv-fileinput-caption").removeClass("file-caption-disabled"),e.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").removeAttr("disabled"),e._initDragDrop(),e.$element},upload:function(){var i,t,a,r=this,n=r.getFileStack().length,l={},o=!e.isEmptyObject(r._getExtraData());if(r.minFileCount>0&&r._getFileCount(n)i;i++)r.uploadCache.content[i]=null,r.uploadCache.config[i]=null,r.uploadCache.tags[i]=null;for(i=0;a>i;i++)void 0!==r.filestack[i]&&r._uploadSingle(i,r.filestack,!0)}},destroy:function(){var e=this,t=e.$container;return t.find(".file-drop-zone").off(),e.$element.insertBefore(t).off(i).removeData(),t.off().remove(),e.$element},refresh:function(i){var t=this,a=t.$element;return i=i?e.extend(!0,{},t.options,i):t.options,t.destroy(),a.fileinput(i),a.val()&&a.trigger("change.fileinput"),a}},e.fn.fileinput=function(i){if(d()||r(9)){var t=Array.apply(null,arguments),a=[];switch(t.shift(),this.each(function(){var r,n=e(this),l=n.data("fileinput"),o="object"==typeof i&&i,s=o.language||n.data("language")||"en",d={};l||("en"===s||K(e.fn.fileinputLocales[s])||(d=e.fn.fileinputLocales[s]),r=e.extend(!0,{},e.fn.fileinput.defaults,e.fn.fileinputLocales.en,d,o,n.data()),l=new q(this,r),n.data("fileinput",l)),"string"==typeof i&&a.push(l[i].apply(l,t))}),a.length){case 0:return this;case 1:return a[0];default:return a}}},e.fn.fileinput.defaults={language:"en",showCaption:!0,showPreview:!0,showRemove:!0,showUpload:!0,showCancel:!0,showClose:!0,showUploadedThumbs:!0,autoReplace:!1,mainClass:"",previewClass:"",captionClass:"",mainTemplate:null,initialCaption:"",initialPreview:[],initialPreviewDelimiter:"*$$*",initialPreviewConfig:[],initialPreviewThumbTags:[],previewThumbTags:{},initialPreviewShowDelete:!0,removeFromPreviewOnError:!1,deleteUrl:"",deleteExtraData:{},overwriteInitial:!0,layoutTemplates:M,previewTemplates:Z,allowedPreviewTypes:null,allowedPreviewMimeTypes:null,allowedFileTypes:null,allowedFileExtensions:null,defaultPreviewContent:null,customLayoutTags:{},customPreviewTags:{},previewSettings:W,fileTypeSettings:V,previewFileIcon:'',previewFileIconClass:"file-icon-4x",previewFileIconSettings:{},previewFileExtSettings:{},buttonLabelClass:"hidden-xs",browseIcon:' ',browseClass:"btn btn-primary",removeIcon:'',removeClass:"btn btn-default",cancelIcon:'',cancelClass:"btn btn-default",uploadIcon:'',uploadClass:"btn btn-default",uploadUrl:null,uploadAsync:!0,uploadExtraData:{},minImageWidth:null,minImageHeight:null,maxImageWidth:null,maxImageHeight:null,resizeImage:!1,resizePreference:"width",resizeQuality:.92,resizeDefaultImageType:"image/jpeg",maxFileSize:0,minFileCount:0,maxFileCount:0,validateInitialCount:!1,msgValidationErrorClass:"text-danger",msgValidationErrorIcon:' ',msgErrorClass:"file-error-message",progressThumbClass:"progress-bar progress-bar-success progress-bar-striped active",progressClass:"progress-bar progress-bar-success progress-bar-striped active",progressCompleteClass:"progress-bar progress-bar-success",progressErrorClass:"progress-bar progress-bar-danger",previewFileType:"image",zoomIndicator:'',elCaptionContainer:null,elCaptionText:null,elPreviewContainer:null,elPreviewImage:null,elPreviewStatus:null,elErrorContainer:null,errorCloseButton:'×',slugCallback:null,dropZoneEnabled:!0,dropZoneTitleClass:"file-drop-zone-title",fileActionSettings:{},otherActionButtons:"",textEncoding:"UTF-8",ajaxSettings:{},ajaxDeleteSettings:{},showAjaxErrorDetails:!0},e.fn.fileinputLocales.en={fileSingle:"file",filePlural:"files",browseLabel:"Browse …",removeLabel:"Remove",removeTitle:"Clear selected files",cancelLabel:"Cancel",cancelTitle:"Abort ongoing upload",uploadLabel:"Upload",uploadTitle:"Upload selected files",msgNo:"No",msgCancelled:"Cancelled",msgZoomTitle:"View details",msgZoomModalHeading:"Detailed Preview",msgSizeTooLarge:'File "{name}" ({size} KB) exceeds maximum allowed upload size of {maxSize} KB.',msgFilesTooLess:"You must select at least {n} {files} to upload.",msgFilesTooMany:"Number of files selected for upload ({n}) exceeds maximum allowed limit of {m}.",msgFileNotFound:'File "{name}" not found!',msgFileSecured:'Security restrictions prevent reading the file "{name}".',msgFileNotReadable:'File "{name}" is not readable.',msgFilePreviewAborted:'File preview aborted for "{name}".',msgFilePreviewError:'An error occurred while reading the file "{name}".',msgInvalidFileType:'Invalid type for file "{name}". Only "{types}" files are supported.',msgInvalidFileExtension:'Invalid extension for file "{name}". Only "{extensions}" files are supported.',msgUploadAborted:"The file upload was aborted",msgValidationError:"Validation Error",msgLoading:"Loading file {index} of {files} …",msgProgress:"Loading file {index} of {files} - {name} - {percent}% completed.",msgSelected:"{n} {files} selected",msgFoldersNotAllowed:"Drag & drop files only! {n} folder(s) dropped were skipped.",msgImageWidthSmall:'Width of image file "{name}" must be at least {size} px.',msgImageHeightSmall:'Height of image file "{name}" must be at least {size} px.',msgImageWidthLarge:'Width of image file "{name}" cannot exceed {size} px.',msgImageHeightLarge:'Height of image file "{name}" cannot exceed {size} px.',msgImageResizeError:"Could not get the image dimensions to resize.",msgImageResizeException:"Error while resizing the image.
    {errors}
    ",dropZoneTitle:"Drag & drop files here …"},e.fn.fileinput.Constructor=q,e(document).ready(function(){var i=e("input.file[type=file]");i.length&&i.fileinput()})}); \ No newline at end of file diff --git a/libs/bootstrap-fileinput/js/fileinput_locale_zh.js b/libs/bootstrap-fileinput/js/fileinput_locale_zh.js new file mode 100644 index 00000000..bf8ec97d --- /dev/null +++ b/libs/bootstrap-fileinput/js/fileinput_locale_zh.js @@ -0,0 +1,61 @@ +/*! + * FileInput Chinese Translations + * + * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or + * any HTML markup tags in the messages must not be converted or translated. + * + * @see http://github.com/kartik-v/bootstrap-fileinput + * @author kangqf + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['zh'] = { + fileSingle: '文件', + filePlural: '多个文件', + browseLabel: '选择 …', + removeLabel: '移除', + removeTitle: '清除选中文件', + cancelLabel: '取消', + cancelTitle: '取消进行中的上传', + uploadLabel: '上传', + uploadTitle: '上传选中文件', + msgNo: '没有', + msgCancelled: '取消', + msgZoomTitle: '查看详情', + msgZoomModalHeading: '详细预览', + msgSizeTooLarge: '文件 "{name}" ({size} KB) 超过了允许大小 {maxSize} KB.', + msgFilesTooLess: '你必须选择最少 {n} {files} 来上传. ', + msgFilesTooMany: '选择的上传文件个数 ({n}) 超出最大文件的限制个数 {m}.', + msgFileNotFound: '文件 "{name}" 未找到!', + msgFileSecured: '安全限制,为了防止读取文件 "{name}".', + msgFileNotReadable: '文件 "{name}" 不可读.', + msgFilePreviewAborted: '取消 "{name}" 的预览.', + msgFilePreviewError: '读取 "{name}" 时出现了一个错误.', + msgInvalidFileType: '不正确的类型 "{name}". 只支持 "{types}" 类型的文件.', + msgInvalidFileExtension: '不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.', + msgUploadAborted: '该文件上传被中止', + msgValidationError: '验证错误', + msgLoading: '加载第 {index} 文件 共 {files} …', + msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', + msgSelected: '{n} {files} 选中', + msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.', + msgImageWidthSmall: '宽度的图像文件的"{name}"的必须是至少{size}像素.', + msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.', + msgImageWidthLarge: '宽度的图像文件"{name}"不能超过{size}像素.', + msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.', + msgImageResizeError: '无法获取的图像尺寸调整。', + msgImageResizeException: '错误而调整图像大小。
    {errors}
    ', + dropZoneTitle: '拖拽文件到这里 …', + fileActionSettings: { + removeTitle: '删除文件', + uploadTitle: '上传文件', + indicatorNewTitle: '没有上传', + indicatorSuccessTitle: '上传', + indicatorErrorTitle: '上传错误', + indicatorLoadingTitle: '上传 ...' + } + }; +})(window.jQuery); \ No newline at end of file diff --git a/libs/bootstrap-fileinput/js/plugins/canvas-to-blob.js b/libs/bootstrap-fileinput/js/plugins/canvas-to-blob.js new file mode 100644 index 00000000..d35ce0ad --- /dev/null +++ b/libs/bootstrap-fileinput/js/plugins/canvas-to-blob.js @@ -0,0 +1,95 @@ +/* + * JavaScript Canvas to Blob 2.0.5 + * https://github.com/blueimp/JavaScript-Canvas-to-Blob + * + * Copyright 2012, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + * + * Based on stackoverflow user Stoive's code snippet: + * http://stackoverflow.com/q/4998908 + */ + +/*jslint nomen: true, regexp: true */ +/*global window, atob, Blob, ArrayBuffer, Uint8Array, define */ + +(function (window) { + 'use strict'; + var CanvasPrototype = window.HTMLCanvasElement && + window.HTMLCanvasElement.prototype, + hasBlobConstructor = window.Blob && (function () { + try { + return Boolean(new Blob()); + } catch (e) { + return false; + } + }()), + hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array && + (function () { + try { + return new Blob([new Uint8Array(100)]).size === 100; + } catch (e) { + return false; + } + }()), + BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || + window.MozBlobBuilder || window.MSBlobBuilder, + dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob && + window.ArrayBuffer && window.Uint8Array && function (dataURI) { + var byteString, + arrayBuffer, + intArray, + i, + mimeString, + bb; + if (dataURI.split(',')[0].indexOf('base64') >= 0) { + // Convert base64 to raw binary data held in a string: + byteString = atob(dataURI.split(',')[1]); + } else { + // Convert base64/URLEncoded data component to raw binary data: + byteString = decodeURIComponent(dataURI.split(',')[1]); + } + // Write the bytes of the string to an ArrayBuffer: + arrayBuffer = new ArrayBuffer(byteString.length); + intArray = new Uint8Array(arrayBuffer); + for (i = 0; i < byteString.length; i += 1) { + intArray[i] = byteString.charCodeAt(i); + } + // Separate out the mime component: + mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; + // Write the ArrayBuffer (or ArrayBufferView) to a blob: + if (hasBlobConstructor) { + return new Blob( + [hasArrayBufferViewSupport ? intArray : arrayBuffer], + {type: mimeString} + ); + } + bb = new BlobBuilder(); + bb.append(arrayBuffer); + return bb.getBlob(mimeString); + }; + if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) { + if (CanvasPrototype.mozGetAsFile) { + CanvasPrototype.toBlob = function (callback, type, quality) { + if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) { + callback(dataURLtoBlob(this.toDataURL(type, quality))); + } else { + callback(this.mozGetAsFile('blob', type)); + } + }; + } else if (CanvasPrototype.toDataURL && dataURLtoBlob) { + CanvasPrototype.toBlob = function (callback, type, quality) { + callback(dataURLtoBlob(this.toDataURL(type, quality))); + }; + } + } + if (typeof define === 'function' && define.amd) { + define(function () { + return dataURLtoBlob; + }); + } else { + window.dataURLtoBlob = dataURLtoBlob; + } +}(window)); diff --git a/libs/bootstrap-fileinput/js/plugins/canvas-to-blob.min.js b/libs/bootstrap-fileinput/js/plugins/canvas-to-blob.min.js new file mode 100644 index 00000000..3a02a8a1 --- /dev/null +++ b/libs/bootstrap-fileinput/js/plugins/canvas-to-blob.min.js @@ -0,0 +1 @@ +!function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,f,g,h,i,j;for(b=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURIComponent(a.split(",")[1]),f=new ArrayBuffer(b.length),g=new Uint8Array(f),h=0;hr&&(r=-50);e(this);return c.each(function(){var a=h(this);M(a);var c=this,b=c.id,e=-r+"%",d=100+2*r+"%",d={position:"absolute",top:e,left:e,display:"block",width:d,height:d,margin:0,padding:0,background:"#fff",border:0,opacity:0},e=J?{position:"absolute",visibility:"hidden"}:r?d:{position:"absolute",opacity:0},k="checkbox"==c[n]?f.checkboxClass||"icheckbox":f.radioClass||"i"+u,m=h(G+'[for="'+b+'"]').add(a.closest(G)), +A=!!f.aria,E=q+"-"+Math.random().toString(36).replace("0.",""),g='
    ")[p]("ifCreated").parent().append(f.insert);d=h('').css(d).appendTo(g);a.data(q,{o:f,s:a.attr("style")}).css(e);f.inheritClass&&g[v](c.className||"");f.inheritID&&b&&g.attr("id",q+"-"+b);"static"==g.css("position")&&g.css("position","relative");F(a,!0,H); +if(m.length)m.on("click.i mouseover.i mouseout.i touchbegin.i touchend.i",function(b){var d=b[n],e=h(this);if(!c[s]){if("click"==d){if(h(b.target).is("a"))return;F(a,!1,!0)}else y&&(/ut|nd/.test(d)?(g[z](B),e[z](C)):(g[v](B),e[v](C)));if(J)b.stopPropagation();else return!1}});a.on("click.i focus.i blur.i keyup.i keydown.i keypress.i",function(b){var d=b[n];b=b.keyCode;if("click"==d)return!1;if("keydown"==d&&32==b)return c[n]==u&&c[l]||(c[l]?t(a,l):D(a,l)),!1;if("keyup"==d&&c[n]==u)!c[l]&&D(a,l);else if(/us|ur/.test(d))g["blur"== +d?z:v](x)});d.on("click mousedown mouseup mouseover mouseout touchbegin.i touchend.i",function(b){var d=b[n],e=/wn|up/.test(d)?w:B;if(!c[s]){if("click"==d)F(a,!1,!0);else{if(/wn|er|in/.test(d))g[v](e);else g[z](e+" "+w);if(m.length&&y&&e==B)m[/ut|nd/.test(d)?z:v](C)}if(J)b.stopPropagation();else return!1}})})}})(window.jQuery||window.Zepto); diff --git a/libs/iCheck/square/blue.css b/libs/iCheck/square/blue.css new file mode 100644 index 00000000..95340fea --- /dev/null +++ b/libs/iCheck/square/blue.css @@ -0,0 +1,62 @@ +/* iCheck plugin Square skin, blue +----------------------------------- */ +.icheckbox_square-blue, +.iradio_square-blue { + display: inline-block; + *display: inline; + vertical-align: middle; + margin: 0; + padding: 0; + width: 22px; + height: 22px; + background: url(blue.png) no-repeat; + border: none; + cursor: pointer; +} + +.icheckbox_square-blue { + background-position: 0 0; +} + .icheckbox_square-blue.hover { + background-position: -24px 0; + } + .icheckbox_square-blue.checked { + background-position: -48px 0; + } + .icheckbox_square-blue.disabled { + background-position: -72px 0; + cursor: default; + } + .icheckbox_square-blue.checked.disabled { + background-position: -96px 0; + } + +.iradio_square-blue { + background-position: -120px 0; +} + .iradio_square-blue.hover { + background-position: -144px 0; + } + .iradio_square-blue.checked { + background-position: -168px 0; + } + .iradio_square-blue.disabled { + background-position: -192px 0; + cursor: default; + } + .iradio_square-blue.checked.disabled { + background-position: -216px 0; + } + +/* Retina support */ +@media only screen and (-webkit-min-device-pixel-ratio: 1.5), + only screen and (-moz-min-device-pixel-ratio: 1.5), + only screen and (-o-min-device-pixel-ratio: 3/2), + only screen and (min-device-pixel-ratio: 1.5) { + .icheckbox_square-blue, + .iradio_square-blue { + background-image: url(blue@2x.png); + -webkit-background-size: 240px 24px; + background-size: 240px 24px; + } +} \ No newline at end of file diff --git a/libs/iCheck/square/blue.png b/libs/iCheck/square/blue.png new file mode 100644 index 0000000000000000000000000000000000000000..a3e040fcce00622a17085d447f1a18c68989357e GIT binary patch literal 2185 zcmV;42zK|0P)8E31pC7N@zyE%Zk8_Tr_5J2?NkFQWJ?Ri+@hcbTw;cz!3GsXOt(x$+eej=y37VgS za0`+se?%|-?>ubk!8gDXPz)Y|Tfhs>f(FnR$+PvHkQgK?KjxYK=;8ay^7vV2qxqSw zl?f~cMZg6@U;y+24`@RjgAwLfBE*`X%;45xp;13=;Ny~9IcV41Solz|3~Q5x%}>ET za2)&rw1B%{CUApFHii$p3VsKI5?#Xmxe^xoKTkG+LukYaKN=|*W#h)=k7fL2KN zCe5q(P07{$X5;7lXs_Q6I=~U&S9~GRL#~5HHscSl?{PF)zeJAipBKZ2;aX5_NV}7!+*$FOz^S~d){0xBe+-D~pMxme08yoXreU8vE z8>rF!Zg857c_xY@th0RWY3_RpjY_|I*i3)?aT|@Fht1D`|AD4B=BJ7KJ_A>#APTxa zTjEc)?oT&x>aiQV2M${}*KwGu*lq)V4Y&w)fItjilLFl5A|1wlt13a{#<%)kVjC0Ow@rpFG*uAIG^4ZJ(Fv*pC%=($B~ATSpx~ z&o-|H%~r*9)X}Mjew#vn$~W-ywQgztNsTNiamjRyd;X%;Pb{fC(|uu=j2zK2-bu1VqeaI4T@h&gJm-vs^8}Ns{Tcw zL+pzeR4RVE>sy)B4V;1 zLlM`NFMRxaIk^R;!W5U4FV8P5+9=3S@WItiPy4BH#6(vFx)b;Y)gO1;#b`t z5*nAOnEu|L_OY>00EbX>-194TjejB<2|gvm|jD z=5|)1{0Xk_XoCNsX*3b_P3i{r^gNL5$6Mw0z_7SxX2{X+JR!f{v{*764r%P{mlyuV z;!e@rAL#$&hVS~ZP-xWea5!g`x)(k-x2WuC2plMGM~CO~$!Lm8?tl`pFY1bZhuadH z+@ktzuP^=TifI$-iXKQneFI5<6056k2t{s_&fcJ8&2UZ>_reXoyzuv{@-Q?eQ$2%$ zf!?l;tH(x1NA5Wsju{ih9Uk)eyjM=5wxJkQ*TCn*zAOco6u*|`Vm+&XsD7L4tNMFD zVFEwkdJ<6I?vywS{Sj8+dK9_sZb07a>X+wFwM%ehOr}eM4+j06-u7c7BM)A~goRgt{B0p2#s4-k3cz}*y z;;N)cKOfU?9d-P?-nI$US{2jLM5iA5Z3_MA22L$r1M9#Z3#*H^?^Bw~z~2g1gA-s* z49%;(_9XZ+XfyF!i?P2MRDhKh=4T}j#hVTM-C{i->;7~Drx08bo(6ltOK~*sJ~sbW zgA3zz|3~0k%3o_mYF_>O^cHYi^MBff{rorjyt1KiPELkzUnewX{gVHmHzigJ4v`~z$QT(>VwIt>6r3;7O{e z!$v=hM%Kr_A;S2N$2xvCN+W7_kyrhEi4E(bAi#$9g4a2pv1Gyzbbn<8f2)~ayDO#D zH-w^`KC3L>5RdX&U8{5dNXNjtQa;l8MJawq)F%hoB7z8A)uyY^gQ+UDNz&>(ZDYJ`)nj(Q&mXsuujWJDgqbZ^ zZSQlI594UTEB$%s^&G3>awG#u3>6n_W=NwOEO>O~Zafl^M?q9{AF_TLJhLQnHD%Mv z+`>I3<|F?ruZErw5c4%8r4+3d_Jq+l7*{z}ExSeSFk<|U6v}8@v2M&sgPhkb+J^H) zgz+25-y1w#$+0f&x5Yu8?tTG^-4p^^aVPftv=CFumbcIG<93wH&DOMHh~2e1l*cN{ zDZJOFU@f+rcAdbNCYi87z28iB;_OTMC-SPikpc?x@T6*?txXVEOx|-)eMzrUw}{?A zegziZ20+;kTmM!(y+-JIVC~OWtY2apP!;5sg#_PDTkx%WW7qbj{iAC}hyi9Oe@5T$ zMDYOI=xXd@x@4S00I*9>6EP`L{Tr#V(k;qt<@FuwDb^gzfIZ0F97Ak^4$`8xP>H;%@}BWw3H$1X|P2 z1AEplN|MRB4tD+F2loYZ#ZgiYWN2%hl~P^A1X`mJ(mSG=04kauXsxqRs)=|&lOgWN zp{r@1{l0|U=tZ4e(!4t6ip)J(U7UTi5mSUb3oUIMJn46)n0y4OFis>20DW`vB}(Ja zqs&W_@k;eiT4vFo?_}e>-4Z$JzZb<6KtJl|+vD5fKQ!1m07|f+WSAdw?7E zsXaucC2sDeXft{YWHX!#20<7*GTv6;-tR^79xXCe2S15K0ZgP5DB;gYzpQ!Iy~hb! zYoOnf^*!EhX=V-y?2yotPF3RjdFq(z1|D*j7TWqWh-A$<7K*IW+qPKCc3rZQV$@kO zclg4_BhA_27H^b{(Qi;XSJrf_EK?bEdUC!dzH9p4i9MLa&ZQ>zxt-pcn@6$N(ZDk9 zRlZ@bJ$9mC<9N@9yrU>L9+Kj38{ww;9acjcY8Lf++;>${e8mai1ZHa!Pne7^!x_$v zoReV%Ond7fT{!E$27FFd=@c#4f}Abk7`{$D0`Z#*B^XKCp@8fjYjU&X4a>Df+{e}K zshi@fPTVp=>mo%s?FrDK)F1c8@Xlv3AaN4vv3BH5(fXKpMn)0_Fc_>vcApPMIkD3k z(miB*$p{X5Efh!b=rK}^{&;I`0;1Y_!xFtUI6vKg=TFdO{VK-KHag5DRadODE*+VP z25e!~7RGHvwz+XCNl378(;>cKXA(qy?cW^f^)TYD4!V7@O_HL`PT`l z1vA-DfkaLS*)3_*l3yOCPhEJV<nW+9+>Q(jMKn4@t`)kX+Mz{{jlx!DozQiWn=-TBsU-nUbR-;JDv%y@2U@ zYIgsS3);*!hVtP0o2AUt+GD;FXga_s+s@ug**xlfn($Q@>`1+Wj-0Kf`K7VDWP0D~ z+EXyzn*lbrJ`C7>kME065M#7|!#1N0g|e?HLJgjSpzC5zczH$<9!O6;25b(bWW`{N zNwGTW#@z3+9o~TT-Qe?WY7DlM$_;HHf1a7yyA?i}?=Hp4i=u-gtlPBseqp1ae_OP< zkvCwtZ*{_`3rf_mOKluf8)v%X;{*;Qzf)DUGDJ;NOG2p_S15d?vr4>pxr6Dd@(=#O zEpG`kd3AMEQqskhR&Kri%52!#xQKiA;KrWtcXY}6Cdki&S8M5E#j;<$La$i`H|*kD z;%YthqTVZ0!)*V(C9o1=p)HZaE^ z_^GXnO*S82qS3j#QEB7XTwRfBcmPetp6t@MV zmwrXZr>M2ey=0`jlmmwQdc6qL=KC_A5EX0o6=8ti+2vFjnJU0^yiYz;t7Ct^JuZABwXV9(>@uu*Lc6PrUOxh-8 zCB($VRV^fP&uJT7(A)T)(D&Unx_yB>zDIuJu$eoCC^?RSy}&Q*EAhZ9+F}gqF@zf- za2VLjJrD5`Ei$#Us}|Uu((oEy__R>5Yp$?3#RWro@?6k3HN>(J*Dbu@)>&Cz<|-Sv z_)P!Z{h{u2%Bli#X;A+DGy&V857jG64rm>7a|H_;L@L+hbatI=w=mXtudJh^W;??A zhO>=LbWKv~HFz-?ngsb5}uu+b}C#R*sZeL`x?a~(s< z!ZUHnRBAeFo3=Xqkq8`gHLl&vOK34Q4OlJpeQDk^Q5|lDu-}IU)@oHP*br*COi+`u zhYOUag3t3tWeW^K&!ijuz(z^E(a6G$Ey!3(T&5RMGl`^l0Qvylwy9k!ioTugl)t4> zJ@hQ^WTAm}evOY9&?LOg^LjinWzb3cE$YQ<5CH3fdf6@I7^kp&ykZ5oX=otIT~p6EmqUQdkdSLu2g=-uBnw6e79>>ZETr?~V8tjFrZ+ zF%>;wgoMndDN$?VHD_Q>89S=rECPJoQ-HgDe8*`8-WDUZ**uz%^P2FU$HI;q%i?&Y zaDni(Lap|)=Z=3Ef5QXULti|jqO)1suGvDXOv-Lj%q;8LwnSOc`{YQh1zp5ob}77o zHE`QGON^0TjcLIM6Ri07=R|+ zh|Fb@K5E6dS}~A{woq*yN`1;mdMgg)>Wt)KJowWa&V;2!*Agb~Fy`!3TWyo`aqkZ7 znbXK_j>Ix?3TNp`&RdIphjLyF`r~2?+@9HOgWvFQqc6N5J`yYg$r9X;5NXXICi3vA zH~*8DJ+!oHUX0I2AKE+?*eAUx5qNygO(UX)`K6c}bF2O_F=T{3p~Z5SbW1}Q`0!Jt z?9S_WP!W`i(SCDlTqWkY#*n_>>(=qu!8?^a>cWUMtc-`7J_EH@Yo6*}VXr=6g$|6$_B{{&qX?&y%~tobe)V!05|ZbzY((jz9Y^kxlHa7N z_~;mf%$+U-Wu}$03{-@7lv>2Q3|^GN0?9%<*&Ck&vlHwWz_>KAbiTzm2$Yq$kZpLz0~F6^$}1w2^t`|!)R<-XKO+s0m^5zM1IyWhJQ1!g$=O0a>y55keC=e) zkXqXrSAuX8=e)0zXocuYcH|p8%S>Y@z<0U-BsQqSi`psNdGbcqN7K;R)5rS!y~y;y zdynEpCnm&-nJ~tTN^|Aom`p0Q9-fw#vkbbe$H41!t#-VqF2O2pe2$7tnqeB#U6L`? z&zy21$*n|@s~aSlq0w5l81_Nx}N+r(y4Nn=y<;}D>uyoYA?S}qzfyJ9cv4~HXta&v;iaGk6a zq+oTIOHMJy!;h8y&DVsQ`hE7}8L8~-bb>|`>v7VF4tfr@ + + EOT; $data['user'] = $user; $data['page_title'] = "皮肤上传"; @@ -43,14 +45,14 @@ View::show('header', $data);
    -
    +
    -
    +
    @@ -82,6 +84,9 @@ View::show('header', $data);
    + + EOT;