diff --git a/.gitignore b/.gitignore index 3f2ebf8ce386ea0bf49af91dca00f2043fc394fb..80e52bf5be754892bd0e7cf898fb347e9801b1cf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,16 +2,17 @@ /thinkphp/ /vendor/ /runtime/* -/addons/* -/application/admin/command/Install/*.lock -/public/assets/libs/ +#/addons/* +#/application/admin/command/Install/*.lock +#/public/assets/libs/ /public/assets/addons/* /public/uploads/* .idea -composer.lock +#composer.lock *.log *.css.map !.gitkeep .env .svn .vscode +.Ds_Store diff --git a/addons/alioss/Alioss.php b/addons/alioss/Alioss.php new file mode 100644 index 0000000000000000000000000000000000000000..161e4d0db46a6eeaab9ffb4f146b78270fbeebf0 --- /dev/null +++ b/addons/alioss/Alioss.php @@ -0,0 +1,96 @@ +getConfig(); + if ($config['uploadmode'] === 'client') { + $upload = [ + 'cdnurl' => $config['cdnurl'], + 'uploadurl' => 'https://' . $config['bucket'] . '.' . $config['endpoint'], + 'bucket' => $config['bucket'], + 'maxsize' => $config['maxsize'], + 'mimetype' => $config['mimetype'], + 'multipart' => [], + 'multiple' => $config['multiple'] ? true : false, + 'storage' => 'alioss' + ]; + } else { + $upload = array_merge($upload, [ + 'cdnurl' => $config['cdnurl'], + 'uploadurl' => addon_url('alioss/index/upload'), + 'maxsize' => $config['maxsize'], + 'mimetype' => $config['mimetype'], + 'multiple' => $config['multiple'] ? true : false, + ]); + } + } + + /** + * 附件删除后 + */ + public function uploadDelete($attachment) + { + $config = $this->getConfig(); + if ($attachment['storage'] == 'alioss' && isset($config['syncdelete']) && $config['syncdelete']) { + $endpoint = "http://" . $config['endpoint']; + try { + $ossClient = new OssClient($config['app_id'], $config['app_key'], $endpoint); + $ossClient->deleteObject($config['bucket'], ltrim($attachment->url, '/')); + } catch (OssException $e) { + return false; + } + //如果是服务端中转,还需要删除本地文件 + if ($config['uploadmode'] == 'server') { + $filePath = ROOT_PATH . 'public' . str_replace('/', DS, $attachment->url); + if ($filePath) { + @unlink($filePath); + } + } + } + return true; + } + +} diff --git a/addons/alioss/__MACOSX/._Alioss.php b/addons/alioss/__MACOSX/._Alioss.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/._Alioss.php differ diff --git a/addons/alioss/__MACOSX/._assets b/addons/alioss/__MACOSX/._assets new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/._assets differ diff --git a/addons/alioss/__MACOSX/._bootstrap.js b/addons/alioss/__MACOSX/._bootstrap.js new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/._bootstrap.js differ diff --git a/addons/alioss/__MACOSX/._config.php b/addons/alioss/__MACOSX/._config.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/._config.php differ diff --git a/addons/alioss/__MACOSX/._controller b/addons/alioss/__MACOSX/._controller new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/._controller differ diff --git a/addons/alioss/__MACOSX/._info.ini b/addons/alioss/__MACOSX/._info.ini new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/._info.ini differ diff --git a/addons/alioss/__MACOSX/._library b/addons/alioss/__MACOSX/._library new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/._library differ diff --git a/addons/alioss/__MACOSX/assets/._js b/addons/alioss/__MACOSX/assets/._js new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/assets/._js differ diff --git a/addons/alioss/__MACOSX/assets/js/._spark.js b/addons/alioss/__MACOSX/assets/js/._spark.js new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/assets/js/._spark.js differ diff --git a/addons/alioss/__MACOSX/controller/._Index.php b/addons/alioss/__MACOSX/controller/._Index.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/controller/._Index.php differ diff --git a/addons/alioss/__MACOSX/library/._Auth.php b/addons/alioss/__MACOSX/library/._Auth.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/._Auth.php differ diff --git a/addons/alioss/__MACOSX/library/._OSS b/addons/alioss/__MACOSX/library/._OSS new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/._OSS differ diff --git a/addons/alioss/__MACOSX/library/OSS/._Core b/addons/alioss/__MACOSX/library/OSS/._Core new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/._Core differ diff --git a/addons/alioss/__MACOSX/library/OSS/._Http b/addons/alioss/__MACOSX/library/OSS/._Http new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/._Http differ diff --git a/addons/alioss/__MACOSX/library/OSS/._Model b/addons/alioss/__MACOSX/library/OSS/._Model new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/._Model differ diff --git a/addons/alioss/__MACOSX/library/OSS/._OssClient.php b/addons/alioss/__MACOSX/library/OSS/._OssClient.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/._OssClient.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/._Result b/addons/alioss/__MACOSX/library/OSS/._Result new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/._Result differ diff --git a/addons/alioss/__MACOSX/library/OSS/Core/._MimeTypes.php b/addons/alioss/__MACOSX/library/OSS/Core/._MimeTypes.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Core/._MimeTypes.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Core/._OssException.php b/addons/alioss/__MACOSX/library/OSS/Core/._OssException.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Core/._OssException.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Core/._OssUtil.php b/addons/alioss/__MACOSX/library/OSS/Core/._OssUtil.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Core/._OssUtil.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Http/._LICENSE b/addons/alioss/__MACOSX/library/OSS/Http/._LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Http/._LICENSE differ diff --git a/addons/alioss/__MACOSX/library/OSS/Http/._RequestCore.php b/addons/alioss/__MACOSX/library/OSS/Http/._RequestCore.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Http/._RequestCore.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Http/._RequestCore_Exception.php b/addons/alioss/__MACOSX/library/OSS/Http/._RequestCore_Exception.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Http/._RequestCore_Exception.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Http/._ResponseCore.php b/addons/alioss/__MACOSX/library/OSS/Http/._ResponseCore.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Http/._ResponseCore.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._BucketInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._BucketInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._BucketInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._BucketListInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._BucketListInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._BucketListInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._CnameConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._CnameConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._CnameConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._CorsConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._CorsConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._CorsConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._CorsRule.php b/addons/alioss/__MACOSX/library/OSS/Model/._CorsRule.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._CorsRule.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelHistory.php b/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelHistory.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelHistory.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelStatus.php b/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelStatus.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._GetLiveChannelStatus.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleAction.php b/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleAction.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleAction.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleRule.php b/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleRule.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._LifecycleRule.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._ListMultipartUploadInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._ListMultipartUploadInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._ListMultipartUploadInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._ListPartsInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._ListPartsInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._ListPartsInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelHistory.php b/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelHistory.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelHistory.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelListInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelListInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._LiveChannelListInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._LoggingConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._LoggingConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._LoggingConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._ObjectInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._ObjectInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._ObjectInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._ObjectListInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._ObjectListInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._ObjectListInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._PartInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._PartInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._PartInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._PrefixInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._PrefixInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._PrefixInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._RefererConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._RefererConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._RefererConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._StorageCapacityConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._StorageCapacityConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._StorageCapacityConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._UploadInfo.php b/addons/alioss/__MACOSX/library/OSS/Model/._UploadInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._UploadInfo.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._WebsiteConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._WebsiteConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._WebsiteConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Model/._XmlConfig.php b/addons/alioss/__MACOSX/library/OSS/Model/._XmlConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Model/._XmlConfig.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._AclResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._AclResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._AclResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._AppendResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._AppendResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._AppendResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._BodyResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._BodyResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._BodyResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._CallbackResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._CallbackResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._CallbackResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._CopyObjectResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._CopyObjectResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._CopyObjectResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._DeleteObjectsResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._DeleteObjectsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._DeleteObjectsResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._ExistResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._ExistResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._ExistResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetCnameResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetCnameResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetCnameResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetCorsResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetCorsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetCorsResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetLifecycleResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetLifecycleResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetLifecycleResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelHistoryResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelHistoryResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelHistoryResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelInfoResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelInfoResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelInfoResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelStatusResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelStatusResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetLiveChannelStatusResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetLocationResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetLocationResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetLocationResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetLoggingResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetLoggingResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetLoggingResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetRefererResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetRefererResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetRefererResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetStorageCapacityResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetStorageCapacityResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetStorageCapacityResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._GetWebsiteResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._GetWebsiteResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._GetWebsiteResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._HeaderResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._HeaderResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._HeaderResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._InitiateMultipartUploadResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._InitiateMultipartUploadResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._InitiateMultipartUploadResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._ListBucketsResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._ListBucketsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._ListBucketsResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._ListLiveChannelResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._ListLiveChannelResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._ListLiveChannelResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._ListMultipartUploadResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._ListMultipartUploadResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._ListMultipartUploadResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._ListObjectsResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._ListObjectsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._ListObjectsResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._ListPartsResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._ListPartsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._ListPartsResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._PutLiveChannelResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._PutLiveChannelResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._PutLiveChannelResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._PutSetDeleteResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._PutSetDeleteResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._PutSetDeleteResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._Result.php b/addons/alioss/__MACOSX/library/OSS/Result/._Result.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._Result.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._SymlinkResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._SymlinkResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._SymlinkResult.php differ diff --git a/addons/alioss/__MACOSX/library/OSS/Result/._UploadPartResult.php b/addons/alioss/__MACOSX/library/OSS/Result/._UploadPartResult.php new file mode 100644 index 0000000000000000000000000000000000000000..04c39370dde3b2365e34cc8bc2b998361edf965a Binary files /dev/null and b/addons/alioss/__MACOSX/library/OSS/Result/._UploadPartResult.php differ diff --git a/addons/alioss/assets/js/spark.js b/addons/alioss/assets/js/spark.js new file mode 100644 index 0000000000000000000000000000000000000000..5a22f703dcaaae60b2b165bee5031e72f42f2c58 --- /dev/null +++ b/addons/alioss/assets/js/spark.js @@ -0,0 +1 @@ +(function(factory){if(typeof exports==="object"){module.exports=factory()}else if(typeof define==="function"&&define.amd){define(factory)}else{var glob;try{glob=window}catch(e){glob=self}glob.SparkMD5=factory()}})(function(undefined){"use strict";var add32=function(a,b){return a+b&4294967295},hex_chr=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function cmn(q,a,b,x,s,t){a=add32(add32(a,q),add32(x,t));return add32(a<>>32-s,b)}function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a+=(b&c|~b&d)+k[0]-680876936|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[1]-389564586|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[2]+606105819|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[3]-1044525330|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[4]-176418897|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[5]+1200080426|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[6]-1473231341|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[7]-45705983|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[8]+1770035416|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[9]-1958414417|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[10]-42063|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[11]-1990404162|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[12]+1804603682|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[13]-40341101|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[14]-1502002290|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[15]+1236535329|0;b=(b<<22|b>>>10)+c|0;a+=(b&d|c&~d)+k[1]-165796510|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[6]-1069501632|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[11]+643717713|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[0]-373897302|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[5]-701558691|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[10]+38016083|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[15]-660478335|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[4]-405537848|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[9]+568446438|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[14]-1019803690|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[3]-187363961|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[8]+1163531501|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[13]-1444681467|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[2]-51403784|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[7]+1735328473|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[12]-1926607734|0;b=(b<<20|b>>>12)+c|0;a+=(b^c^d)+k[5]-378558|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[8]-2022574463|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[11]+1839030562|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[14]-35309556|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[1]-1530992060|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[4]+1272893353|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[7]-155497632|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[10]-1094730640|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[13]+681279174|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[0]-358537222|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[3]-722521979|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[6]+76029189|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[9]-640364487|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[12]-421815835|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[15]+530742520|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[2]-995338651|0;b=(b<<23|b>>>9)+c|0;a+=(c^(b|~d))+k[0]-198630844|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[7]+1126891415|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[14]-1416354905|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[5]-57434055|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[12]+1700485571|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[3]-1894986606|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[10]-1051523|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[1]-2054922799|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[8]+1873313359|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[15]-30611744|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[6]-1560198380|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[13]+1309151649|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[4]-145523070|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[11]-1120210379|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[2]+718787259|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[9]-343485551|0;b=(b<<21|b>>>11)+c|0;x[0]=a+x[0]|0;x[1]=b+x[1]|0;x[2]=c+x[2]|0;x[3]=d+x[3]|0}function md5blk(s){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24)}return md5blks}function md5blk_array(a){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=a[i]+(a[i+1]<<8)+(a[i+2]<<16)+(a[i+3]<<24)}return md5blks}function md51(s){var n=s.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk(s.substring(i-64,i)))}s=s.substring(i-64);length=s.length;tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function md51_array(a){var n=a.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk_array(a.subarray(i-64,i)))}a=i-64>2]|=a[i]<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function rhex(n){var s="",j;for(j=0;j<4;j+=1){s+=hex_chr[n>>j*8+4&15]+hex_chr[n>>j*8&15]}return s}function hex(x){var i;for(i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}}if(typeof ArrayBuffer!=="undefined"&&!ArrayBuffer.prototype.slice){(function(){function clamp(val,length){val=val|0||0;if(val<0){return Math.max(val+length,0)}return Math.min(val,length)}ArrayBuffer.prototype.slice=function(from,to){var length=this.byteLength,begin=clamp(from,length),end=length,num,target,targetArray,sourceArray;if(to!==undefined){end=clamp(to,length)}if(begin>end){return new ArrayBuffer(0)}num=end-begin;target=new ArrayBuffer(num);targetArray=new Uint8Array(target);sourceArray=new Uint8Array(this,begin,num);targetArray.set(sourceArray);return target}})()}function toUtf8(str){if(/[\u0080-\uFFFF]/.test(str)){str=unescape(encodeURIComponent(str))}return str}function utf8Str2ArrayBuffer(str,returnUInt8Array){var length=str.length,buff=new ArrayBuffer(length),arr=new Uint8Array(buff),i;for(i=0;i>2]|=buff.charCodeAt(i)<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.prototype.reset=function(){this._buff="";this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}};SparkMD5.prototype.setState=function(state){this._buff=state.buff;this._length=state.length;this._hash=state.hash;return this};SparkMD5.prototype.destroy=function(){delete this._hash;delete this._buff;delete this._length};SparkMD5.prototype._finish=function(tail,length){var i=length,tmp,lo,hi;tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(this._hash,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=this._length*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(this._hash,tail)};SparkMD5.hash=function(str,raw){return SparkMD5.hashBinary(toUtf8(str),raw)};SparkMD5.hashBinary=function(content,raw){var hash=md51(content),ret=hex(hash);return raw?hexToBinaryString(ret):ret};SparkMD5.ArrayBuffer=function(){this.reset()};SparkMD5.ArrayBuffer.prototype.append=function(arr){var buff=concatenateArrayBuffers(this._buff.buffer,arr,true),length=buff.length,i;this._length+=arr.byteLength;for(i=64;i<=length;i+=64){md5cycle(this._hash,md5blk_array(buff.subarray(i-64,i)))}this._buff=i-64>2]|=buff[i]<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.ArrayBuffer.prototype.reset=function(){this._buff=new Uint8Array(0);this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.ArrayBuffer.prototype.getState=function(){var state=SparkMD5.prototype.getState.call(this);state.buff=arrayBuffer2Utf8Str(state.buff);return state};SparkMD5.ArrayBuffer.prototype.setState=function(state){state.buff=utf8Str2ArrayBuffer(state.buff,true);return SparkMD5.prototype.setState.call(this,state)};SparkMD5.ArrayBuffer.prototype.destroy=SparkMD5.prototype.destroy;SparkMD5.ArrayBuffer.prototype._finish=SparkMD5.prototype._finish;SparkMD5.ArrayBuffer.hash=function(arr,raw){var hash=md51_array(new Uint8Array(arr)),ret=hex(hash);return raw?hexToBinaryString(ret):ret};return SparkMD5}); diff --git a/addons/alioss/bootstrap.js b/addons/alioss/bootstrap.js new file mode 100644 index 0000000000000000000000000000000000000000..bbafc44856e38cae25f560fa74980682eebfd7aa --- /dev/null +++ b/addons/alioss/bootstrap.js @@ -0,0 +1,104 @@ +//如果开启了alioss客户端上传模式 +if (typeof Config.upload.storage !== 'undefined' && Config.upload.storage === 'alioss') { + require(['upload', '../addons/alioss/js/spark'], function (Upload, SparkMD5) { + var _onFileAdded = Upload.events.onFileAdded; + var _onUploadResponse = Upload.events.onUploadResponse; + var getFileMd5 = function (file, cb) { + var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice, + file = file.getNative(), + chunkSize = 2097152, // Read in chunks of 2MB + chunks = Math.ceil(file.size / chunkSize), + currentChunk = 0, + spark = new SparkMD5.ArrayBuffer(), + fileReader = new FileReader(); + + fileReader.onload = function (e) { + spark.append(e.target.result); // Append array buffer + currentChunk++; + if (currentChunk < chunks) { + loadNext(); + } else { + cb && cb(spark.end()); // Compute hash + } + }; + + fileReader.onerror = function () { + console.warn('oops, something went wrong.'); + }; + + function loadNext() { + var start = currentChunk * chunkSize, + end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize; + + fileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); + } + + loadNext(); + }; + var _process = function (up, file) { + (function (up, file) { + getFileMd5(file, function (md5) { + Fast.api.ajax({ + url: "/addons/alioss/index/params", + data: {method: 'POST', md5: md5, name: file.name, type: file.type, size: file.size}, + }, function (data) { + file.md5 = md5; + file.status = 1; + file.key = data.key; + file.OSSAccessKeyId = data.id; + file.policy = data.policy; + file.signature = data.signature; + up.start(); + return false; + }); + }); + })(up, file); + }; + Upload.events.onFileAdded = function (up, files) { + return _onFileAdded.call(this, up, files); + }; + Upload.events.onBeforeUpload = function (up, file) { + if (typeof file.md5 === 'undefined') { + up.stop(); + _process(up, file); + } else { + up.settings.headers = up.settings.headers || {}; + up.settings.multipart_params.key = file.key; + up.settings.multipart_params.OSSAccessKeyId = file.OSSAccessKeyId; + up.settings.multipart_params.success_action_status = 200; + if (typeof file.callback !== 'undefined') { + up.settings.multipart_params.callback = file.callback; + } + up.settings.multipart_params.policy = file.policy; + up.settings.multipart_params.signature = file.signature; + //up.settings.send_file_name = false; + } + }; + Upload.events.onUploadResponse = function (response, info, up, file) { + try { + var ret = {}; + if (info.status === 200) { + var url = '/' + file.key; + Fast.api.ajax({ + url: "/addons/alioss/index/notify", + data: {method: 'POST', name: file.name, url: url, md5: file.md5, size: file.size, type: file.type, policy: file.policy, signature: file.signature} + }, function () { + return false; + }); + ret.code = 1; + ret.data = { + url: url + }; + } else { + ret.code = 0; + ret.msg = info.response; + } + return _onUploadResponse.call(this, JSON.stringify(ret)); + + } catch (e) { + } + return _onUploadResponse.call(this, response); + + }; + }); +} \ No newline at end of file diff --git a/addons/alioss/config.php b/addons/alioss/config.php new file mode 100644 index 0000000000000000000000000000000000000000..9f0a5a63d4ea3c1ad1895caebba64814a3b4d71e --- /dev/null +++ b/addons/alioss/config.php @@ -0,0 +1,176 @@ + 'app_id', + 'title' => 'app_id', + 'type' => 'string', + 'content' => + array(), + 'value' => 'your app id', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'app_key', + 'title' => 'app_key', + 'type' => 'string', + 'content' => + array(), + 'value' => 'your app key', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'bucket', + 'title' => 'Bucket', + 'type' => 'string', + 'content' => + array(), + 'value' => 'yourbucket', + 'rule' => 'required', + 'msg' => '', + 'tip' => '阿里云OSS的空间名', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'endpoint', + 'title' => 'EndPoint', + 'type' => 'string', + 'content' => + array(), + 'value' => 'oss-cn-shenzhen.aliyuncs.com', + 'rule' => 'required', + 'msg' => '', + 'tip' => '如果是服务器中转模式,可填写内网域名,前面不可加http://', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'cdnurl', + 'title' => 'CDN地址', + 'type' => 'string', + 'content' => + array(), + 'value' => 'http://yourbucket.oss-cn-shenzhen.aliyuncs.com', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请填写CDN地址,必须以http://开头', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'uploadmode', + 'title' => '上传模式', + 'type' => 'select', + 'content' => + array( + 'client' => '客户端直传(速度快,无备份)', + 'server' => '服务器中转(占用服务器带宽,有备份)', + ), + 'value' => 'server', + 'rule' => '', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'savekey', + 'title' => '保存文件名', + 'type' => 'string', + 'content' => + array(), + 'value' => '/uploads/{year}{mon}{day}/{filemd5}{.suffix}', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'expire', + 'title' => '上传有效时长', + 'type' => 'string', + 'content' => + array(), + 'value' => '600', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'maxsize', + 'title' => '最大可上传', + 'type' => 'string', + 'content' => + array(), + 'value' => '10M', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'mimetype', + 'title' => '可上传后缀格式', + 'type' => 'string', + 'content' => + array(), + 'value' => '*', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'multiple', + 'title' => '多文件上传', + 'type' => 'bool', + 'content' => + array(), + 'value' => '0', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'syncdelete', + 'title' => '附件删除时是否同步删除文件', + 'type' => 'bool', + 'content' => + array(), + 'value' => '0', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => '__tips__', + 'title' => '温馨提示', + 'type' => '', + 'content' => + array(), + 'value' => '在使用之前请注册阿里云账号并进行认证和创建空间,注册链接:https://oss.console.aliyun.com/index
FastAdmin赠送你阿里云最高1888云产品通用代金券,如有需要可以点击领取', + 'rule' => '', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), +); diff --git a/addons/alioss/controller/Index.php b/addons/alioss/controller/Index.php new file mode 100644 index 0000000000000000000000000000000000000000..14f59442c36188b29149f85abddfbdbe40107c2d --- /dev/null +++ b/addons/alioss/controller/Index.php @@ -0,0 +1,188 @@ +error("当前插件暂无前台页面"); + } + + /** + * 获取签名 + */ + public function params() + { + Config::set('default_return_type', 'json'); + + $name = $this->request->post('name'); + $md5 = $this->request->post('md5'); + $auth = new \addons\alioss\library\Auth(); + $params = $auth->params($name, $md5); + $this->success('', null, $params); + return; + } + + /** + * 服务器中转上传文件 + */ + public function upload() + { + Config::set('default_return_type', 'json'); + if (!session('admin') && !$this->auth->id) { + $this->error("请登录后再进行操作"); + } + $config = get_addon_config('alioss'); + + $endpoint = "http://" . $config['endpoint']; + + $file = $this->request->file('file'); + if (!$file || !$file->isValid()) { + $this->error("请上传有效的文件"); + } + $fileInfo = $file->getInfo(); + + $filePath = $file->getRealPath() ?: $file->getPathname(); + + preg_match('/(\d+)(\w+)/', $config['maxsize'], $matches); + $type = strtolower($matches[2]); + $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3]; + $size = (int)$config['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0); + + $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION)); + $suffix = $suffix ? $suffix : 'file'; + + $md5 = md5_file($filePath); + $search = ['{year}', '{mon}', '{month}', '{day}', '{filemd5}', '{suffix}', '{.suffix}']; + $replace = [date("Y"), date("m"), date("m"), date("d"), $md5, $suffix, '.' . $suffix]; + $object = ltrim(str_replace($search, $replace, $config['savekey']), '/'); + + $mimetypeArr = explode(',', strtolower($config['mimetype'])); + $typeArr = explode('/', $fileInfo['type']); + + //检查文件大小 + if (!$file->checkSize($size)) { + $this->error("起过最大可上传文件限制"); + } + + //验证文件后缀 + if ($config['mimetype'] !== '*' && + ( + !in_array($suffix, $mimetypeArr) + || (stripos($typeArr[0] . '/', $config['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr))) + ) + ) { + $this->error(__('上传格式限制')); + } + + $savekey = '/' . $object; + + $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1); + $fileName = substr($savekey, strripos($savekey, '/') + 1); + //先上传到本地 + $splInfo = $file->move(ROOT_PATH . '/public' . $uploadDir, $fileName); + if ($splInfo) { + $extparam = $this->request->post(); + $filePath = $splInfo->getRealPath() ?: $splInfo->getPathname(); + + $sha1 = sha1_file($filePath); + $imagewidth = $imageheight = 0; + if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'])) { + $imgInfo = getimagesize($splInfo->getPathname()); + $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth; + $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight; + } + $params = array( + 'admin_id' => session('admin.id'), + 'user_id' => $this->auth->id, + 'filesize' => $fileInfo['size'], + 'imagewidth' => $imagewidth, + 'imageheight' => $imageheight, + 'imagetype' => $suffix, + 'imageframes' => 0, + 'mimetype' => $fileInfo['type'], + 'url' => $uploadDir . $splInfo->getSaveName(), + 'uploadtime' => time(), + 'storage' => 'local', + 'sha1' => $sha1, + 'extparam' => json_encode($extparam), + ); + $attachment = new Attachment; + $attachment->data(array_filter($params)); + $attachment->save(); + + //上传到远程 + try { + $ossClient = new OssClient($config['app_id'], $config['app_key'], $endpoint); + $ossClient->uploadFile($config['bucket'], $object, $filePath); + } catch (OssException $e) { + $this->error('上传失败'); + return; + } + $url = '/' . $object; + + //上传成功后将存储变更为alioss + $attachment->storage = 'alioss'; + $attachment->save(); + + $this->success("上传成功", null, ['url' => $url]); + } else { + $this->error('上传失败'); + } + return; + } + + /** + * 回调 + */ + public function notify() + { + Config::set('default_return_type', 'json'); + $size = $this->request->post('size'); + $name = $this->request->post('name'); + $md5 = $this->request->post('md5'); + $type = $this->request->post('type'); + $signature = $this->request->post('signature'); + $policy = $this->request->post('policy'); + $url = $this->request->post('url'); + $suffix = substr($name, stripos($name, '.') + 1); + $auth = new \addons\alioss\library\Auth(); + if ($auth->check($signature, $policy)) { + $attachment = Attachment::getBySha1($md5); + if (!$attachment) { + $params = array( + 'admin_id' => (int)session('admin.id'), + 'user_id' => (int)cookie('uid'), + 'filesize' => $size, + 'imagewidth' => 0, + 'imageheight' => 0, + 'imagetype' => $suffix, + 'imageframes' => 0, + 'mimetype' => $type, + 'url' => $url, + 'uploadtime' => time(), + 'storage' => 'alioss', + 'sha1' => $md5, + ); + Attachment::create($params); + } + $this->success(); + } else { + $this->error(__('You have no permission')); + } + return; + } + +} diff --git a/addons/alioss/info.ini b/addons/alioss/info.ini new file mode 100644 index 0000000000000000000000000000000000000000..6d53a1d381c9dc6b041ea78fd489eef45ca90aeb --- /dev/null +++ b/addons/alioss/info.ini @@ -0,0 +1,8 @@ +name = alioss +title = 阿里OSS上传 +intro = 使用阿里OSS存储,上传时直传阿里云OSS +author = Karson +website = http://www.fastadmin.net +version = 1.0.3 +state = 1 +url = /fastadmin/my/public/addons/alioss diff --git a/addons/alioss/library/Auth.php b/addons/alioss/library/Auth.php new file mode 100644 index 0000000000000000000000000000000000000000..1235db2406f07c74b404b83013a09c4a22b3b74c --- /dev/null +++ b/addons/alioss/library/Auth.php @@ -0,0 +1,78 @@ + isset($config['notifyurl']) ? $config['notifyurl'] : '', + 'callbackBody' => 'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}', + 'callbackBodyType' => "application/x-www-form-urlencoded" + ); + + $base64_callback_body = base64_encode(json_encode($callback_param)); + + $now = time(); + $end = $now + $config['expire']; //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问 + $expiration = $this->gmt_iso8601($end); + + preg_match('/(\d+)(\w+)/', $config['maxsize'], $matches); + $type = strtolower($matches[2]); + $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3]; + $size = (int)$config['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0); + + //最大文件大小.用户可以自己设置 + $condition = array(0 => 'content-length-range', 1 => 0, 2 => $size); + $conditions[] = $condition; + + //表示用户上传的数据,必须是以$dir开始, 不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录 + //$start = array(0 => 'starts-with', 1 => '$key', 2 => $dir); + //$conditions[] = $start; + + $arr = array('expiration' => $expiration, 'conditions' => $conditions); + + $policy = base64_encode(json_encode($arr)); + $signature = base64_encode(hash_hmac('sha1', $policy, $config['app_key'], true)); + + $suffix = substr($name, stripos($name, '.') + 1); + $search = ['{year}', '{mon}', '{month}', '{day}', '{filemd5}', '{suffix}', '{.suffix}']; + $replace = [date("Y"), date("m"), date("m"), date("d"), $md5, $suffix, '.' . $suffix]; + $key = ltrim(str_replace($search, $replace, $config['savekey']), '/'); + + $response = array(); + $response['id'] = $config['app_id']; + $response['key'] = $key; + $response['policy'] = $policy; + $response['signature'] = $signature; + $response['expire'] = $end; + $response['callback'] = ''; + return $response; + } + + public function check($signature, $policy) + { + $config = get_addon_config('alioss'); + $sign = base64_encode(hash_hmac('sha1', $policy, $config['app_key'], true)); + return $signature == $sign; + } + + private function gmt_iso8601($time) + { + $dtStr = date("c", $time); + $mydatetime = new \DateTime($dtStr); + $expiration = $mydatetime->format(\DateTime::ISO8601); + $pos = strpos($expiration, '+'); + $expiration = substr($expiration, 0, $pos); + return $expiration . "Z"; + } + +} diff --git a/addons/alioss/library/OSS/Core/MimeTypes.php b/addons/alioss/library/OSS/Core/MimeTypes.php new file mode 100644 index 0000000000000000000000000000000000000000..e9b88ffa86b2fb11dd18fbe272e2461b6aba1d9f --- /dev/null +++ b/addons/alioss/library/OSS/Core/MimeTypes.php @@ -0,0 +1,262 @@ + 1) { + $ext = strtolower(end($parts)); + if (isset(self::$mime_types[$ext])) { + return self::$mime_types[$ext]; + } + } + + return null; + } + + private static $mime_types = array( + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'apk' => 'application/vnd.android.package-archive', + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'doc' => 'application/msword', + 'ogg' => 'audio/ogg', + 'pdf' => 'application/pdf', + 'rtf' => 'text/rtf', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'sxw' => 'application/vnd.sun.xml.writer', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'sxc' => 'application/vnd.sun.xml.calc', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'sxd' => 'application/vnd.sun.xml.draw', + 'std' => 'application/vnd.sun.xml.draw.template', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'sxm' => 'application/vnd.sun.xml.math', + 'sis' => 'application/vnd.symbian.install', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'bcpio' => 'application/x-bcpio', + 'torrent' => 'application/x-bittorrent', + 'bz2' => 'application/x-bzip2', + 'vcd' => 'application/x-cdlink', + 'pgn' => 'application/x-chess-pgn', + 'cpio' => 'application/x-cpio', + 'csh' => 'application/x-csh', + 'dvi' => 'application/x-dvi', + 'spl' => 'application/x-futuresplash', + 'gtar' => 'application/x-gtar', + 'hdf' => 'application/x-hdf', + 'jar' => 'application/java-archive', + 'jnlp' => 'application/x-java-jnlp-file', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'ksp' => 'application/x-kspread', + 'chrt' => 'application/x-kchart', + 'kil' => 'application/x-killustrator', + 'latex' => 'application/x-latex', + 'rpm' => 'application/x-rpm', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'tar' => 'application/x-tar', + 'tcl' => 'application/x-tcl', + 'tex' => 'application/x-tex', + 'man' => 'application/x-troff-man', + 'me' => 'application/x-troff-me', + 'ms' => 'application/x-troff-ms', + 'ustar' => 'application/x-ustar', + 'src' => 'application/x-wais-source', + 'zip' => 'application/zip', + 'm3u' => 'audio/x-mpegurl', + 'ra' => 'audio/x-pn-realaudio', + 'wav' => 'audio/x-wav', + 'wma' => 'audio/x-ms-wma', + 'wax' => 'audio/x-ms-wax', + 'pdb' => 'chemical/x-pdb', + 'xyz' => 'chemical/x-xyz', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'ief' => 'image/ief', + 'png' => 'image/png', + 'wbmp' => 'image/vnd.wap.wbmp', + 'ras' => 'image/x-cmu-raster', + 'pnm' => 'image/x-portable-anymap', + 'pbm' => 'image/x-portable-bitmap', + 'pgm' => 'image/x-portable-graymap', + 'ppm' => 'image/x-portable-pixmap', + 'rgb' => 'image/x-rgb', + 'xbm' => 'image/x-xbitmap', + 'xpm' => 'image/x-xpixmap', + 'xwd' => 'image/x-xwindowdump', + 'css' => 'text/css', + 'rtx' => 'text/richtext', + 'tsv' => 'text/tab-separated-values', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'wml' => 'text/vnd.wap.wml', + 'wmls' => 'text/vnd.wap.wmlscript', + 'etx' => 'text/x-setext', + 'mxu' => 'video/vnd.mpegurl', + 'flv' => 'video/x-flv', + 'wm' => 'video/x-ms-wm', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wvx' => 'video/x-ms-wvx', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'ice' => 'x-conference/x-cooltalk', + '3gp' => 'video/3gpp', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'asc' => 'text/plain', + 'atom' => 'application/atom+xml', + 'au' => 'audio/basic', + 'bin' => 'application/octet-stream', + 'cdf' => 'application/x-netcdf', + 'cgm' => 'image/cgm', + 'class' => 'application/octet-stream', + 'dcr' => 'application/x-director', + 'dif' => 'video/x-dv', + 'dir' => 'application/x-director', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/octet-stream', + 'dmg' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'dtd' => 'application/xml-dtd', + 'dv' => 'video/x-dv', + 'dxr' => 'application/x-director', + 'eps' => 'application/postscript', + 'exe' => 'application/octet-stream', + 'ez' => 'application/andrew-inset', + 'gram' => 'application/srgs', + 'grxml' => 'application/srgs+xml', + 'gz' => 'application/x-gzip', + 'htm' => 'text/html', + 'html' => 'text/html', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ifb' => 'text/calendar', + 'iges' => 'model/iges', + 'igs' => 'model/iges', + 'jp2' => 'image/jp2', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'kar' => 'audio/midi', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'm4a' => 'audio/mp4a-latm', + 'm4p' => 'audio/mp4a-latm', + 'm4u' => 'video/vnd.mpegurl', + 'm4v' => 'video/x-m4v', + 'mac' => 'image/x-macpaint', + 'mathml' => 'application/mathml+xml', + 'mesh' => 'model/mesh', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mov' => 'video/quicktime', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpga' => 'audio/mpeg', + 'msh' => 'model/mesh', + 'nc' => 'application/x-netcdf', + 'oda' => 'application/oda', + 'ogv' => 'video/ogv', + 'pct' => 'image/pict', + 'pic' => 'image/pict', + 'pict' => 'image/pict', + 'pnt' => 'image/x-macpaint', + 'pntg' => 'image/x-macpaint', + 'ps' => 'application/postscript', + 'qt' => 'video/quicktime', + 'qti' => 'image/x-quicktime', + 'qtif' => 'image/x-quicktime', + 'ram' => 'audio/x-pn-realaudio', + 'rdf' => 'application/rdf+xml', + 'rm' => 'application/vnd.rn-realmedia', + 'roff' => 'application/x-troff', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'silo' => 'model/mesh', + 'skd' => 'application/x-koan', + 'skm' => 'application/x-koan', + 'skp' => 'application/x-koan', + 'skt' => 'application/x-koan', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'snd' => 'audio/basic', + 'so' => 'application/octet-stream', + 'svg' => 'image/svg+xml', + 't' => 'application/x-troff', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tr' => 'application/x-troff', + 'txt' => 'text/plain', + 'vrml' => 'model/vrml', + 'vxml' => 'application/voicexml+xml', + 'webm' => 'video/webm', + 'webp' => 'image/webp', + 'wrl' => 'model/vrml', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xml' => 'application/xml', + 'xsl' => 'application/xml', + 'xslt' => 'application/xslt+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + ); +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Core/OssException.php b/addons/alioss/library/OSS/Core/OssException.php new file mode 100644 index 0000000000000000000000000000000000000000..b0e9e8b0d1e097d49e2aa34f039e948b308c5c27 --- /dev/null +++ b/addons/alioss/library/OSS/Core/OssException.php @@ -0,0 +1,54 @@ +details = $details; + } else { + $message = $details; + parent::__construct($message); + } + } + + public function getHTTPStatus() + { + return isset($this->details['status']) ? $this->details['status'] : ''; + } + + public function getRequestId() + { + return isset($this->details['request-id']) ? $this->details['request-id'] : ''; + } + + public function getErrorCode() + { + return isset($this->details['code']) ? $this->details['code'] : ''; + } + + public function getErrorMessage() + { + return isset($this->details['message']) ? $this->details['message'] : ''; + } + + public function getDetails() + { + return isset($this->details['body']) ? $this->details['body'] : ''; + } +} diff --git a/addons/alioss/library/OSS/Core/OssUtil.php b/addons/alioss/library/OSS/Core/OssUtil.php new file mode 100644 index 0000000000000000000000000000000000000000..6e5d4133dcdbbbfbd3d80a14f090536a09f33947 --- /dev/null +++ b/addons/alioss/library/OSS/Core/OssUtil.php @@ -0,0 +1,461 @@ + $value) { + if (is_string($key) && !is_array($value)) { + $temp[] = rawurlencode($key) . '=' . rawurlencode($value); + } + } + return implode('&', $temp); + } + + /** + * 转义字符替换 + * + * @param string $subject + * @return string + */ + public static function sReplace($subject) + { + $search = array('<', '>', '&', '\'', '"'); + $replace = array('<', '>', '&', ''', '"'); + return str_replace($search, $replace, $subject); + } + + /** + * 检查是否是中文编码 + * + * @param $str + * @return int + */ + public static function chkChinese($str) + { + return preg_match('/[\x80-\xff]./', $str); + } + + /** + * 检测是否GB2312编码 + * + * @param string $str + * @return boolean false UTF-8编码 TRUE GB2312编码 + */ + public static function isGb2312($str) + { + for ($i = 0; $i < strlen($str); $i++) { + $v = ord($str[$i]); + if ($v > 127) { + if (($v >= 228) && ($v <= 233)) { + if (($i + 2) >= (strlen($str) - 1)) return true; // not enough characters + $v1 = ord($str[$i + 1]); + $v2 = ord($str[$i + 2]); + if (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) + return false; + else + return true; + } + } + } + return false; + } + + /** + * 检测是否GBK编码 + * + * @param string $str + * @param boolean $gbk + * @return boolean + */ + public static function checkChar($str, $gbk = true) + { + for ($i = 0; $i < strlen($str); $i++) { + $v = ord($str[$i]); + if ($v > 127) { + if (($v >= 228) && ($v <= 233)) { + if (($i + 2) >= (strlen($str) - 1)) return $gbk ? true : FALSE; // not enough characters + $v1 = ord($str[$i + 1]); + $v2 = ord($str[$i + 2]); + if ($gbk) { + return (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) ? FALSE : TRUE;//GBK + } else { + return (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) ? TRUE : FALSE; + } + } + } + } + return $gbk ? TRUE : FALSE; + } + + /** + * 检验bucket名称是否合法 + * bucket的命名规范: + * 1. 只能包括小写字母,数字 + * 2. 必须以小写字母或者数字开头 + * 3. 长度必须在3-63字节之间 + * + * @param string $bucket Bucket名称 + * @return boolean + */ + public static function validateBucket($bucket) + { + $pattern = '/^[a-z0-9][a-z0-9-]{2,62}$/'; + if (!preg_match($pattern, $bucket)) { + return false; + } + return true; + } + + /** + * 检验object名称是否合法 + * object命名规范: + * 1. 规则长度必须在1-1023字节之间 + * 2. 使用UTF-8编码 + * 3. 不能以 "/" "\\"开头 + * + * @param string $object Object名称 + * @return boolean + */ + public static function validateObject($object) + { + $pattern = '/^.{1,1023}$/'; + if (empty($object) || !preg_match($pattern, $object) || + self::startsWith($object, '/') || self::startsWith($object, '\\') + ) { + return false; + } + return true; + } + + + /** + * 判断字符串$str是不是以$findMe开始 + * + * @param string $str + * @param string $findMe + * @return bool + */ + public static function startsWith($str, $findMe) + { + if (strpos($str, $findMe) === 0) { + return true; + } else { + return false; + } + } + + /** + * 生成createBucketXmlBody接口的xml消息 + * + * @param string $storageClass + * @return string + */ + public static function createBucketXmlBody($storageClass) + { + $xml = new \SimpleXMLElement(''); + $xml->addChild('StorageClass', $storageClass); + return $xml->asXML(); + } + + /** + * 检验$options + * + * @param array $options + * @throws OssException + * @return boolean + */ + public static function validateOptions($options) + { + //$options + if ($options != NULL && !is_array($options)) { + throw new OssException ($options . ':' . 'option must be array'); + } + } + + /** + * 检查上传文件的内容是否合法 + * + * @param $content string + * @throws OssException + */ + public static function validateContent($content) + { + if (empty($content)) { + throw new OssException("http body content is invalid"); + } + } + + /** + * 校验BUCKET/OBJECT/OBJECT GROUP是否为空 + * + * @param string $name + * @param string $errMsg + * @throws OssException + * @return void + */ + public static function throwOssExceptionWithMessageIfEmpty($name, $errMsg) + { + if (empty($name)) { + throw new OssException($errMsg); + } + } + + /** + * 仅供测试使用的接口,请勿使用 + * + * @param $filename + * @param $size + */ + public static function generateFile($filename, $size) + { + if (file_exists($filename) && $size == filesize($filename)) { + echo $filename . " already exists, no need to create again. "; + return; + } + $part_size = 1 * 1024 * 1024; + $fp = fopen($filename, "w"); + $characters = << 0) { + if ($size < $part_size) { + $write_size = $size; + } else { + $write_size = $part_size; + } + $size -= $write_size; + $a = $characters[rand(0, $charactersLength - 1)]; + $content = str_repeat($a, $write_size); + $flag = fwrite($fp, $content); + if (!$flag) { + echo "write to " . $filename . " failed.
"; + break; + } + } + } else { + echo "open " . $filename . " failed.
"; + } + fclose($fp); + } + + /** + * 得到文件的md5编码 + * + * @param $filename + * @param $from_pos + * @param $to_pos + * @return string + */ + public static function getMd5SumForFile($filename, $from_pos, $to_pos) + { + $content_md5 = ""; + if (($to_pos - $from_pos) > self::OSS_MAX_PART_SIZE) { + return $content_md5; + } + $filesize = filesize($filename); + if ($from_pos >= $filesize || $to_pos >= $filesize || $from_pos < 0 || $to_pos < 0) { + return $content_md5; + } + + $total_length = $to_pos - $from_pos + 1; + $buffer = 8192; + $left_length = $total_length; + if (!file_exists($filename)) { + return $content_md5; + } + + if (false === $fh = fopen($filename, 'rb')) { + return $content_md5; + } + + fseek($fh, $from_pos); + $data = ''; + while (!feof($fh)) { + if ($left_length >= $buffer) { + $read_length = $buffer; + } else { + $read_length = $left_length; + } + if ($read_length <= 0) { + break; + } else { + $data .= fread($fh, $read_length); + $left_length = $left_length - $read_length; + } + } + fclose($fh); + $content_md5 = base64_encode(md5($data, true)); + return $content_md5; + } + + /** + * 检测是否windows系统,因为windows系统默认编码为GBK + * + * @return bool + */ + public static function isWin() + { + return strtoupper(substr(PHP_OS, 0, 3)) == "WIN"; + } + + /** + * 主要是由于windows系统编码是gbk,遇到中文时候,如果不进行转换处理会出现找不到文件的问题 + * + * @param $file_path + * @return string + */ + public static function encodePath($file_path) + { + if (self::chkChinese($file_path) && self::isWin()) { + $file_path = iconv('utf-8', 'gbk', $file_path); + } + return $file_path; + } + + /** + * 判断用户输入的endpoint是否是 xxx.xxx.xxx.xxx:port 或者 xxx.xxx.xxx.xxx的ip格式 + * + * @param string $endpoint 需要做判断的endpoint + * @return boolean + */ + public static function isIPFormat($endpoint) + { + $ip_array = explode(":", $endpoint); + $hostname = $ip_array[0]; + $ret = filter_var($hostname, FILTER_VALIDATE_IP); + if (!$ret) { + return false; + } else { + return true; + } + } + + /** + * 生成DeleteMultiObjects接口的xml消息 + * + * @param string[] $objects + * @param bool $quiet + * @return string + */ + public static function createDeleteObjectsXmlBody($objects, $quiet) + { + $xml = new \SimpleXMLElement(''); + $xml->addChild('Quiet', $quiet); + foreach ($objects as $object) { + $sub_object = $xml->addChild('Object'); + $object = OssUtil::sReplace($object); + $sub_object->addChild('Key', $object); + } + return $xml->asXML(); + } + + /** + * 生成CompleteMultipartUpload接口的xml消息 + * + * @param array[] $listParts + * @return string + */ + public static function createCompleteMultipartUploadXmlBody($listParts) + { + $xml = new \SimpleXMLElement(''); + foreach ($listParts as $node) { + $part = $xml->addChild('Part'); + $part->addChild('PartNumber', $node['PartNumber']); + $part->addChild('ETag', $node['ETag']); + } + return $xml->asXML(); + } + + /** + * 读取目录 + * + * @param string $dir + * @param string $exclude + * @param bool $recursive + * @return string[] + */ + public static function readDir($dir, $exclude = ".|..|.svn|.git", $recursive = false) + { + $file_list_array = array(); + $base_path = $dir; + $exclude_array = explode("|", $exclude); + $exclude_array = array_unique(array_merge($exclude_array, array('.', '..'))); + + if ($recursive) { + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)) as $new_file) { + if ($new_file->isDir()) continue; + $object = str_replace($base_path, '', $new_file); + if (!in_array(strtolower($object), $exclude_array)) { + $object = ltrim($object, '/'); + if (is_file($new_file)) { + $key = md5($new_file . $object, false); + $file_list_array[$key] = array('path' => $new_file, 'file' => $object,); + } + } + } + } else if ($handle = opendir($dir)) { + while (false !== ($file = readdir($handle))) { + if (!in_array(strtolower($file), $exclude_array)) { + $new_file = $dir . '/' . $file; + $object = $file; + $object = ltrim($object, '/'); + if (is_file($new_file)) { + $key = md5($new_file . $object, false); + $file_list_array[$key] = array('path' => $new_file, 'file' => $object,); + } + } + } + closedir($handle); + } + return $file_list_array; + } + + /** + * Decode key based on the encoding type + * + * @param string $key + * @param string $encoding + * @return string + */ + public static function decodeKey($key, $encoding) + { + if ($encoding == "") { + return $key; + } + + if ($encoding == "url") { + return rawurldecode($key); + } else { + throw new OssException("Unrecognized encoding type: " . $encoding); + } + } +} diff --git a/addons/alioss/library/OSS/Http/LICENSE b/addons/alioss/library/OSS/Http/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..49b38bd620ac6d804660351a60b6e37e80a691ac --- /dev/null +++ b/addons/alioss/library/OSS/Http/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2006-2010 Ryan Parman, Foleeo Inc., and contributors. 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 name of Ryan Parman, Foleeo Inc. 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 HOLDERS +AND 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. diff --git a/addons/alioss/library/OSS/Http/RequestCore.php b/addons/alioss/library/OSS/Http/RequestCore.php new file mode 100644 index 0000000000000000000000000000000000000000..06d0f87839f3579484ad619d3f7a95a487068107 --- /dev/null +++ b/addons/alioss/library/OSS/Http/RequestCore.php @@ -0,0 +1,896 @@ +). + */ + public $request_class = 'OSS\Http\RequestCore'; + + /** + * The default class to use for HTTP Responses (defaults to ). + */ + public $response_class = 'OSS\Http\ResponseCore'; + + /** + * Default useragent string to use. + */ + public $useragent = 'RequestCore/1.4.3'; + + /** + * File to read from while streaming up. + */ + public $read_file = null; + + /** + * The resource to read from while streaming up. + */ + public $read_stream = null; + + /** + * The size of the stream to read from. + */ + public $read_stream_size = null; + + /** + * The length already read from the stream. + */ + public $read_stream_read = 0; + + /** + * File to write to while streaming down. + */ + public $write_file = null; + + /** + * The resource to write to while streaming down. + */ + public $write_stream = null; + + /** + * Stores the intended starting seek position. + */ + public $seek_position = null; + + /** + * The location of the cacert.pem file to use. + */ + public $cacert_location = false; + + /** + * The state of SSL certificate verification. + */ + public $ssl_verification = true; + + /** + * The user-defined callback function to call when a stream is read from. + */ + public $registered_streaming_read_callback = null; + + /** + * The user-defined callback function to call when a stream is written to. + */ + public $registered_streaming_write_callback = null; + + /** + * 请求超时时间, 默认是5184000秒,6天 + * + * @var int + */ + public $timeout = 5184000; + + /** + * 连接超时时间,默认是10秒 + * + * @var int + */ + public $connect_timeout = 10; + + /*%******************************************************************************************%*/ + // CONSTANTS + + /** + * GET HTTP Method + */ + const HTTP_GET = 'GET'; + + /** + * POST HTTP Method + */ + const HTTP_POST = 'POST'; + + /** + * PUT HTTP Method + */ + const HTTP_PUT = 'PUT'; + + /** + * DELETE HTTP Method + */ + const HTTP_DELETE = 'DELETE'; + + /** + * HEAD HTTP Method + */ + const HTTP_HEAD = 'HEAD'; + + + /*%******************************************************************************************%*/ + // CONSTRUCTOR/DESTRUCTOR + + /** + * Constructs a new instance of this class. + * + * @param string $url (Optional) The URL to request or service endpoint to query. + * @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` + * @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class. + * @return $this A reference to the current instance. + */ + public function __construct($url = null, $proxy = null, $helpers = null) + { + // Set some default values. + $this->request_url = $url; + $this->method = self::HTTP_GET; + $this->request_headers = array(); + $this->request_body = ''; + + // Set a new Request class if one was set. + if (isset($helpers['request']) && !empty($helpers['request'])) { + $this->request_class = $helpers['request']; + } + + // Set a new Request class if one was set. + if (isset($helpers['response']) && !empty($helpers['response'])) { + $this->response_class = $helpers['response']; + } + + if ($proxy) { + $this->set_proxy($proxy); + } + + return $this; + } + + /** + * Destructs the instance. Closes opened file handles. + * + * @return $this A reference to the current instance. + */ + public function __destruct() + { + if (isset($this->read_file) && isset($this->read_stream)) { + fclose($this->read_stream); + } + + if (isset($this->write_file) && isset($this->write_stream)) { + fclose($this->write_stream); + } + + return $this; + } + + + /*%******************************************************************************************%*/ + // REQUEST METHODS + + /** + * Sets the credentials to use for authentication. + * + * @param string $user (Required) The username to authenticate with. + * @param string $pass (Required) The password to authenticate with. + * @return $this A reference to the current instance. + */ + public function set_credentials($user, $pass) + { + $this->username = $user; + $this->password = $pass; + return $this; + } + + /** + * Adds a custom HTTP header to the cURL request. + * + * @param string $key (Required) The custom HTTP header to set. + * @param mixed $value (Required) The value to assign to the custom HTTP header. + * @return $this A reference to the current instance. + */ + public function add_header($key, $value) + { + $this->request_headers[$key] = $value; + return $this; + } + + /** + * Removes an HTTP header from the cURL request. + * + * @param string $key (Required) The custom HTTP header to set. + * @return $this A reference to the current instance. + */ + public function remove_header($key) + { + if (isset($this->request_headers[$key])) { + unset($this->request_headers[$key]); + } + return $this; + } + + /** + * Set the method type for the request. + * + * @param string $method (Required) One of the following constants: , , , , . + * @return $this A reference to the current instance. + */ + public function set_method($method) + { + $this->method = strtoupper($method); + return $this; + } + + /** + * Sets a custom useragent string for the class. + * + * @param string $ua (Required) The useragent string to use. + * @return $this A reference to the current instance. + */ + public function set_useragent($ua) + { + $this->useragent = $ua; + return $this; + } + + /** + * Set the body to send in the request. + * + * @param string $body (Required) The textual content to send along in the body of the request. + * @return $this A reference to the current instance. + */ + public function set_body($body) + { + $this->request_body = $body; + return $this; + } + + /** + * Set the URL to make the request to. + * + * @param string $url (Required) The URL to make the request to. + * @return $this A reference to the current instance. + */ + public function set_request_url($url) + { + $this->request_url = $url; + return $this; + } + + /** + * Set additional CURLOPT settings. These will merge with the default settings, and override if + * there is a duplicate. + * + * @param array $curlopts (Optional) A set of key-value pairs that set `CURLOPT` options. These will merge with the existing CURLOPTs, and ones passed here will override the defaults. Keys should be the `CURLOPT_*` constants, not strings. + * @return $this A reference to the current instance. + */ + public function set_curlopts($curlopts) + { + $this->curlopts = $curlopts; + return $this; + } + + /** + * Sets the length in bytes to read from the stream while streaming up. + * + * @param integer $size (Required) The length in bytes to read from the stream. + * @return $this A reference to the current instance. + */ + public function set_read_stream_size($size) + { + $this->read_stream_size = $size; + + return $this; + } + + /** + * Sets the resource to read from while streaming up. Reads the stream from its current position until + * EOF or `$size` bytes have been read. If `$size` is not given it will be determined by and + * . + * + * @param resource $resource (Required) The readable resource to read from. + * @param integer $size (Optional) The size of the stream to read. + * @return $this A reference to the current instance. + */ + public function set_read_stream($resource, $size = null) + { + if (!isset($size) || $size < 0) { + $stats = fstat($resource); + + if ($stats && $stats['size'] >= 0) { + $position = ftell($resource); + + if ($position !== false && $position >= 0) { + $size = $stats['size'] - $position; + } + } + } + + $this->read_stream = $resource; + + return $this->set_read_stream_size($size); + } + + /** + * Sets the file to read from while streaming up. + * + * @param string $location (Required) The readable location to read from. + * @return $this A reference to the current instance. + */ + public function set_read_file($location) + { + $this->read_file = $location; + $read_file_handle = fopen($location, 'r'); + + return $this->set_read_stream($read_file_handle); + } + + /** + * Sets the resource to write to while streaming down. + * + * @param resource $resource (Required) The writeable resource to write to. + * @return $this A reference to the current instance. + */ + public function set_write_stream($resource) + { + $this->write_stream = $resource; + + return $this; + } + + /** + * Sets the file to write to while streaming down. + * + * @param string $location (Required) The writeable location to write to. + * @return $this A reference to the current instance. + */ + public function set_write_file($location) + { + $this->write_file = $location; + } + + /** + * Set the proxy to use for making requests. + * + * @param string $proxy (Required) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` + * @return $this A reference to the current instance. + */ + public function set_proxy($proxy) + { + $proxy = parse_url($proxy); + $proxy['user'] = isset($proxy['user']) ? $proxy['user'] : null; + $proxy['pass'] = isset($proxy['pass']) ? $proxy['pass'] : null; + $proxy['port'] = isset($proxy['port']) ? $proxy['port'] : null; + $this->proxy = $proxy; + return $this; + } + + /** + * Set the intended starting seek position. + * + * @param integer $position (Required) The byte-position of the stream to begin reading from. + * @return $this A reference to the current instance. + */ + public function set_seek_position($position) + { + $this->seek_position = isset($position) ? (integer)$position : null; + + return $this; + } + + /** + * A callback function that is invoked by cURL for streaming up. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param resource $header_content (Required) The header callback result. + * @return headers from a stream. + */ + public function streaming_header_callback($curl_handle, $header_content) + { + $code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); + + if (isset($this->write_file) && intval($code) / 100 == 2 && !isset($this->write_file_handle)) + { + $this->write_file_handle = fopen($this->write_file, 'w'); + $this->set_write_stream($this->write_file_handle); + } + + $this->response_raw_headers .= $header_content; + return strlen($header_content); + } + + + /** + * Register a callback function to execute whenever a data stream is read from using + * . + * + * The user-defined callback function should accept three arguments: + * + *
    + *
  • $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
  • + *
  • $file_handle - resource - Required - The file handle resource that represents the file on the local file system.
  • + *
  • $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
  • + *
+ * + * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
    + *
  • The name of a global function to execute, passed as a string.
  • + *
  • A method to execute, passed as array('ClassName', 'MethodName').
  • + *
  • An anonymous function (PHP 5.3+).
+ * @return $this A reference to the current instance. + */ + public function register_streaming_read_callback($callback) + { + $this->registered_streaming_read_callback = $callback; + + return $this; + } + + /** + * Register a callback function to execute whenever a data stream is written to using + * . + * + * The user-defined callback function should accept two arguments: + * + *
    + *
  • $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
  • + *
  • $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
  • + *
+ * + * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
    + *
  • The name of a global function to execute, passed as a string.
  • + *
  • A method to execute, passed as array('ClassName', 'MethodName').
  • + *
  • An anonymous function (PHP 5.3+).
+ * @return $this A reference to the current instance. + */ + public function register_streaming_write_callback($callback) + { + $this->registered_streaming_write_callback = $callback; + + return $this; + } + + + /*%******************************************************************************************%*/ + // PREPARE, SEND, AND PROCESS REQUEST + + /** + * A callback function that is invoked by cURL for streaming up. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param resource $file_handle (Required) The open file handle resource. + * @param integer $length (Required) The maximum number of bytes to read. + * @return binary Binary data from a stream. + */ + public function streaming_read_callback($curl_handle, $file_handle, $length) + { + // Once we've sent as much as we're supposed to send... + if ($this->read_stream_read >= $this->read_stream_size) { + // Send EOF + return ''; + } + + // If we're at the beginning of an upload and need to seek... + if ($this->read_stream_read == 0 && isset($this->seek_position) && $this->seek_position !== ftell($this->read_stream)) { + if (fseek($this->read_stream, $this->seek_position) !== 0) { + throw new RequestCore_Exception('The stream does not support seeking and is either not at the requested position or the position is unknown.'); + } + } + + $read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size + $this->read_stream_read += strlen($read); + + $out = $read === false ? '' : $read; + + // Execute callback function + if ($this->registered_streaming_read_callback) { + call_user_func($this->registered_streaming_read_callback, $curl_handle, $file_handle, $out); + } + + return $out; + } + + /** + * A callback function that is invoked by cURL for streaming down. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param binary $data (Required) The data to write. + * @return integer The number of bytes written. + */ + public function streaming_write_callback($curl_handle, $data) + { + $code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); + + if (intval($code) / 100 != 2) + { + $this->response_error_body .= $data; + return strlen($data); + } + + $length = strlen($data); + $written_total = 0; + $written_last = 0; + + while ($written_total < $length) { + $written_last = fwrite($this->write_stream, substr($data, $written_total)); + + if ($written_last === false) { + return $written_total; + } + + $written_total += $written_last; + } + + // Execute callback function + if ($this->registered_streaming_write_callback) { + call_user_func($this->registered_streaming_write_callback, $curl_handle, $written_total); + } + + return $written_total; + } + + /** + * Prepares and adds the details of the cURL request. This can be passed along to a + * function. + * + * @return resource The handle for the cURL object. + * + */ + public function prep_request() + { + $curl_handle = curl_init(); + + // Set default options. + curl_setopt($curl_handle, CURLOPT_URL, $this->request_url); + curl_setopt($curl_handle, CURLOPT_FILETIME, true); + curl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false); +// curl_setopt($curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED); + curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5); + curl_setopt($curl_handle, CURLOPT_HEADER, true); + curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl_handle, CURLOPT_TIMEOUT, $this->timeout); + curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, $this->connect_timeout); + curl_setopt($curl_handle, CURLOPT_NOSIGNAL, true); + curl_setopt($curl_handle, CURLOPT_REFERER, $this->request_url); + curl_setopt($curl_handle, CURLOPT_USERAGENT, $this->useragent); + curl_setopt($curl_handle, CURLOPT_HEADERFUNCTION, array($this, 'streaming_header_callback')); + curl_setopt($curl_handle, CURLOPT_READFUNCTION, array($this, 'streaming_read_callback')); + + // Verification of the SSL cert + if ($this->ssl_verification) { + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 2); + } else { + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false); + } + + // chmod the file as 0755 + if ($this->cacert_location === true) { + curl_setopt($curl_handle, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); + } elseif (is_string($this->cacert_location)) { + curl_setopt($curl_handle, CURLOPT_CAINFO, $this->cacert_location); + } + + // Debug mode + if ($this->debug_mode) { + curl_setopt($curl_handle, CURLOPT_VERBOSE, true); + } + + // Handle open_basedir & safe mode + if (!ini_get('safe_mode') && !ini_get('open_basedir')) { + curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true); + } + + // Enable a proxy connection if requested. + if ($this->proxy) { + + $host = $this->proxy['host']; + $host .= ($this->proxy['port']) ? ':' . $this->proxy['port'] : ''; + curl_setopt($curl_handle, CURLOPT_PROXY, $host); + + if (isset($this->proxy['user']) && isset($this->proxy['pass'])) { + curl_setopt($curl_handle, CURLOPT_PROXYUSERPWD, $this->proxy['user'] . ':' . $this->proxy['pass']); + } + } + + // Set credentials for HTTP Basic/Digest Authentication. + if ($this->username && $this->password) { + curl_setopt($curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($curl_handle, CURLOPT_USERPWD, $this->username . ':' . $this->password); + } + + // Handle the encoding if we can. + if (extension_loaded('zlib')) { + curl_setopt($curl_handle, CURLOPT_ENCODING, ''); + } + + // Process custom headers + if (isset($this->request_headers) && count($this->request_headers)) { + $temp_headers = array(); + + foreach ($this->request_headers as $k => $v) { + $temp_headers[] = $k . ': ' . $v; + } + + curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $temp_headers); + } + + switch ($this->method) { + case self::HTTP_PUT: + //unset($this->read_stream); + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT'); + if (isset($this->read_stream)) { + if (!isset($this->read_stream_size) || $this->read_stream_size < 0) { + throw new RequestCore_Exception('The stream size for the streaming upload cannot be determined.'); + } + curl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size); + curl_setopt($curl_handle, CURLOPT_UPLOAD, true); + } else { + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + } + break; + + case self::HTTP_POST: + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'POST'); + if (isset($this->read_stream)) { + if (!isset($this->read_stream_size) || $this->read_stream_size < 0) { + throw new RequestCore_Exception('The stream size for the streaming upload cannot be determined.'); + } + curl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size); + curl_setopt($curl_handle, CURLOPT_UPLOAD, true); + } else { + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + } + break; + + case self::HTTP_HEAD: + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, self::HTTP_HEAD); + curl_setopt($curl_handle, CURLOPT_NOBODY, 1); + break; + + default: // Assumed GET + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, $this->method); + if (isset($this->write_stream) || isset($this->write_file)) { + curl_setopt($curl_handle, CURLOPT_WRITEFUNCTION, array($this, 'streaming_write_callback')); + curl_setopt($curl_handle, CURLOPT_HEADER, false); + } else { + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + } + break; + } + + // Merge in the CURLOPTs + if (isset($this->curlopts) && sizeof($this->curlopts) > 0) { + foreach ($this->curlopts as $k => $v) { + curl_setopt($curl_handle, $k, $v); + } + } + + return $curl_handle; + } + + /** + * Take the post-processed cURL data and break it down into useful header/body/info chunks. Uses the + * data stored in the `curl_handle` and `response` properties unless replacement data is passed in via + * parameters. + * + * @param resource $curl_handle (Optional) The reference to the already executed cURL request. + * @param string $response (Optional) The actual response content itself that needs to be parsed. + * @return ResponseCore A object containing a parsed HTTP response. + */ + public function process_response($curl_handle = null, $response = null) + { + // Accept a custom one if it's passed. + if ($curl_handle && $response) { + $this->response = $response; + } + + // As long as this came back as a valid resource... + if (is_resource($curl_handle)) { + // Determine what's what. + $header_size = curl_getinfo($curl_handle, CURLINFO_HEADER_SIZE); + $this->response_headers = substr($this->response, 0, $header_size); + $this->response_body = substr($this->response, $header_size); + $this->response_code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); + $this->response_info = curl_getinfo($curl_handle); + + if (intval($this->response_code) / 100 != 2 && isset($this->write_file)) + { + $this->response_headers = $this->response_raw_headers; + $this->response_body = $this->response_error_body; + } + + // Parse out the headers + $this->response_headers = explode("\r\n\r\n", trim($this->response_headers)); + $this->response_headers = array_pop($this->response_headers); + $this->response_headers = explode("\r\n", $this->response_headers); + array_shift($this->response_headers); + + // Loop through and split up the headers. + $header_assoc = array(); + foreach ($this->response_headers as $header) { + $kv = explode(': ', $header); + $header_assoc[strtolower($kv[0])] = isset($kv[1]) ? $kv[1] : ''; + } + + // Reset the headers to the appropriate property. + $this->response_headers = $header_assoc; + $this->response_headers['info'] = $this->response_info; + $this->response_headers['info']['method'] = $this->method; + + if ($curl_handle && $response) { + return new ResponseCore($this->response_headers, $this->response_body, $this->response_code); + } + } + + // Return false + return false; + } + + /** + * Sends the request, calling necessary utility functions to update built-in properties. + * + * @param boolean $parse (Optional) Whether to parse the response with ResponseCore or not. + * @return string The resulting unparsed data from the request. + */ + public function send_request($parse = false) + { + set_time_limit(0); + + $curl_handle = $this->prep_request(); + $this->response = curl_exec($curl_handle); + + if ($this->response === false) { + throw new RequestCore_Exception('cURL resource: ' . (string)$curl_handle . '; cURL error: ' . curl_error($curl_handle) . ' (' . curl_errno($curl_handle) . ')'); + } + + $parsed_response = $this->process_response($curl_handle, $this->response); + + curl_close($curl_handle); + + if ($parse) { + return $parsed_response; + } + + return $this->response; + } + + /*%******************************************************************************************%*/ + // RESPONSE METHODS + + /** + * Get the HTTP response headers from the request. + * + * @param string $header (Optional) A specific header value to return. Defaults to all headers. + * @return string|array All or selected header values. + */ + public function get_response_header($header = null) + { + if ($header) { + return $this->response_headers[strtolower($header)]; + } + return $this->response_headers; + } + + /** + * Get the HTTP response body from the request. + * + * @return string The response body. + */ + public function get_response_body() + { + return $this->response_body; + } + + /** + * Get the HTTP response code from the request. + * + * @return string The HTTP response code. + */ + public function get_response_code() + { + return $this->response_code; + } +} diff --git a/addons/alioss/library/OSS/Http/RequestCore_Exception.php b/addons/alioss/library/OSS/Http/RequestCore_Exception.php new file mode 100644 index 0000000000000000000000000000000000000000..cb4e83c652f728f30418ba3b48dc9b2566364b74 --- /dev/null +++ b/addons/alioss/library/OSS/Http/RequestCore_Exception.php @@ -0,0 +1,8 @@ +). + * @param string $body (Required) XML-formatted response from AWS. + * @param integer $status (Optional) HTTP response status code from the request. + * @return Mixed Contains an `header` property (HTTP headers as an associative array), a or `body` property, and an `status` code. + */ + public function __construct($header, $body, $status = null) + { + $this->header = $header; + $this->body = $body; + $this->status = $status; + + return $this; + } + + /** + * Did we receive the status code we expected? + * + * @param integer|array $codes (Optional) The status code(s) to expect. Pass an for a single acceptable value, or an of integers for multiple acceptable values. + * @return boolean Whether we received the expected status code or not. + */ + public function isOK($codes = array(200, 201, 204, 206)) + { + if (is_array($codes)) { + return in_array($this->status, $codes); + } + + return $this->status === $codes; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/BucketInfo.php b/addons/alioss/library/OSS/Model/BucketInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..9b89674f974640b8a1dab4fb600a66c436022fdd --- /dev/null +++ b/addons/alioss/library/OSS/Model/BucketInfo.php @@ -0,0 +1,78 @@ +location = $location; + $this->name = $name; + $this->createDate = $createDate; + } + + /** + * 得到bucket所在的region + * + * @return string + */ + public function getLocation() + { + return $this->location; + } + + /** + * 得到bucket的名称 + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * 得到bucket的创建时间 + * + * @return string + */ + public function getCreateDate() + { + return $this->createDate; + } + + /** + * bucket所在的region + * + * @var string + */ + private $location; + /** + * bucket的名称 + * + * @var string + */ + private $name; + + /** + * bucket的创建事件 + * + * @var string + */ + private $createDate; + +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/BucketListInfo.php b/addons/alioss/library/OSS/Model/BucketListInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..910717f924d3d7a713cb725ae2990cbf7f5b269a --- /dev/null +++ b/addons/alioss/library/OSS/Model/BucketListInfo.php @@ -0,0 +1,39 @@ +bucketList = $bucketList; + } + + /** + * 得到BucketInfo列表 + * + * @return BucketInfo[] + */ + public function getBucketList() + { + return $this->bucketList; + } + + /** + * BucketInfo信息列表 + * + * @var array + */ + private $bucketList = array(); +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/CnameConfig.php b/addons/alioss/library/OSS/Model/CnameConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..f3597d2f06bbc754bb23f1f43131bc78f75f7852 --- /dev/null +++ b/addons/alioss/library/OSS/Model/CnameConfig.php @@ -0,0 +1,99 @@ +cnameList = array(); + } + + /** + * @return array + * @example + * array(2) { + * [0]=> + * array(3) { + * ["Domain"]=> + * string(11) "www.foo.com" + * ["Status"]=> + * string(7) "enabled" + * ["LastModified"]=> + * string(8) "20150101" + * } + * [1]=> + * array(3) { + * ["Domain"]=> + * string(7) "bar.com" + * ["Status"]=> + * string(8) "disabled" + * ["LastModified"]=> + * string(8) "20160101" + * } + * } + */ + public function getCnames() + { + return $this->cnameList; + } + + + public function addCname($cname) + { + if (count($this->cnameList) >= self::OSS_MAX_RULES) { + throw new OssException( + "num of cname in the config exceeds self::OSS_MAX_RULES: " . strval(self::OSS_MAX_RULES)); + } + $this->cnameList[] = array('Domain' => $cname); + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->Cname)) return; + foreach ($xml->Cname as $entry) { + $cname = array(); + foreach ($entry as $key => $value) { + $cname[strval($key)] = strval($value); + } + $this->cnameList[] = $cname; + } + } + + public function serializeToXml() + { + $strXml = << + + +EOF; + $xml = new \SimpleXMLElement($strXml); + foreach ($this->cnameList as $cname) { + $node = $xml->addChild('Cname'); + foreach ($cname as $key => $value) { + $node->addChild($key, $value); + } + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + const OSS_MAX_RULES = 10; + + private $cnameList = array(); +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/CorsConfig.php b/addons/alioss/library/OSS/Model/CorsConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..c44c10a1a2d176058b032457b51f535000628151 --- /dev/null +++ b/addons/alioss/library/OSS/Model/CorsConfig.php @@ -0,0 +1,113 @@ +rules = array(); + } + + /** + * 得到CorsRule列表 + * + * @return CorsRule[] + */ + public function getRules() + { + return $this->rules; + } + + + /** + * 添加一条CorsRule + * + * @param CorsRule $rule + * @throws OssException + */ + public function addRule($rule) + { + if (count($this->rules) >= self::OSS_MAX_RULES) { + throw new OssException("num of rules in the config exceeds self::OSS_MAX_RULES: " . strval(self::OSS_MAX_RULES)); + } + $this->rules[] = $rule; + } + + /** + * 从xml数据中解析出CorsConfig + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->CORSRule)) return; + foreach ($xml->CORSRule as $rule) { + $corsRule = new CorsRule(); + foreach ($rule as $key => $value) { + if ($key === self::OSS_CORS_ALLOWED_HEADER) { + $corsRule->addAllowedHeader(strval($value)); + } elseif ($key === self::OSS_CORS_ALLOWED_METHOD) { + $corsRule->addAllowedMethod(strval($value)); + } elseif ($key === self::OSS_CORS_ALLOWED_ORIGIN) { + $corsRule->addAllowedOrigin(strval($value)); + } elseif ($key === self::OSS_CORS_EXPOSE_HEADER) { + $corsRule->addExposeHeader(strval($value)); + } elseif ($key === self::OSS_CORS_MAX_AGE_SECONDS) { + $corsRule->setMaxAgeSeconds(strval($value)); + } + } + $this->addRule($corsRule); + } + return; + } + + /** + * 生成xml字符串 + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + foreach ($this->rules as $rule) { + $xmlRule = $xml->addChild('CORSRule'); + $rule->appendToXml($xmlRule); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + const OSS_CORS_ALLOWED_ORIGIN = 'AllowedOrigin'; + const OSS_CORS_ALLOWED_METHOD = 'AllowedMethod'; + const OSS_CORS_ALLOWED_HEADER = 'AllowedHeader'; + const OSS_CORS_EXPOSE_HEADER = 'ExposeHeader'; + const OSS_CORS_MAX_AGE_SECONDS = 'MaxAgeSeconds'; + const OSS_MAX_RULES = 10; + + /** + * orsRule列表 + * + * @var CorsRule[] + */ + private $rules = array(); +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/CorsRule.php b/addons/alioss/library/OSS/Model/CorsRule.php new file mode 100644 index 0000000000000000000000000000000000000000..2cbe1c17b43552d8d14b51442e53538d89de2966 --- /dev/null +++ b/addons/alioss/library/OSS/Model/CorsRule.php @@ -0,0 +1,150 @@ +allowedOrigins[] = $allowedOrigin; + } + } + + /** + * Rule中增加一条allowedMethod + * + * @param string $allowedMethod + */ + public function addAllowedMethod($allowedMethod) + { + if (!empty($allowedMethod)) { + $this->allowedMethods[] = $allowedMethod; + } + } + + /** + * Rule中增加一条allowedHeader + * + * @param string $allowedHeader + */ + public function addAllowedHeader($allowedHeader) + { + if (!empty($allowedHeader)) { + $this->allowedHeaders[] = $allowedHeader; + } + } + + /** + * Rule中增加一条exposeHeader + * + * @param string $exposeHeader + */ + public function addExposeHeader($exposeHeader) + { + if (!empty($exposeHeader)) { + $this->exposeHeaders[] = $exposeHeader; + } + } + + /** + * @return int + */ + public function getMaxAgeSeconds() + { + return $this->maxAgeSeconds; + } + + /** + * @param int $maxAgeSeconds + */ + public function setMaxAgeSeconds($maxAgeSeconds) + { + $this->maxAgeSeconds = $maxAgeSeconds; + } + + /** + * 得到AllowedHeaders列表 + * + * @return string[] + */ + public function getAllowedHeaders() + { + return $this->allowedHeaders; + } + + /** + * 得到AllowedOrigins列表 + * + * @return string[] + */ + public function getAllowedOrigins() + { + return $this->allowedOrigins; + } + + /** + * 得到AllowedMethods列表 + * + * @return string[] + */ + public function getAllowedMethods() + { + return $this->allowedMethods; + } + + /** + * 得到ExposeHeaders列表 + * + * @return string[] + */ + public function getExposeHeaders() + { + return $this->exposeHeaders; + } + + /** + * 根据提供的xmlRule, 把this按照一定的规则插入到$xmlRule中 + * + * @param \SimpleXMLElement $xmlRule + * @throws OssException + */ + public function appendToXml(&$xmlRule) + { + if (!isset($this->maxAgeSeconds)) { + throw new OssException("maxAgeSeconds is not set in the Rule"); + } + foreach ($this->allowedOrigins as $allowedOrigin) { + $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_ORIGIN, $allowedOrigin); + } + foreach ($this->allowedMethods as $allowedMethod) { + $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_METHOD, $allowedMethod); + } + foreach ($this->allowedHeaders as $allowedHeader) { + $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_HEADER, $allowedHeader); + } + foreach ($this->exposeHeaders as $exposeHeader) { + $xmlRule->addChild(CorsConfig::OSS_CORS_EXPOSE_HEADER, $exposeHeader); + } + $xmlRule->addChild(CorsConfig::OSS_CORS_MAX_AGE_SECONDS, strval($this->maxAgeSeconds)); + } + + private $allowedHeaders = array(); + private $allowedOrigins = array(); + private $allowedMethods = array(); + private $exposeHeaders = array(); + private $maxAgeSeconds = null; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/GetLiveChannelHistory.php b/addons/alioss/library/OSS/Model/GetLiveChannelHistory.php new file mode 100644 index 0000000000000000000000000000000000000000..6643444aac51180d67a12510da3a25a01337b599 --- /dev/null +++ b/addons/alioss/library/OSS/Model/GetLiveChannelHistory.php @@ -0,0 +1,34 @@ +liveRecordList; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + + if (isset($xml->LiveRecord)) { + foreach ($xml->LiveRecord as $record) { + $liveRecord = new LiveChannelHistory(); + $liveRecord->parseFromXmlNode($record); + $this->liveRecordList[] = $liveRecord; + } + } + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $liveRecordList = array(); +} diff --git a/addons/alioss/library/OSS/Model/GetLiveChannelInfo.php b/addons/alioss/library/OSS/Model/GetLiveChannelInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..0b5edfc4d1ede684ab48e3302de29f36d54a14a3 --- /dev/null +++ b/addons/alioss/library/OSS/Model/GetLiveChannelInfo.php @@ -0,0 +1,68 @@ +description; + } + + public function getStatus() + { + return $this->status; + } + + public function getType() + { + return $this->type; + } + + public function getFragDuration() + { + return $this->fragDuration; + } + + public function getFragCount() + { + return $this->fragCount; + } + + public function getPlayListName() + { + return $this->playlistName; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + + $this->description = strval($xml->Description); + $this->status = strval($xml->Status); + + if (isset($xml->Target)) { + foreach ($xml->Target as $target) { + $this->type = strval($target->Type); + $this->fragDuration = strval($target->FragDuration); + $this->fragCount = strval($target->FragCount); + $this->playlistName = strval($target->PlaylistName); + } + } + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $description; + private $status; + private $type; + private $fragDuration; + private $fragCount; + private $playlistName; +} diff --git a/addons/alioss/library/OSS/Model/GetLiveChannelStatus.php b/addons/alioss/library/OSS/Model/GetLiveChannelStatus.php new file mode 100644 index 0000000000000000000000000000000000000000..2ee7a68b242d550238cd558ae4c44552c99c5093 --- /dev/null +++ b/addons/alioss/library/OSS/Model/GetLiveChannelStatus.php @@ -0,0 +1,107 @@ +status; + } + + public function getConnectedTime() + { + return $this->connectedTime; + } + + public function getRemoteAddr() + { + return $this->remoteAddr; + } + + public function getVideoWidth() + { + return $this->videoWidth; + } + public function getVideoHeight() + { + return $this->videoHeight; + } + public function getVideoFrameRate() + { + return $this->videoFrameRate; + } + public function getVideoBandwidth() + { + return $this->videoBandwidth; + } + public function getVideoCodec() + { + return $this->videoCodec; + } + + public function getAudioBandwidth() + { + return $this->audioBandwidth; + } + public function getAudioSampleRate() + { + return $this->audioSampleRate; + } + public function getAudioCodec() + { + return $this->audioCodec; + } + + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->status = strval($xml->Status); + $this->connectedTime = strval($xml->ConnectedTime); + $this->remoteAddr = strval($xml->RemoteAddr); + + if (isset($xml->Video)) { + foreach ($xml->Video as $video) { + $this->videoWidth = intval($video->Width); + $this->videoHeight = intval($video->Height); + $this->videoFrameRate = intval($video->FrameRate); + $this->videoBandwidth = intval($video->Bandwidth); + $this->videoCodec = strval($video->Codec); + } + } + + if (isset($xml->Video)) { + foreach ($xml->Audio as $audio) { + $this->audioBandwidth = intval($audio->Bandwidth); + $this->audioSampleRate = intval($audio->SampleRate); + $this->audioCodec = strval($audio->Codec); + } + } + + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $status; + private $connectedTime; + private $remoteAddr; + + private $videoWidth; + private $videoHeight; + private $videoFrameRate; + private $videoBandwidth; + private $videoCodec; + + private $audioBandwidth; + private $audioSampleRate; + private $audioCodec; + + +} diff --git a/addons/alioss/library/OSS/Model/LifecycleAction.php b/addons/alioss/library/OSS/Model/LifecycleAction.php new file mode 100644 index 0000000000000000000000000000000000000000..5abd825d0cc57639264b0c47f942fd644620c174 --- /dev/null +++ b/addons/alioss/library/OSS/Model/LifecycleAction.php @@ -0,0 +1,88 @@ +action = $action; + $this->timeSpec = $timeSpec; + $this->timeValue = $timeValue; + } + + /** + * @return LifecycleAction + */ + public function getAction() + { + return $this->action; + } + + /** + * @param string $action + */ + public function setAction($action) + { + $this->action = $action; + } + + /** + * @return string + */ + public function getTimeSpec() + { + return $this->timeSpec; + } + + /** + * @param string $timeSpec + */ + public function setTimeSpec($timeSpec) + { + $this->timeSpec = $timeSpec; + } + + /** + * @return string + */ + public function getTimeValue() + { + return $this->timeValue; + } + + /** + * @param string $timeValue + */ + public function setTimeValue($timeValue) + { + $this->timeValue = $timeValue; + } + + /** + * appendToXml 把actions插入到xml中 + * + * @param \SimpleXMLElement $xmlRule + */ + public function appendToXml(&$xmlRule) + { + $xmlAction = $xmlRule->addChild($this->action); + $xmlAction->addChild($this->timeSpec, $this->timeValue); + } + + private $action; + private $timeSpec; + private $timeValue; + +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/LifecycleConfig.php b/addons/alioss/library/OSS/Model/LifecycleConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..fc4f5755a63cc057ec704c8b84fae886c5f5ab41 --- /dev/null +++ b/addons/alioss/library/OSS/Model/LifecycleConfig.php @@ -0,0 +1,107 @@ +rules = array(); + $xml = simplexml_load_string($strXml); + if (!isset($xml->Rule)) return; + $this->rules = array(); + foreach ($xml->Rule as $rule) { + $id = strval($rule->ID); + $prefix = strval($rule->Prefix); + $status = strval($rule->Status); + $actions = array(); + foreach ($rule as $key => $value) { + if ($key === 'ID' || $key === 'Prefix' || $key === 'Status') continue; + $action = $key; + $timeSpec = null; + $timeValue = null; + foreach ($value as $timeSpecKey => $timeValueValue) { + $timeSpec = $timeSpecKey; + $timeValue = strval($timeValueValue); + } + $actions[] = new LifecycleAction($action, $timeSpec, $timeValue); + } + $this->rules[] = new LifecycleRule($id, $prefix, $status, $actions); + } + return; + } + + + /** + * 生成xml字符串 + * + * @return string + */ + public function serializeToXml() + { + + $xml = new \SimpleXMLElement(''); + foreach ($this->rules as $rule) { + $xmlRule = $xml->addChild('Rule'); + $rule->appendToXml($xmlRule); + } + return $xml->asXML(); + } + + /** + * + * 添加LifecycleRule + * + * @param LifecycleRule $lifecycleRule + * @throws OssException + */ + public function addRule($lifecycleRule) + { + if (!isset($lifecycleRule)) { + throw new OssException("lifecycleRule is null"); + } + $this->rules[] = $lifecycleRule; + } + + /** + * 将配置转换成字符串,便于用户查看 + * + * @return string + */ + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * 得到所有的生命周期规则 + * + * @return LifecycleRule[] + */ + public function getRules() + { + return $this->rules; + } + + /** + * @var LifecycleRule[] + */ + private $rules; +} + + diff --git a/addons/alioss/library/OSS/Model/LifecycleRule.php b/addons/alioss/library/OSS/Model/LifecycleRule.php new file mode 100644 index 0000000000000000000000000000000000000000..ec615b9af18394b519db6f31d4444d3c6f30c576 --- /dev/null +++ b/addons/alioss/library/OSS/Model/LifecycleRule.php @@ -0,0 +1,126 @@ +id; + } + + /** + * @param string $id 规则ID + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * 得到文件前缀 + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * 设置文件前缀 + * + * @param string $prefix 文件前缀 + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + /** + * Lifecycle规则的状态 + * + * @return string + */ + public function getStatus() + { + return $this->status; + } + + /** + * 设置Lifecycle规则状态 + * + * @param string $status + */ + public function setStatus($status) + { + $this->status = $status; + } + + /** + * + * @return LifecycleAction[] + */ + public function getActions() + { + return $this->actions; + } + + /** + * @param LifecycleAction[] $actions + */ + public function setActions($actions) + { + $this->actions = $actions; + } + + + /** + * LifecycleRule constructor. + * + * @param string $id 规则ID + * @param string $prefix 文件前缀 + * @param string $status 规则状态,可选[self::LIFECYCLE_STATUS_ENABLED, self::LIFECYCLE_STATUS_DISABLED] + * @param LifecycleAction[] $actions + */ + public function __construct($id, $prefix, $status, $actions) + { + $this->id = $id; + $this->prefix = $prefix; + $this->status = $status; + $this->actions = $actions; + } + + /** + * @param \SimpleXMLElement $xmlRule + */ + public function appendToXml(&$xmlRule) + { + $xmlRule->addChild('ID', $this->id); + $xmlRule->addChild('Prefix', $this->prefix); + $xmlRule->addChild('Status', $this->status); + foreach ($this->actions as $action) { + $action->appendToXml($xmlRule); + } + } + + private $id; + private $prefix; + private $status; + private $actions = array(); + + const LIFECYCLE_STATUS_ENABLED = 'Enabled'; + const LIFECYCLE_STATUS_DISABLED = 'Disabled'; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/ListMultipartUploadInfo.php b/addons/alioss/library/OSS/Model/ListMultipartUploadInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..105d005b2fd319095471ae54f101f291fcc1d25a --- /dev/null +++ b/addons/alioss/library/OSS/Model/ListMultipartUploadInfo.php @@ -0,0 +1,134 @@ +bucket = $bucket; + $this->keyMarker = $keyMarker; + $this->uploadIdMarker = $uploadIdMarker; + $this->nextKeyMarker = $nextKeyMarker; + $this->nextUploadIdMarker = $nextUploadIdMarker; + $this->delimiter = $delimiter; + $this->prefix = $prefix; + $this->maxUploads = $maxUploads; + $this->isTruncated = $isTruncated; + $this->uploads = $uploads; + } + + /** + * 得到bucket名称 + * + * @return string + */ + public function getBucket() + { + return $this->bucket; + } + + /** + * @return string + */ + public function getKeyMarker() + { + return $this->keyMarker; + } + + /** + * + * @return string + */ + public function getUploadIdMarker() + { + return $this->uploadIdMarker; + } + + /** + * @return string + */ + public function getNextKeyMarker() + { + return $this->nextKeyMarker; + } + + /** + * @return string + */ + public function getNextUploadIdMarker() + { + return $this->nextUploadIdMarker; + } + + /** + * @return string + */ + public function getDelimiter() + { + return $this->delimiter; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * @return int + */ + public function getMaxUploads() + { + return $this->maxUploads; + } + + /** + * @return string + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * @return UploadInfo[] + */ + public function getUploads() + { + return $this->uploads; + } + + private $bucket = ""; + private $keyMarker = ""; + private $uploadIdMarker = ""; + private $nextKeyMarker = ""; + private $nextUploadIdMarker = ""; + private $delimiter = ""; + private $prefix = ""; + private $maxUploads = 0; + private $isTruncated = "false"; + private $uploads = array(); +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/ListPartsInfo.php b/addons/alioss/library/OSS/Model/ListPartsInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..f1d10ee9ee6788c7340f138b9edc9202f48dc856 --- /dev/null +++ b/addons/alioss/library/OSS/Model/ListPartsInfo.php @@ -0,0 +1,97 @@ +bucket = $bucket; + $this->key = $key; + $this->uploadId = $uploadId; + $this->nextPartNumberMarker = $nextPartNumberMarker; + $this->maxParts = $maxParts; + $this->isTruncated = $isTruncated; + $this->listPart = $listPart; + } + + /** + * @return string + */ + public function getBucket() + { + return $this->bucket; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getUploadId() + { + return $this->uploadId; + } + + /** + * @return int + */ + public function getNextPartNumberMarker() + { + return $this->nextPartNumberMarker; + } + + /** + * @return int + */ + public function getMaxParts() + { + return $this->maxParts; + } + + /** + * @return string + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * @return array + */ + public function getListPart() + { + return $this->listPart; + } + + private $bucket = ""; + private $key = ""; + private $uploadId = ""; + private $nextPartNumberMarker = 0; + private $maxParts = 0; + private $isTruncated = ""; + private $listPart = array(); +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/LiveChannelConfig.php b/addons/alioss/library/OSS/Model/LiveChannelConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..dadedc911b5b77aa5fde42536aecdcdbbd4ecdb1 --- /dev/null +++ b/addons/alioss/library/OSS/Model/LiveChannelConfig.php @@ -0,0 +1,121 @@ +description = $option['description']; + } + if (isset($option['status'])) { + $this->status = $option['status']; + } + if (isset($option['type'])) { + $this->type = $option['type']; + } + if (isset($option['fragDuration'])) { + $this->fragDuration = $option['fragDuration']; + } + if (isset($option['fragCount'])) { + $this->fragCount = $option['fragCount']; + } + if (isset($option['playListName'])) { + $this->playListName = $option['playListName']; + } + } + + public function getDescription() + { + return $this->description; + } + + public function getStatus() + { + return $this->status; + } + + public function getType() + { + return $this->type; + } + + public function getFragDuration() + { + return $this->fragDuration; + } + + public function getFragCount() + { + return $this->fragCount; + } + + public function getPlayListName() + { + return $this->playListName; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->description = strval($xml->Description); + $this->status = strval($xml->Status); + $target = $xml->Target; + $this->type = strval($target->Type); + $this->fragDuration = intval($target->FragDuration); + $this->fragCount = intval($target->FragCount); + $this->playListName = strval($target->PlayListName); + } + + public function serializeToXml() + { + $strXml = << + + +EOF; + $xml = new \SimpleXMLElement($strXml); + if (isset($this->description)) { + $xml->addChild('Description', $this->description); + } + + if (isset($this->status)) { + $xml->addChild('Status', $this->status); + } + + $node = $xml->addChild('Target'); + $node->addChild('Type', $this->type); + + if (isset($this->fragDuration)) { + $node->addChild('FragDuration', $this->fragDuration); + } + + if (isset($this->fragCount)) { + $node->addChild('FragCount', $this->fragCount); + } + + if (isset($this->playListName)) { + $node->addChild('PlayListName', $this->playListName); + } + + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + private $description; + private $status = "enabled"; + private $type; + private $fragDuration = 5; + private $fragCount = 3; + private $playListName = "playlist.m3u8"; +} diff --git a/addons/alioss/library/OSS/Model/LiveChannelHistory.php b/addons/alioss/library/OSS/Model/LiveChannelHistory.php new file mode 100644 index 0000000000000000000000000000000000000000..1c1fd4dbcdfa3b052bbf1bd61c04c73fcc279ddd --- /dev/null +++ b/addons/alioss/library/OSS/Model/LiveChannelHistory.php @@ -0,0 +1,59 @@ +startTime; + } + + public function getEndTime() + { + return $this->endTime; + } + + public function getRemoteAddr() + { + return $this->remoteAddr; + } + + public function parseFromXmlNode($xml) + { + if (isset($xml->StartTime)) { + $this->startTime = strval($xml->StartTime); + } + + if (isset($xml->EndTime)) { + $this->endTime = strval($xml->EndTime); + } + + if (isset($xml->RemoteAddr)) { + $this->remoteAddr = strval($xml->RemoteAddr); + } + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->parseFromXmlNode($xml); + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $startTime; + private $endTime; + private $remoteAddr; +} diff --git a/addons/alioss/library/OSS/Model/LiveChannelInfo.php b/addons/alioss/library/OSS/Model/LiveChannelInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..c63ec54d615171570a0351e4ee6b1d2b60e42fab --- /dev/null +++ b/addons/alioss/library/OSS/Model/LiveChannelInfo.php @@ -0,0 +1,107 @@ +name = $name; + $this->description = $description; + $this->publishUrls = array(); + $this->playUrls = array(); + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + public function getPublishUrls() + { + return $this->publishUrls; + } + + public function getPlayUrls() + { + return $this->playUrls; + } + + public function getStatus() + { + return $this->status; + } + + public function getLastModified() + { + return $this->lastModified; + } + + public function getDescription() + { + return $this->description; + } + + public function setDescription($description) + { + $this->description = $description; + } + + public function parseFromXmlNode($xml) + { + if (isset($xml->Name)) { + $this->name = strval($xml->Name); + } + + if (isset($xml->Description)) { + $this->description = strval($xml->Description); + } + + if (isset($xml->Status)) { + $this->status = strval($xml->Status); + } + + if (isset($xml->LastModified)) { + $this->lastModified = strval($xml->LastModified); + } + + if (isset($xml->PublishUrls)) { + foreach ($xml->PublishUrls as $url) { + $this->publishUrls[] = strval($url->Url); + } + } + + if (isset($xml->PlayUrls)) { + foreach ($xml->PlayUrls as $url) { + $this->playUrls[] = strval($url->Url); + } + } + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->parseFromXmlNode($xml); + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $name; + private $description; + private $publishUrls; + private $playUrls; + private $status; + private $lastModified; +} diff --git a/addons/alioss/library/OSS/Model/LiveChannelListInfo.php b/addons/alioss/library/OSS/Model/LiveChannelListInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..bb5093aa8eb948675228c560bfd06d444df91cb4 --- /dev/null +++ b/addons/alioss/library/OSS/Model/LiveChannelListInfo.php @@ -0,0 +1,107 @@ +bucket; + } + + public function setBucketName($name) + { + $this->bucket = $name; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * @return string + */ + public function getMarker() + { + return $this->marker; + } + + /** + * @return int + */ + public function getMaxKeys() + { + return $this->maxKeys; + } + + /** + * @return mixed + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * @return LiveChannelInfo[] + */ + public function getChannelList() + { + return $this->channelList; + } + + /** + * @return string + */ + public function getNextMarker() + { + return $this->nextMarker; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + + $this->prefix = strval($xml->Prefix); + $this->marker = strval($xml->Marker); + $this->maxKeys = intval($xml->MaxKeys); + $this->isTruncated = (strval($xml->IsTruncated) == 'true'); + $this->nextMarker = strval($xml->NextMarker); + + if (isset($xml->LiveChannel)) { + foreach ($xml->LiveChannel as $chan) { + $channel = new LiveChannelInfo(); + $channel->parseFromXmlNode($chan); + $this->channelList[] = $channel; + } + } + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $bucket = ''; + private $prefix = ''; + private $marker = ''; + private $nextMarker = ''; + private $maxKeys = 100; + private $isTruncated = 'false'; + private $channelList = array(); +} diff --git a/addons/alioss/library/OSS/Model/LoggingConfig.php b/addons/alioss/library/OSS/Model/LoggingConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..978421a2504839422198cea5f7ea5517ae5bedcb --- /dev/null +++ b/addons/alioss/library/OSS/Model/LoggingConfig.php @@ -0,0 +1,86 @@ +targetBucket = $targetBucket; + $this->targetPrefix = $targetPrefix; + } + + /** + * @param $strXml + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->LoggingEnabled)) return; + foreach ($xml->LoggingEnabled as $status) { + foreach ($status as $key => $value) { + if ($key === 'TargetBucket') { + $this->targetBucket = strval($value); + } elseif ($key === 'TargetPrefix') { + $this->targetPrefix = strval($value); + } + } + break; + } + } + + /** + * 序列化成xml字符串 + * + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + if (isset($this->targetBucket) && isset($this->targetPrefix)) { + $loggingEnabled = $xml->addChild('LoggingEnabled'); + $loggingEnabled->addChild('TargetBucket', $this->targetBucket); + $loggingEnabled->addChild('TargetPrefix', $this->targetPrefix); + } + return $xml->asXML(); + } + + /** + * @return string + */ + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return string + */ + public function getTargetBucket() + { + return $this->targetBucket; + } + + /** + * @return string + */ + public function getTargetPrefix() + { + return $this->targetPrefix; + } + + private $targetBucket = ""; + private $targetPrefix = ""; + +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/ObjectInfo.php b/addons/alioss/library/OSS/Model/ObjectInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..2ae6c99bd8ffcba68c04359c5438d05d10d4c369 --- /dev/null +++ b/addons/alioss/library/OSS/Model/ObjectInfo.php @@ -0,0 +1,93 @@ +key = $key; + $this->lastModified = $lastModified; + $this->eTag = $eTag; + $this->type = $type; + $this->size = $size; + $this->storageClass = $storageClass; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getLastModified() + { + return $this->lastModified; + } + + /** + * @return string + */ + public function getETag() + { + return $this->eTag; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @return int + */ + public function getSize() + { + return $this->size; + } + + /** + * @return string + */ + public function getStorageClass() + { + return $this->storageClass; + } + + private $key = ""; + private $lastModified = ""; + private $eTag = ""; + private $type = ""; + private $size = 0; + private $storageClass = ""; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/ObjectListInfo.php b/addons/alioss/library/OSS/Model/ObjectListInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..dbe7c7a7626ac9d22bdc8862815e66f3d6bfeac7 --- /dev/null +++ b/addons/alioss/library/OSS/Model/ObjectListInfo.php @@ -0,0 +1,126 @@ +bucketName = $bucketName; + $this->prefix = $prefix; + $this->marker = $marker; + $this->nextMarker = $nextMarker; + $this->maxKeys = $maxKeys; + $this->delimiter = $delimiter; + $this->isTruncated = $isTruncated; + $this->objectList = $objectList; + $this->prefixList = $prefixList; + } + + /** + * @return string + */ + public function getBucketName() + { + return $this->bucketName; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * @return string + */ + public function getMarker() + { + return $this->marker; + } + + /** + * @return int + */ + public function getMaxKeys() + { + return $this->maxKeys; + } + + /** + * @return string + */ + public function getDelimiter() + { + return $this->delimiter; + } + + /** + * @return mixed + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * 返回ListObjects接口返回数据中的ObjectInfo列表 + * + * @return ObjectInfo[] + */ + public function getObjectList() + { + return $this->objectList; + } + + /** + * 返回ListObjects接口返回数据中的PrefixInfo列表 + * + * @return PrefixInfo[] + */ + public function getPrefixList() + { + return $this->prefixList; + } + + /** + * @return string + */ + public function getNextMarker() + { + return $this->nextMarker; + } + + private $bucketName = ""; + private $prefix = ""; + private $marker = ""; + private $nextMarker = ""; + private $maxKeys = 0; + private $delimiter = ""; + private $isTruncated = null; + private $objectList = array(); + private $prefixList = array(); +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/PartInfo.php b/addons/alioss/library/OSS/Model/PartInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..439a84d31634d3bf80477e912c02f36855fcbfcb --- /dev/null +++ b/addons/alioss/library/OSS/Model/PartInfo.php @@ -0,0 +1,63 @@ +partNumber = $partNumber; + $this->lastModified = $lastModified; + $this->eTag = $eTag; + $this->size = $size; + } + + /** + * @return int + */ + public function getPartNumber() + { + return $this->partNumber; + } + + /** + * @return string + */ + public function getLastModified() + { + return $this->lastModified; + } + + /** + * @return string + */ + public function getETag() + { + return $this->eTag; + } + + /** + * @return int + */ + public function getSize() + { + return $this->size; + } + + private $partNumber = 0; + private $lastModified = ""; + private $eTag = ""; + private $size = 0; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/PrefixInfo.php b/addons/alioss/library/OSS/Model/PrefixInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..e61eac4493f6294036699b3dafac0fc82440d76f --- /dev/null +++ b/addons/alioss/library/OSS/Model/PrefixInfo.php @@ -0,0 +1,36 @@ +prefix = $prefix; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + private $prefix; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/RefererConfig.php b/addons/alioss/library/OSS/Model/RefererConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..1d7d975c5873efd67ed1b03899d6932221498672 --- /dev/null +++ b/addons/alioss/library/OSS/Model/RefererConfig.php @@ -0,0 +1,93 @@ +AllowEmptyReferer)) return; + if (!isset($xml->RefererList)) return; + $this->allowEmptyReferer = + (strval($xml->AllowEmptyReferer) === 'TRUE' || strval($xml->AllowEmptyReferer) === 'true') ? true : false; + + foreach ($xml->RefererList->Referer as $key => $refer) { + $this->refererList[] = strval($refer); + } + } + + + /** + * 把RefererConfig序列化成xml + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + if ($this->allowEmptyReferer) { + $xml->addChild('AllowEmptyReferer', 'true'); + } else { + $xml->addChild('AllowEmptyReferer', 'false'); + } + $refererList = $xml->addChild('RefererList'); + foreach ($this->refererList as $referer) { + $refererList->addChild('Referer', $referer); + } + return $xml->asXML(); + } + + /** + * @return string + */ + function __toString() + { + return $this->serializeToXml(); + } + + /** + * @param boolean $allowEmptyReferer + */ + public function setAllowEmptyReferer($allowEmptyReferer) + { + $this->allowEmptyReferer = $allowEmptyReferer; + } + + /** + * @param string $referer + */ + public function addReferer($referer) + { + $this->refererList[] = $referer; + } + + /** + * @return boolean + */ + public function isAllowEmptyReferer() + { + return $this->allowEmptyReferer; + } + + /** + * @return array + */ + public function getRefererList() + { + return $this->refererList; + } + + private $allowEmptyReferer = true; + private $refererList = array(); +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/StorageCapacityConfig.php b/addons/alioss/library/OSS/Model/StorageCapacityConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..05e6332c2cb9d432e73d67f472fe0ccd1ae5d599 --- /dev/null +++ b/addons/alioss/library/OSS/Model/StorageCapacityConfig.php @@ -0,0 +1,74 @@ +storageCapacity = $storageCapacity; + } + + /** + * Not implemented + */ + public function parseFromXml($strXml) + { + throw new OssException("Not implemented."); + } + + /** + * 把StorageCapacityConfig序列化成xml + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + $xml->addChild('StorageCapacity', strval($this->storageCapacity)); + return $xml->asXML(); + } + + /** + * To string + * + * @return string + */ + function __toString() + { + return $this->serializeToXml(); + } + + /** + * Set storage capacity + * + * @param int $storageCapacity + */ + public function setStorageCapacity($storageCapacity) + { + $this->storageCapacity = $storageCapacity; + } + + /** + * Get storage capacity + * + * @return int + */ + public function getStorageCapacity() + { + return $this->storageCapacity; + } + + private $storageCapacity = 0; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/UploadInfo.php b/addons/alioss/library/OSS/Model/UploadInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..8eaa3639fa8b76996d18f84b7a6a91d7e861ba86 --- /dev/null +++ b/addons/alioss/library/OSS/Model/UploadInfo.php @@ -0,0 +1,55 @@ +key = $key; + $this->uploadId = $uploadId; + $this->initiated = $initiated; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getUploadId() + { + return $this->uploadId; + } + + /** + * @return string + */ + public function getInitiated() + { + return $this->initiated; + } + + private $key = ""; + private $uploadId = ""; + private $initiated = ""; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/WebsiteConfig.php b/addons/alioss/library/OSS/Model/WebsiteConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..8ea08a030fff2a17ee603c3c8ae0b209d527c441 --- /dev/null +++ b/addons/alioss/library/OSS/Model/WebsiteConfig.php @@ -0,0 +1,76 @@ +indexDocument = $indexDocument; + $this->errorDocument = $errorDocument; + } + + /** + * @param string $strXml + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (isset($xml->IndexDocument) && isset($xml->IndexDocument->Suffix)) { + $this->indexDocument = strval($xml->IndexDocument->Suffix); + } + if (isset($xml->ErrorDocument) && isset($xml->ErrorDocument->Key)) { + $this->errorDocument = strval($xml->ErrorDocument->Key); + } + } + + /** + * 把WebsiteConfig序列化成xml + * + * @return string + * @throws OssException + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement(''); + $index_document_part = $xml->addChild('IndexDocument'); + $error_document_part = $xml->addChild('ErrorDocument'); + $index_document_part->addChild('Suffix', $this->indexDocument); + $error_document_part->addChild('Key', $this->errorDocument); + return $xml->asXML(); + } + + /** + * @return string + */ + public function getIndexDocument() + { + return $this->indexDocument; + } + + /** + * @return string + */ + public function getErrorDocument() + { + return $this->errorDocument; + } + + private $indexDocument = ""; + private $errorDocument = ""; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Model/XmlConfig.php b/addons/alioss/library/OSS/Model/XmlConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..d353a2221b75fc3d4a1678ea92f6e624596cf62e --- /dev/null +++ b/addons/alioss/library/OSS/Model/XmlConfig.php @@ -0,0 +1,27 @@ +hostname = $this->checkEndpoint($endpoint, $isCName); + $this->accessKeyId = $accessKeyId; + $this->accessKeySecret = $accessKeySecret; + $this->securityToken = $securityToken; + $this->requestProxy = $requestProxy; + + self::checkEnv(); + } + + /** + * 列举用户所有的Bucket[GetService], Endpoint类型为cname不能进行此操作 + * + * @param array $options + * @throws OssException + * @return BucketListInfo + */ + public function listBuckets($options = NULL) + { + if ($this->hostType === self::OSS_HOST_TYPE_CNAME) { + throw new OssException("operation is not permitted with CName host"); + } + $this->precheckOptions($options); + $options[self::OSS_BUCKET] = ''; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $response = $this->auth($options); + $result = new ListBucketsResult($response); + return $result->getData(); + } + + /** + * 创建bucket,默认创建的bucket的ACL是OssClient::OSS_ACL_TYPE_PRIVATE + * + * @param string $bucket + * @param string $acl + * @param array $options + * @param string $storageType + * @return null + */ + public function createBucket($bucket, $acl = self::OSS_ACL_TYPE_PRIVATE, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl); + if (isset($options[self::OSS_STORAGE])) { + $this->precheckStorage($options[self::OSS_STORAGE]); + $options[self::OSS_CONTENT] = OssUtil::createBucketXmlBody($options[self::OSS_STORAGE]); + unset($options[self::OSS_STORAGE]); + } + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 删除bucket + * 如果Bucket不为空(Bucket中有Object,或者有分块上传的碎片),则Bucket无法删除, + * 必须删除Bucket中的所有Object以及碎片后,Bucket才能成功删除。 + * + * @param string $bucket + * @param array $options + * @return null + */ + public function deleteBucket($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 判断bucket是否存在 + * + * @param string $bucket + * @return bool + * @throws OssException + */ + public function doesBucketExist($bucket) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new ExistResult($response); + return $result->getData(); + } + + /** + * 获取bucket所属的数据中心位置信息 + * + * @param string $bucket + * @param array $options + * @throws OssException + * @return string + */ + public function getBucketLocation($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'location'; + $response = $this->auth($options); + $result = new GetLocationResult($response); + return $result->getData(); + } + + /** + * 获取Bucket的Meta信息 + * + * @param string $bucket + * @param array $options 具体参考SDK文档 + * @return array + */ + public function getBucketMeta($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD; + $options[self::OSS_OBJECT] = '/'; + $response = $this->auth($options); + $result = new HeaderResult($response); + return $result->getData(); + } + + /** + * 获取bucket的ACL配置情况 + * + * @param string $bucket + * @param array $options + * @throws OssException + * @return string + */ + public function getBucketAcl($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new AclResult($response); + return $result->getData(); + } + + /** + * 设置bucket的ACL配置情况 + * + * @param string $bucket bucket名称 + * @param string $acl 读写权限,可选值 ['private', 'public-read', 'public-read-write'] + * @param array $options 可以为空 + * @throws OssException + * @return null + */ + public function putBucketAcl($bucket, $acl, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl); + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取object的ACL属性 + * + * @param string $bucket + * @param string $object + * @throws OssException + * @return string + */ + public function getObjectAcl($bucket, $object) + { + $options = array(); + $this->precheckCommon($bucket, $object, $options, true); + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new AclResult($response); + return $result->getData(); + } + + /** + * 设置object的ACL属性 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param string $acl 读写权限,可选值 ['default', 'private', 'public-read', 'public-read-write'] + * @throws OssException + * @return null + */ + public function putObjectAcl($bucket, $object, $acl) + { + $this->precheckCommon($bucket, $object, $options, true); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_ACL => $acl); + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取Bucket的访问日志配置情况 + * + * @param string $bucket bucket名称 + * @param array $options 可以为空 + * @throws OssException + * @return LoggingConfig + */ + public function getBucketLogging($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'logging'; + $response = $this->auth($options); + $result = new GetLoggingResult($response); + return $result->getData(); + } + + /** + * 开启Bucket访问日志记录功能,只有Bucket的所有者才能更改 + * + * @param string $bucket bucket名称 + * @param string $targetBucket 日志文件存放的bucket + * @param string $targetPrefix 日志的文件前缀 + * @param array $options 可以为空 + * @throws OssException + * @return null + */ + public function putBucketLogging($bucket, $targetBucket, $targetPrefix, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $this->precheckBucket($targetBucket, 'targetbucket is not allowed empty'); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'logging'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + + $loggingConfig = new LoggingConfig($targetBucket, $targetPrefix); + $options[self::OSS_CONTENT] = $loggingConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 关闭bucket访问日志记录功能 + * + * @param string $bucket bucket名称 + * @param array $options 可以为空 + * @throws OssException + * @return null + */ + public function deleteBucketLogging($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'logging'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 将bucket设置成静态网站托管模式 + * + * @param string $bucket bucket名称 + * @param WebsiteConfig $websiteConfig + * @param array $options 可以为空 + * @throws OssException + * @return null + */ + public function putBucketWebsite($bucket, $websiteConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'website'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $websiteConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取bucket的静态网站托管状态 + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return WebsiteConfig + */ + public function getBucketWebsite($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'website'; + $response = $this->auth($options); + $result = new GetWebsiteResult($response); + return $result->getData(); + } + + /** + * 关闭bucket的静态网站托管模式 + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketWebsite($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'website'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 在指定的bucket上设定一个跨域资源共享(CORS)的规则,如果原规则存在则覆盖原规则 + * + * @param string $bucket bucket名称 + * @param CorsConfig $corsConfig 跨域资源共享配置,具体规则参见SDK文档 + * @param array $options array + * @throws OssException + * @return null + */ + public function putBucketCors($bucket, $corsConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cors'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $corsConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取Bucket的CORS配置情况 + * + * @param string $bucket bucket名称 + * @param array $options 可以为空 + * @throws OssException + * @return CorsConfig + */ + public function getBucketCors($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cors'; + $response = $this->auth($options); + $result = new GetCorsResult($response, __FUNCTION__); + return $result->getData(); + } + + /** + * 关闭指定Bucket对应的CORS功能并清空所有规则 + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketCors($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cors'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 为指定Bucket增加CNAME绑定 + * + * @param string $bucket bucket名称 + * @param string $cname + * @param array $options + * @throws OssException + * @return null + */ + public function addBucketCname($bucket, $cname, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cname'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $cnameConfig = new CnameConfig(); + $cnameConfig->addCname($cname); + $options[self::OSS_CONTENT] = $cnameConfig->serializeToXml(); + $options[self::OSS_COMP] = 'add'; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取指定Bucket已绑定的CNAME列表 + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return CnameConfig + */ + public function getBucketCname($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cname'; + $response = $this->auth($options); + $result = new GetCnameResult($response); + return $result->getData(); + } + + /** + * 解除指定Bucket的CNAME绑定 + * + * @param string $bucket bucket名称 + * @param CnameConfig $cnameConfig + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketCname($bucket, $cname, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cname'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $cnameConfig = new CnameConfig(); + $cnameConfig->addCname($cname); + $options[self::OSS_CONTENT] = $cnameConfig->serializeToXml(); + $options[self::OSS_COMP] = 'delete'; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 为指定Bucket创建LiveChannel + * + * @param string $bucket bucket名称 + * @param string channelName $channelName + * @param LiveChannelConfig $channelConfig + * @param array $options + * @throws OssException + * @return LiveChannelInfo + */ + public function putBucketLiveChannel($bucket, $channelName, $channelConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $channelConfig->serializeToXml(); + + $response = $this->auth($options); + $result = new PutLiveChannelResult($response); + $info = $result->getData(); + $info->setName($channelName); + $info->setDescription($channelConfig->getDescription()); + + return $info; + } + + /** + * 设置LiveChannel的status + * + * @param string $bucket bucket名称 + * @param string channelName $channelName + * @param string channelStatus $channelStatus 为enabled或disabled + * @param array $options + * @throws OssException + * @return null + */ + public function putLiveChannelStatus($bucket, $channelName, $channelStatus, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_LIVE_CHANNEL_STATUS] = $channelStatus; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取LiveChannel信息 + * + * @param string $bucket bucket名称 + * @param string channelName $channelName + * @param array $options + * @throws OssException + * @return GetLiveChannelInfo + */ + public function getLiveChannelInfo($bucket, $channelName, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + + $response = $this->auth($options); + $result = new GetLiveChannelInfoResult($response); + return $result->getData(); + } + + /** + * 获取LiveChannel状态信息 + * + * @param string $bucket bucket名称 + * @param string channelName $channelName + * @param array $options + * @throws OssException + * @return GetLiveChannelStatus + */ + public function getLiveChannelStatus($bucket, $channelName, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_COMP] = 'stat'; + + $response = $this->auth($options); + $result = new GetLiveChannelStatusResult($response); + return $result->getData(); + } + + /** + *获取LiveChannel推流记录 + * + * @param string $bucket bucket名称 + * @param string channelName $channelName + * @param array $options + * @throws OssException + * @return GetLiveChannelHistory + */ + public function getLiveChannelHistory($bucket, $channelName, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_COMP] = 'history'; + + $response = $this->auth($options); + $result = new GetLiveChannelHistoryResult($response); + return $result->getData(); + } + + /** + *获取指定Bucket下的live channel列表 + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return LiveChannelListInfo + */ + public function listBucketLiveChannels($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_QUERY_STRING] = array( + 'prefix' => isset($options['prefix']) ? $options['prefix'] : '', + 'marker' => isset($options['marker']) ? $options['marker'] : '', + 'max-keys' => isset($options['max-keys']) ? $options['max-keys'] : '', + ); + $response = $this->auth($options); + $result = new ListLiveChannelResult($response); + $list = $result->getData(); + $list->setBucketName($bucket); + + return $list; + } + + /** + * 为指定LiveChannel生成播放列表 + * + * @param string $bucket bucket名称 + * @param string channelName $channelName + * @param string $playlistName 指定生成的点播播放列表的名称,必须以“.m3u8”结尾 + * @param array $setTime startTime和EndTime以unix时间戳格式给定,跨度不能超过一天 + * @throws OssException + * @return null + */ + public function postVodPlaylist($bucket, $channelName, $playlistName, $setTime) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = $channelName . '/' . $playlistName; + $options[self::OSS_SUB_RESOURCE] = 'vod'; + $options[self::OSS_LIVE_CHANNEL_END_TIME] = $setTime['EndTime']; + $options[self::OSS_LIVE_CHANNEL_START_TIME] = $setTime['StartTime']; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 删除指定Bucket的LiveChannel + * + * @param string $bucket bucket名称 + * @param string channelName $channelName + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketLiveChannel($bucket, $channelName, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 生成带签名的推流地址 + * + * @param string $bucket bucket名称 + * @param string channelName $channelName + * @param int timeout 设置超时时间,单位为秒 + * @param array $options + * @throws OssException + * @return 推流地址 + */ + public function signRtmpUrl($bucket, $channelName, $timeout = 60, $options = NULL) + { + $this->precheckCommon($bucket, $channelName, $options, false); + $expires = time() + $timeout; + $proto = 'rtmp://'; + $hostname = $this->generateHostname($bucket); + $cano_params = ''; + $query_items = array(); + $params = isset($options['params']) ? $options['params'] : array(); + uksort($params, 'strnatcasecmp'); + foreach ($params as $key => $value) { + $cano_params = $cano_params . $key . ':' . $value . "\n"; + $query_items[] = rawurlencode($key) . '=' . rawurlencode($value); + } + $resource = '/' . $bucket . '/' . $channelName; + + $string_to_sign = $expires . "\n" . $cano_params . $resource; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true)); + + $query_items[] = 'OSSAccessKeyId=' . rawurlencode($this->accessKeyId); + $query_items[] = 'Expires=' . rawurlencode($expires); + $query_items[] = 'Signature=' . rawurlencode($signature); + + return $proto . $hostname . '/live/' . $channelName . '?' . implode('&', $query_items); + } + + /** + * 检验跨域资源请求, 发送跨域请求之前会发送一个preflight请求(OPTIONS)并带上特定的来源域, + * HTTP方法和header信息等给OSS以决定是否发送真正的请求。 OSS可以通过putBucketCors接口 + * 来开启Bucket的CORS支持,开启CORS功能之后,OSS在收到浏览器preflight请求时会根据设定的 + * 规则评估是否允许本次请求 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param string $origin 请求来源域 + * @param string $request_method 表明实际请求中会使用的HTTP方法 + * @param string $request_headers 表明实际请求中会使用的除了简单头部之外的headers + * @param array $options + * @return array + * @throws OssException + * @link http://help.aliyun.com/document_detail/oss/api-reference/cors/OptionObject.html + */ + public function optionsObject($bucket, $object, $origin, $request_method, $request_headers, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_OPTIONS; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_HEADERS] = array( + self::OSS_OPTIONS_ORIGIN => $origin, + self::OSS_OPTIONS_REQUEST_HEADERS => $request_headers, + self::OSS_OPTIONS_REQUEST_METHOD => $request_method + ); + $response = $this->auth($options); + $result = new HeaderResult($response); + return $result->getData(); + } + + /** + * 设置Bucket的Lifecycle配置 + * + * @param string $bucket bucket名称 + * @param LifecycleConfig $lifecycleConfig Lifecycle配置类 + * @param array $options + * @throws OssException + * @return null + */ + public function putBucketLifecycle($bucket, $lifecycleConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $lifecycleConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取Bucket的Lifecycle配置情况 + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return LifecycleConfig + */ + public function getBucketLifecycle($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $response = $this->auth($options); + $result = new GetLifecycleResult($response); + return $result->getData(); + } + + /** + * 删除指定Bucket的生命周期配置 + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketLifecycle($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 设置一个bucket的referer访问白名单和是否允许referer字段为空的请求访问 + * Bucket Referer防盗链具体见OSS防盗链 + * + * @param string $bucket bucket名称 + * @param RefererConfig $refererConfig + * @param array $options + * @return ResponseCore + * @throws null + */ + public function putBucketReferer($bucket, $refererConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'referer'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $refererConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取Bucket的Referer配置情况 + * Bucket Referer防盗链具体见OSS防盗链 + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return RefererConfig + */ + public function getBucketReferer($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'referer'; + $response = $this->auth($options); + $result = new GetRefererResult($response); + return $result->getData(); + } + + /** + * 设置bucket的容量大小,单位GB + * 当bucket的容量大于设置的容量时,禁止继续写入 + * + * @param string $bucket bucket名称 + * @param int $storageCapacity + * @param array $options + * @return ResponseCore + * @throws null + */ + public function putBucketStorageCapacity($bucket, $storageCapacity, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'qos'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $storageCapacityConfig = new StorageCapacityConfig($storageCapacity); + $options[self::OSS_CONTENT] = $storageCapacityConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取bucket的容量大小,单位GB + * + * @param string $bucket bucket名称 + * @param array $options + * @throws OssException + * @return int + */ + public function getBucketStorageCapacity($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'qos'; + $response = $this->auth($options); + $result = new GetStorageCapacityResult($response); + return $result->getData(); + } + + /** + * 获取bucket下的object列表 + * + * @param string $bucket + * @param array $options + * 其中options中的参数如下 + * $options = array( + * 'max-keys' => max-keys用于限定此次返回object的最大数,如果不设定,默认为100,max-keys取值不能大于1000。 + * 'prefix' => 限定返回的object key必须以prefix作为前缀。注意使用prefix查询时,返回的key中仍会包含prefix。 + * 'delimiter' => 是一个用于对Object名字进行分组的字符。所有名字包含指定的前缀且第一次出现delimiter字符之间的object作为一组元素 + * 'marker' => 用户设定结果从marker之后按字母排序的第一个开始返回。 + * ) + * 其中 prefix,marker用来实现分页显示效果,参数的长度必须小于256字节。 + * @throws OssException + * @return ObjectListInfo + */ + public function listObjects($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_HEADERS] = array( + self::OSS_DELIMITER => isset($options[self::OSS_DELIMITER]) ? $options[self::OSS_DELIMITER] : '/', + self::OSS_PREFIX => isset($options[self::OSS_PREFIX]) ? $options[self::OSS_PREFIX] : '', + self::OSS_MAX_KEYS => isset($options[self::OSS_MAX_KEYS]) ? $options[self::OSS_MAX_KEYS] : self::OSS_MAX_KEYS_VALUE, + self::OSS_MARKER => isset($options[self::OSS_MARKER]) ? $options[self::OSS_MARKER] : '', + ); + $query = isset($options[self::OSS_QUERY_STRING]) ? $options[self::OSS_QUERY_STRING] : array(); + $options[self::OSS_QUERY_STRING] = array_merge( + $query, + array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL) + ); + + $response = $this->auth($options); + $result = new ListObjectsResult($response); + return $result->getData(); + } + + /** + * 创建虚拟目录 (本函数会在object名称后增加'/', 所以创建目录的object名称不需要'/'结尾,否则,目录名称会变成'//') + * + * 暂不开放此接口 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param array $options + * @return null + */ + public function createObjectDir($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $object . '/'; + $options[self::OSS_CONTENT_LENGTH] = array(self::OSS_CONTENT_LENGTH => 0); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 上传内存中的内容 + * + * @param string $bucket bucket名称 + * @param string $object objcet名称 + * @param string $content 上传的内容 + * @param array $options + * @return null + */ + public function putObject($bucket, $object, $content, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + + $options[self::OSS_CONTENT] = $content; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $object; + + if (!isset($options[self::OSS_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]); + } else { + $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; + } + + $is_check_md5 = $this->isCheckMD5($options); + if ($is_check_md5) { + $content_md5 = base64_encode(md5($content, true)); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); + } + $response = $this->auth($options); + + if (isset($options[self::OSS_CALLBACK]) && !empty($options[self::OSS_CALLBACK])) { + $result = new CallbackResult($response); + } else { + $result = new PutSetDeleteResult($response); + } + + return $result->getData(); + } + + /** + * 创建symlink + * @param string $bucket bucket名称 + * @param string $symlink symlink名称 + * @param string $targetObject 目标object名称 + * @param array $options + * @return null + */ + public function putSymlink($bucket, $symlink, $targetObject, $options = NULL) + { + $this->precheckCommon($bucket, $symlink, $options); + + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $symlink; + $options[self::OSS_SUB_RESOURCE] = self::OSS_SYMLINK; + $options[self::OSS_HEADERS][self::OSS_SYMLINK_TARGET] = rawurlencode($targetObject); + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取symlink + * @param string $bucket bucket名称 + * @param string $symlink symlink名称 + * @return null + */ + public function getSymlink($bucket, $symlink) + { + $this->precheckCommon($bucket, $symlink, $options); + + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $symlink; + $options[self::OSS_SUB_RESOURCE] = self::OSS_SYMLINK; + + $response = $this->auth($options); + $result = new SymlinkResult($response); + return $result->getData(); + } + + /** + * 上传本地文件 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param string $file 本地文件路径 + * @param array $options + * @return null + * @throws OssException + */ + public function uploadFile($bucket, $object, $file, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + OssUtil::throwOssExceptionWithMessageIfEmpty($file, "file path is invalid"); + $file = OssUtil::encodePath($file); + if (!file_exists($file)) { + throw new OssException($file . " file does not exist"); + } + $options[self::OSS_FILE_UPLOAD] = $file; + $file_size = filesize($options[self::OSS_FILE_UPLOAD]); + $is_check_md5 = $this->isCheckMD5($options); + if ($is_check_md5) { + $content_md5 = base64_encode(md5_file($options[self::OSS_FILE_UPLOAD], true)); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $file); + } + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_CONTENT_LENGTH] = $file_size; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 追加上传内存中的内容 + * + * @param string $bucket bucket名称 + * @param string $object objcet名称 + * @param string $content 本次追加上传的内容 + * @param array $options + * @return int next append position + * @throws OssException + */ + public function appendObject($bucket, $object, $content, $position, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + + $options[self::OSS_CONTENT] = $content; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = 'append'; + $options[self::OSS_POSITION] = strval($position); + + if (!isset($options[self::OSS_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]); + } else { + $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; + } + + $is_check_md5 = $this->isCheckMD5($options); + if ($is_check_md5) { + $content_md5 = base64_encode(md5($content, true)); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); + } + $response = $this->auth($options); + $result = new AppendResult($response); + return $result->getData(); + } + + /** + * 追加上传本地文件 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param string $file 追加上传的本地文件路径 + * @param array $options + * @return int next append position + * @throws OssException + */ + public function appendFile($bucket, $object, $file, $position, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + + OssUtil::throwOssExceptionWithMessageIfEmpty($file, "file path is invalid"); + $file = OssUtil::encodePath($file); + if (!file_exists($file)) { + throw new OssException($file . " file does not exist"); + } + $options[self::OSS_FILE_UPLOAD] = $file; + $file_size = filesize($options[self::OSS_FILE_UPLOAD]); + $is_check_md5 = $this->isCheckMD5($options); + if ($is_check_md5) { + $content_md5 = base64_encode(md5_file($options[self::OSS_FILE_UPLOAD], true)); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $file); + } + + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_CONTENT_LENGTH] = $file_size; + $options[self::OSS_SUB_RESOURCE] = 'append'; + $options[self::OSS_POSITION] = strval($position); + + $response = $this->auth($options); + $result = new AppendResult($response); + return $result->getData(); + } + + /** + * 拷贝一个在OSS上已经存在的object成另外一个object + * + * @param string $fromBucket 源bucket名称 + * @param string $fromObject 源object名称 + * @param string $toBucket 目标bucket名称 + * @param string $toObject 目标object名称 + * @param array $options + * @return null + * @throws OssException + */ + public function copyObject($fromBucket, $fromObject, $toBucket, $toObject, $options = NULL) + { + $this->precheckCommon($fromBucket, $fromObject, $options); + $this->precheckCommon($toBucket, $toObject, $options); + $options[self::OSS_BUCKET] = $toBucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $toObject; + if (isset($options[self::OSS_HEADERS])) { + $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = '/' . $fromBucket . '/' . $fromObject; + } else { + $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_COPY_SOURCE => '/' . $fromBucket . '/' . $fromObject); + } + $response = $this->auth($options); + $result = new CopyObjectResult($response); + return $result->getData(); + } + + /** + * 获取Object的Meta信息 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param string $options 具体参考SDK文档 + * @return array + */ + public function getObjectMeta($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD; + $options[self::OSS_OBJECT] = $object; + $response = $this->auth($options); + $result = new HeaderResult($response); + return $result->getData(); + } + + /** + * 删除某个Object + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param array $options + * @return null + */ + public function deleteObject($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = $object; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 删除同一个Bucket中的多个Object + * + * @param string $bucket bucket名称 + * @param array $objects object列表 + * @param array $options + * @return ResponseCore + * @throws null + */ + public function deleteObjects($bucket, $objects, $options = null) + { + $this->precheckCommon($bucket, NULL, $options, false); + if (!is_array($objects) || !$objects) { + throw new OssException('objects must be array'); + } + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'delete'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $quiet = 'false'; + if (isset($options['quiet'])) { + if (is_bool($options['quiet'])) { //Boolean + $quiet = $options['quiet'] ? 'true' : 'false'; + } elseif (is_string($options['quiet'])) { // string + $quiet = ($options['quiet'] === 'true') ? 'true' : 'false'; + } + } + $xmlBody = OssUtil::createDeleteObjectsXmlBody($objects, $quiet); + $options[self::OSS_CONTENT] = $xmlBody; + $response = $this->auth($options); + $result = new DeleteObjectsResult($response); + return $result->getData(); + } + + /** + * 获得Object内容 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param array $options 该参数中必须设置ALIOSS::OSS_FILE_DOWNLOAD,ALIOSS::OSS_RANGE可选,可以根据实际情况设置;如果不设置,默认会下载全部内容 + * @return string + */ + public function getObject($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $object; + if (isset($options[self::OSS_LAST_MODIFIED])) { + $options[self::OSS_HEADERS][self::OSS_IF_MODIFIED_SINCE] = $options[self::OSS_LAST_MODIFIED]; + unset($options[self::OSS_LAST_MODIFIED]); + } + if (isset($options[self::OSS_ETAG])) { + $options[self::OSS_HEADERS][self::OSS_IF_NONE_MATCH] = $options[self::OSS_ETAG]; + unset($options[self::OSS_ETAG]); + } + if (isset($options[self::OSS_RANGE])) { + $range = $options[self::OSS_RANGE]; + $options[self::OSS_HEADERS][self::OSS_RANGE] = "bytes=$range"; + unset($options[self::OSS_RANGE]); + } + $response = $this->auth($options); + $result = new BodyResult($response); + return $result->getData(); + } + + /** + * 检测Object是否存在 + * 通过获取Object的Meta信息来判断Object是否存在, 用户需要自行解析ResponseCore判断object是否存在 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param array $options + * @return bool + */ + public function doesObjectExist($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD; + $options[self::OSS_OBJECT] = $object; + $response = $this->auth($options); + $result = new ExistResult($response); + return $result->getData(); + } + + /** + * 针对Archive类型的Object读取 + * 需要使用Restore操作让服务端执行解冻任务 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @return null + * @throws OssException + */ + public function restoreObject($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = self::OSS_RESTORE; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 获取分片大小,根据用户提供的part_size,重新计算一个更合理的partsize + * + * @param int $partSize + * @return int + */ + private function computePartSize($partSize) + { + $partSize = (integer)$partSize; + if ($partSize <= self::OSS_MIN_PART_SIZE) { + $partSize = self::OSS_MIN_PART_SIZE; + } elseif ($partSize > self::OSS_MAX_PART_SIZE) { + $partSize = self::OSS_MAX_PART_SIZE; + } + return $partSize; + } + + /** + * 计算文件可以分成多少个part,以及每个part的长度以及起始位置 + * 方法必须在 中调用 + * + * @param integer $file_size 文件大小 + * @param integer $partSize part大小,默认5M + * @return array An array 包含 key-value 键值对. Key 为 `seekTo` 和 `length`. + */ + public function generateMultiuploadParts($file_size, $partSize = 5242880) + { + $i = 0; + $size_count = $file_size; + $values = array(); + $partSize = $this->computePartSize($partSize); + while ($size_count > 0) { + $size_count -= $partSize; + $values[] = array( + self::OSS_SEEK_TO => ($partSize * $i), + self::OSS_LENGTH => (($size_count > 0) ? $partSize : ($size_count + $partSize)), + ); + $i++; + } + return $values; + } + + /** + * 初始化multi-part upload + * + * @param string $bucket Bucket名称 + * @param string $object Object名称 + * @param array $options Key-Value数组 + * @throws OssException + * @return string 返回uploadid + */ + public function initiateMultipartUpload($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = 'uploads'; + $options[self::OSS_CONTENT] = ''; + + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); + } + if (!isset($options[self::OSS_HEADERS])) { + $options[self::OSS_HEADERS] = array(); + } + $response = $this->auth($options); + $result = new InitiateMultipartUploadResult($response); + return $result->getData(); + } + + /** + * 分片上传的块上传接口 + * + * @param string $bucket Bucket名称 + * @param string $object Object名称 + * @param string $uploadId + * @param array $options Key-Value数组 + * @return string eTag + * @throws OssException + */ + public function uploadPart($bucket, $object, $uploadId, $options = null) + { + $this->precheckCommon($bucket, $object, $options); + $this->precheckParam($options, self::OSS_FILE_UPLOAD, __FUNCTION__); + $this->precheckParam($options, self::OSS_PART_NUM, __FUNCTION__); + + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_UPLOAD_ID] = $uploadId; + + if (isset($options[self::OSS_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; + } + $response = $this->auth($options); + $result = new UploadPartResult($response); + return $result->getData(); + } + + /** + * 获取已成功上传的part + * + * @param string $bucket Bucket名称 + * @param string $object Object名称 + * @param string $uploadId uploadId + * @param array $options Key-Value数组 + * @return ListPartsInfo + * @throws OssException + */ + public function listParts($bucket, $object, $uploadId, $options = null) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_UPLOAD_ID] = $uploadId; + $options[self::OSS_QUERY_STRING] = array(); + foreach (array('max-parts', 'part-number-marker') as $param) { + if (isset($options[$param])) { + $options[self::OSS_QUERY_STRING][$param] = $options[$param]; + unset($options[$param]); + } + } + $response = $this->auth($options); + $result = new ListPartsResult($response); + return $result->getData(); + } + + /** + * 中止进行一半的分片上传操作 + * + * @param string $bucket Bucket名称 + * @param string $object Object名称 + * @param string $uploadId uploadId + * @param array $options Key-Value数组 + * @return null + * @throws OssException + */ + public function abortMultipartUpload($bucket, $object, $uploadId, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_UPLOAD_ID] = $uploadId; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * 在将所有数据Part都上传完成后,调用此接口完成本次分块上传 + * + * @param string $bucket Bucket名称 + * @param string $object Object名称 + * @param string $uploadId uploadId + * @param array $listParts array( array("PartNumber"=> int, "ETag"=>string)) + * @param array $options Key-Value数组 + * @throws OssException + * @return null + */ + public function completeMultipartUpload($bucket, $object, $uploadId, $listParts, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_UPLOAD_ID] = $uploadId; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + if (!is_array($listParts)) { + throw new OssException("listParts must be array type"); + } + $options[self::OSS_CONTENT] = OssUtil::createCompleteMultipartUploadXmlBody($listParts); + $response = $this->auth($options); + if (isset($options[self::OSS_CALLBACK]) && !empty($options[self::OSS_CALLBACK])) { + $result = new CallbackResult($response); + } else { + $result = new PutSetDeleteResult($response); + } + return $result->getData(); + } + + /** + * 罗列出所有执行中的Multipart Upload事件,即已经被初始化的Multipart Upload但是未被 + * Complete或者Abort的Multipart Upload事件 + * + * @param string $bucket bucket + * @param array $options 关联数组 + * @throws OssException + * @return ListMultipartUploadInfo + */ + public function listMultipartUploads($bucket, $options = null) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'uploads'; + + foreach (array('delimiter', 'key-marker', 'max-uploads', 'prefix', 'upload-id-marker') as $param) { + if (isset($options[$param])) { + $options[self::OSS_QUERY_STRING][$param] = $options[$param]; + unset($options[$param]); + } + } + $query = isset($options[self::OSS_QUERY_STRING]) ? $options[self::OSS_QUERY_STRING] : array(); + $options[self::OSS_QUERY_STRING] = array_merge( + $query, + array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL) + ); + + $response = $this->auth($options); + $result = new ListMultipartUploadResult($response); + return $result->getData(); + } + + /** + * 从一个已存在的Object中拷贝数据来上传一个Part + * + * @param string $fromBucket 源bucket名称 + * @param string $fromObject 源object名称 + * @param string $toBucket 目标bucket名称 + * @param string $toObject 目标object名称 + * @param int $partNumber 分块上传的块id + * @param string $uploadId 初始化multipart upload返回的uploadid + * @param array $options Key-Value数组 + * @return null + * @throws OssException + */ + public function uploadPartCopy($fromBucket, $fromObject, $toBucket, $toObject, $partNumber, $uploadId, $options = NULL) + { + $this->precheckCommon($fromBucket, $fromObject, $options); + $this->precheckCommon($toBucket, $toObject, $options); + + //如果没有设置$options['isFullCopy'],则需要强制判断copy的起止位置 + $start_range = "0"; + if (isset($options['start'])) { + $start_range = $options['start']; + } + $end_range = ""; + if (isset($options['end'])) { + $end_range = $options['end']; + } + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_BUCKET] = $toBucket; + $options[self::OSS_OBJECT] = $toObject; + $options[self::OSS_PART_NUM] = $partNumber; + $options[self::OSS_UPLOAD_ID] = $uploadId; + + if (!isset($options[self::OSS_HEADERS])) { + $options[self::OSS_HEADERS] = array(); + } + + $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = '/' . $fromBucket . '/' . $fromObject; + $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE_RANGE] = "bytes=" . $start_range . "-" . $end_range; + $response = $this->auth($options); + $result = new UploadPartResult($response); + return $result->getData(); + } + + /** + * multipart上传统一封装,从初始化到完成multipart,以及出错后中止动作 + * + * @param string $bucket bucket名称 + * @param string $object object名称 + * @param string $file 需要上传的本地文件的路径 + * @param array $options Key-Value数组 + * @return null + * @throws OssException + */ + public function multiuploadFile($bucket, $object, $file, $options = null) + { + $this->precheckCommon($bucket, $object, $options); + if (isset($options[self::OSS_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; + unset($options[self::OSS_LENGTH]); + } + if (empty($file)) { + throw new OssException("parameter invalid, file is empty"); + } + $uploadFile = OssUtil::encodePath($file); + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $uploadFile); + } + + $upload_position = isset($options[self::OSS_SEEK_TO]) ? (integer)$options[self::OSS_SEEK_TO] : 0; + + if (isset($options[self::OSS_CONTENT_LENGTH])) { + $upload_file_size = (integer)$options[self::OSS_CONTENT_LENGTH]; + } else { + $upload_file_size = filesize($uploadFile); + if ($upload_file_size !== false) { + $upload_file_size -= $upload_position; + } + } + + if ($upload_position === false || !isset($upload_file_size) || $upload_file_size === false || $upload_file_size < 0) { + throw new OssException('The size of `fileUpload` cannot be determined in ' . __FUNCTION__ . '().'); + } + // 处理partSize + if (isset($options[self::OSS_PART_SIZE])) { + $options[self::OSS_PART_SIZE] = $this->computePartSize($options[self::OSS_PART_SIZE]); + } else { + $options[self::OSS_PART_SIZE] = self::OSS_MID_PART_SIZE; + } + + $is_check_md5 = $this->isCheckMD5($options); + // 如果上传的文件小于partSize,则直接使用普通方式上传 + if ($upload_file_size < $options[self::OSS_PART_SIZE] && !isset($options[self::OSS_UPLOAD_ID])) { + return $this->uploadFile($bucket, $object, $uploadFile, $options); + } + + // 初始化multipart + if (isset($options[self::OSS_UPLOAD_ID])) { + $uploadId = $options[self::OSS_UPLOAD_ID]; + } else { + // 初始化 + $uploadId = $this->initiateMultipartUpload($bucket, $object, $options); + } + + // 获取的分片 + $pieces = $this->generateMultiuploadParts($upload_file_size, (integer)$options[self::OSS_PART_SIZE]); + $response_upload_part = array(); + foreach ($pieces as $i => $piece) { + $from_pos = $upload_position + (integer)$piece[self::OSS_SEEK_TO]; + $to_pos = (integer)$piece[self::OSS_LENGTH] + $from_pos - 1; + $up_options = array( + self::OSS_FILE_UPLOAD => $uploadFile, + self::OSS_PART_NUM => ($i + 1), + self::OSS_SEEK_TO => $from_pos, + self::OSS_LENGTH => $to_pos - $from_pos + 1, + self::OSS_CHECK_MD5 => $is_check_md5, + ); + if ($is_check_md5) { + $content_md5 = OssUtil::getMd5SumForFile($uploadFile, $from_pos, $to_pos); + $up_options[self::OSS_CONTENT_MD5] = $content_md5; + } + $response_upload_part[] = $this->uploadPart($bucket, $object, $uploadId, $up_options); + } + + $uploadParts = array(); + foreach ($response_upload_part as $i => $etag) { + $uploadParts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $etag, + ); + } + return $this->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts); + } + + /** + * 上传本地目录内的文件或者目录到指定bucket的指定prefix的object中 + * + * @param string $bucket bucket名称 + * @param string $prefix 需要上传到的object的key前缀,可以理解成bucket中的子目录,结尾不能是'/',接口中会补充'/' + * @param string $localDirectory 需要上传的本地目录 + * @param string $exclude 需要排除的目录 + * @param bool $recursive 是否递归的上传localDirectory下的子目录内容 + * @param bool $checkMd5 + * @return array 返回两个列表 array("succeededList" => array("object"), "failedList" => array("object"=>"errorMessage")) + * @throws OssException + */ + public function uploadDir($bucket, $prefix, $localDirectory, $exclude = '.|..|.svn|.git', $recursive = false, $checkMd5 = true) + { + $retArray = array("succeededList" => array(), "failedList" => array()); + if (empty($bucket)) throw new OssException("parameter error, bucket is empty"); + if (!is_string($prefix)) throw new OssException("parameter error, prefix is not string"); + if (empty($localDirectory)) throw new OssException("parameter error, localDirectory is empty"); + $directory = $localDirectory; + $directory = OssUtil::encodePath($directory); + //判断是否目录 + if (!is_dir($directory)) { + throw new OssException('parameter error: ' . $directory . ' is not a directory, please check it'); + } + //read directory + $file_list_array = OssUtil::readDir($directory, $exclude, $recursive); + if (!$file_list_array) { + throw new OssException($directory . ' is empty...'); + } + foreach ($file_list_array as $k => $item) { + if (is_dir($item['path'])) { + continue; + } + $options = array( + self::OSS_PART_SIZE => self::OSS_MIN_PART_SIZE, + self::OSS_CHECK_MD5 => $checkMd5, + ); + $realObject = (!empty($prefix) ? $prefix . '/' : '') . $item['file']; + + try { + $this->multiuploadFile($bucket, $realObject, $item['path'], $options); + $retArray["succeededList"][] = $realObject; + } catch (OssException $e) { + $retArray["failedList"][$realObject] = $e->getMessage(); + } + } + return $retArray; + } + + /** + * 支持生成get和put签名, 用户可以生成一个具有一定有效期的 + * 签名过的url + * + * @param string $bucket + * @param string $object + * @param int $timeout + * @param string $method + * @param array $options Key-Value数组 + * @return string + * @throws OssException + */ + public function signUrl($bucket, $object, $timeout = 60, $method = self::OSS_HTTP_GET, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + //method + if (self::OSS_HTTP_GET !== $method && self::OSS_HTTP_PUT !== $method) { + throw new OssException("method is invalid"); + } + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_METHOD] = $method; + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = ''; + } + $timeout = time() + $timeout; + $options[self::OSS_PREAUTH] = $timeout; + $options[self::OSS_DATE] = $timeout; + $this->setSignStsInUrl(true); + return $this->auth($options); + } + + /** + * 检测options参数 + * + * @param array $options + * @throws OssException + */ + private function precheckOptions(&$options) + { + OssUtil::validateOptions($options); + if (!$options) { + $options = array(); + } + } + + /** + * 校验bucket参数 + * + * @param string $bucket + * @param string $errMsg + * @throws OssException + */ + private function precheckBucket($bucket, $errMsg = 'bucket is not allowed empty') + { + OssUtil::throwOssExceptionWithMessageIfEmpty($bucket, $errMsg); + } + + /** + * 校验object参数 + * + * @param string $object + * @throws OssException + */ + private function precheckObject($object) + { + OssUtil::throwOssExceptionWithMessageIfEmpty($object, "object name is empty"); + } + + /** + * 校验option restore + * + * @param string $restore + * @throws OssException + */ + private function precheckStorage($storage) + { + if (is_string($storage)) { + switch ($storage) { + case self::OSS_STORAGE_ARCHIVE: + return; + case self::OSS_STORAGE_IA: + return; + case self::OSS_STORAGE_STANDARD: + return; + default: + break; + } + } + throw new OssException('storage name is invalid'); + } + + /** + * 校验bucket,options参数 + * + * @param string $bucket + * @param string $object + * @param array $options + * @param bool $isCheckObject + */ + private function precheckCommon($bucket, $object, &$options, $isCheckObject = true) + { + if ($isCheckObject) { + $this->precheckObject($object); + } + $this->precheckOptions($options); + $this->precheckBucket($bucket); + } + + /** + * 参数校验 + * + * @param array $options + * @param string $param + * @param string $funcName + * @throws OssException + */ + private function precheckParam($options, $param, $funcName) + { + if (!isset($options[$param])) { + throw new OssException('The `' . $param . '` options is required in ' . $funcName . '().'); + } + } + + /** + * 检测md5 + * + * @param array $options + * @return bool|null + */ + private function isCheckMD5($options) + { + return $this->getValue($options, self::OSS_CHECK_MD5, false, true, true); + } + + /** + * 获取value + * + * @param array $options + * @param string $key + * @param string $default + * @param bool $isCheckEmpty + * @param bool $isCheckBool + * @return bool|null + */ + private function getValue($options, $key, $default = NULL, $isCheckEmpty = false, $isCheckBool = false) + { + $value = $default; + if (isset($options[$key])) { + if ($isCheckEmpty) { + if (!empty($options[$key])) { + $value = $options[$key]; + } + } else { + $value = $options[$key]; + } + unset($options[$key]); + } + if ($isCheckBool) { + if ($value !== true && $value !== false) { + $value = false; + } + } + return $value; + } + + /** + * 获取mimetype类型 + * + * @param string $object + * @return string + */ + private function getMimeType($object, $file = null) + { + if (!is_null($file)) { + $type = MimeTypes::getMimetype($file); + if (!is_null($type)) { + return $type; + } + } + + $type = MimeTypes::getMimetype($object); + if (!is_null($type)) { + return $type; + } + + return self::DEFAULT_CONTENT_TYPE; + } + + /** + * 验证并且执行请求,按照OSS Api协议,执行操作 + * + * @param array $options + * @return ResponseCore + * @throws OssException + * @throws RequestCore_Exception + */ + private function auth($options) + { + OssUtil::validateOptions($options); + //验证bucket,list_bucket时不需要验证 + $this->authPrecheckBucket($options); + //验证object + $this->authPrecheckObject($options); + //Object名称的编码必须是utf8 + $this->authPrecheckObjectEncoding($options); + //验证ACL + $this->authPrecheckAcl($options); + // 获得当次请求使用的协议头,是https还是http + $scheme = $this->useSSL ? 'https://' : 'http://'; + // 获得当次请求使用的hostname,如果是公共域名或者专有域名,bucket拼在前面构成三级域名 + $hostname = $this->generateHostname($options[self::OSS_BUCKET]); + $string_to_sign = ''; + $headers = $this->generateHeaders($options, $hostname); + $signable_query_string_params = $this->generateSignableQueryStringParam($options); + $signable_query_string = OssUtil::toQueryString($signable_query_string_params); + $resource_uri = $this->generateResourceUri($options); + //生成请求URL + $conjunction = '?'; + $non_signable_resource = ''; + if (isset($options[self::OSS_SUB_RESOURCE])) { + $conjunction = '&'; + } + if ($signable_query_string !== '') { + $signable_query_string = $conjunction . $signable_query_string; + $conjunction = '&'; + } + $query_string = $this->generateQueryString($options); + if ($query_string !== '') { + $non_signable_resource .= $conjunction . $query_string; + $conjunction = '&'; + } + $this->requestUrl = $scheme . $hostname . $resource_uri . $signable_query_string . $non_signable_resource; + + //创建请求 + $request = new RequestCore($this->requestUrl, $this->requestProxy); + $request->set_useragent($this->generateUserAgent()); + // Streaming uploads + if (isset($options[self::OSS_FILE_UPLOAD])) { + if (is_resource($options[self::OSS_FILE_UPLOAD])) { + $length = null; + + if (isset($options[self::OSS_CONTENT_LENGTH])) { + $length = $options[self::OSS_CONTENT_LENGTH]; + } elseif (isset($options[self::OSS_SEEK_TO])) { + $stats = fstat($options[self::OSS_FILE_UPLOAD]); + if ($stats && $stats[self::OSS_SIZE] >= 0) { + $length = $stats[self::OSS_SIZE] - (integer)$options[self::OSS_SEEK_TO]; + } + } + $request->set_read_stream($options[self::OSS_FILE_UPLOAD], $length); + } else { + $request->set_read_file($options[self::OSS_FILE_UPLOAD]); + $length = $request->read_stream_size; + if (isset($options[self::OSS_CONTENT_LENGTH])) { + $length = $options[self::OSS_CONTENT_LENGTH]; + } elseif (isset($options[self::OSS_SEEK_TO]) && isset($length)) { + $length -= (integer)$options[self::OSS_SEEK_TO]; + } + $request->set_read_stream_size($length); + } + } + if (isset($options[self::OSS_SEEK_TO])) { + $request->set_seek_position((integer)$options[self::OSS_SEEK_TO]); + } + if (isset($options[self::OSS_FILE_DOWNLOAD])) { + if (is_resource($options[self::OSS_FILE_DOWNLOAD])) { + $request->set_write_stream($options[self::OSS_FILE_DOWNLOAD]); + } else { + $request->set_write_file($options[self::OSS_FILE_DOWNLOAD]); + } + } + + if (isset($options[self::OSS_METHOD])) { + $request->set_method($options[self::OSS_METHOD]); + $string_to_sign .= $options[self::OSS_METHOD] . "\n"; + } + + if (isset($options[self::OSS_CONTENT])) { + $request->set_body($options[self::OSS_CONTENT]); + if ($headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded') { + $headers[self::OSS_CONTENT_TYPE] = 'application/octet-stream'; + } + + $headers[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]); + $headers[self::OSS_CONTENT_MD5] = base64_encode(md5($options[self::OSS_CONTENT], true)); + } + + if (isset($options[self::OSS_CALLBACK])) { + $headers[self::OSS_CALLBACK] = base64_encode($options[self::OSS_CALLBACK]); + } + if (isset($options[self::OSS_CALLBACK_VAR])) { + $headers[self::OSS_CALLBACK_VAR] = base64_encode($options[self::OSS_CALLBACK_VAR]); + } + + if (!isset($headers[self::OSS_ACCEPT_ENCODING])) { + $headers[self::OSS_ACCEPT_ENCODING] = ''; + } + + uksort($headers, 'strnatcasecmp'); + + foreach ($headers as $header_key => $header_value) { + $header_value = str_replace(array("\r", "\n"), '', $header_value); + if ($header_value !== '' || $header_key === self::OSS_ACCEPT_ENCODING) { + $request->add_header($header_key, $header_value); + } + + if ( + strtolower($header_key) === 'content-md5' || + strtolower($header_key) === 'content-type' || + strtolower($header_key) === 'date' || + (isset($options['self::OSS_PREAUTH']) && (integer)$options['self::OSS_PREAUTH'] > 0) + ) { + $string_to_sign .= $header_value . "\n"; + } elseif (substr(strtolower($header_key), 0, 6) === self::OSS_DEFAULT_PREFIX) { + $string_to_sign .= strtolower($header_key) . ':' . $header_value . "\n"; + } + } + // 生成 signable_resource + $signable_resource = $this->generateSignableResource($options); + $string_to_sign .= rawurldecode($signable_resource) . urldecode($signable_query_string); + + //对?后面的要签名的string字母序排序 + $string_to_sign_ordered = $this->stringToSignSorted($string_to_sign); + + $signature = base64_encode(hash_hmac('sha1', $string_to_sign_ordered, $this->accessKeySecret, true)); + $request->add_header('Authorization', 'OSS ' . $this->accessKeyId . ':' . $signature); + + if (isset($options[self::OSS_PREAUTH]) && (integer)$options[self::OSS_PREAUTH] > 0) { + $signed_url = $this->requestUrl . $conjunction . self::OSS_URL_ACCESS_KEY_ID . '=' . rawurlencode($this->accessKeyId) . '&' . self::OSS_URL_EXPIRES . '=' . $options[self::OSS_PREAUTH] . '&' . self::OSS_URL_SIGNATURE . '=' . rawurlencode($signature); + return $signed_url; + } elseif (isset($options[self::OSS_PREAUTH])) { + return $this->requestUrl; + } + + if ($this->timeout !== 0) { + $request->timeout = $this->timeout; + } + if ($this->connectTimeout !== 0) { + $request->connect_timeout = $this->connectTimeout; + } + + try { + $request->send_request(); + } catch (RequestCore_Exception $e) { + throw(new OssException('RequestCoreException: ' . $e->getMessage())); + } + $response_header = $request->get_response_header(); + $response_header['oss-request-url'] = $this->requestUrl; + $response_header['oss-redirects'] = $this->redirects; + $response_header['oss-stringtosign'] = $string_to_sign; + $response_header['oss-requestheaders'] = $request->request_headers; + + $data = new ResponseCore($response_header, $request->get_response_body(), $request->get_response_code()); + //retry if OSS Internal Error + if ((integer)$request->get_response_code() === 500) { + if ($this->redirects <= $this->maxRetries) { + //设置休眠 + $delay = (integer)(pow(4, $this->redirects) * 100000); + usleep($delay); + $this->redirects++; + $data = $this->auth($options); + } + } + + $this->redirects = 0; + return $data; + } + + /** + * 设置最大尝试次数 + * + * @param int $maxRetries + * @return void + */ + public function setMaxTries($maxRetries = 3) + { + $this->maxRetries = $maxRetries; + } + + /** + * 获取最大尝试次数 + * + * @return int + */ + public function getMaxRetries() + { + return $this->maxRetries; + } + + /** + * 打开sts enable标志,使用户构造函数中传入的$sts生效 + * + * @param boolean $enable + */ + public function setSignStsInUrl($enable) + { + $this->enableStsInUrl = $enable; + } + + /** + * @return boolean + */ + public function isUseSSL() + { + return $this->useSSL; + } + + /** + * @param boolean $useSSL + */ + public function setUseSSL($useSSL) + { + $this->useSSL = $useSSL; + } + + /** + * 检查bucket名称格式是否正确,如果非法抛出异常 + * + * @param $options + * @throws OssException + */ + private function authPrecheckBucket($options) + { + if (!(('/' == $options[self::OSS_OBJECT]) && ('' == $options[self::OSS_BUCKET]) && ('GET' == $options[self::OSS_METHOD])) && !OssUtil::validateBucket($options[self::OSS_BUCKET])) { + throw new OssException('"' . $options[self::OSS_BUCKET] . '"' . 'bucket name is invalid'); + } + } + + /** + * + * 检查object名称格式是否正确,如果非法抛出异常 + * + * @param $options + * @throws OssException + */ + private function authPrecheckObject($options) + { + if (isset($options[self::OSS_OBJECT]) && $options[self::OSS_OBJECT] === '/') { + return; + } + + if (isset($options[self::OSS_OBJECT]) && !OssUtil::validateObject($options[self::OSS_OBJECT])) { + throw new OssException('"' . $options[self::OSS_OBJECT] . '"' . ' object name is invalid'); + } + } + + /** + * 检查object的编码,如果是gbk或者gb2312则尝试将其转化为utf8编码 + * + * @param mixed $options 参数 + */ + private function authPrecheckObjectEncoding(&$options) + { + $tmp_object = $options[self::OSS_OBJECT]; + try { + if (OssUtil::isGb2312($options[self::OSS_OBJECT])) { + $options[self::OSS_OBJECT] = iconv('GB2312', "UTF-8//IGNORE", $options[self::OSS_OBJECT]); + } elseif (OssUtil::checkChar($options[self::OSS_OBJECT], true)) { + $options[self::OSS_OBJECT] = iconv('GBK', "UTF-8//IGNORE", $options[self::OSS_OBJECT]); + } + } catch (\Exception $e) { + try { + $tmp_object = iconv(mb_detect_encoding($tmp_object), "UTF-8", $tmp_object); + } catch (\Exception $e) { + } + } + $options[self::OSS_OBJECT] = $tmp_object; + } + + /** + * 检查ACL是否是预定义中三种之一,如果不是抛出异常 + * + * @param $options + * @throws OssException + */ + private function authPrecheckAcl($options) + { + if (isset($options[self::OSS_HEADERS][self::OSS_ACL]) && !empty($options[self::OSS_HEADERS][self::OSS_ACL])) { + if (!in_array(strtolower($options[self::OSS_HEADERS][self::OSS_ACL]), self::$OSS_ACL_TYPES)) { + throw new OssException($options[self::OSS_HEADERS][self::OSS_ACL] . ':' . 'acl is invalid(private,public-read,public-read-write)'); + } + } + } + + /** + * 获得档次请求使用的域名 + * bucket在前的三级域名,或者二级域名,如果是cname或者ip的话,则是二级域名 + * + * @param $bucket + * @return string 剥掉协议头的域名 + */ + private function generateHostname($bucket) + { + if ($this->hostType === self::OSS_HOST_TYPE_IP) { + $hostname = $this->hostname; + } elseif ($this->hostType === self::OSS_HOST_TYPE_CNAME) { + $hostname = $this->hostname; + } else { + // 专有域或者官网endpoint + $hostname = ($bucket == '') ? $this->hostname : ($bucket . '.') . $this->hostname; + } + return $hostname; + } + + /** + * 获得当次请求的资源定位字段 + * + * @param $options + * @return string 资源定位字段 + */ + private function generateResourceUri($options) + { + $resource_uri = ""; + + // resource_uri + bucket + if (isset($options[self::OSS_BUCKET]) && '' !== $options[self::OSS_BUCKET]) { + if ($this->hostType === self::OSS_HOST_TYPE_IP) { + $resource_uri = '/' . $options[self::OSS_BUCKET]; + } + } + + // resource_uri + object + if (isset($options[self::OSS_OBJECT]) && '/' !== $options[self::OSS_OBJECT]) { + $resource_uri .= '/' . str_replace(array('%2F', '%25'), array('/', '%'), rawurlencode($options[self::OSS_OBJECT])); + } + + // resource_uri + sub_resource + $conjunction = '?'; + if (isset($options[self::OSS_SUB_RESOURCE])) { + $resource_uri .= $conjunction . $options[self::OSS_SUB_RESOURCE]; + } + return $resource_uri; + } + + /** + * 生成signalbe_query_string_param, array类型 + * + * @param array $options + * @return array + */ + private function generateSignableQueryStringParam($options) + { + $signableQueryStringParams = array(); + $signableList = array( + self::OSS_PART_NUM, + 'response-content-type', + 'response-content-language', + 'response-cache-control', + 'response-content-encoding', + 'response-expires', + 'response-content-disposition', + self::OSS_UPLOAD_ID, + self::OSS_COMP, + self::OSS_LIVE_CHANNEL_STATUS, + self::OSS_LIVE_CHANNEL_START_TIME, + self::OSS_LIVE_CHANNEL_END_TIME, + self::OSS_PROCESS, + self::OSS_POSITION, + self::OSS_SYMLINK, + self::OSS_RESTORE, + ); + + foreach ($signableList as $item) { + if (isset($options[$item])) { + $signableQueryStringParams[$item] = $options[$item]; + } + } + + if ($this->enableStsInUrl && (!is_null($this->securityToken))) { + $signableQueryStringParams["security-token"] = $this->securityToken; + } + + return $signableQueryStringParams; + } + + /** + * 生成用于签名resource段 + * + * @param mixed $options + * @return string + */ + private function generateSignableResource($options) + { + $signableResource = ""; + $signableResource .= '/'; + if (isset($options[self::OSS_BUCKET]) && '' !== $options[self::OSS_BUCKET]) { + $signableResource .= $options[self::OSS_BUCKET]; + // 如果操作没有Object操作的话,这里最后是否有斜线有个trick,ip的域名下,不需要加'/', 否则需要加'/' + if ($options[self::OSS_OBJECT] == '/') { + if ($this->hostType !== self::OSS_HOST_TYPE_IP) { + $signableResource .= "/"; + } + } + } + //signable_resource + object + if (isset($options[self::OSS_OBJECT]) && '/' !== $options[self::OSS_OBJECT]) { + $signableResource .= '/' . str_replace(array('%2F', '%25'), array('/', '%'), rawurlencode($options[self::OSS_OBJECT])); + } + if (isset($options[self::OSS_SUB_RESOURCE])) { + $signableResource .= '?' . $options[self::OSS_SUB_RESOURCE]; + } + return $signableResource; + } + + /** + * 生成query_string + * + * @param mixed $options + * @return string + */ + private function generateQueryString($options) + { + //请求参数 + $queryStringParams = array(); + if (isset($options[self::OSS_QUERY_STRING])) { + $queryStringParams = array_merge($queryStringParams, $options[self::OSS_QUERY_STRING]); + } + return OssUtil::toQueryString($queryStringParams); + } + + private function stringToSignSorted($string_to_sign) + { + $queryStringSorted = ''; + $explodeResult = explode('?', $string_to_sign); + $index = count($explodeResult); + if ($index === 1) + return $string_to_sign; + + $queryStringParams = explode('&', $explodeResult[$index - 1]); + sort($queryStringParams); + + foreach ($queryStringParams as $params) { + $queryStringSorted .= $params . '&'; + } + + $queryStringSorted = substr($queryStringSorted, 0, -1); + + return $explodeResult[0] . '?' . $queryStringSorted; + } + + /** + * 初始化headers + * + * @param mixed $options + * @param string $hostname hostname + * @return array + */ + private function generateHeaders($options, $hostname) + { + $headers = array( + self::OSS_CONTENT_MD5 => '', + self::OSS_CONTENT_TYPE => isset($options[self::OSS_CONTENT_TYPE]) ? $options[self::OSS_CONTENT_TYPE] : self::DEFAULT_CONTENT_TYPE, + self::OSS_DATE => isset($options[self::OSS_DATE]) ? $options[self::OSS_DATE] : gmdate('D, d M Y H:i:s \G\M\T'), + self::OSS_HOST => $hostname, + ); + if (isset($options[self::OSS_CONTENT_MD5])) { + $headers[self::OSS_CONTENT_MD5] = $options[self::OSS_CONTENT_MD5]; + } + + //添加stsSecurityToken + if ((!is_null($this->securityToken)) && (!$this->enableStsInUrl)) { + $headers[self::OSS_SECURITY_TOKEN] = $this->securityToken; + } + //合并HTTP headers + if (isset($options[self::OSS_HEADERS])) { + $headers = array_merge($headers, $options[self::OSS_HEADERS]); + } + return $headers; + } + + /** + * 生成请求用的UserAgent + * + * @return string + */ + private function generateUserAgent() + { + return self::OSS_NAME . "/" . self::OSS_VERSION . " (" . php_uname('s') . "/" . php_uname('r') . "/" . php_uname('m') . ";" . PHP_VERSION . ")"; + } + + /** + * 检查endpoint的种类 + * 如有有协议头,剥去协议头 + * 并且根据参数 is_cname 和endpoint本身,判定域名类型,是ip,cname,还是专有域或者官网域名 + * + * @param string $endpoint + * @param boolean $isCName + * @return string 剥掉协议头的域名 + */ + private function checkEndpoint($endpoint, $isCName) + { + $ret_endpoint = null; + if (strpos($endpoint, 'http://') === 0) { + $ret_endpoint = substr($endpoint, strlen('http://')); + } elseif (strpos($endpoint, 'https://') === 0) { + $ret_endpoint = substr($endpoint, strlen('https://')); + $this->useSSL = true; + } else { + $ret_endpoint = $endpoint; + } + + if ($isCName) { + $this->hostType = self::OSS_HOST_TYPE_CNAME; + } elseif (OssUtil::isIPFormat($ret_endpoint)) { + $this->hostType = self::OSS_HOST_TYPE_IP; + } else { + $this->hostType = self::OSS_HOST_TYPE_NORMAL; + } + return $ret_endpoint; + } + + /** + * 用来检查sdk所以来的扩展是否打开 + * + * @throws OssException + */ + public static function checkEnv() + { + if (function_exists('get_loaded_extensions')) { + //检测curl扩展 + $enabled_extension = array("curl"); + $extensions = get_loaded_extensions(); + if ($extensions) { + foreach ($enabled_extension as $item) { + if (!in_array($item, $extensions)) { + throw new OssException("Extension {" . $item . "} is not installed or not enabled, please check your php env."); + } + } + } else { + throw new OssException("function get_loaded_extensions not found."); + } + } else { + throw new OssException('Function get_loaded_extensions has been disabled, please check php config.'); + } + } + + /** + * //* 设置http库的请求超时时间,单位秒 + * + * @param int $timeout + */ + public function setTimeout($timeout) + { + $this->timeout = $timeout; + } + + /** + * 设置http库的连接超时时间,单位秒 + * + * @param int $connectTimeout + */ + public function setConnectTimeout($connectTimeout) + { + $this->connectTimeout = $connectTimeout; + } + + // 生命周期相关常量 + const OSS_LIFECYCLE_EXPIRATION = "Expiration"; + const OSS_LIFECYCLE_TIMING_DAYS = "Days"; + const OSS_LIFECYCLE_TIMING_DATE = "Date"; + //OSS 内部常量 + const OSS_BUCKET = 'bucket'; + const OSS_OBJECT = 'object'; + const OSS_HEADERS = OssUtil::OSS_HEADERS; + const OSS_METHOD = 'method'; + const OSS_QUERY = 'query'; + const OSS_BASENAME = 'basename'; + const OSS_MAX_KEYS = 'max-keys'; + const OSS_UPLOAD_ID = 'uploadId'; + const OSS_PART_NUM = 'partNumber'; + const OSS_COMP = 'comp'; + const OSS_LIVE_CHANNEL_STATUS = 'status'; + const OSS_LIVE_CHANNEL_START_TIME = 'startTime'; + const OSS_LIVE_CHANNEL_END_TIME = 'endTime'; + const OSS_POSITION = 'position'; + const OSS_MAX_KEYS_VALUE = 100; + const OSS_MAX_OBJECT_GROUP_VALUE = OssUtil::OSS_MAX_OBJECT_GROUP_VALUE; + const OSS_MAX_PART_SIZE = OssUtil::OSS_MAX_PART_SIZE; + const OSS_MID_PART_SIZE = OssUtil::OSS_MID_PART_SIZE; + const OSS_MIN_PART_SIZE = OssUtil::OSS_MIN_PART_SIZE; + const OSS_FILE_SLICE_SIZE = 8192; + const OSS_PREFIX = 'prefix'; + const OSS_DELIMITER = 'delimiter'; + const OSS_MARKER = 'marker'; + const OSS_ACCEPT_ENCODING = 'Accept-Encoding'; + const OSS_CONTENT_MD5 = 'Content-Md5'; + const OSS_SELF_CONTENT_MD5 = 'x-oss-meta-md5'; + const OSS_CONTENT_TYPE = 'Content-Type'; + const OSS_CONTENT_LENGTH = 'Content-Length'; + const OSS_IF_MODIFIED_SINCE = 'If-Modified-Since'; + const OSS_IF_UNMODIFIED_SINCE = 'If-Unmodified-Since'; + const OSS_IF_MATCH = 'If-Match'; + const OSS_IF_NONE_MATCH = 'If-None-Match'; + const OSS_CACHE_CONTROL = 'Cache-Control'; + const OSS_EXPIRES = 'Expires'; + const OSS_PREAUTH = 'preauth'; + const OSS_CONTENT_COING = 'Content-Coding'; + const OSS_CONTENT_DISPOSTION = 'Content-Disposition'; + const OSS_RANGE = 'range'; + const OSS_ETAG = 'etag'; + const OSS_LAST_MODIFIED = 'lastmodified'; + const OS_CONTENT_RANGE = 'Content-Range'; + const OSS_CONTENT = OssUtil::OSS_CONTENT; + const OSS_BODY = 'body'; + const OSS_LENGTH = OssUtil::OSS_LENGTH; + const OSS_HOST = 'Host'; + const OSS_DATE = 'Date'; + const OSS_AUTHORIZATION = 'Authorization'; + const OSS_FILE_DOWNLOAD = 'fileDownload'; + const OSS_FILE_UPLOAD = 'fileUpload'; + const OSS_PART_SIZE = 'partSize'; + const OSS_SEEK_TO = 'seekTo'; + const OSS_SIZE = 'size'; + const OSS_QUERY_STRING = 'query_string'; + const OSS_SUB_RESOURCE = 'sub_resource'; + const OSS_DEFAULT_PREFIX = 'x-oss-'; + const OSS_CHECK_MD5 = 'checkmd5'; + const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + const OSS_SYMLINK_TARGET = 'x-oss-symlink-target'; + const OSS_SYMLINK = 'symlink'; + const OSS_HTTP_CODE = 'http_code'; + const OSS_REQUEST_ID = 'x-oss-request-id'; + const OSS_INFO = 'info'; + const OSS_STORAGE = 'storage'; + const OSS_RESTORE = 'restore'; + const OSS_STORAGE_STANDARD = 'Standard'; + const OSS_STORAGE_IA = 'IA'; + const OSS_STORAGE_ARCHIVE = 'Archive'; + + //私有URL变量 + const OSS_URL_ACCESS_KEY_ID = 'OSSAccessKeyId'; + const OSS_URL_EXPIRES = 'Expires'; + const OSS_URL_SIGNATURE = 'Signature'; + //HTTP方法 + const OSS_HTTP_GET = 'GET'; + const OSS_HTTP_PUT = 'PUT'; + const OSS_HTTP_HEAD = 'HEAD'; + const OSS_HTTP_POST = 'POST'; + const OSS_HTTP_DELETE = 'DELETE'; + const OSS_HTTP_OPTIONS = 'OPTIONS'; + //其他常量 + const OSS_ACL = 'x-oss-acl'; + const OSS_OBJECT_ACL = 'x-oss-object-acl'; + const OSS_OBJECT_GROUP = 'x-oss-file-group'; + const OSS_MULTI_PART = 'uploads'; + const OSS_MULTI_DELETE = 'delete'; + const OSS_OBJECT_COPY_SOURCE = 'x-oss-copy-source'; + const OSS_OBJECT_COPY_SOURCE_RANGE = "x-oss-copy-source-range"; + const OSS_PROCESS = "x-oss-process"; + const OSS_CALLBACK = "x-oss-callback"; + const OSS_CALLBACK_VAR = "x-oss-callback-var"; + //支持STS SecurityToken + const OSS_SECURITY_TOKEN = "x-oss-security-token"; + const OSS_ACL_TYPE_PRIVATE = 'private'; + const OSS_ACL_TYPE_PUBLIC_READ = 'public-read'; + const OSS_ACL_TYPE_PUBLIC_READ_WRITE = 'public-read-write'; + const OSS_ENCODING_TYPE = "encoding-type"; + const OSS_ENCODING_TYPE_URL = "url"; + + // 域名类型 + const OSS_HOST_TYPE_NORMAL = "normal";//http://bucket.oss-cn-hangzhou.aliyuncs.com/object + const OSS_HOST_TYPE_IP = "ip"; //http://1.1.1.1/bucket/object + const OSS_HOST_TYPE_SPECIAL = 'special'; //http://bucket.guizhou.gov/object + const OSS_HOST_TYPE_CNAME = "cname"; //http://mydomain.com/object + //OSS ACL数组 + static $OSS_ACL_TYPES = array( + self::OSS_ACL_TYPE_PRIVATE, + self::OSS_ACL_TYPE_PUBLIC_READ, + self::OSS_ACL_TYPE_PUBLIC_READ_WRITE + ); + // OssClient版本信息 + const OSS_NAME = "aliyun-sdk-php"; + const OSS_VERSION = "2.3.0"; + const OSS_BUILD = "20180105"; + const OSS_AUTHOR = ""; + const OSS_OPTIONS_ORIGIN = 'Origin'; + const OSS_OPTIONS_REQUEST_METHOD = 'Access-Control-Request-Method'; + const OSS_OPTIONS_REQUEST_HEADERS = 'Access-Control-Request-Headers'; + + //是否使用ssl + private $useSSL = false; + private $maxRetries = 3; + private $redirects = 0; + + // 用户提供的域名类型,有四种 OSS_HOST_TYPE_NORMAL, OSS_HOST_TYPE_IP, OSS_HOST_TYPE_SPECIAL, OSS_HOST_TYPE_CNAME + private $hostType = self::OSS_HOST_TYPE_NORMAL; + private $requestUrl; + private $accessKeyId; + private $accessKeySecret; + private $hostname; + private $securityToken; + private $requestProxy = null; + private $enableStsInUrl = false; + private $timeout = 0; + private $connectTimeout = 0; +} diff --git a/addons/alioss/library/OSS/Result/AclResult.php b/addons/alioss/library/OSS/Result/AclResult.php new file mode 100644 index 0000000000000000000000000000000000000000..6da0860420ff90be9707490fc6f53370077781f2 --- /dev/null +++ b/addons/alioss/library/OSS/Result/AclResult.php @@ -0,0 +1,32 @@ +rawResponse->body; + if (empty($content)) { + throw new OssException("body is null"); + } + $xml = simplexml_load_string($content); + if (isset($xml->AccessControlList->Grant)) { + return strval($xml->AccessControlList->Grant); + } else { + throw new OssException("xml format exception"); + } + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/AppendResult.php b/addons/alioss/library/OSS/Result/AppendResult.php new file mode 100644 index 0000000000000000000000000000000000000000..433c03eb13cfae73113d332beb6e23e8c367e4b8 --- /dev/null +++ b/addons/alioss/library/OSS/Result/AppendResult.php @@ -0,0 +1,27 @@ +rawResponse->header; + if (isset($header["x-oss-next-append-position"])) { + return intval($header["x-oss-next-append-position"]); + } + throw new OssException("cannot get next-append-position"); + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/BodyResult.php b/addons/alioss/library/OSS/Result/BodyResult.php new file mode 100644 index 0000000000000000000000000000000000000000..44ba15ef5864bbed254158fb440e24ee8345670c --- /dev/null +++ b/addons/alioss/library/OSS/Result/BodyResult.php @@ -0,0 +1,19 @@ +rawResponse->body) ? "" : $this->rawResponse->body; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/CallbackResult.php b/addons/alioss/library/OSS/Result/CallbackResult.php new file mode 100644 index 0000000000000000000000000000000000000000..514e985c244d47b0c3993b8280e103a49c0f3527 --- /dev/null +++ b/addons/alioss/library/OSS/Result/CallbackResult.php @@ -0,0 +1,21 @@ +rawResponse->status; + if ((int)(intval($status) / 100) == 2 && (int)(intval($status)) !== 203) { + return true; + } + return false; + } + +} diff --git a/addons/alioss/library/OSS/Result/CopyObjectResult.php b/addons/alioss/library/OSS/Result/CopyObjectResult.php new file mode 100644 index 0000000000000000000000000000000000000000..498723e1b0b8045018c4b83df25ae8d1d19e0d75 --- /dev/null +++ b/addons/alioss/library/OSS/Result/CopyObjectResult.php @@ -0,0 +1,30 @@ +rawResponse->body; + $xml = simplexml_load_string($body); + $result = array(); + + if (isset($xml->LastModified)) { + $result[] = $xml->LastModified; + } + if (isset($xml->ETag)) { + $result[] = $xml->ETag; + } + + return $result; + } +} diff --git a/addons/alioss/library/OSS/Result/DeleteObjectsResult.php b/addons/alioss/library/OSS/Result/DeleteObjectsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..dc373b85459b9fb6e5041cf37ab14f7d5df48c1e --- /dev/null +++ b/addons/alioss/library/OSS/Result/DeleteObjectsResult.php @@ -0,0 +1,27 @@ +rawResponse->body; + $xml = simplexml_load_string($body); + $objects = array(); + + if (isset($xml->Deleted)) { + foreach($xml->Deleted as $deleteKey) + $objects[] = $deleteKey->Key; + } + return $objects; + } +} diff --git a/addons/alioss/library/OSS/Result/ExistResult.php b/addons/alioss/library/OSS/Result/ExistResult.php new file mode 100644 index 0000000000000000000000000000000000000000..f7aa287c8d566aba591a11ab8328c9938dd6293d --- /dev/null +++ b/addons/alioss/library/OSS/Result/ExistResult.php @@ -0,0 +1,35 @@ +rawResponse->status) === 200 ? true : false; + } + + /** + * 根据返回http状态码判断,[200-299]即认为是OK, 判断是否存在的接口,404也认为是一种 + * 有效响应 + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/GetCnameResult.php b/addons/alioss/library/OSS/Result/GetCnameResult.php new file mode 100644 index 0000000000000000000000000000000000000000..eed01f9021cb7acadbd77a249c82e8ff9e3e8db9 --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetCnameResult.php @@ -0,0 +1,19 @@ +rawResponse->body; + $config = new CnameConfig(); + $config->parseFromXml($content); + return $config; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/GetCorsResult.php b/addons/alioss/library/OSS/Result/GetCorsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..a51afe2a80787220943acab953147a7381e232ca --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetCorsResult.php @@ -0,0 +1,35 @@ +rawResponse->body; + $config = new CorsConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种 + * 有效响应 + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/GetLifecycleResult.php b/addons/alioss/library/OSS/Result/GetLifecycleResult.php new file mode 100644 index 0000000000000000000000000000000000000000..6b440c35217829ef537230ed3fc6c8c38c7fab6e --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetLifecycleResult.php @@ -0,0 +1,41 @@ +rawResponse->body; + $config = new LifecycleConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种 + * 有效响应 + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/GetLiveChannelHistoryResult.php b/addons/alioss/library/OSS/Result/GetLiveChannelHistoryResult.php new file mode 100644 index 0000000000000000000000000000000000000000..202a6681df7829ffe5ddc482c60b7f47e4432e65 --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetLiveChannelHistoryResult.php @@ -0,0 +1,19 @@ +rawResponse->body; + $channelList = new GetLiveChannelHistory(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/addons/alioss/library/OSS/Result/GetLiveChannelInfoResult.php b/addons/alioss/library/OSS/Result/GetLiveChannelInfoResult.php new file mode 100644 index 0000000000000000000000000000000000000000..d5a9005e756073db2e1db7bf02db84f7b5579129 --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetLiveChannelInfoResult.php @@ -0,0 +1,19 @@ +rawResponse->body; + $channelList = new GetLiveChannelInfo(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/addons/alioss/library/OSS/Result/GetLiveChannelStatusResult.php b/addons/alioss/library/OSS/Result/GetLiveChannelStatusResult.php new file mode 100644 index 0000000000000000000000000000000000000000..6b8a60f5946af98b5b92b369948d35996095ae96 --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetLiveChannelStatusResult.php @@ -0,0 +1,19 @@ +rawResponse->body; + $channelList = new GetLiveChannelStatus(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/addons/alioss/library/OSS/Result/GetLocationResult.php b/addons/alioss/library/OSS/Result/GetLocationResult.php new file mode 100644 index 0000000000000000000000000000000000000000..71c4c96e9629489435ebe69328d67623e62663fa --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetLocationResult.php @@ -0,0 +1,30 @@ +rawResponse->body; + if (empty($content)) { + throw new OssException("body is null"); + } + $xml = simplexml_load_string($content); + return $xml; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/GetLoggingResult.php b/addons/alioss/library/OSS/Result/GetLoggingResult.php new file mode 100644 index 0000000000000000000000000000000000000000..72fc3aeb19931a7c99065a079fe0418284ed1726 --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetLoggingResult.php @@ -0,0 +1,41 @@ +rawResponse->body; + $config = new LoggingConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种 + * 有效响应 + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/GetRefererResult.php b/addons/alioss/library/OSS/Result/GetRefererResult.php new file mode 100644 index 0000000000000000000000000000000000000000..aee50d3aec447928c3e4aabdda5c6b1c8fb65ec6 --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetRefererResult.php @@ -0,0 +1,41 @@ +rawResponse->body; + $config = new RefererConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种 + * 有效响应 + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/GetStorageCapacityResult.php b/addons/alioss/library/OSS/Result/GetStorageCapacityResult.php new file mode 100644 index 0000000000000000000000000000000000000000..84e4916067a262cbdd6ef2e04eae9f388a30fb1e --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetStorageCapacityResult.php @@ -0,0 +1,34 @@ +rawResponse->body; + if (empty($content)) { + throw new OssException("body is null"); + } + $xml = simplexml_load_string($content); + if (isset($xml->StorageCapacity)) { + return intval($xml->StorageCapacity); + } else { + throw new OssException("xml format exception"); + } + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/GetWebsiteResult.php b/addons/alioss/library/OSS/Result/GetWebsiteResult.php new file mode 100644 index 0000000000000000000000000000000000000000..3099172cd6fdeeb7c14af1c102cf95026bf0073c --- /dev/null +++ b/addons/alioss/library/OSS/Result/GetWebsiteResult.php @@ -0,0 +1,40 @@ +rawResponse->body; + $config = new WebsiteConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * 根据返回http状态码判断,[200-299]即认为是OK, 获取bucket相关配置的接口,404也认为是一种 + * 有效响应 + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/HeaderResult.php b/addons/alioss/library/OSS/Result/HeaderResult.php new file mode 100644 index 0000000000000000000000000000000000000000..c9aae561ffd2608ce44135994e0b2046c94c9388 --- /dev/null +++ b/addons/alioss/library/OSS/Result/HeaderResult.php @@ -0,0 +1,23 @@ +rawResponse->header) ? array() : $this->rawResponse->header; + } + +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/InitiateMultipartUploadResult.php b/addons/alioss/library/OSS/Result/InitiateMultipartUploadResult.php new file mode 100644 index 0000000000000000000000000000000000000000..af985f272418e85a5fb148a1a7e7df23745de9dc --- /dev/null +++ b/addons/alioss/library/OSS/Result/InitiateMultipartUploadResult.php @@ -0,0 +1,29 @@ +rawResponse->body; + $xml = simplexml_load_string($content); + if (isset($xml->UploadId)) { + return strval($xml->UploadId); + } + throw new OssException("cannot get UploadId"); + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/ListBucketsResult.php b/addons/alioss/library/OSS/Result/ListBucketsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..a58fb2d612a25cc227e7abf0d8c76587cf4afa73 --- /dev/null +++ b/addons/alioss/library/OSS/Result/ListBucketsResult.php @@ -0,0 +1,33 @@ +rawResponse->body; + $xml = new \SimpleXMLElement($content); + if (isset($xml->Buckets) && isset($xml->Buckets->Bucket)) { + foreach ($xml->Buckets->Bucket as $bucket) { + $bucketInfo = new BucketInfo(strval($bucket->Location), + strval($bucket->Name), + strval($bucket->CreationDate)); + $bucketList[] = $bucketInfo; + } + } + return new BucketListInfo($bucketList); + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/ListLiveChannelResult.php b/addons/alioss/library/OSS/Result/ListLiveChannelResult.php new file mode 100644 index 0000000000000000000000000000000000000000..1a6e2a41fe96377000669f0c84bb66c490d3e44b --- /dev/null +++ b/addons/alioss/library/OSS/Result/ListLiveChannelResult.php @@ -0,0 +1,16 @@ +rawResponse->body; + $channelList = new LiveChannelListInfo(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/addons/alioss/library/OSS/Result/ListMultipartUploadResult.php b/addons/alioss/library/OSS/Result/ListMultipartUploadResult.php new file mode 100644 index 0000000000000000000000000000000000000000..bcb20bf5945cdb83f6c97579e8c5a218c5dcffe9 --- /dev/null +++ b/addons/alioss/library/OSS/Result/ListMultipartUploadResult.php @@ -0,0 +1,55 @@ +rawResponse->body; + $xml = simplexml_load_string($content); + + $encodingType = isset($xml->EncodingType) ? strval($xml->EncodingType) : ""; + $bucket = isset($xml->Bucket) ? strval($xml->Bucket) : ""; + $keyMarker = isset($xml->KeyMarker) ? strval($xml->KeyMarker) : ""; + $keyMarker = OssUtil::decodeKey($keyMarker, $encodingType); + $uploadIdMarker = isset($xml->UploadIdMarker) ? strval($xml->UploadIdMarker) : ""; + $nextKeyMarker = isset($xml->NextKeyMarker) ? strval($xml->NextKeyMarker) : ""; + $nextKeyMarker = OssUtil::decodeKey($nextKeyMarker, $encodingType); + $nextUploadIdMarker = isset($xml->NextUploadIdMarker) ? strval($xml->NextUploadIdMarker) : ""; + $delimiter = isset($xml->Delimiter) ? strval($xml->Delimiter) : ""; + $delimiter = OssUtil::decodeKey($delimiter, $encodingType); + $prefix = isset($xml->Prefix) ? strval($xml->Prefix) : ""; + $prefix = OssUtil::decodeKey($prefix, $encodingType); + $maxUploads = isset($xml->MaxUploads) ? intval($xml->MaxUploads) : 0; + $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : ""; + $listUpload = array(); + + if (isset($xml->Upload)) { + foreach ($xml->Upload as $upload) { + $key = isset($upload->Key) ? strval($upload->Key) : ""; + $key = OssUtil::decodeKey($key, $encodingType); + $uploadId = isset($upload->UploadId) ? strval($upload->UploadId) : ""; + $initiated = isset($upload->Initiated) ? strval($upload->Initiated) : ""; + $listUpload[] = new UploadInfo($key, $uploadId, $initiated); + } + } + return new ListMultipartUploadInfo($bucket, $keyMarker, $uploadIdMarker, + $nextKeyMarker, $nextUploadIdMarker, + $delimiter, $prefix, $maxUploads, $isTruncated, $listUpload); + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/ListObjectsResult.php b/addons/alioss/library/OSS/Result/ListObjectsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..fcf493d25d166d9e58d12add25fa907af9931cd6 --- /dev/null +++ b/addons/alioss/library/OSS/Result/ListObjectsResult.php @@ -0,0 +1,71 @@ +rawResponse->body); + $encodingType = isset($xml->EncodingType) ? strval($xml->EncodingType) : ""; + $objectList = $this->parseObjectList($xml, $encodingType); + $prefixList = $this->parsePrefixList($xml, $encodingType); + $bucketName = isset($xml->Name) ? strval($xml->Name) : ""; + $prefix = isset($xml->Prefix) ? strval($xml->Prefix) : ""; + $prefix = OssUtil::decodeKey($prefix, $encodingType); + $marker = isset($xml->Marker) ? strval($xml->Marker) : ""; + $marker = OssUtil::decodeKey($marker, $encodingType); + $maxKeys = isset($xml->MaxKeys) ? intval($xml->MaxKeys) : 0; + $delimiter = isset($xml->Delimiter) ? strval($xml->Delimiter) : ""; + $delimiter = OssUtil::decodeKey($delimiter, $encodingType); + $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : ""; + $nextMarker = isset($xml->NextMarker) ? strval($xml->NextMarker) : ""; + $nextMarker = OssUtil::decodeKey($nextMarker, $encodingType); + return new ObjectListInfo($bucketName, $prefix, $marker, $nextMarker, $maxKeys, $delimiter, $isTruncated, $objectList, $prefixList); + } + + private function parseObjectList($xml, $encodingType) + { + $retList = array(); + if (isset($xml->Contents)) { + foreach ($xml->Contents as $content) { + $key = isset($content->Key) ? strval($content->Key) : ""; + $key = OssUtil::decodeKey($key, $encodingType); + $lastModified = isset($content->LastModified) ? strval($content->LastModified) : ""; + $eTag = isset($content->ETag) ? strval($content->ETag) : ""; + $type = isset($content->Type) ? strval($content->Type) : ""; + $size = isset($content->Size) ? intval($content->Size) : 0; + $storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : ""; + $retList[] = new ObjectInfo($key, $lastModified, $eTag, $type, $size, $storageClass); + } + } + return $retList; + } + + private function parsePrefixList($xml, $encodingType) + { + $retList = array(); + if (isset($xml->CommonPrefixes)) { + foreach ($xml->CommonPrefixes as $commonPrefix) { + $prefix = isset($commonPrefix->Prefix) ? strval($commonPrefix->Prefix) : ""; + $prefix = OssUtil::decodeKey($prefix, $encodingType); + $retList[] = new PrefixInfo($prefix); + } + } + return $retList; + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/ListPartsResult.php b/addons/alioss/library/OSS/Result/ListPartsResult.php new file mode 100644 index 0000000000000000000000000000000000000000..fd8a1b863f063ae570990b9fc409769226d19ea7 --- /dev/null +++ b/addons/alioss/library/OSS/Result/ListPartsResult.php @@ -0,0 +1,42 @@ +rawResponse->body; + $xml = simplexml_load_string($content); + $bucket = isset($xml->Bucket) ? strval($xml->Bucket) : ""; + $key = isset($xml->Key) ? strval($xml->Key) : ""; + $uploadId = isset($xml->UploadId) ? strval($xml->UploadId) : ""; + $nextPartNumberMarker = isset($xml->NextPartNumberMarker) ? intval($xml->NextPartNumberMarker) : ""; + $maxParts = isset($xml->MaxParts) ? intval($xml->MaxParts) : ""; + $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : ""; + $partList = array(); + if (isset($xml->Part)) { + foreach ($xml->Part as $part) { + $partNumber = isset($part->PartNumber) ? intval($part->PartNumber) : ""; + $lastModified = isset($part->LastModified) ? strval($part->LastModified) : ""; + $eTag = isset($part->ETag) ? strval($part->ETag) : ""; + $size = isset($part->Size) ? intval($part->Size) : ""; + $partList[] = new PartInfo($partNumber, $lastModified, $eTag, $size); + } + } + return new ListPartsInfo($bucket, $key, $uploadId, $nextPartNumberMarker, $maxParts, $isTruncated, $partList); + } +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/PutLiveChannelResult.php b/addons/alioss/library/OSS/Result/PutLiveChannelResult.php new file mode 100644 index 0000000000000000000000000000000000000000..dcac86b78ea3c026a19cbf44f0d66e9513861227 --- /dev/null +++ b/addons/alioss/library/OSS/Result/PutLiveChannelResult.php @@ -0,0 +1,16 @@ +rawResponse->body; + $channel = new LiveChannelInfo(); + $channel->parseFromXml($content); + return $channel; + } +} diff --git a/addons/alioss/library/OSS/Result/PutSetDeleteResult.php b/addons/alioss/library/OSS/Result/PutSetDeleteResult.php new file mode 100644 index 0000000000000000000000000000000000000000..97af003b6c05fece815cae0eb0f2357523a0c435 --- /dev/null +++ b/addons/alioss/library/OSS/Result/PutSetDeleteResult.php @@ -0,0 +1,20 @@ + $this->rawResponse->body); + return array_merge($this->rawResponse->header, $body); + } +} diff --git a/addons/alioss/library/OSS/Result/Result.php b/addons/alioss/library/OSS/Result/Result.php new file mode 100644 index 0000000000000000000000000000000000000000..491256f00a46b3167eb699c7e4428ac643146544 --- /dev/null +++ b/addons/alioss/library/OSS/Result/Result.php @@ -0,0 +1,175 @@ +rawResponse = $response; + $this->parseResponse(); + } + + /** + * 获取requestId + * + * @return string + */ + public function getRequestId() + { + if (isset($this->rawResponse) && + isset($this->rawResponse->header) && + isset($this->rawResponse->header['x-oss-request-id']) + ) { + return $this->rawResponse->header['x-oss-request-id']; + } else { + return ''; + } + } + + /** + * 得到返回数据,不同的请求返回数据格式不同 + * + * $return mixed + */ + public function getData() + { + return $this->parsedData; + } + + /** + * 由子类实现,不同的请求返回数据有不同的解析逻辑,由子类实现 + * + * @return mixed + */ + abstract protected function parseDataFromResponse(); + + /** + * 操作是否成功 + * + * @return mixed + */ + public function isOK() + { + return $this->isOk; + } + + /** + * @throws OssException + */ + public function parseResponse() + { + $this->isOk = $this->isResponseOk(); + if ($this->isOk) { + $this->parsedData = $this->parseDataFromResponse(); + } else { + $httpStatus = strval($this->rawResponse->status); + $requestId = strval($this->getRequestId()); + $code = $this->retrieveErrorCode($this->rawResponse->body); + $message = $this->retrieveErrorMessage($this->rawResponse->body); + $body = $this->rawResponse->body; + + $details = array( + 'status' => $httpStatus, + 'request-id' => $requestId, + 'code' => $code, + 'message' => $message, + 'body' => $body + ); + throw new OssException($details); + } + } + + /** + * 尝试从body中获取错误Message + * + * @param $body + * @return string + */ + private function retrieveErrorMessage($body) + { + if (empty($body) || false === strpos($body, 'Message)) { + return strval($xml->Message); + } + return ''; + } + + /** + * 尝试从body中获取错误Code + * + * @param $body + * @return string + */ + private function retrieveErrorCode($body) + { + if (empty($body) || false === strpos($body, 'Code)) { + return strval($xml->Code); + } + return ''; + } + + /** + * 根据返回http状态码判断,[200-299]即认为是OK + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2) { + return true; + } + return false; + } + + /** + * 返回原始的返回数据 + * + * @return ResponseCore + */ + public function getRawResponse() + { + return $this->rawResponse; + } + + /** + * 标示请求是否成功 + */ + protected $isOk = false; + /** + * 由子类解析过的数据 + */ + protected $parsedData = null; + /** + * 存放auth函数返回的原始Response + * + * @var ResponseCore + */ + protected $rawResponse; +} \ No newline at end of file diff --git a/addons/alioss/library/OSS/Result/SymlinkResult.php b/addons/alioss/library/OSS/Result/SymlinkResult.php new file mode 100644 index 0000000000000000000000000000000000000000..9c6d861a6675584f06f2f7692c060d6f4bf37d49 --- /dev/null +++ b/addons/alioss/library/OSS/Result/SymlinkResult.php @@ -0,0 +1,24 @@ +rawResponse->header[OssClient::OSS_SYMLINK_TARGET] = rawurldecode($this->rawResponse->header[OssClient::OSS_SYMLINK_TARGET]); + return $this->rawResponse->header; + } +} + diff --git a/addons/alioss/library/OSS/Result/UploadPartResult.php b/addons/alioss/library/OSS/Result/UploadPartResult.php new file mode 100644 index 0000000000000000000000000000000000000000..c6b66d4547eae3031f6d5943e4cc0d797f97ff8b --- /dev/null +++ b/addons/alioss/library/OSS/Result/UploadPartResult.php @@ -0,0 +1,28 @@ +rawResponse->header; + if (isset($header["etag"])) { + return $header["etag"]; + } + throw new OssException("cannot get ETag"); + + } +} \ No newline at end of file diff --git a/addons/cos/Cos.php b/addons/cos/Cos.php new file mode 100644 index 0000000000000000000000000000000000000000..3d5214ba2381e26ebaa58f2e6edcb49bed766e27 --- /dev/null +++ b/addons/cos/Cos.php @@ -0,0 +1,98 @@ +getConfig(); + $upload = [ + 'cdnurl' => $cosConfig['cdnurl'], + 'uploadurl' => $cosConfig['uploadurl'], + 'bucket' => $cosConfig['bucket'], + 'maxsize' => $cosConfig['maxsize'], + 'mimetype' => $cosConfig['mimetype'], + 'multipart' => [], + 'multiple' => $cosConfig['multiple'] ? true : false, + ]; + } + + /** + * 附件删除后 + */ + public function uploadDelete($attachment) + { + $config = $this->getConfig(); + if ($attachment['storage'] == 'cos' && isset($config['syncdelete']) && $config['syncdelete']) { + $url = $config['uploadurl'] . ltrim($attachment->url, '/'); + list($authorization, $token) = Auth::getAuthorization('DELETE', ltrim($attachment->url, '/')); + //删除云储存文件 + $ret = Http::sendRequest($url, [], 'DELETE', [CURLOPT_CUSTOMREQUEST => 'DELETE', CURLOPT_HTTPHEADER => ['Authorization: ' . $authorization, 'x-cos-security-token: ' . $token]]); + } + return true; + } +} diff --git a/addons/cos/assets/js/spark.js b/addons/cos/assets/js/spark.js new file mode 100644 index 0000000000000000000000000000000000000000..5a22f703dcaaae60b2b165bee5031e72f42f2c58 --- /dev/null +++ b/addons/cos/assets/js/spark.js @@ -0,0 +1 @@ +(function(factory){if(typeof exports==="object"){module.exports=factory()}else if(typeof define==="function"&&define.amd){define(factory)}else{var glob;try{glob=window}catch(e){glob=self}glob.SparkMD5=factory()}})(function(undefined){"use strict";var add32=function(a,b){return a+b&4294967295},hex_chr=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function cmn(q,a,b,x,s,t){a=add32(add32(a,q),add32(x,t));return add32(a<>>32-s,b)}function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a+=(b&c|~b&d)+k[0]-680876936|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[1]-389564586|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[2]+606105819|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[3]-1044525330|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[4]-176418897|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[5]+1200080426|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[6]-1473231341|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[7]-45705983|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[8]+1770035416|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[9]-1958414417|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[10]-42063|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[11]-1990404162|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[12]+1804603682|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[13]-40341101|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[14]-1502002290|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[15]+1236535329|0;b=(b<<22|b>>>10)+c|0;a+=(b&d|c&~d)+k[1]-165796510|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[6]-1069501632|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[11]+643717713|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[0]-373897302|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[5]-701558691|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[10]+38016083|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[15]-660478335|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[4]-405537848|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[9]+568446438|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[14]-1019803690|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[3]-187363961|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[8]+1163531501|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[13]-1444681467|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[2]-51403784|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[7]+1735328473|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[12]-1926607734|0;b=(b<<20|b>>>12)+c|0;a+=(b^c^d)+k[5]-378558|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[8]-2022574463|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[11]+1839030562|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[14]-35309556|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[1]-1530992060|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[4]+1272893353|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[7]-155497632|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[10]-1094730640|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[13]+681279174|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[0]-358537222|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[3]-722521979|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[6]+76029189|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[9]-640364487|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[12]-421815835|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[15]+530742520|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[2]-995338651|0;b=(b<<23|b>>>9)+c|0;a+=(c^(b|~d))+k[0]-198630844|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[7]+1126891415|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[14]-1416354905|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[5]-57434055|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[12]+1700485571|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[3]-1894986606|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[10]-1051523|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[1]-2054922799|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[8]+1873313359|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[15]-30611744|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[6]-1560198380|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[13]+1309151649|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[4]-145523070|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[11]-1120210379|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[2]+718787259|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[9]-343485551|0;b=(b<<21|b>>>11)+c|0;x[0]=a+x[0]|0;x[1]=b+x[1]|0;x[2]=c+x[2]|0;x[3]=d+x[3]|0}function md5blk(s){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24)}return md5blks}function md5blk_array(a){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=a[i]+(a[i+1]<<8)+(a[i+2]<<16)+(a[i+3]<<24)}return md5blks}function md51(s){var n=s.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk(s.substring(i-64,i)))}s=s.substring(i-64);length=s.length;tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function md51_array(a){var n=a.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk_array(a.subarray(i-64,i)))}a=i-64>2]|=a[i]<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function rhex(n){var s="",j;for(j=0;j<4;j+=1){s+=hex_chr[n>>j*8+4&15]+hex_chr[n>>j*8&15]}return s}function hex(x){var i;for(i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}}if(typeof ArrayBuffer!=="undefined"&&!ArrayBuffer.prototype.slice){(function(){function clamp(val,length){val=val|0||0;if(val<0){return Math.max(val+length,0)}return Math.min(val,length)}ArrayBuffer.prototype.slice=function(from,to){var length=this.byteLength,begin=clamp(from,length),end=length,num,target,targetArray,sourceArray;if(to!==undefined){end=clamp(to,length)}if(begin>end){return new ArrayBuffer(0)}num=end-begin;target=new ArrayBuffer(num);targetArray=new Uint8Array(target);sourceArray=new Uint8Array(this,begin,num);targetArray.set(sourceArray);return target}})()}function toUtf8(str){if(/[\u0080-\uFFFF]/.test(str)){str=unescape(encodeURIComponent(str))}return str}function utf8Str2ArrayBuffer(str,returnUInt8Array){var length=str.length,buff=new ArrayBuffer(length),arr=new Uint8Array(buff),i;for(i=0;i>2]|=buff.charCodeAt(i)<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.prototype.reset=function(){this._buff="";this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}};SparkMD5.prototype.setState=function(state){this._buff=state.buff;this._length=state.length;this._hash=state.hash;return this};SparkMD5.prototype.destroy=function(){delete this._hash;delete this._buff;delete this._length};SparkMD5.prototype._finish=function(tail,length){var i=length,tmp,lo,hi;tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(this._hash,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=this._length*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(this._hash,tail)};SparkMD5.hash=function(str,raw){return SparkMD5.hashBinary(toUtf8(str),raw)};SparkMD5.hashBinary=function(content,raw){var hash=md51(content),ret=hex(hash);return raw?hexToBinaryString(ret):ret};SparkMD5.ArrayBuffer=function(){this.reset()};SparkMD5.ArrayBuffer.prototype.append=function(arr){var buff=concatenateArrayBuffers(this._buff.buffer,arr,true),length=buff.length,i;this._length+=arr.byteLength;for(i=64;i<=length;i+=64){md5cycle(this._hash,md5blk_array(buff.subarray(i-64,i)))}this._buff=i-64>2]|=buff[i]<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.ArrayBuffer.prototype.reset=function(){this._buff=new Uint8Array(0);this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.ArrayBuffer.prototype.getState=function(){var state=SparkMD5.prototype.getState.call(this);state.buff=arrayBuffer2Utf8Str(state.buff);return state};SparkMD5.ArrayBuffer.prototype.setState=function(state){state.buff=utf8Str2ArrayBuffer(state.buff,true);return SparkMD5.prototype.setState.call(this,state)};SparkMD5.ArrayBuffer.prototype.destroy=SparkMD5.prototype.destroy;SparkMD5.ArrayBuffer.prototype._finish=SparkMD5.prototype._finish;SparkMD5.ArrayBuffer.hash=function(arr,raw){var hash=md51_array(new Uint8Array(arr)),ret=hex(hash);return raw?hexToBinaryString(ret):ret};return SparkMD5}); diff --git a/addons/cos/bootstrap.js b/addons/cos/bootstrap.js new file mode 100644 index 0000000000000000000000000000000000000000..731de2f3bded515ed879ffe90edaab4ba3dfb9be --- /dev/null +++ b/addons/cos/bootstrap.js @@ -0,0 +1,92 @@ +//修改上传的接口调用 +require(['upload', '../addons/cos/js/spark'], function (Upload, SparkMD5) { + var _onFileAdded = Upload.events.onFileAdded; + var _onUploadResponse = Upload.events.onUploadResponse; + var _process = function (up, file) { + (function (up, file) { + var blob = file.getNative(); + var loadedBytes = file.loaded; + var chunkSize = 2097152; + var chunkBlob = blob.slice(loadedBytes, loadedBytes + chunkSize); + var reader = new FileReader(); + reader.addEventListener('loadend', function (e) { + var spark = new SparkMD5.ArrayBuffer(); + spark.append(e.target.result); + var md5 = spark.end(); + Fast.api.ajax({ + url: "/addons/cos/index/params", + data: {method: 'POST', md5: md5, name: file.name, type: file.type, size: file.size}, + }, function (data) { + file.md5 = md5; + file.status = 1; + file.key = data.key; + file.filename = data.filename; + file.token = data.token; + file.signature = data.signature; + file.notifysignature = data.notifysignature; + up.start(); + return false; + }); + return; + }); + reader.readAsArrayBuffer(chunkBlob); + })(up, file); + }; + Upload.events.onFileAdded = function (up, files) { + return _onFileAdded.call(this, up, files); + }; + Upload.events.onBeforeUpload = function (up, file) { + if (up.settings.url == Config.upload.uploadurl) { + if (typeof file.md5 === 'undefined') { + up.stop(); + _process(up, file); + } else { + up.settings.headers = up.settings.headers || {}; + up.settings.multipart_params.key = file.key; + up.settings.multipart_params.Signature = file.signature; + up.settings.multipart_params.success_action_status = 200; + up.settings.multipart_params['Content-Disposition'] = 'inline; filename=' + file.filename; + up.settings.multipart_params['Content-Type'] = file.type; + up.settings.multipart_params['x-cos-security-token'] = file.token; + up.settings.send_file_name = false; + } + } + }; + Upload.events.onUploadResponse = function (response, info, up, file) { + if (up.settings.url == Config.upload.uploadurl) { + try { + var ret = {}; + if (info.status === 200) { + var url = '/' + file.key; + Fast.api.ajax({ + url: "/addons/cos/index/notify", + data: { + method: 'POST', + name: file.name, + url: url, + md5: file.md5, + size: file.size, + type: file.type, + signature: file.signature, + token: file.token, + notifysignature: file.notifysignature + } + }, function () { + return false; + }); + ret.code = 1; + ret.data = { + url: url + }; + } else { + ret.code = 0; + ret.msg = info.response; + } + return _onUploadResponse.call(this, JSON.stringify(ret)); + + } catch (e) { + } + } + return _onUploadResponse.call(this, response); + }; +}); \ No newline at end of file diff --git a/addons/cos/config.php b/addons/cos/config.php new file mode 100644 index 0000000000000000000000000000000000000000..abce612a364dd3e006d02a423b9d6d3c5cee05c0 --- /dev/null +++ b/addons/cos/config.php @@ -0,0 +1,173 @@ + 'appid', + 'title' => 'AppID', + 'type' => 'string', + 'content' => + array(), + 'value' => 'your appid', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请前往腾讯控制台 > 访问管理 > API密钥', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'secretid', + 'title' => 'SecretId', + 'type' => 'string', + 'content' => + array(), + 'value' => 'your secretid', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请前往腾讯控制台 > 访问管理 > API密钥', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'secretkey', + 'title' => 'SecretKey', + 'type' => 'string', + 'content' => + array(), + 'value' => 'your secretkey', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请前往腾讯控制台 > 访问管理 > API密钥', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'bucket', + 'title' => '存储桶名称', + 'type' => 'string', + 'content' => + array(), + 'value' => 'yourbucket-1234567890', + 'rule' => 'required', + 'msg' => '', + 'tip' => '存储空间名称', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'region', + 'title' => '地域名称', + 'type' => 'string', + 'content' => + array(), + 'value' => 'ap-guangzhou', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请输入地域简称,请注意使用英文', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'uploadurl', + 'title' => '上传接口地址', + 'type' => 'string', + 'content' => + array(), + 'value' => 'https://yourbucket-1234567890.cos.ap-guangzhou.myqcloud.com/', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请输入你的上传接口地址', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'cdnurl', + 'title' => 'CDN地址', + 'type' => 'string', + 'content' => + array(), + 'value' => 'https://yourbucket-1234567890.file.myqcloud.com', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请配置你的CDN地址或在存储桶基础配置中获取', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'savekey', + 'title' => '保存文件名', + 'type' => 'string', + 'content' => + array(), + 'value' => '/uploads/{year}{mon}{day}/{filemd5}{.suffix}', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'expire', + 'title' => '上传有效时长', + 'type' => 'string', + 'content' => + array(), + 'value' => '600', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'maxsize', + 'title' => '最大可上传', + 'type' => 'string', + 'content' => + array(), + 'value' => '10M', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'mimetype', + 'title' => '可上传后缀格式', + 'type' => 'string', + 'content' => + array(), + 'value' => 'jpg,png,bmp,jpeg,gif,zip,rar,xls,xlsx', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'multiple', + 'title' => '多文件上传', + 'type' => 'bool', + 'content' => + array(), + 'value' => '0', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + array( + 'name' => 'syncdelete', + 'title' => '附件删除时是否同步删除文件', + 'type' => 'bool', + 'content' => + array(), + 'value' => '0', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), +); diff --git a/addons/cos/controller/Index.php b/addons/cos/controller/Index.php new file mode 100644 index 0000000000000000000000000000000000000000..f19374d0de74ef2f1c48718e928e8bb8fca36f80 --- /dev/null +++ b/addons/cos/controller/Index.php @@ -0,0 +1,80 @@ +error("当前插件暂无前台页面"); + } + + public function params() + { + $config = get_addon_config('cos'); + $name = $this->request->post('name'); + $md5 = $this->request->post('md5'); + + $suffix = substr($name, stripos($name, '.') + 1); + $search = ['{year}', '{mon}', '{month}', '{day}', '{filemd5}', '{suffix}', '{.suffix}', '{filename}']; + $replace = [date("Y"), date("m"), date("m"), date("d"), $md5, $suffix, '.' . $suffix, $name]; + $filename = ltrim(str_replace($search, $replace, $config['savekey']), '/'); + + list($signature, $token) = Auth::getAuthorization(); + $params = [ + 'key' => $filename, + 'filename' => basename($filename), + 'signature' => $signature, + 'token' => $token, + 'notifysignature' => md5($signature) + ]; + $this->success('', null, $params); + return; + } + + public function notify() + { + $size = $this->request->post('size'); + $name = $this->request->post('name'); + $md5 = $this->request->post('md5'); + $type = $this->request->post('type'); + $signature = $this->request->post('signature', '', 'trim'); + $notifysignature = $this->request->post('notifysignature', '', 'trim'); + $url = $this->request->post('url'); + $suffix = substr($name, stripos($name, '.') + 1); + if ($notifysignature == md5($signature)) { + $attachment = Attachment::getBySha1($md5); + if (!$attachment) { + $params = array( + 'admin_id' => (int)session('admin.id'), + 'user_id' => (int)cookie('uid'), + 'filesize' => $size, + 'imagewidth' => 0, + 'imageheight' => 0, + 'imagetype' => $suffix, + 'imageframes' => 0, + 'mimetype' => $type, + 'url' => $url, + 'uploadtime' => time(), + 'storage' => 'cos', + 'sha1' => $md5, + ); + Attachment::create($params); + } + $this->success(); + } else { + $this->error(__('You have no permission')); + } + return; + } + +} diff --git a/addons/cos/info.ini b/addons/cos/info.ini new file mode 100644 index 0000000000000000000000000000000000000000..475e42ada8b09250b158414412e3be51b9fec4bd --- /dev/null +++ b/addons/cos/info.ini @@ -0,0 +1,8 @@ +name = cos +title = 腾讯COS云存储 +intro = 腾讯COS云存储插件 +author = Karson +website = https://www.fastadmin.net +version = 1.0.3 +state = 1 +url = /fastadmin/my/public/addons/cos diff --git a/addons/cos/library/Auth.php b/addons/cos/library/Auth.php new file mode 100644 index 0000000000000000000000000000000000000000..19c7045a68e38e6dad8993f4f1f520c66effab44 --- /dev/null +++ b/addons/cos/library/Auth.php @@ -0,0 +1,242 @@ + $val) { + array_push($arr, $key . '=' . $val); + } + return join('&', $arr); + } + + // 计算临时密钥用的签名 + private static function getSignature($opt, $key, $method) + { + $formatString = $method . self::DOMAIN . '/v2/index.php?' . self::json2str($opt); + $sign = hash_hmac('sha1', $formatString, $key); + $sign = base64_encode(hex2bin($sign)); + return $sign; + } + + // 获取临时密钥 + private static function getTempKeys() + { + $cosConfig = get_addon_config('cos'); + $config = array( + 'Url' => self::STSURL, + 'Domain' => self::DOMAIN, + 'Proxy' => '', + 'SecretId' => $cosConfig['secretid'], // 固定密钥 + 'SecretKey' => $cosConfig['secretkey'], // 固定密钥 + 'Bucket' => $cosConfig['bucket'], + 'Region' => $cosConfig['region'], + 'AllowPrefix' => '*', // 这里改成允许的路径前缀,这里可以根据自己网站的用户登录态判断允许上传的目录,例子:* 或者 a/* 或者 a.jpg + ); + + $ShortBucketName = substr($config['Bucket'], 0, strripos($config['Bucket'], '-')); + $AppId = substr($config['Bucket'], 1 + strripos($config['Bucket'], '-')); + $policy = array( + 'version' => '2.0', + 'statement' => array( + array( + 'action' => array( + // // 这里可以从临时密钥的权限上控制前端允许的操作 + // 'name/cos:*', // 这样写可以包含下面所有权限 + + // // 列出所有允许的操作 + // // ACL 读写 + // 'name/cos:GetBucketACL', + // 'name/cos:PutBucketACL', + // 'name/cos:GetObjectACL', + // 'name/cos:PutObjectACL', + // // 简单 Bucket 操作 + // 'name/cos:PutBucket', + // 'name/cos:HeadBucket', + // 'name/cos:GetBucket', + // 'name/cos:DeleteBucket', + // 'name/cos:GetBucketLocation', + // // Versioning + // 'name/cos:PutBucketVersioning', + // 'name/cos:GetBucketVersioning', + // // CORS + // 'name/cos:PutBucketCORS', + // 'name/cos:GetBucketCORS', + // 'name/cos:DeleteBucketCORS', + // // Lifecycle + // 'name/cos:PutBucketLifecycle', + // 'name/cos:GetBucketLifecycle', + // 'name/cos:DeleteBucketLifecycle', + // // Replication + // 'name/cos:PutBucketReplication', + // 'name/cos:GetBucketReplication', + // 'name/cos:DeleteBucketReplication', + // // 删除文件 + // 'name/cos:DeleteMultipleObject', + 'name/cos:DeleteObject', + // 简单文件操作 + 'name/cos:PutObject', + 'name/cos:PostObject', + 'name/cos:AppendObject', + 'name/cos:GetObject', + 'name/cos:HeadObject', + 'name/cos:OptionsObject', + 'name/cos:PutObjectCopy', + 'name/cos:PostObjectRestore', + // 分片上传操作 + 'name/cos:InitiateMultipartUpload', + 'name/cos:ListMultipartUploads', + 'name/cos:ListParts', + 'name/cos:UploadPart', + 'name/cos:CompleteMultipartUpload', + 'name/cos:AbortMultipartUpload', + ), + 'effect' => 'allow', + 'principal' => array('qcs' => array('*')), + 'resource' => array( + 'qcs::cos:' . $config['Region'] . ':uid/' . $AppId . ':prefix//' . $AppId . '/' . $ShortBucketName . '/', + 'qcs::cos:' . $config['Region'] . ':uid/' . $AppId . ':prefix//' . $AppId . '/' . $ShortBucketName . '/' . $config['AllowPrefix'] + ) + ) + ) + ); + + $policyStr = str_replace('\\/', '/', json_encode($policy)); + + // 有效时间小于 30 秒就重新获取临时密钥,否则使用缓存的临时密钥 + if (isset($_SESSION['tempKeysCache']) && isset($_SESSION['tempKeysCache']['expiredTime']) && isset($_SESSION['tempKeysCache']['policyStr']) && + $_SESSION['tempKeysCache']['expiredTime'] - time() > 30 && $_SESSION['tempKeysCache']['policyStr'] === $policyStr) { + return $_SESSION['tempKeysCache']; + } + + $Action = 'GetFederationToken'; + $Nonce = rand(10000, 20000); + $Timestamp = time() - 1; + $Method = 'GET'; + + $params = array( + 'Action' => $Action, + 'Nonce' => $Nonce, + 'Region' => '', + 'SecretId' => $config['SecretId'], + 'Timestamp' => $Timestamp, + 'durationSeconds' => 7200, + 'name' => '', + 'policy' => $policyStr + ); + $params['Signature'] = urlencode(self::getSignature($params, $config['SecretKey'], $Method)); + $url = $config['Url'] . '?' . self::json2str($params); + $ch = curl_init($url); + $config['Proxy'] && curl_setopt($ch, CURLOPT_PROXY, $config['Proxy']); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + $result = curl_exec($ch); + if (curl_errno($ch)) $result = curl_error($ch); + curl_close($ch); + + $result = json_decode($result, 1); + if (isset($result['data'])) $result = $result['data']; + + $_SESSION['tempKeysCache'] = $result; + $_SESSION['tempKeysCache']['policyStr'] = $policyStr; + + return $result; + } +} \ No newline at end of file diff --git a/addons/nkeditor/Nkeditor.php b/addons/nkeditor/Nkeditor.php new file mode 100644 index 0000000000000000000000000000000000000000..c10e1b79cbb23d7dcabbe3b4e80c61de7e0b0bd0 --- /dev/null +++ b/addons/nkeditor/Nkeditor.php @@ -0,0 +1,63 @@ +getConfig(); + $params['nkeditor'] = ['theme' => $config['theme']]; + } + +} diff --git a/addons/nkeditor/README.md b/addons/nkeditor/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6ee75c73575df38d7b42bc56f50a8c5249379375 --- /dev/null +++ b/addons/nkeditor/README.md @@ -0,0 +1,17 @@ +# NKeditor +NKedtior是基于 kindeditor 进行二次开发的项目 +kindeditor 是一款优秀的开源在线编辑器。轻量级且功能强大,代码量却不到百度的ueditor编辑器的一半。可惜已经4年没有更新了,由于业务的需求我们在kindeditor的基础上开发了 NKeditor, 主要做了一下工作: +1. 调整编辑器和弹出 dialog 的样式,美化了UI +2. 重写图片上传和批量图片上传插件,使用 html5 上传代替了 flash,实现了待上传图片预览,优化用户体验 +3. 修复一些已知的bug,如 ajax 提交无法获取内容等 +4. 新增涂鸦等功能 + +再次感谢 kindeditor 的开发者,为我们提供了如此优秀的在线编辑器,让我们能在前人的基础上继续贡献自己的微薄之力。 + +# 开源说明 +本插件基于Nkeditor进行二次开发,修改的核心文件已开源于 https://gitee.com/karson/kindeditor + +# 特别感谢 +[Kindeditor](https://gitee.com/luolonghao/kindeditor) +[Nkeditor](https://gitee.com/blackfox/kindeditor) + diff --git a/addons/nkeditor/assets/css/common.css b/addons/nkeditor/assets/css/common.css new file mode 100644 index 0000000000000000000000000000000000000000..12fa84ef15bafb41f02241244354476d84ef7567 --- /dev/null +++ b/addons/nkeditor/assets/css/common.css @@ -0,0 +1,5 @@ + +.ke-container-black .ke-toolbar .ke-icon-remoteimage { + background-image: url(../img/download.png); + background-size: 16px 16px; +} \ No newline at end of file diff --git a/addons/nkeditor/assets/img/download.png b/addons/nkeditor/assets/img/download.png new file mode 100644 index 0000000000000000000000000000000000000000..1945ae7792909fc55eeff0353029ca2beb410822 Binary files /dev/null and b/addons/nkeditor/assets/img/download.png differ diff --git a/addons/nkeditor/assets/img/downloading.png b/addons/nkeditor/assets/img/downloading.png new file mode 100644 index 0000000000000000000000000000000000000000..1d6cbd1e13b01904c430f35cbf9c3aa292258c52 Binary files /dev/null and b/addons/nkeditor/assets/img/downloading.png differ diff --git a/addons/nkeditor/assets/js/customplugin.js b/addons/nkeditor/assets/js/customplugin.js new file mode 100644 index 0000000000000000000000000000000000000000..79075e9369d26be69c089432b2805aa4a56fa229 --- /dev/null +++ b/addons/nkeditor/assets/js/customplugin.js @@ -0,0 +1,74 @@ +define(['nkeditor-core'], function (Nkeditor) { + Nkeditor.plugin('multiimage', function (K) { + var self = this, name = 'multiimage', lang = self.lang(name + '.'), + allowImages = K.undef(self.allowImages, false); + + var click = function () { + + var html = [ + '
', + '
', + '
' + + '
' + + '' + + '' + + '
' + + '
', + '
', + '
' + ].join(''); + var dialog = self.createDialog({ + name: name, + width: 450, + height: 260, + title: self.lang(name), + body: html, + noBtn: { + name: self.lang('no'), + click: function (e) { + self.hideDialog().focus(); + } + } + }), + div = dialog.div; + $("input[name=imgFiles]", div).change(function () { + dialog.showLoading(); + var files = $(this).prop('files'); + $.each(files, function (i, file) { + self.beforeUpload.call(self, function (data) { + self.exec('insertimage', Fast.api.cdnurl(data.data.url)); + }, file); + }); + setTimeout(function () { + self.hideDialog().focus(); + }, 0); + }); + $(".ke-select-image", div).click(function () { + self.loadPlugin('filemanager', function () { + self.plugin.filemanagerDialog({ + dirName: 'image', + multiple: true, + clickFn: function (urls) { + $.each(urls, function(i, url){ + self.exec('insertimage', url); + }); + } + }); + }); + self.hideDialog().focus(); + // parent.Fast.api.open("general/attachment/select?element_id=&multiple=true&mimetype=*", __('Choose'), { + // callback: function (data) { + // var urlArr = data.url.split(/\,/); + // $.each(urlArr, function () { + // var url = Fast.api.cdnurl(this); + // self.exec('insertimage', url); + // }); + // } + // }); + }); + }; + self.clickToolbar(name, click); + }); + + return Nkeditor; +}); diff --git a/addons/nkeditor/assets/lang/ar.js b/addons/nkeditor/assets/lang/ar.js new file mode 100644 index 0000000000000000000000000000000000000000..6eb4b7e3ac69e8f2525a793b07e338030be5764a --- /dev/null +++ b/addons/nkeditor/assets/lang/ar.js @@ -0,0 +1,242 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +* Arabic Translation By daif alotaibi (http://daif.net/) +*******************************************************************************/ + +KindEditor.lang({ + source : 'عرض المصدر', + preview : 'معاينة الصفحة', + undo : 'تراجع(Ctrl+Z)', + redo : 'إعادة التراجع(Ctrl+Y)', + cut : 'قص(Ctrl+X)', + copy : 'نسخ(Ctrl+C)', + paste : 'لصق(Ctrl+V)', + plainpaste : 'لصق كنص عادي', + wordpaste : 'لصق من مايكروسفت ورد', + selectall : 'تحديد الكل', + justifyleft : 'محاذاه لليسار', + justifycenter : 'محاذاه للوسط', + justifyright : 'محاذاه لليمين', + justifyfull : 'محاذاه تلقائية', + insertorderedlist : 'قائمة مرقمه', + insertunorderedlist : 'قائمة نقطية', + indent : 'إزاحه النص', + outdent : 'إلغاء الازاحة', + subscript : 'أسفل النص', + superscript : 'أعلى النص', + formatblock : 'Paragraph format', + fontname : 'نوع الخط', + fontsize : 'حجم الخط', + forecolor : 'لون النص', + hilitecolor : 'لون خلفية النص', + bold : 'عريض(Ctrl+B)', + italic : 'مائل(Ctrl+I)', + underline : 'خط تحت النص(Ctrl+U)', + strikethrough : 'خط على النص', + removeformat : 'إزالة التنسيق', + image : 'إدراج صورة', + multiimage : 'Multi image', + flash : 'إدراج فلاش', + media : 'إدراج وسائط متعددة', + table : 'إدراج جدول', + tablecell : 'خلية', + hr : 'إدراج خط أفقي', + emoticons : 'إدراج وجه ضاحك', + link : 'رابط', + unlink : 'إزالة الرابط', + fullscreen : 'محرر ملئ الشاشة', + about : 'حول', + print : 'طباعة', + filemanager : 'مدير الملفات', + code : 'إدراج نص برمجي', + map : 'خرائط قووقل', + baidumap : 'خرائط قووقل', + lineheight : 'إرتفاع السطر', + clearhtml : 'مسح كود HTML', + pagebreak : 'إدراج فاصل صفحات', + quickformat : 'تنسيق سريع', + insertfile : 'إدراج ملف', + template : 'إدراج قالب', + anchor : 'رابط', + yes : 'موافق', + no : 'إلغاء', + close : 'إغلاق', + editImage : 'خصائص الصورة', + deleteImage : 'حذفالصورة', + editFlash : 'خصائص الفلاش', + deleteFlash : 'حذف الفلاش', + editMedia : 'خصائص الوسائط', + deleteMedia : 'حذف الوسائط', + editLink : 'خصائص الرابط', + deleteLink : 'إزالة الرابط', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : 'خصائص الجدول', + tablecellprop : 'خصائص الخلية', + tableinsert : 'إدراج جدول', + tabledelete : 'حذف جدول', + tablecolinsertleft : 'إدراج عمود لليسار', + tablecolinsertright : 'إدراج عمود لليسار', + tablerowinsertabove : 'إدراج صف للأعلى', + tablerowinsertbelow : 'إدراج صف للأسفل', + tablerowmerge : 'دمج للأسفل', + tablecolmerge : 'دمج لليمين', + tablerowsplit : 'تقسم الصف', + tablecolsplit : 'تقسيم العمود', + tablecoldelete : 'حذف العمود', + tablerowdelete : 'حذف الصف', + noColor : 'إفتراضي', + pleaseSelectFile : 'Please select file.', + invalidImg : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: jpg,gif,bmp,png", + invalidMedia : "الرجاء إدخال رابط صحيح.\nالملفات المسموح بها: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb", + invalidWidth : "العرض يجب أن يكون رقم.", + invalidHeight : "الإرتفاع يجب أن يكون رقم.", + invalidBorder : "عرض الحد يجب أن يكون رقم.", + invalidUrl : "الرجاء إدخال رابط حيح.", + invalidRows : 'صفوف غير صحيح.', + invalidCols : 'أعمدة غير صحيحة.', + invalidPadding : 'The padding must be number.', + invalidSpacing : 'The spacing must be number.', + invalidJson : 'Invalid JSON string.', + uploadSuccess : 'تم رفع الملف بنجاح.', + cutError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+X).', + copyError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+C).', + pasteError : 'حاليا غير مدعومة من المتصفح, إستخدم إختصار لوحة المفاتيح (Ctrl+V).', + ajaxLoading : 'Loading ...', + uploadLoading : 'Uploading ...', + uploadError : 'Upload Error', + 'plainpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.', + 'wordpaste.comment' : 'إستخدم إختصار لوحة المفاتيح (Ctrl+V) للصق داخل النافذة.', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : 'الرابط', + 'link.linkType' : 'الهدف', + 'link.newWindow' : 'نافذة جديدة', + 'link.selfWindow' : 'نفس النافذة', + 'flash.url' : 'الرابط', + 'flash.width' : 'العرض', + 'flash.height' : 'الإرتفاع', + 'flash.upload' : 'رفع', + 'flash.viewServer' : 'أستعراض', + 'media.url' : 'الرابط', + 'media.width' : 'العرض', + 'media.height' : 'الإرتفاع', + 'media.autostart' : 'تشغيل تلقائي', + 'media.upload' : 'رفع', + 'media.viewServer' : 'أستعراض', + 'image.remoteImage' : 'إدراج الرابط', + 'image.localImage' : 'رفع', + 'image.remoteUrl' : 'الرابط', + 'image.localUrl' : 'الملف', + 'image.size' : 'الحجم', + 'image.width' : 'العرض', + 'image.height' : 'الإرتفاع', + 'image.resetSize' : 'إستعادة الأبعاد', + 'image.align' : 'محاذاة', + 'image.defaultAlign' : 'الإفتراضي', + 'image.leftAlign' : 'اليسار', + 'image.rightAlign' : 'اليمين', + 'image.imgTitle' : 'العنوان', + 'image.upload' : 'أستعراض', + 'image.viewServer' : 'أستعراض', + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>', + 'multiimage.startUpload' : 'Start upload', + 'multiimage.clearAll' : 'Clear all', + 'multiimage.insertAll' : 'Insert all', + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.', + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.', + 'multiimage.zeroByteFile' : 'Zero byte file.', + 'multiimage.invalidFiletype' : 'Invalid file type.', + 'multiimage.unknownError' : 'Unknown upload error.', + 'multiimage.pending' : 'Pending ...', + 'multiimage.uploadError' : 'Upload error', + 'filemanager.emptyFolder' : 'فارغ', + 'filemanager.moveup' : 'المجلد الأب', + 'filemanager.viewType' : 'العرض: ', + 'filemanager.viewImage' : 'مصغرات', + 'filemanager.listImage' : 'قائمة', + 'filemanager.orderType' : 'الترتيب: ', + 'filemanager.fileName' : 'بالإسم', + 'filemanager.fileSize' : 'بالحجم', + 'filemanager.fileType' : 'بالنوع', + 'insertfile.url' : 'الرابط', + 'insertfile.title' : 'العنوان', + 'insertfile.upload' : 'رفع', + 'insertfile.viewServer' : 'أستعراض', + 'table.cells' : 'خلايا', + 'table.rows' : 'صفوف', + 'table.cols' : 'أعمدة', + 'table.size' : 'الأبعاد', + 'table.width' : 'العرض', + 'table.height' : 'الإرتفاع', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : 'الخارج', + 'table.padding' : 'الداخل', + 'table.spacing' : 'الفراغات', + 'table.align' : 'محاذاه', + 'table.textAlign' : 'افقى', + 'table.verticalAlign' : 'رأسي', + 'table.alignDefault' : 'إفتراضي', + 'table.alignLeft' : 'يسار', + 'table.alignCenter' : 'وسط', + 'table.alignRight' : 'يمين', + 'table.alignTop' : 'أعلى', + 'table.alignMiddle' : 'منتصف', + 'table.alignBottom' : 'أسفل', + 'table.alignBaseline' : 'Baseline', + 'table.border' : 'الحدود', + 'table.borderWidth' : 'العرض', + 'table.borderColor' : 'اللون', + 'table.backgroundColor' : 'الخلفية', + 'map.address' : 'العنوان: ', + 'map.search' : 'بحث', + 'baidumap.address' : 'العنوان: ', + 'baidumap.search' : 'بحث', + 'baidumap.insertDynamicMap' : 'Dynamic Map', + 'anchor.name' : 'إسم الرابط', + 'formatblock.formatBlock' : { + h1 : 'عنوان 1', + h2 : 'عنوان 2', + h3 : 'عنوان 3', + h4 : 'عنوان 4', + p : 'عادي' + }, + 'fontname.fontName' : { + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : 'إرتفاع السطر 1'}, + {'1.5' : 'إرتفاع السطر 1.5'}, + {'2' : 'إرتفاع السطر 2'}, + {'2.5' : 'إرتفاع السطر 2.5'}, + {'3' : 'إرتفاع السطر 3'} + ], + 'template.selectTemplate' : 'قالب', + 'template.replaceContent' : 'إستبدال المحتوى الحالي', + 'template.fileList' : { + '1.html' : 'صورة ونص', + '2.html' : 'جدول', + '3.html' : 'قائمة' + } +}, 'ar'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'ar'; \ No newline at end of file diff --git a/addons/nkeditor/assets/lang/en.js b/addons/nkeditor/assets/lang/en.js new file mode 100644 index 0000000000000000000000000000000000000000..dbaa616b1519f5d23109cd9f9739f5956fcb7dcb --- /dev/null +++ b/addons/nkeditor/assets/lang/en.js @@ -0,0 +1,243 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : 'Source', + preview : 'Preview', + undo : 'Undo(Ctrl+Z)', + redo : 'Redo(Ctrl+Y)', + cut : 'Cut(Ctrl+X)', + copy : 'Copy(Ctrl+C)', + paste : 'Paste(Ctrl+V)', + plainpaste : 'Paste as plain text', + wordpaste : 'Paste from Word', + selectall : 'Select all', + justifyleft : 'Align left', + justifycenter : 'Align center', + justifyright : 'Align right', + justifyfull : 'Align full', + insertorderedlist : 'Ordered list', + insertunorderedlist : 'Unordered list', + indent : 'Increase indent', + outdent : 'Decrease indent', + subscript : 'Subscript', + superscript : 'Superscript', + formatblock : 'Paragraph format', + fontname : 'Font family', + fontsize : 'Font size', + forecolor : 'Text color', + hilitecolor : 'Highlight color', + bold : 'Bold(Ctrl+B)', + italic : 'Italic(Ctrl+I)', + underline : 'Underline(Ctrl+U)', + strikethrough : 'Strikethrough', + removeformat : 'Remove format', + image : 'Image', + multiimage : 'Multi image', + flash : 'Flash', + media : 'Embeded media', + table : 'Table', + tablecell : 'Cell', + hr : 'Insert horizontal line', + emoticons : 'Insert emoticon', + link : 'Link', + unlink : 'Unlink', + fullscreen : 'Toggle fullscreen mode', + about : 'About', + print : 'Print', + filemanager : 'File Manager', + code : 'Insert code', + map : 'Google Maps', + baidumap : 'Baidu Maps', + lineheight : 'Line height', + clearhtml : 'Clear HTML code', + pagebreak : 'Insert Page Break', + quickformat : 'Quick Format', + insertfile : 'Insert file', + template : 'Insert Template', + anchor : 'Anchor', + yes : 'OK', + no : 'Cancel', + close : 'Close', + editImage : 'Image properties', + deleteImage : 'Delete image', + editFlash : 'Flash properties', + deleteFlash : 'Delete flash', + editMedia : 'Media properties', + deleteMedia : 'Delete media', + editLink : 'Link properties', + deleteLink : 'Unlink', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : 'Table properties', + tablecellprop : 'Cell properties', + tableinsert : 'Insert table', + tabledelete : 'Delete table', + tablecolinsertleft : 'Insert column left', + tablecolinsertright : 'Insert column right', + tablerowinsertabove : 'Insert row above', + tablerowinsertbelow : 'Insert row below', + tablerowmerge : 'Merge down', + tablecolmerge : 'Merge right', + tablerowsplit : 'Split row', + tablecolsplit : 'Split column', + tablecoldelete : 'Delete column', + tablerowdelete : 'Delete row', + noColor : 'Default', + pleaseSelectFile : 'Please select file.', + invalidImg : "Please type valid URL.\nAllowed file extension: jpg,gif,bmp,png", + invalidMedia : "Please type valid URL.\nAllowed file extension: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb", + invalidWidth : "The width must be number.", + invalidHeight : "The height must be number.", + invalidBorder : "The border must be number.", + invalidUrl : "Please type valid URL.", + invalidRows : 'Invalid rows.', + invalidCols : 'Invalid columns.', + invalidPadding : 'The padding must be number.', + invalidSpacing : 'The spacing must be number.', + invalidJson : 'Invalid JSON string.', + uploadSuccess : 'Upload success.', + cutError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+X) instead.', + copyError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+C) instead.', + pasteError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+V) instead.', + ajaxLoading : 'Loading ...', + uploadLoading : 'Uploading ...', + uploadError : 'Upload Error', + 'plainpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.', + 'wordpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : 'URL', + 'link.linkType' : 'Target', + 'link.newWindow' : 'New window', + 'link.selfWindow' : 'Same window', + 'flash.url' : 'URL', + 'flash.width' : 'Width', + 'flash.height' : 'Height', + 'flash.upload' : 'Upload', + 'flash.viewServer' : 'Browse', + 'media.url' : 'URL', + 'media.width' : 'Width', + 'media.height' : 'Height', + 'media.autostart' : 'Auto start', + 'media.upload' : 'Upload', + 'media.viewServer' : 'Browse', + 'image.remoteImage' : 'Insert URL', + 'image.localImage' : 'Upload', + 'image.remoteUrl' : 'URL', + 'image.localUrl' : 'File', + 'image.size' : 'Size', + 'image.width' : 'Width', + 'image.height' : 'Height', + 'image.resetSize' : 'Reset dimensions', + 'image.align' : 'Align', + 'image.defaultAlign' : 'Default', + 'image.leftAlign' : 'Left', + 'image.rightAlign' : 'Right', + 'image.imgTitle' : 'Title', + 'image.upload' : 'Browse', + 'image.viewServer' : 'Browse', + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>', + 'multiimage.startUpload' : 'Start upload', + 'multiimage.clearAll' : 'Clear all', + 'multiimage.insertAll' : 'Insert all', + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.', + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.', + 'multiimage.zeroByteFile' : 'Zero byte file.', + 'multiimage.invalidFiletype' : 'Invalid file type.', + 'multiimage.unknownError' : 'Unknown upload error.', + 'multiimage.pending' : 'Pending ...', + 'multiimage.uploadError' : 'Upload error', + 'filemanager.emptyFolder' : 'Blank', + 'filemanager.moveup' : 'Parent folder', + 'filemanager.viewType' : 'Display: ', + 'filemanager.viewImage' : 'Thumbnails', + 'filemanager.listImage' : 'List', + 'filemanager.orderType' : 'Sorting: ', + 'filemanager.fileName' : 'By name', + 'filemanager.fileSize' : 'By size', + 'filemanager.fileType' : 'By type', + 'insertfile.url' : 'URL', + 'insertfile.title' : 'Title', + 'insertfile.upload' : 'Upload', + 'insertfile.viewServer' : 'Browse', + 'table.cells' : 'Cells', + 'table.rows' : 'Rows', + 'table.cols' : 'Columns', + 'table.size' : 'Dimensions', + 'table.width' : 'Width', + 'table.height' : 'Height', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : 'Space', + 'table.padding' : 'Padding', + 'table.spacing' : 'Spacing', + 'table.align' : 'Align', + 'table.textAlign' : 'Horizontal', + 'table.verticalAlign' : 'Vertical', + 'table.alignDefault' : 'Default', + 'table.alignLeft' : 'Left', + 'table.alignCenter' : 'Center', + 'table.alignRight' : 'Right', + 'table.alignTop' : 'Top', + 'table.alignMiddle' : 'Middle', + 'table.alignBottom' : 'Bottom', + 'table.alignBaseline' : 'Baseline', + 'table.border' : 'Border', + 'table.borderWidth' : 'Width', + 'table.borderColor' : 'Color', + 'table.backgroundColor' : 'Background', + 'map.address' : 'Address: ', + 'map.search' : 'Search', + 'baidumap.address' : 'Address: ', + 'baidumap.search' : 'Search', + 'baidumap.insertDynamicMap' : 'Dynamic Map', + 'anchor.name' : 'Anchor name', + 'formatblock.formatBlock' : { + h1 : 'Heading 1', + h2 : 'Heading 2', + h3 : 'Heading 3', + h4 : 'Heading 4', + p : 'Normal' + }, + 'fontname.fontName' : { + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : 'Line height 1'}, + {'1.5' : 'Line height 1.5'}, + {'2' : 'Line height 2'}, + {'2.5' : 'Line height 2.5'}, + {'3' : 'Line height 3'} + ], + 'template.selectTemplate' : 'Template', + 'template.replaceContent' : 'Replace current content', + 'template.fileList' : { + '1.html' : 'Image and Text', + '2.html' : 'Table', + '3.html' : 'List' + } +}, 'en'); + +//自动加载代码美化的js插件 +// KindEditor.loadScript(KindEditor.options.pluginsPath+"code/prettify.js"); +// KindEditor.each(KindEditor.options.items, function(i, name) { +// if (name == 'code') { +// KindEditor.options.items[i] = 'map'; +// } +// }); +KindEditor.options.langType = 'en'; diff --git a/addons/nkeditor/assets/lang/ja-JP.js b/addons/nkeditor/assets/lang/ja-JP.js new file mode 100644 index 0000000000000000000000000000000000000000..7806d089942b164a0b173cd9ce220774d4dd9dce --- /dev/null +++ b/addons/nkeditor/assets/lang/ja-JP.js @@ -0,0 +1,234 @@ +/******************************************************************************* +* @author 您的名字 お名前 +*******************************************************************************/ + +KindEditor.lang({ + source : 'HTMLコード', + preview : 'プレビュー', + undo : '戻る(Ctrl+Z)', + redo : '進む(Ctrl+Y)', + cut : 'カット(Ctrl+X)', + copy : 'コピー(Ctrl+C)', + paste : '貼り付け(Ctrl+V)', + plainpaste : 'フォーマットされていないテキストとして貼り付ける', + wordpaste : '「word」ドからペースト', + selectall : 'すべて選択(Ctrl+A)', + justifyleft : '左揃え', + justifycenter : '中央揃え', + justifyright : '右揃え', + justifyfull : '両端揃え', + insertorderedlist : '番号', + insertunorderedlist : '箇条書き', + indent : 'インデントを増やす', + outdent : 'インデントを減らす', + subscript : '下付き', + superscript : '上付き', + formatblock : '段落', + fontname : 'フォント', + fontsize : 'フォントサイズ', + forecolor : 'フォントカラー', + hilitecolor : 'テキストの背景', + bold : '太字(Ctrl+B)', + italic : '斜体(Ctrl+I)', + underline : '下線(Ctrl+U)', + strikethrough : '取り消し線', + removeformat : 'フォーマットを削除', + image : '画像', + multiimage : '一括画像アップロード', + flash : 'Flash', + media : 'ビデオとオーディオ', + table : 'テーブル', + tablecell : 'セル', + hr : '水平線を挿入する', + emoticons : '絵文字を挿入する', + link : 'ハイパーリンク', + unlink : 'ハイパーリンクをキャンセル', + fullscreen : 'フルスクリーン表示', + about : 'について', + print : 'プリント(Ctrl+P)', + filemanager : 'ファイルスペース', + code : 'プログラムコードを挿入', + map : 'Googleマップ', + baidumap : 'Baiduマップ', + lineheight : '行間隔', + clearhtml : 'HTMLコードをクリア', + pagebreak : 'ページ区切りの挿入', + quickformat : 'ワンクリックレイアウト', + insertfile : 'ファイルの挿入', + template : 'テンプレートの挿入', + anchor : 'アンカー', + yes : 'はい', + no : 'いいえ', + close : '閉じる', + editImage : 'イメージプロパティ', + deleteImage : 'イメージを削除', + editFlash : 'Flashプロパティ', + deleteFlash : 'Flashを削除', + editMedia : 'ビデオとオーディオのプロパティ', + deleteMedia : 'ビデオとオーディオを削除', + editLink : 'ハイパーリンク属性', + deleteLink : 'ハイパーリンクを削除', + editAnchor : 'アンカー属性', + deleteAnchor : 'アンカーを削除', + tableprop : 'テーブル属性', + tablecellprop : 'セル属性', + tableinsert : 'テーブルを挿入', + tabledelete : 'テーブルを削除', + tablecolinsertleft : '左に列を挿入する', + tablecolinsertright : '右に列を挿入する', + tablerowinsertabove : '上に行を挿入する', + tablerowinsertbelow : '下に行を挿入する', + tablerowmerge : '下にセルをマージする', + tablecolmerge : '右にセルをマージする', + tablerowsplit : '行を分割', + tablecolsplit : '列を分割', + tablecoldelete : '列を削除', + tablerowdelete : '行を削除', + noColor : '色なし', + pleaseSelectFile : 'ファイルを選択してください。', + invalidImg : "有効なURLアドレスを入力してください。\ n jpg、gif、bmp、png形式のみが許可されています。", + invalidMedia : "有効なURLアドレスを入力してください。swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb形式のみが許可されています。", + invalidWidth : "幅は数字でなければなりません。", + invalidHeight : "高さは数字でなければなりません。", + invalidBorder : "ボーダーは数字でなければなりません。", + invalidUrl : "有効なURLアドレスを入力してください。", + invalidRows : '行数は必須項目で、0以上の数字を入力してください。', + invalidCols : '列数は必須項目で、0以上の数字を入力してください。', + invalidPadding : 'マージンは数字でなければなりません。', + invalidSpacing : 'スペースは数字でなければなりません。', + invalidJson : 'サーバーエラー。', + uploadSuccess : 'アップロード成功。', + cutError : 'ブラウザのセキュリティ設定によってカット操作を使用できないので、ショートカットキー(Ctrl + X)を使用してください。', + copyError : 'ブラウザのセキュリティ設定によってコピー操作をできないので、ショートカットキー(Ctrl + C)を使用してください。', + pasteError : 'ブラウザのセキュリティ設定によって貼り付け操作をできないので、ショートカットキー(Ctrl + V)を使用してください。', + ajaxLoading : '読み込み中、お待ちください...', + uploadLoading : 'アップロード、しばらくお待ちください...', + uploadError : 'アップロードエラー', + 'plainpaste.comment' : 'ショートカットキー(Ctrl + V)でコンテンツを下のボックスに貼り付けてください。', + 'wordpaste.comment' : 'ショートカットキー(Ctrl + V)でコンテンツを下のボックスに貼り付けてください。', + 'code.pleaseInput' : 'プログラムコードを入力してください。 ', + 'link.url' : 'URL', + 'link.linkType' : 'タイプを開く', + 'link.newWindow' : '新しいウィンドウ', + 'link.selfWindow' : '現在のウィンドウ', + 'flash.url' : 'URL', + 'flash.width' : '幅', + 'flash.height' : '高さ', + 'flash.upload' : 'アップロード', + 'flash.viewServer' : 'ファイルスペース', + 'media.url' : 'URL', + 'media.width' : '幅', + 'media.height' : '高さ', + 'media.autostart' : '自動再生', + 'media.upload' : 'アップロード', + 'media.viewServer' : 'ファイルスペース', + 'image.remoteImage' : 'ネットワークイメージ', + 'image.localImage' : 'ローカルアップロード', + 'image.remoteUrl' : 'イメージアドレス ', + 'image.localUrl' : 'アップロードファイル', + 'image.size' : 'イメージサイズ', + 'image.width' : '幅', + 'image.height' : '高さ', + 'image.resetSize' : 'リセットサイズ', + 'image.align' : '配置', + 'image.defaultAlign' : 'デフォルト', + 'image.leftAlign' : '左揃え', + 'image.rightAlign' : '右揃え', + 'image.imgTitle' : '画像の説明', + 'image.upload' : 'ブラウズ...', + 'image.viewServer' : 'イメージスペース', + 'multiimage.uploadDesc' : 'ユーザーが<%= uploadLimit%>画像を同時にアップロードできますが、画像の容量は<%= sizeLimit%>を超えることができません', + 'multiimage.startUpload' : 'アップロード', + 'multiimage.clearAll' : 'すべてクリア', + 'multiimage.insertAll' : 'すべて挿入', + 'multiimage.queueLimitExceeded' : 'ファイルの数が上限を超えています。', + 'multiimage.fileExceedsSizeLimit' : 'ファイルサイズが制限を超えています。', + 'multiimage.zeroByteFile' : '空のファイルをアップロードできません。 ', + 'multiimage.invalidFiletype' : 'ファイル形式は正しくありません。', + 'multiimage.unknownError' : 'エラー、アップロードできません。', + 'multiimage.pending' : 'アップロード待ち', + 'multiimage.uploadError' : 'アップロード失敗', + 'filemanager.emptyFolder' : '空のフォルダ', + 'filemanager.moveup' : '前のフォルダに移動', + 'filemanager.viewType' : '表示モード:', + 'filemanager.viewImage' : 'サムネイル', + 'filemanager.listImage' : '詳細', + 'filemanager.orderType' : '並べ替え:', + 'filemanager.fileName' : 'ネーム', + 'filemanager.fileSize' : 'サイズ', + 'filemanager.fileType' : 'タイプ', + 'insertfile.url' : 'URL', + 'insertfile.title' : 'ファイルの説明', + 'insertfile.upload' : 'アップロード', + 'insertfile.viewServer' : 'ファイルスペース', + 'table.cells' : 'セル番号', + 'table.rows' : '行数', + 'table.cols' : '列数', + 'table.size' : 'サイズ', + 'table.width' : '幅', + 'table.height' : '高さ', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : 'テーブルスペース', + 'table.padding' : 'パッディング', + 'table.spacing' : 'スペース', + 'table.align' : '配置', + 'table.textAlign' : '水平配置', + 'table.verticalAlign' : '垂直配置', + 'table.alignDefault' : 'デフォルト', + 'table.alignLeft' : '左揃え', + 'table.alignCenter' : '中央揃え', + 'table.alignRight' : '右揃え', + 'table.alignTop' : 'トップ', + 'table.alignMiddle' : 'ミドル', + 'table.alignBottom' : 'ボトム', + 'table.alignBaseline' : 'ベースライン', + 'table.border' : 'ボーダー', + 'table.borderWidth' : 'ボーダー', + 'table.borderColor' : 'カラー', + 'table.backgroundColor' : '背景色', + 'map.address' : 'アドレス: ', + 'map.search' : '検索', + 'baidumap.address' : 'アドレス: ', + 'baidumap.search' : '検索', + 'baidumap.insertDynamicMap' : 'ダイナミックマップの挿入', + 'anchor.name' : 'アンカー名', + + 'formatblock.formatBlock' : { + h1 : '見出し1', + h2 : '見出し2', + h3 : '見出し3', + h4 : '見出し4', + p : '正 文' + }, + 'fontname.fontName' : { + 'SimSun' : '明朝体', + 'NSimSun' : '新宋体', + 'FangSong_GB2312' : '仿宋_GB2312', + 'KaiTi_GB2312' : '楷書体_GB2312', + 'SimHei' : 'ゴチック体', + 'Microsoft YaHei' : 'Msyh', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Times New Roman' : 'Times New Roman', + 'Courier New' : 'Courier New', + 'Tahoma' : 'Tahoma', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '行間1倍'}, + {'1.5' : '行間1.5倍'}, + {'2' : '行間2倍'}, + {'2.5' : '行間2.5倍'}, + {'3' : '行間3倍'} + ], + 'template.selectTemplate' : 'オプションテンプレート', + 'template.replaceContent' : '現在のコンテンツを置き換える', + 'template.fileList' : { + '1.html' : 'イメージとテキスト', + '2.html' : '表', + '3.html' : '段落番号' + } +}, 'ja-JP'); + +KindEditor.options.langType = 'ja-JP'; \ No newline at end of file diff --git a/addons/nkeditor/assets/lang/ko.js b/addons/nkeditor/assets/lang/ko.js new file mode 100644 index 0000000000000000000000000000000000000000..bf5eb2255bc8417193da34d007476c4e78efba95 --- /dev/null +++ b/addons/nkeditor/assets/lang/ko.js @@ -0,0 +1,246 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Composite +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : '소스', + preview : '미리보기', + undo : '작업취소(Ctrl+Z)', + redo : '작업재개(Ctrl+Y)', + cut : '잘라내기(Ctrl+X)', + copy : '복사(Ctrl+C)', + paste : '붙여넣기(Ctrl+V)', + plainpaste : '일반 텍스트로 붙여넣기', + wordpaste : '워드 문서로 붙여넣기', + selectall : '전체 선택', + justifyleft : '왼쪽 정렬', + justifycenter : '가운데 정렬', + justifyright : '오른쪽 정렬', + justifyfull : '양쪽 정렬', + insertorderedlist : '순서 목록', + insertunorderedlist : '비순서 목록', + indent : '들여쓰기', + outdent : '내어쓰기', + subscript : '아랫첨자', + superscript : '윗첨자', + formatblock : '문단 형식', + fontname : '글꼴', + fontsize : '글자 크기', + forecolor : '글자색', + hilitecolor : '강조색', + bold : '굵게(Ctrl+B)', + italic : '이텔릭(Ctrl+I)', + underline : '빝줄(Ctrl+U)', + strikethrough : '취소선', + removeformat : '형식 제거', + image : '이미지 추가', + multiimage : '여러 이미지 추가', + flash : '플래시 추가', + media : '미디어 추가', + table : '표', + tablecell : '열', + hr : '구분선 추가', + emoticons : '이모티콘 추가', + link : '링크', + unlink : '링크 제거', + fullscreen : '전체 화면 모드', + about : '이 에디터는...', + print : '인쇄', + filemanager : '파일 관리자', + code : '코드 추가', + map : '구글 맵 추가', + baidumap : '바이두 맵 추가', + lineheight : '행 간격', + clearhtml : 'HTML 코드 정리', + pagebreak : '페이지 구분 추가', + quickformat : '빠른 형식', + insertfile : '파일 추가', + template : '템플릿 추가', + anchor : '책갈피', + yes : '확인', + no : '취소', + close : '닫기', + editImage : '이미지 속성', + deleteImage : '이미지 삭제', + editFlash : '플래시 속성', + deleteFlash : '플래시 삭제', + editMedia : '미디어 속성', + deleteMedia : '미디어 삭제', + editLink : '링크 속성', + deleteLink : '링크 삭제', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : '표 속성', + tablecellprop : '열 속성', + tableinsert : '표 추가', + tabledelete : '표 삭제', + tablecolinsertleft : '왼쪽으로 열 추가', + tablecolinsertright : '오른쪽으로 열 추가', + tablerowinsertabove : '위쪽으로 열 추가', + tablerowinsertbelow : '아래쪽으로 열 추가', + tablerowmerge : '아래로 병합', + tablecolmerge : '오른쪽으로 병합', + tablerowsplit : '행 나누기', + tablecolsplit : '열 나누기', + tablecoldelete : '열 삭제', + tablerowdelete : '행 삭제', + noColor : '기본색', + pleaseSelectFile : '파일 선택', + invalidImg : "올바른 주소를 입력하세요.\njpg,gif,bmp,png 형식이 가능합니다.", + invalidMedia : "올바른 주소를 입력하세요.\nswf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb 형식이 가능합니다.", + invalidWidth : "넓이 값은 숫자여야 합니다.", + invalidHeight : "높이 값은 숫자여야 합니다.", + invalidBorder : "굵기 값은 숫자여야 합니다.", + invalidUrl : "올바른 주소를 입력하세요.", + invalidRows : '올바른 행이 아닙니다.', + invalidCols : '올바른 열이 아닙니다.', + invalidPadding : '안쪽 여백 값은 숫자여야 합니다.', + invalidSpacing : '간격 길이 값은 숫자여야 합니다.', + invalidJson : '올바른 JSON 형식이 아닙니다.', + uploadSuccess : '업로드가 완료되었습니다.', + cutError : '브라우저가 잘라내기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)', + copyError : '브라우저가 복사 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)', + pasteError : '브라우저가 붙여넣기 기능을 지원하지 않습니다, 단축키로 대신 사용하세요. (Ctrl+X)', + ajaxLoading : '불러오는 중 ...', + uploadLoading : '업로드 중 ...', + uploadError : '업로드 오류', + 'plainpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 텍스트를 붙여넣으세요.', + 'wordpaste.comment' : '단축키(Ctrl+V)를 통하여 여기에 워드 텍스트를 붙여넣으세요.', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : '주소', + 'link.linkType' : '창', + 'link.newWindow' : '새 창', + 'link.selfWindow' : '현재 창', + 'flash.url' : '주소', + 'flash.width' : '넓이', + 'flash.height' : '높이', + 'flash.upload' : '업로드', + 'flash.viewServer' : '찾아보기', + 'media.url' : '주소', + 'media.width' : '넓이', + 'media.height' : '높이', + 'media.autostart' : '자동 시작', + 'media.upload' : '업로드', + 'media.viewServer' : '찾아보기', + 'image.remoteImage' : '외부 이미지', + 'image.localImage' : '내부 이미지', + 'image.remoteUrl' : '주소', + 'image.localUrl' : '파일', + 'image.size' : '크기', + 'image.width' : '넓이', + 'image.height' : '높이', + 'image.resetSize' : '기본 크기로', + 'image.align' : '정렬', + 'image.defaultAlign' : '기본', + 'image.leftAlign' : '왼쪽', + 'image.rightAlign' : '오른쪽', + 'image.imgTitle' : '제목', + 'image.upload' : '찾아보기', + 'image.viewServer' : '찾아보기', + 'multiimage.uploadDesc' : '최대 이미지 개수: <%=uploadLimit%>개, 개당 이미지 크기: <%=sizeLimit%>', + 'multiimage.startUpload' : '업로드 시작', + 'multiimage.clearAll' : '모두 삭제', + 'multiimage.insertAll' : '모두 삽입', + 'multiimage.queueLimitExceeded' : '업로드 개수가 초과되었습니다.', + 'multiimage.fileExceedsSizeLimit' : '업로드 크기가 초과되었습니다.', + 'multiimage.zeroByteFile' : '파일 크기가 없습니다.', + 'multiimage.invalidFiletype' : '올바른 이미지가 아닙니다.', + 'multiimage.unknownError' : '알 수 없는 업로드 오류가 발생하였습니다.', + 'multiimage.pending' : '처리 중 ...', + 'multiimage.uploadError' : '업로드 오류', + 'filemanager.emptyFolder' : '빈 폴더', + 'filemanager.moveup' : '위로', + 'filemanager.viewType' : '보기 방식: ', + 'filemanager.viewImage' : '미리 보기', + 'filemanager.listImage' : '목록', + 'filemanager.orderType' : '정렬 방식: ', + 'filemanager.fileName' : '이름별', + 'filemanager.fileSize' : '크기별', + 'filemanager.fileType' : '종류별', + 'insertfile.url' : '주소', + 'insertfile.title' : '제목', + 'insertfile.upload' : '업로드', + 'insertfile.viewServer' : '찾아보기', + 'table.cells' : '열', + 'table.rows' : '행', + 'table.cols' : '열', + 'table.size' : '표 크기', + 'table.width' : '넓이', + 'table.height' : '높이', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '간격', + 'table.padding' : '안쪽여백', + 'table.spacing' : '간격', + 'table.align' : '정렬', + 'table.textAlign' : '수직', + 'table.verticalAlign' : '수평', + 'table.alignDefault' : '기본', + 'table.alignLeft' : '왼쪽', + 'table.alignCenter' : '가운데', + 'table.alignRight' : '오른쪽', + 'table.alignTop' : '위쪽', + 'table.alignMiddle' : '중간', + 'table.alignBottom' : '아래쪽', + 'table.alignBaseline' : '글자기준', + 'table.border' : '테두리', + 'table.borderWidth' : '크기', + 'table.borderColor' : '색상', + 'table.backgroundColor' : '배경', + 'map.address' : '주소: ', + 'map.search' : '검색', + 'baidumap.address' : '주소: ', + 'baidumap.search' : '검색', + 'baidumap.insertDynamicMap' : '동적 지도', + 'anchor.name' : '책갈피명', + 'formatblock.formatBlock' : { + h1 : '제목 1', + h2 : '제목 2', + h3 : '제목 3', + h4 : '제목 4', + p : '본문' + }, + 'fontname.fontName' : { + 'Gulim' : '굴림', + 'Dotum' : '돋움', + 'Batang' : '바탕', + 'Gungsuh' : '궁서', + 'Malgun Gothic' : '맑은 고딕', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '행간 1'}, + {'1.5' : '행간 1.5'}, + {'2' : '행간 2'}, + {'2.5' : '행간 2.5'}, + {'3' : '행간 3'} + ], + 'template.selectTemplate' : '템플릿', + 'template.replaceContent' : '내용 바꾸기', + 'template.fileList' : { + '1.html' : '이미지와 텍스트', + '2.html' : '표', + '3.html' : '목록' + } +}, 'ko'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'ko'; diff --git a/addons/nkeditor/assets/lang/ru.js b/addons/nkeditor/assets/lang/ru.js new file mode 100644 index 0000000000000000000000000000000000000000..dda10bf3a96f0eecdc344eb9c4f230d574db864b --- /dev/null +++ b/addons/nkeditor/assets/lang/ru.js @@ -0,0 +1,242 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +* Translated to Russian by Valery Votintsev (http://codersclub.org/) +*******************************************************************************/ + +KindEditor.lang({ + source : 'Source', + preview : 'Preview', + undo : 'Отмена(Ctrl+Z)', + redo : 'Повтор(Ctrl+Y)', + cut : 'Вырезать(Ctrl+X)', + copy : 'Копировать(Ctrl+C)', + paste : 'Вставить(Ctrl+V)', + plainpaste : 'Вставить как простой текст', + wordpaste : 'Вставить из Word', + selectall : 'Выбрать все', + justifyleft : 'Выравнивание влево', + justifycenter : 'Выравнивание по центру', + justifyright : 'Выравнивание вправо', + justifyfull : 'Выравнивание по обеим сторонам', + insertorderedlist : 'Нумерованый список', + insertunorderedlist : 'Ненумерованый список', + indent : 'Добавить отступ', + outdent : 'Убрать отступ', + subscript : 'Надстрочный', + superscript : 'Подстрочный', + formatblock : 'Формат параграфа', + fontname : 'Шрифт', + fontsize : 'Размер', + forecolor : 'Цвет текста', + hilitecolor : 'Цвет фона', + bold : 'Жирный(Ctrl+B)', + italic : 'Наклонный(Ctrl+I)', + underline : 'Подчёркнутый(Ctrl+U)', + strikethrough : 'Перечёркнутый', + removeformat : 'Удалить формат', + image : 'Изображение', + multiimage : 'Мульти-загрузка', + flash : 'Flash', + media : 'Встроенные данные', + table : 'Таблица', + tablecell : 'Ячейка', + hr : 'Горизонтальный разделитель', + emoticons : 'Смайл', + link : 'Ссылка', + unlink : 'Убрать ссылку', + fullscreen : 'На весь экран', + about : 'О программе', + print : 'Печать', + filemanager : 'Файлы', + code : 'Код', + map : 'Карта Google', + baidumap : 'Карта Baidu', + lineheight : 'Межстрочный интервал', + clearhtml : 'Очистить HTML код', + pagebreak : 'Разрыв страницы', + quickformat : 'Быстрый формат', + insertfile : 'Вставить файл', + template : 'Вставить шаблон', + anchor : 'Якорь', + yes : 'OK', + no : 'Отмена', + close : 'Закрыть', + editImage : 'Свойства изображения', + deleteImage : 'Удалить изображение', + editFlash : 'Свойства Flash', + deleteFlash : 'Удалить Flash', + editMedia : 'Свойства Media', + deleteMedia : 'Удалить Media', + editLink : 'Свойства ссылки', + deleteLink : 'Удалить ссылку', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : 'Свойства таблицы', + tablecellprop : 'Свойства ячейки', + tableinsert : 'Вставить таблицу', + tabledelete : 'Удалить таблицу', + tablecolinsertleft : 'Добавить столбец слева', + tablecolinsertright : 'Добавить столбец справа', + tablerowinsertabove : 'Добавить строку выше', + tablerowinsertbelow : 'Добавить строку ниже', + tablerowmerge : 'Объединить вниз', + tablecolmerge : 'Объединить вправо', + tablerowsplit : 'Разделить строку', + tablecolsplit : 'Разделить столбец', + tablecoldelete : 'Удалить столбец', + tablerowdelete : 'Удалить строку', + noColor : 'По умолчанию', + pleaseSelectFile : 'Выберите файл.', + invalidImg : "Укажите корректный URL изображения.\nРазрешённые форматы: jpg,gif,bmp,png", + invalidMedia : "Укажите корректный тип медиа-объекта.\nРазрешённые типы: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb", + invalidWidth : "Ширина должна быть числом.", + invalidHeight : "Высота должна быть числом.", + invalidBorder : "Ширина рамки должна быть числом.", + invalidUrl : "Укажите корректный URL.", + invalidRows : 'Неверные строки.', + invalidCols : 'Неверные столбцы.', + invalidPadding : 'padding должен быть числом.', + invalidSpacing : 'spacing должен быть числом.', + invalidJson : 'Неверная JSON строка.', + uploadSuccess : 'Загрузка завершена.', + cutError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+X).', + copyError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+C).', + pasteError : 'Данная опция не поддерживается вашим браузером, воспользуйтесь комбинацией клавиш (Ctrl+V).', + ajaxLoading : 'Загрузка ...', + uploadLoading : 'Загрузка ...', + uploadError : 'Сбой загрузки', + 'plainpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).', + 'wordpaste.comment' : 'Для вставки скопированного текста воспользуйтесь комбинацией клавиш (Ctrl+V).', + 'code.pleaseInput' : 'Введите код.', + 'link.url' : 'URL', + 'link.linkType' : 'Открывать ссылку', + 'link.newWindow' : 'в новом окне', + 'link.selfWindow' : 'в том же окне', + 'flash.url' : 'URL', + 'flash.width' : 'Ширина', + 'flash.height' : 'Высота', + 'flash.upload' : 'Загрузить', + 'flash.viewServer' : 'Выбрать', + 'media.url' : 'URL', + 'media.width' : 'Ширина', + 'media.height' : 'Высота', + 'media.autostart' : 'Автостарт', + 'media.upload' : 'Загрузить', + 'media.viewServer' : 'Выбрать', + 'image.remoteImage' : 'Вставить URL изображения', + 'image.localImage' : 'Загрузить', + 'image.remoteUrl' : 'URL', + 'image.localUrl' : 'Файл', + 'image.size' : 'Размер', + 'image.width' : 'Ширина', + 'image.height' : 'Высота', + 'image.resetSize' : 'Сбросить размеры', + 'image.align' : 'Выравнивание', + 'image.defaultAlign' : 'По умолчанию', + 'image.leftAlign' : 'Влево', + 'image.rightAlign' : 'Вправо', + 'image.imgTitle' : 'Название', + 'image.upload' : 'Загрузить', + 'image.viewServer' : 'Выбрать', + 'multiimage.uploadDesc' : 'Максимальное кол-во изображений: <%=uploadLimit%>, Максимальный размер одного изображения: <%=sizeLimit%>', + 'multiimage.startUpload' : 'Начать загрузку', + 'multiimage.clearAll' : 'Очистить все', + 'multiimage.insertAll' : 'Вставить все', + 'multiimage.queueLimitExceeded' : 'Превышен лимит очереди.', + 'multiimage.fileExceedsSizeLimit' : 'Превышен максимальный размер файла.', + 'multiimage.zeroByteFile' : 'Файл нулевой длины.', + 'multiimage.invalidFiletype' : 'Недопустимый тип файла.', + 'multiimage.unknownError' : 'Непредвиденная ошибка загрузки.', + 'multiimage.pending' : 'Ожидает ...', + 'multiimage.uploadError' : 'Ошибка загрузки', + 'filemanager.emptyFolder' : 'Папка пуста', + 'filemanager.moveup' : 'Наверх', + 'filemanager.viewType' : 'Тип показа: ', + 'filemanager.viewImage' : 'Превьюшки', + 'filemanager.listImage' : 'Список', + 'filemanager.orderType' : 'Сортировка: ', + 'filemanager.fileName' : 'По имени', + 'filemanager.fileSize' : 'По размеру', + 'filemanager.fileType' : 'По типу', + 'insertfile.url' : 'URL', + 'insertfile.title' : 'Название', + 'insertfile.upload' : 'Загрузить', + 'insertfile.viewServer' : 'Выбрать', + 'table.cells' : 'Ячейки', + 'table.rows' : 'Строки', + 'table.cols' : 'Столбцы', + 'table.size' : 'Размеры', + 'table.width' : 'Ширина', + 'table.height' : 'Высота', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : 'Space', + 'table.padding' : 'Padding', + 'table.spacing' : 'Spacing', + 'table.align' : 'Выравнивание', + 'table.textAlign' : 'По горизонтали', + 'table.verticalAlign' : 'По вертикали', + 'table.alignDefault' : 'По умолчанию', + 'table.alignLeft' : 'Влево', + 'table.alignCenter' : 'По центру', + 'table.alignRight' : 'Вправо', + 'table.alignTop' : 'Вверх', + 'table.alignMiddle' : 'Посередине', + 'table.alignBottom' : 'Вниз', + 'table.alignBaseline' : 'По базовой линии', + 'table.border' : 'Рамка', + 'table.borderWidth' : 'Ширина', + 'table.borderColor' : 'Цвет', + 'table.backgroundColor' : 'Цвет фона', + 'map.address' : 'Адрес: ', + 'map.search' : 'Поиск', + 'baidumap.address' : 'Адрес: ', + 'baidumap.search' : 'Поиск', + 'baidumap.insertDynamicMap' : 'Динамическая карта', + 'anchor.name' : 'Имя якоря', + 'formatblock.formatBlock' : { + h1 : 'Заголовок 1', + h2 : 'Заголовок 2', + h3 : 'Заголовок 3', + h4 : 'Заголовок 4', + p : 'Обычный текст' + }, + 'fontname.fontName' : { + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '1'}, + {'1.5' : '1.5'}, + {'2' : '2'}, + {'2.5' : '2.5'}, + {'3' : '3'} + ], + 'template.selectTemplate' : 'Шаблон', + 'template.replaceContent' : 'Заменить текущий шаблон', + 'template.fileList' : { + '1.html' : 'Текст и изображения', + '2.html' : 'Таблица', + '3.html' : 'Список' + } +}, 'en'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'ru'; diff --git a/addons/nkeditor/assets/lang/zh-CN.js b/addons/nkeditor/assets/lang/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..405e2f44425be5bae48a2a553bd7eecbbe6a8083 --- /dev/null +++ b/addons/nkeditor/assets/lang/zh-CN.js @@ -0,0 +1,267 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : 'HTML代码', + preview : '预览', + undo : '后退(Ctrl+Z)', + redo : '前进(Ctrl+Y)', + cut : '剪切(Ctrl+X)', + copy : '复制(Ctrl+C)', + paste : '粘贴(Ctrl+V)', + plainpaste : '粘贴为无格式文本', + wordpaste : '从Word粘贴', + selectall : '全选(Ctrl+A)', + justifyleft : '左对齐', + justifycenter : '居中', + justifyright : '右对齐', + justifyfull : '两端对齐', + insertorderedlist : '编号', + insertunorderedlist : '项目符号', + indent : '增加缩进', + outdent : '减少缩进', + subscript : '下标', + superscript : '上标', + formatblock : '段落', + fontname : '字体', + fontsize : '文字大小', + forecolor : '文字颜色', + hilitecolor : '文字背景', + bold : '粗体(Ctrl+B)', + italic : '斜体(Ctrl+I)', + underline : '下划线(Ctrl+U)', + strikethrough : '删除线', + removeformat : '删除格式', + image : '图片', + multiimage : '批量图片上传', + graft : '涂鸦', + flash : 'Flash', + media : '视音频', + table : '表格', + tablecell : '单元格', + hr : '插入横线', + emoticons : '插入表情', + link : '超级链接', + unlink : '取消超级链接', + fullscreen : '全屏显示', + about : '关于', + print : '打印(Ctrl+P)', + filemanager : '文件空间', + code : '插入程序代码', + quote : '插入引用', + map : 'Google地图', + baidumap : '百度地图', + lineheight : '行距', + clearhtml : '清理HTML代码', + pagebreak : '插入分页符', + quickformat : '一键排版', + insertfile : '插入文件', + template : '插入模板', + anchor : '锚点', + yes : '确定', + no : '取消', + close : '关闭', + editImage : '图片属性', + deleteImage : '删除图片', + editFlash : 'Flash属性', + deleteFlash : '删除Flash', + editMedia : '视音频属性', + deleteMedia : '删除视音频', + editLink : '超级链接属性', + deleteLink : '取消超级链接', + editAnchor : '锚点属性', + deleteAnchor : '删除锚点', + tableprop : '表格属性', + tablecellprop : '单元格属性', + tableinsert : '插入表格', + tabledelete : '删除表格', + tablecolinsertleft : '左侧插入列', + tablecolinsertright : '右侧插入列', + tablerowinsertabove : '上方插入行', + tablerowinsertbelow : '下方插入行', + tablerowmerge : '向下合并单元格', + tablecolmerge : '向右合并单元格', + tablerowsplit : '拆分行', + tablecolsplit : '拆分列', + tablecoldelete : '删除列', + tablerowdelete : '删除行', + noColor : '无颜色', + pleaseSelectFile : '请选择文件。', + invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。", + invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。", + invalidWidth : "宽度必须为数字。", + invalidHeight : "高度必须为数字。", + invalidBorder : "边框必须为数字。", + invalidUrl : "请输入有效的URL地址。", + invalidRows : '行数为必选项,只允许输入大于0的数字。', + invalidCols : '列数为必选项,只允许输入大于0的数字。', + invalidPadding : '边距必须为数字。', + invalidSpacing : '间距必须为数字。', + invalidJson : '服务器发生故障。', + uploadSuccess : '上传成功。', + cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。', + copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。', + pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。', + ajaxLoading : '加载中,请稍候 ...', + uploadLoading : '上传中,请稍候 ...', + uploadError : '上传错误', + + 'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。', + 'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。', + 'code.pleaseInput' : '请输入程序代码。', + 'link.url' : 'URL', + 'link.linkType' : '打开类型', + 'link.newWindow' : '新窗口', + 'link.selfWindow' : '当前窗口', + 'flash.url' : 'URL', + 'flash.width' : '宽度', + 'flash.height' : '高度', + 'flash.upload' : '上传', + 'flash.viewServer' : '文件空间', + 'media.url' : 'URL', + 'media.width' : '宽度', + 'media.height' : '高度', + 'media.autostart' : '自动播放', + 'media.upload' : '上传', + 'media.viewServer' : '文件空间', + 'image.remoteImage' : '网络图片', + 'image.localImage' : '本地上传', + 'image.remoteUrl' : '图片地址', + 'image.localUrl' : '上传文件', + 'image.size' : '图片大小', + 'image.width' : '宽', + 'image.height' : '高', + 'image.resetSize' : '重置大小', + 'image.align' : '对齐方式', + 'image.defaultAlign' : '默认方式', + 'image.leftAlign' : '左对齐', + 'image.rightAlign' : '右对齐', + 'image.imgTitle' : '图片说明', + 'image.upload' : '浏览...', + 'image.viewServer' : '图片空间', + + 'multiimage.title' : '多图上传', + 'multiimage.uploadDesc' : '共选择了 <%=numSelect%> 张图片,共 <%=totalSize%>, 还可以添加 <%=numLeft%> 张图片.', + 'multiimage.startUpload' : '开始上传', + 'multiimage.noListUrl' : '无法获取图片,请先配置 fileManagerJson.', + 'multiimage.noSearchUrl' : '无法进行图片搜索,请先配置 imageSearchJson.', + 'multiimage.noDataText' : '(⊙o⊙)亲,没有多数据了。', + 'multiimage.closeText' : '关闭对话框', + 'multiimage.confirmBtnText' : '确定', + 'multiimage.cancelBtnText' : '取消', + 'multiimage.loadMoreData' : '往下拉动滚动条可以加载更多数据.', + 'multiimage.depJQueryError' : '文件管理插件依赖 jQuery, 请先引入 jQuery.', + 'multiimage.localUpload' : '本地上传', + 'multiimage.fileServer' : '文件服务器', + 'multiimage.imgSearch' : '图片搜索', + 'multiimage.selectFile' : '点击选择图片', + 'multiimage.continueAdd' : '继续添加', + 'multiimage.searchBtn' : '搜索一下', + 'multiimage.searchPlaceholder' : '请输入搜索关键词', + 'multiimage.searchClear' : '清空搜索', + 'multiimage.noFileAdded' : '请至少添加一个文件!', + 'multiimage.uploading' : '正在上传', + 'multiimage.fileNotUpload' : '您还有文件没有上传!', + 'multiimage.uploadLimit' : '您本次最多上传 <%=uploadLimit%> 个文件.', + 'multiimage.sizeLimit' : '文件大小不能超过 <%=sizeLimit%> KB.', + 'multiimage.invalidExt' : '非法的文件后缀 <%=invalidExt%>.', + 'multiimage.remove' : '删除', + 'multiimage.rotateRight' : '向右旋转', + 'multiimage.rotateLeft' : '向左旋转', + 'multiimage.uploadFail' : '发生异常,上传失败!', + 'multiimage.noFileSelected' : '请至少选择一个文件或一张图片.', + + 'filemanager.noDataText' : '(⊙o⊙)亲,没有多数据了。', + 'filemanager.title' : '文件服务器', + 'filemanager.noListUrl' : '无法获取图片,请先配置 fileManagerJson.', + 'filemanager.closeText' : '关闭对话框', + 'filemanager.confirmBtnText' : '确定', + 'filemanager.cancelBtnText' : '取消', + 'filemanager.loadMoreData' : '往下拉动滚动条可以加载更多数据.', + 'filemanager.depJQueryError' : '文件管理插件依赖 jQuery, 请先引入 jQuery.', + 'filemanager.fileType' : '类型', + + 'graft.btnText' : '保存并插入涂鸦', + 'graft.uploadSuccess' : '涂鸦上传成功', + 'graft.uploadFaild' : '涂鸦上传失败', + 'graft.empty' : '您没有在画布上绘制任何图像', + + 'insertfile.url' : 'URL', + 'insertfile.title' : '文件说明', + 'insertfile.upload' : '上传', + 'insertfile.viewServer' : '文件空间', + 'table.cells' : '单元格数', + 'table.rows' : '行数', + 'table.cols' : '列数', + 'table.size' : '大小', + 'table.width' : '宽度', + 'table.height' : '高度', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '边距间距', + 'table.padding' : '边距', + 'table.spacing' : '间距', + 'table.align' : '对齐方式', + 'table.textAlign' : '水平对齐', + 'table.verticalAlign' : '垂直对齐', + 'table.alignDefault' : '默认', + 'table.alignLeft' : '左对齐', + 'table.alignCenter' : '居中', + 'table.alignRight' : '右对齐', + 'table.alignTop' : '顶部', + 'table.alignMiddle' : '中部', + 'table.alignBottom' : '底部', + 'table.alignBaseline' : '基线', + 'table.border' : '边框', + 'table.borderWidth' : '宽度', + 'table.borderColor' : '颜色', + 'table.backgroundColor' : '背景颜色', + 'map.address' : '地址: ', + 'map.search' : '搜索', + 'baidumap.address' : '地址: ', + 'baidumap.search' : '搜索', + 'baidumap.insertDynamicMap' : '插入动态地图', + 'anchor.name' : '锚点名称', + 'formatblock.formatBlock' : { + h1 : '标题 1', + h2 : '标题 2', + h3 : '标题 3', + h4 : '标题 4', + p : '正 文' + }, + 'fontname.fontName' : { + 'SimSun' : '宋体', + 'NSimSun' : '新宋体', + 'FangSong' : '仿宋', + 'KaiTi' : '楷体', + 'SimHei' : '黑体', + 'Microsoft YaHei' : '微软雅黑', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Times New Roman' : 'Times New Roman', + 'Courier New' : 'Courier New', + 'Tahoma' : 'Tahoma', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '单倍行距'}, + {'1.5' : '1.5倍行距'}, + {'2' : '2倍行距'}, + {'2.5' : '2.5倍行距'}, + {'3' : '3倍行距'} + ], + 'template.selectTemplate' : '可选模板', + 'template.replaceContent' : '替换当前内容', + 'template.fileList' : { + '1.html' : '图片和文字', + '2.html' : '表格', + '3.html' : '项目编号' + } +}, 'zh-CN'); +KindEditor.options.langType = 'zh-CN'; diff --git a/addons/nkeditor/assets/lang/zh-TW.js b/addons/nkeditor/assets/lang/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..49468980f618aab6f8ff4824df5bed50eea59663 --- /dev/null +++ b/addons/nkeditor/assets/lang/zh-TW.js @@ -0,0 +1,243 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : '原始碼', + preview : '預覽', + undo : '復原(Ctrl+Z)', + redo : '重複(Ctrl+Y)', + cut : '剪下(Ctrl+X)', + copy : '複製(Ctrl+C)', + paste : '貼上(Ctrl+V)', + plainpaste : '貼為純文字格式', + wordpaste : '自Word貼上', + selectall : '全選(Ctrl+A)', + justifyleft : '靠左對齊', + justifycenter : '置中', + justifyright : '靠右對齊', + justifyfull : '左右對齊', + insertorderedlist : '編號清單', + insertunorderedlist : '項目清單', + indent : '增加縮排', + outdent : '減少縮排', + subscript : '下標', + superscript : '上標', + formatblock : '標題', + fontname : '字體', + fontsize : '文字大小', + forecolor : '文字顏色', + hilitecolor : '背景顏色', + bold : '粗體(Ctrl+B)', + italic : '斜體(Ctrl+I)', + underline : '底線(Ctrl+U)', + strikethrough : '刪除線', + removeformat : '清除格式', + image : '影像', + multiimage : '批量影像上傳', + flash : 'Flash', + media : '多媒體', + table : '表格', + tablecell : '儲存格', + hr : '插入水平線', + emoticons : '插入表情', + link : '超連結', + unlink : '移除超連結', + fullscreen : '最大化', + about : '關於', + print : '列印(Ctrl+P)', + filemanager : '瀏覽伺服器', + code : '插入程式代碼', + map : 'Google地圖', + baidumap : 'Baidu地圖', + lineheight : '行距', + clearhtml : '清理HTML代碼', + pagebreak : '插入分頁符號', + quickformat : '快速排版', + insertfile : '插入文件', + template : '插入樣板', + anchor : '錨點', + yes : '確定', + no : '取消', + close : '關閉', + editImage : '影像屬性', + deleteImage : '刪除影像', + editFlash : 'Flash屬性', + deleteFlash : '删除Flash', + editMedia : '多媒體屬性', + deleteMedia : '删除多媒體', + editLink : '超連結屬性', + deleteLink : '移除超連結', + editAnchor : '锚点属性', + deleteAnchor : '删除锚点', + tableprop : '表格屬性', + tablecellprop : '儲存格屬性', + tableinsert : '插入表格', + tabledelete : '刪除表格', + tablecolinsertleft : '向左插入列', + tablecolinsertright : '向右插入列', + tablerowinsertabove : '向上插入欄', + tablerowinsertbelow : '下方插入欄', + tablerowmerge : '向下合併單元格', + tablecolmerge : '向右合併單元格', + tablerowsplit : '分割欄', + tablecolsplit : '分割列', + tablecoldelete : '删除列', + tablerowdelete : '删除欄', + noColor : '自動', + pleaseSelectFile : '請選擇文件。', + invalidImg : "請輸入有效的URL。\n只允許jpg,gif,bmp,png格式。", + invalidMedia : "請輸入有效的URL。\n只允許swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。", + invalidWidth : "寬度必須是數字。", + invalidHeight : "高度必須是數字。", + invalidBorder : "邊框必須是數字。", + invalidUrl : "請輸入有效的URL。", + invalidRows : '欄數是必須輸入項目,只允許輸入大於0的數字。', + invalidCols : '列數是必須輸入項目,只允許輸入大於0的數字。', + invalidPadding : '內距必須是數字。', + invalidSpacing : '間距必須是數字。', + invalidJson : '伺服器發生故障。', + uploadSuccess : '上傳成功。', + cutError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+X)完成。', + copyError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+C)完成。', + pasteError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+V)完成。', + ajaxLoading : '加載中,請稍候 ...', + uploadLoading : '上傳中,請稍候 ...', + uploadError : '上傳錯誤', + 'plainpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。', + 'wordpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : 'URL', + 'link.linkType' : '打開類型', + 'link.newWindow' : '新窗口', + 'link.selfWindow' : '本頁窗口', + 'flash.url' : 'URL', + 'flash.width' : '寬度', + 'flash.height' : '高度', + 'flash.upload' : '上傳', + 'flash.viewServer' : '瀏覽', + 'media.url' : 'URL', + 'media.width' : '寬度', + 'media.height' : '高度', + 'media.autostart' : '自動播放', + 'media.upload' : '上傳', + 'media.viewServer' : '瀏覽', + 'image.remoteImage' : '網絡影像', + 'image.localImage' : '上傳影像', + 'image.remoteUrl' : '影像URL', + 'image.localUrl' : '影像URL', + 'image.size' : '影像大小', + 'image.width' : '寬度', + 'image.height' : '高度', + 'image.resetSize' : '原始大小', + 'image.align' : '對齊方式', + 'image.defaultAlign' : '未設定', + 'image.leftAlign' : '向左對齊', + 'image.rightAlign' : '向右對齊', + 'image.imgTitle' : '影像說明', + 'image.upload' : '瀏覽...', + 'image.viewServer' : '瀏覽...', + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>', + 'multiimage.startUpload' : 'Start upload', + 'multiimage.clearAll' : 'Clear all', + 'multiimage.insertAll' : 'Insert all', + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.', + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.', + 'multiimage.zeroByteFile' : 'Zero byte file.', + 'multiimage.invalidFiletype' : 'Invalid file type.', + 'multiimage.unknownError' : 'Unknown upload error.', + 'multiimage.pending' : 'Pending ...', + 'multiimage.uploadError' : 'Upload error', + 'filemanager.emptyFolder' : '空文件夾', + 'filemanager.moveup' : '至上一級文件夾', + 'filemanager.viewType' : '顯示方式:', + 'filemanager.viewImage' : '縮略圖', + 'filemanager.listImage' : '詳細信息', + 'filemanager.orderType' : '排序方式:', + 'filemanager.fileName' : '名稱', + 'filemanager.fileSize' : '大小', + 'filemanager.fileType' : '類型', + 'insertfile.url' : 'URL', + 'insertfile.title' : '文件說明', + 'insertfile.upload' : '上傳', + 'insertfile.viewServer' : '瀏覽', + 'table.cells' : '儲存格數', + 'table.rows' : '欄數', + 'table.cols' : '列數', + 'table.size' : '表格大小', + 'table.width' : '寬度', + 'table.height' : '高度', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '內距間距', + 'table.padding' : '內距', + 'table.spacing' : '間距', + 'table.align' : '對齊方式', + 'table.textAlign' : '水平對齊', + 'table.verticalAlign' : '垂直對齊', + 'table.alignDefault' : '未設定', + 'table.alignLeft' : '向左對齊', + 'table.alignCenter' : '置中', + 'table.alignRight' : '向右對齊', + 'table.alignTop' : '靠上', + 'table.alignMiddle' : '置中', + 'table.alignBottom' : '靠下', + 'table.alignBaseline' : '基線', + 'table.border' : '表格邊框', + 'table.borderWidth' : '邊框', + 'table.borderColor' : '顏色', + 'table.backgroundColor' : '背景顏色', + 'map.address' : '住所: ', + 'map.search' : '尋找', + 'baidumap.address' : '住所: ', + 'baidumap.search' : '尋找', + 'baidumap.insertDynamicMap' : '插入動態地圖', + 'anchor.name' : '錨點名稱', + 'formatblock.formatBlock' : { + h1 : '標題 1', + h2 : '標題 2', + h3 : '標題 3', + h4 : '標題 4', + p : '一般' + }, + 'fontname.fontName' : { + 'MingLiU' : '細明體', + 'PMingLiU' : '新細明體', + 'DFKai-SB' : '標楷體', + 'SimSun' : '宋體', + 'NSimSun' : '新宋體', + 'FangSong' : '仿宋體', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Times New Roman' : 'Times New Roman', + 'Courier New' : 'Courier New', + 'Tahoma' : 'Tahoma', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '单倍行距'}, + {'1.5' : '1.5倍行距'}, + {'2' : '2倍行距'}, + {'2.5' : '2.5倍行距'}, + {'3' : '3倍行距'} + ], + 'template.selectTemplate' : '可選樣板', + 'template.replaceContent' : '取代當前內容', + 'template.fileList' : { + '1.html' : '影像和文字', + '2.html' : '表格', + '3.html' : '项目清單' + } +}, 'zh-TW'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'zh-TW'; \ No newline at end of file diff --git a/addons/nkeditor/assets/nkeditor.js b/addons/nkeditor/assets/nkeditor.js new file mode 100644 index 0000000000000000000000000000000000000000..cb9d8d1de6316468d866e3409c2aa56ae42aee52 --- /dev/null +++ b/addons/nkeditor/assets/nkeditor.js @@ -0,0 +1,9503 @@ +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2018 kindsoft.net + * + * @author Roddy + * @website http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + * @version 5.0.3 (2018-10-25) + *******************************************************************************/ +(function (window, undefined) { + if (window.KindEditor) { + return; + } + + + if (!window.console) { + window.console = {}; + } + if (!console.log) { + console.log = function () { + }; + } + var _VERSION = '5.0.3 (2018-10-25)', + _ua = navigator.userAgent.toLowerCase(), + _IE = _ua.indexOf('msie') > -1 && _ua.indexOf('opera') == -1, + _NEWIE = _ua.indexOf('msie') == -1 && _ua.indexOf('trident') > -1, + _GECKO = _ua.indexOf('gecko') > -1 && _ua.indexOf('khtml') == -1, + _WEBKIT = _ua.indexOf('applewebkit') > -1, + _OPERA = _ua.indexOf('opera') > -1, + _MOBILE = _ua.indexOf('mobile') > -1, + _IOS = /ipad|iphone|ipod/.test(_ua), + _QUIRKS = document.compatMode != 'CSS1Compat', + _IERANGE = !window.getSelection, + _matches = /(?:msie|firefox|webkit|opera)[\/:\s](\d+)/.exec(_ua), + _V = _matches ? _matches[1] : '0', + _TIME = new Date().getTime(); + + function _isArray(val) { + if (!val) { + return false; + } + return Object.prototype.toString.call(val) === '[object Array]'; + } + + function _isFunction(val) { + if (!val) { + return false; + } + return Object.prototype.toString.call(val) === '[object Function]'; + } + + function _inArray(val, arr) { + for (var i = 0, len = arr.length; i < len; i++) { + if (val === arr[i]) { + return i; + } + } + return -1; + } + + function _each(obj, fn) { + if (_isArray(obj)) { + for (var i = 0, len = obj.length; i < len; i++) { + if (fn.call(obj[i], i, obj[i]) === false) { + break; + } + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if (fn.call(obj[key], key, obj[key]) === false) { + break; + } + } + } + } + } + + function _trim(str) { + return str.replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, ''); + } + + function _inString(val, str, delimiter) { + delimiter = delimiter === undefined ? ',' : delimiter; + return (delimiter + str + delimiter).indexOf(delimiter + val + delimiter) >= 0; + } + + function _addUnit(val, unit) { + unit = unit || 'px'; + return val && /^-?\d+(?:\.\d+)?$/.test(val) ? val + unit : val; + } + + function _removeUnit(val) { + var match; + return val && (match = /(\d+)/.exec(val)) ? parseInt(match[1], 10) : 0; + } + + function _escape(val) { + return val.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); + } + + function _unescape(val) { + return val.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/&/g, '&'); + } + + function _toCamel(str) { + var arr = str.split('-'); + str = ''; + _each(arr, function (key, val) { + str += (key > 0) ? val.charAt(0).toUpperCase() + val.substr(1) : val; + }); + return str; + } + + function _toHex(val) { + function hex(d) { + var s = parseInt(d, 10).toString(16).toUpperCase(); + return s.length > 1 ? s : '0' + s; + } + + return val.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/ig, + function ($0, $1, $2, $3) { + return '#' + hex($1) + hex($2) + hex($3); + } + ); + } + + function _toMap(val, delimiter) { + delimiter = delimiter === undefined ? ',' : delimiter; + var map = {}, arr = _isArray(val) ? val : val.split(delimiter), match; + _each(arr, function (key, val) { + if ((match = /^(\d+)\.\.(\d+)$/.exec(val))) { + for (var i = parseInt(match[1], 10); i <= parseInt(match[2], 10); i++) { + map[i.toString()] = true; + } + } else { + map[val] = true; + } + }); + return map; + } + + function _toArray(obj, offset) { + return Array.prototype.slice.call(obj, offset || 0); + } + + function _undef(val, defaultVal) { + return val === undefined ? defaultVal : val; + } + + function _invalidUrl(url) { + return !url || /[<>"]/.test(url); + } + + function _addParam(url, param) { + return url.indexOf('?') >= 0 ? url + '&' + param : url + '?' + param; + } + + function _extend(child, parent, proto) { + if (!proto) { + proto = parent; + parent = null; + } + var childProto; + if (parent) { + var fn = function () { + }; + fn.prototype = parent.prototype; + childProto = new fn(); + _each(proto, function (key, val) { + childProto[key] = val; + }); + } else { + childProto = proto; + } + childProto.constructor = child; + child.prototype = childProto; + child.parent = parent ? parent.prototype : null; + } + + + function _json(text) { + var match; + if ((match = /\{[\s\S]*\}|\[[\s\S]*\]/.exec(text))) { + text = match[0]; + } + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + return eval('(' + text + ')'); + } + throw 'JSON parse error'; + } + + + function _merge(distObj, obj) { + for (var name in distObj) { + obj[name] = distObj[name]; + } + return obj; + } + + var _round = Math.round; + var K = { + DEBUG: false, + VERSION: _VERSION, + IE: _IE, + GECKO: _GECKO, + WEBKIT: _WEBKIT, + OPERA: _OPERA, + V: _V, + TIME: _TIME, + each: _each, + isArray: _isArray, + isFunction: _isFunction, + inArray: _inArray, + inString: _inString, + trim: _trim, + addUnit: _addUnit, + removeUnit: _removeUnit, + escape: _escape, + unescape: _unescape, + toCamel: _toCamel, + toHex: _toHex, + toMap: _toMap, + toArray: _toArray, + undef: _undef, + invalidUrl: _invalidUrl, + addParam: _addParam, + extend: _extend, + merge: _merge, + json: _json + }; + var _INLINE_TAG_MAP = _toMap('a,abbr,acronym,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,img,input,ins,kbd,label,map,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'), + _BLOCK_TAG_MAP = _toMap('address,applet,blockquote,body,center,dd,dir,div,dl,dt,fieldset,form,frameset,h1,h2,h3,h4,h5,h6,head,hr,html,iframe,ins,isindex,li,map,menu,meta,noframes,noscript,object,ol,p,pre,script,style,table,tbody,td,tfoot,th,thead,title,tr,ul'), + _SINGLE_TAG_MAP = _toMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'), + _STYLE_TAG_MAP = _toMap('b,basefont,big,del,em,font,i,s,small,span,strike,strong,sub,sup,u'), + _CONTROL_TAG_MAP = _toMap('img,table,input,textarea,button'), + _PRE_TAG_MAP = _toMap('pre,style,script'), + _NOSPLIT_TAG_MAP = _toMap('html,head,body,td,tr,table,ol,ul,li'), + _AUTOCLOSE_TAG_MAP = _toMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'), + _FILL_ATTR_MAP = _toMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'), + _VALUE_TAG_MAP = _toMap('input,button,textarea,select'); + + + function _getBasePath() { + var els = document.getElementsByTagName('script'), src; + for (var i = 0, len = els.length; i < len; i++) { + src = els[i].src || ''; + if (/NKeditor[\w\-\.]*\.js/i.test(src)) { + return src.substring(0, src.lastIndexOf('/') + 1); + } + } + return ''; + } + + K.basePath = _getBasePath(); + K.options = { + designMode: true, + fullscreenMode: false, + filterMode: true, + wellFormatMode: true, + loadStyleMode: true, + basePath: K.basePath, + themesPath: K.basePath + 'themes/', + langPath: K.basePath + 'lang/', + pluginsPath: K.basePath + 'plugins/', + themeType: 'primary', + langType: 'zh-CN', + urlType: '', + newlineTag: 'p', + resizeType: 2, + syncType: 'form', + pasteType: 2, + dialogAlignType: 'page', + useContextmenu: true, + fullscreenShortcut: false, + bodyClass: 'ke-content', + indentChar: '\t', + cssPath: [], + jsPath: [], + showHelpGrid: false, + cssData: '', + minWidth: 650, + minHeight: 300, + minChangeSize: 50, + zIndex: 811213, + items: [ + 'source', 'undo', 'redo', 'preview', 'print', 'template', 'code', 'quote', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', + 'formatblock', 'fontname', 'fontsize', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', 'image', 'multiimage', 'graft', + 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', 'about', 'fullscreen' + ], + noDisableItems: ['source', 'fullscreen'], + colorTable: [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#DDDDDD', '#999999', '#666666', '#333333', '#000000'] + ], + fontSizeTable: ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'], + htmlTags: { + font: ['id', 'class', 'color', 'size', 'face', '.background-color'], + span: [ + 'id', 'class', '.color', '.background-color', '.font-size', '.font-family', '.background', + '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height' + ], + div: [ + 'id', 'class', 'align', '.border', '.margin', '.padding', '.text-align', '.color', + '.background-color', '.font-size', '.font-family', '.font-weight', '.background', + '.font-style', '.text-decoration', '.vertical-align', '.margin-left' + ], + table: [ + 'id', 'class', 'border', 'cellspacing', 'cellpadding', 'width', 'height', 'align', 'bordercolor', + '.padding', '.margin', '.border', 'bgcolor', '.text-align', '.color', '.background-color', + '.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.background', + '.width', '.height', '.border-collapse' + ], + 'td,th': [ + 'id', 'class', 'align', 'valign', 'width', 'height', 'colspan', 'rowspan', 'bgcolor', + '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight', + '.font-style', '.text-decoration', '.vertical-align', '.background', '.border' + ], + a: ['id', 'class', 'href', 'target', 'name'], + embed: ['id', 'class', 'src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess', 'wmode', 'controls'], + img: ['id', 'class', 'src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'], + 'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6': [ + 'id', 'class', 'align', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.background', + '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.text-indent', '.margin-left' + ], + pre: ['id', 'class'], + hr: ['id', 'class', '.page-break-after'], + 'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del': ['id', 'class'], + iframe: ['id', 'class', 'src', 'frameborder', 'width', 'height', '.width', '.height'] + }, + layout: '
', + afterBlur: function () { + this.sync(); + }, + errorMsgHandler: function (message, type) { + console.log(message); + console.log(type); + alert(message); + }, + dialogOffset: 0, + allowUploadGraft: true, + resLoadCache: {}, + tableBorderColor: '#cccccc', + }; + + + var _useCapture = false; + + + var _INPUT_KEY_MAP = _toMap('8,9,13,32,46,48..57,59,61,65..90,106,109..111,188,190..192,219..222'); + + var _CURSORMOVE_KEY_MAP = _toMap('33..40'); + + var _CHANGE_KEY_MAP = {}; + _each(_INPUT_KEY_MAP, function (key, val) { + _CHANGE_KEY_MAP[key] = val; + }); + _each(_CURSORMOVE_KEY_MAP, function (key, val) { + _CHANGE_KEY_MAP[key] = val; + }); + + + function _bindEvent(el, type, fn) { + if (el.addEventListener) { + el.addEventListener(type, fn, _useCapture); + } else if (el.attachEvent) { + el.attachEvent('on' + type, fn); + } + } + + function _unbindEvent(el, type, fn) { + if (el.removeEventListener) { + el.removeEventListener(type, fn, _useCapture); + } else if (el.detachEvent) { + el.detachEvent('on' + type, fn); + } + } + + var _EVENT_PROPS = ('altKey,attrChange,attrName,bubbles,button,cancelable,charCode,clientX,clientY,ctrlKey,currentTarget,' + + 'data,detail,eventPhase,fromElement,handler,keyCode,metaKey,newValue,offsetX,offsetY,originalTarget,pageX,' + + 'pageY,prevValue,relatedNode,relatedTarget,screenX,screenY,shiftKey,srcElement,target,toElement,view,wheelDelta,which').split(','); + + + function KEvent(el, event) { + this.init(el, event); + } + + _extend(KEvent, { + init: function (el, event) { + var self = this, doc = el.ownerDocument || el.document || el; + self.event = event; + _each(_EVENT_PROPS, function (key, val) { + self[val] = event[val]; + }); + if (!self.target) { + self.target = self.srcElement || doc; + } + if (self.target.nodeType === 3) { + self.target = self.target.parentNode; + } + if (!self.relatedTarget && self.fromElement) { + self.relatedTarget = self.fromElement === self.target ? self.toElement : self.fromElement; + } + if (self.pageX == null && self.clientX != null) { + var d = doc.documentElement, body = doc.body; + self.pageX = self.clientX + (d && d.scrollLeft || body && body.scrollLeft || 0) - (d && d.clientLeft || body && body.clientLeft || 0); + self.pageY = self.clientY + (d && d.scrollTop || body && body.scrollTop || 0) - (d && d.clientTop || body && body.clientTop || 0); + } + if (!self.which && ((self.charCode || self.charCode === 0) ? self.charCode : self.keyCode)) { + self.which = self.charCode || self.keyCode; + } + if (!self.metaKey && self.ctrlKey) { + self.metaKey = self.ctrlKey; + } + if (!self.which && self.button !== undefined) { + self.which = (self.button & 1 ? 1 : (self.button & 2 ? 3 : (self.button & 4 ? 2 : 0))); + } + switch (self.which) { + case 186 : + self.which = 59; + break; + case 187 : + case 107 : + case 43 : + self.which = 61; + break; + case 189 : + case 45 : + self.which = 109; + break; + case 42 : + self.which = 106; + break; + case 47 : + self.which = 111; + break; + case 78 : + self.which = 110; + break; + } + if (self.which >= 96 && self.which <= 105) { + self.which -= 48; + } + }, + preventDefault: function () { + var ev = this.event; + if (ev.preventDefault) { + ev.preventDefault(); + } else { + ev.returnValue = false; + } + }, + stopPropagation: function () { + var ev = this.event; + if (ev.stopPropagation) { + ev.stopPropagation(); + } else { + ev.cancelBubble = true; + } + }, + stop: function () { + this.preventDefault(); + this.stopPropagation(); + } + }); + var _eventExpendo = 'kindeditor_' + _TIME, _eventId = 0, _eventData = {}; + + function _getId(el) { + return el[_eventExpendo] || null; + } + + function _setId(el) { + el[_eventExpendo] = ++_eventId; + return _eventId; + } + + function _removeId(el) { + try { + delete el[_eventExpendo]; + } catch (e) { + if (el.removeAttribute) { + el.removeAttribute(_eventExpendo); + } + } + } + + function _bind(el, type, fn) { + if (type.indexOf(',') >= 0) { + _each(type.split(','), function () { + _bind(el, this, fn); + }); + return; + } + var id = _getId(el); + if (!id) { + id = _setId(el); + } + if (_eventData[id] === undefined) { + _eventData[id] = {}; + } + var events = _eventData[id][type]; + if (events && events.length > 0) { + _unbindEvent(el, type, events[0]); + } else { + _eventData[id][type] = []; + _eventData[id].el = el; + } + events = _eventData[id][type]; + if (events.length === 0) { + events[0] = function (e) { + var kevent = e ? new KEvent(el, e) : undefined; + _each(events, function (i, event) { + if (i > 0 && event) { + event.call(el, kevent); + } + }); + }; + } + if (_inArray(fn, events) < 0) { + events.push(fn); + } + _bindEvent(el, type, events[0]); + } + + function _unbind(el, type, fn) { + if (type && type.indexOf(',') >= 0) { + _each(type.split(','), function () { + _unbind(el, this, fn); + }); + return; + } + var id = _getId(el); + if (!id) { + return; + } + if (type === undefined) { + if (id in _eventData) { + _each(_eventData[id], function (key, events) { + if (key != 'el' && events.length > 0) { + _unbindEvent(el, key, events[0]); + } + }); + delete _eventData[id]; + _removeId(el); + } + return; + } + if (!_eventData[id]) { + return; + } + var events = _eventData[id][type]; + if (events && events.length > 0) { + if (fn === undefined) { + _unbindEvent(el, type, events[0]); + delete _eventData[id][type]; + } else { + _each(events, function (i, event) { + if (i > 0 && event === fn) { + events.splice(i, 1); + } + }); + if (events.length == 1) { + _unbindEvent(el, type, events[0]); + delete _eventData[id][type]; + } + } + var count = 0; + _each(_eventData[id], function () { + count++; + }); + if (count < 2) { + delete _eventData[id]; + _removeId(el); + } + } + } + + function _fire(el, type) { + if (type.indexOf(',') >= 0) { + _each(type.split(','), function () { + _fire(el, this); + }); + return; + } + var id = _getId(el); + if (!id) { + return; + } + var events = _eventData[id][type]; + if (_eventData[id] && events && events.length > 0) { + events[0](); + } + } + + function _ctrl(el, key, fn) { + var self = this; + key = /^\d{2,}$/.test(key) ? key : key.toUpperCase().charCodeAt(0); + _bind(el, 'keydown', function (e) { + if (e.ctrlKey && e.which == key && !e.shiftKey && !e.altKey) { + fn.call(el); + e.stop(); + } + }); + } + + var _readyFinished = false; + + function _ready(fn) { + if (_readyFinished) { + fn(KindEditor); + return; + } + var loaded = false; + + function readyFunc() { + if (!loaded) { + loaded = true; + fn(KindEditor); + _readyFinished = true; + } + } + + function ieReadyFunc() { + if (!loaded) { + try { + document.documentElement.doScroll('left'); + } catch (e) { + setTimeout(ieReadyFunc, 100); + return; + } + readyFunc(); + } + } + + function ieReadyStateFunc() { + if (document.readyState === 'complete') { + readyFunc(); + } + } + + if (document.addEventListener) { + _bind(document, 'DOMContentLoaded', readyFunc); + } else if (document.attachEvent) { + _bind(document, 'readystatechange', ieReadyStateFunc); + var toplevel = false; + try { + toplevel = window.frameElement == null; + } catch (e) { + } + if (document.documentElement.doScroll && toplevel) { + ieReadyFunc(); + } + } + _bind(window, 'load', readyFunc); + } + + if (window.attachEvent) { + window.attachEvent('onunload', function () { + _each(_eventData, function (key, events) { + if (events.el) { + _unbind(events.el); + } + }); + }); + } + K.ctrl = _ctrl; + K.ready = _ready; + + function _getCssList(css) { + css = css.replace(/"/g, '"'); + var list = {}, + reg = /\s*([\w\-]+)\s*:([^;]*)(;|$)/g, + match; + while ((match = reg.exec(css))) { + var key = _trim(match[1].toLowerCase()), + val = _trim(_toHex(match[2])); + list[key] = val; + } + return list; + } + + function _getAttrList(tag) { + var list = {}, + reg = /\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g, + match; + while ((match = reg.exec(tag))) { + var key = (match[1] || match[2] || match[4] || match[6]).toLowerCase(), + val = (match[2] ? match[3] : (match[4] ? match[5] : match[7])) || ''; + list[key] = val; + } + return list; + } + + function _addClassToTag(tag, className) { + if (/\s+class\s*=/.test(tag)) { + tag = tag.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/, function ($0, $1, $2, $3) { + if ((' ' + $2 + ' ').indexOf(' ' + className + ' ') < 0) { + return $2 === '' ? $1 + className + $3 : $1 + $2 + ' ' + className + $3; + } else { + return $0; + } + }); + } else { + tag = tag.substr(0, tag.length - 1) + ' class="' + className + '">'; + } + return tag; + } + + function _formatCss(css) { + var str = ''; + _each(_getCssList(css), function (key, val) { + str += key + ':' + val + ';'; + }); + return str; + } + + function _formatUrl(url, mode, host, pathname) { + mode = _undef(mode, '').toLowerCase(); + if (url.substr(0, 5) != 'data:') { + url = url.replace(/([^:])\/\//g, '$1/'); + } + if (_inArray(mode, ['absolute', 'relative', 'domain']) < 0) { + return url; + } + host = host || location.protocol + '//' + location.host; + if (pathname === undefined) { + var m = location.pathname.match(/^(\/.*)\//); + pathname = m ? m[1] : ''; + } + var match; + if ((match = /^(\w+:\/\/[^\/]*)/.exec(url))) { + if (match[1] !== host) { + return url; + } + } else if (/^\w+:/.test(url)) { + return url; + } + + function getRealPath(path) { + var parts = path.split('/'), paths = []; + for (var i = 0, len = parts.length; i < len; i++) { + var part = parts[i]; + if (part == '..') { + if (paths.length > 0) { + paths.pop(); + } + } else if (part !== '' && part != '.') { + paths.push(part); + } + } + return '/' + paths.join('/'); + } + + if (/^\//.test(url)) { + url = host + getRealPath(url.substr(1)); + } else if (!/^\w+:\/\//.test(url)) { + url = host + getRealPath(pathname + '/' + url); + } + + function getRelativePath(path, depth) { + if (url.substr(0, path.length) === path) { + var arr = []; + for (var i = 0; i < depth; i++) { + arr.push('..'); + } + var prefix = '.'; + if (arr.length > 0) { + prefix += '/' + arr.join('/'); + } + if (pathname == '/') { + prefix += '/'; + } + return prefix + url.substr(path.length); + } else { + if ((match = /^(.*)\//.exec(path))) { + return getRelativePath(match[1], ++depth); + } + } + } + + if (mode === 'relative') { + url = getRelativePath(host + pathname, 0).substr(2); + } else if (mode === 'absolute') { + if (url.substr(0, host.length) === host) { + url = url.substr(host.length); + } + } + return url; + } + + function _formatHtml(html, htmlTags, urlType, wellFormatted, indentChar) { + if (html == null) { + html = ''; + } + urlType = urlType || ''; + wellFormatted = _undef(wellFormatted, false); + indentChar = _undef(indentChar, '\t'); + var fontSizeList = 'xx-small,x-small,small,medium,large,x-large,xx-large'.split(','); + html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function ($0, $1, $2, $3) { + return $1 + $2.replace(/<(?:br|br\s[^>]*)>/ig, '\n') + $3; + }); + html = html.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/ig, '

'); + html = html.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/ig, '$1
$2'); + html = html.replace(/\u200B/g, ''); + html = html.replace(/\u00A9/g, '©'); + html = html.replace(/\u00AE/g, '®'); + html = html.replace(/\u2003/g, ' '); + html = html.replace(/\u3000/g, ' '); + html = html.replace(/<[^>]+/g, function ($0) { + return $0.replace(/\s+/g, ' '); + }); + var htmlTagMap = {}; + if (htmlTags) { + _each(htmlTags, function (key, val) { + var arr = key.split(','); + for (var i = 0, len = arr.length; i < len; i++) { + htmlTagMap[arr[i]] = _toMap(val); + } + }); + if (!htmlTagMap.script) { + html = html.replace(/(<(?:script|script\s[^>]*)>)([\s\S]*?)(<\/script>)/ig, ''); + } + if (!htmlTagMap.style) { + html = html.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/ig, ''); + } + } + var re = /(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>(\s*)/g; + var tagStack = []; + html = html.replace(re, function ($0, $1, $2, $3, $4, $5, $6) { + var full = $0, + startNewline = $1 || '', + startSlash = $2 || '', + tagName = $3.toLowerCase(), + attr = $4 || '', + endSlash = $5 ? ' ' + $5 : '', + endNewline = $6 || ''; + if (tagName == 'code') { + return full; + } + if (htmlTags && !htmlTagMap[tagName]) { + return ''; + } + if (endSlash === '' && _SINGLE_TAG_MAP[tagName]) { + endSlash = ' /'; + } + if (_INLINE_TAG_MAP[tagName]) { + if (startNewline) { + startNewline = ' '; + } + if (endNewline) { + endNewline = ' '; + } + } + if (_PRE_TAG_MAP[tagName]) { + if (startSlash) { + endNewline = '\n'; + } else { + startNewline = '\n'; + } + } + if (wellFormatted && tagName == 'br') { + endNewline = '\n'; + } + if (_BLOCK_TAG_MAP[tagName] && !_PRE_TAG_MAP[tagName]) { + if (wellFormatted) { + if (startSlash && tagStack.length > 0 && tagStack[tagStack.length - 1] === tagName) { + tagStack.pop(); + } else { + tagStack.push(tagName); + } + startNewline = '\n'; + endNewline = '\n'; + for (var i = 0, len = startSlash ? tagStack.length : tagStack.length - 1; i < len; i++) { + startNewline += indentChar; + if (!startSlash) { + endNewline += indentChar; + } + } + if (endSlash) { + tagStack.pop(); + } else if (!startSlash) { + endNewline += indentChar; + } + } else { + startNewline = endNewline = ''; + } + } + if (attr !== '') { + var attrMap = _getAttrList(full); + if (tagName === 'font') { + var fontStyleMap = {}, fontStyle = ''; + _each(attrMap, function (key, val) { + if (key === 'color') { + fontStyleMap.color = val; + delete attrMap[key]; + } + if (key === 'size') { + fontStyleMap['font-size'] = fontSizeList[parseInt(val, 10) - 1] || ''; + delete attrMap[key]; + } + if (key === 'face') { + fontStyleMap['font-family'] = val; + delete attrMap[key]; + } + if (key === 'style') { + fontStyle = val; + } + }); + if (fontStyle && !/;$/.test(fontStyle)) { + fontStyle += ';'; + } + _each(fontStyleMap, function (key, val) { + if (val === '') { + return; + } + if (/\s/.test(val)) { + val = "'" + val + "'"; + } + fontStyle += key + ':' + val + ';'; + }); + attrMap.style = fontStyle; + } + _each(attrMap, function (key, val) { + if (_FILL_ATTR_MAP[key]) { + attrMap[key] = key; + } + if (_inArray(key, ['src', 'href']) >= 0) { + attrMap[key] = _formatUrl(val, urlType); + } + if (htmlTags && key !== 'style' && !htmlTagMap[tagName]['*'] && !htmlTagMap[tagName][key] || + tagName === 'body' && key === 'contenteditable' || + /^kindeditor_\d+$/.test(key)) { + delete attrMap[key]; + } + if (key === 'style' && val !== '') { + var styleMap = _getCssList(val); + _each(styleMap, function (k, v) { + if (htmlTags && !htmlTagMap[tagName].style && !htmlTagMap[tagName]['.' + k]) { + delete styleMap[k]; + } + }); + var style = ''; + _each(styleMap, function (k, v) { + style += k + ':' + v + ';'; + }); + attrMap.style = style; + } + }); + attr = ''; + _each(attrMap, function (key, val) { + if (key === 'style' && val === '') { + return; + } + val = val.replace(/"/g, '"'); + attr += ' ' + key + '="' + val + '"'; + }); + } + if (tagName === 'font') { + tagName = 'span'; + } + return startNewline + '<' + startSlash + tagName + attr + endSlash + '>' + endNewline; + }); + html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function ($0, $1, $2, $3) { + return $1 + $2.replace(/\n/g, '\n') + $3; + }); + html = html.replace(/\n\s*\n/g, '\n'); + html = html.replace(/\n/g, '\n'); + return _trim(html); + } + + function _clearMsWord(html, htmlTags) { + html = html.replace(//ig, '') + .replace(//ig, '') + .replace(/]*>[\s\S]*?<\/style>/ig, '') + .replace(/]*>[\s\S]*?<\/script>/ig, '') + .replace(/]+>[\s\S]*?<\/w:[^>]+>/ig, '') + .replace(/]+>[\s\S]*?<\/o:[^>]+>/ig, '') + .replace(/[\s\S]*?<\/xml>/ig, '') + .replace(/<(?:table|td)[^>]*>/ig, function (full) { + return full.replace(/border-bottom:([#\w\s]+)/ig, 'border:$1'); + }); + return _formatHtml(html, htmlTags); + } + + function _mediaType(src) { + if (/\.(rm|rmvb)(\?|$)/i.test(src)) { + return 'audio/x-pn-realaudio-plugin'; + } + if (/\.(mp4)(\?|$)/i.test(src)) { + return 'video/mpeg4'; + } + if (/\.(swf|flv)(\?|$)/i.test(src)) { + return 'application/x-shockwave-flash'; + } + return 'video/x-ms-asf-plugin'; + } + + function _mediaClass(type) { + if (/realaudio/i.test(type)) { + return 'ke-rm'; + } + if (/flash/i.test(type)) { + return 'ke-flash'; + } + return 'ke-media'; + } + + function _mediaAttrs(srcTag) { + return _getAttrList(unescape(srcTag)); + } + + function _mediaEmbed(attrs) { + var type = attrs.type == 'video/mpeg4' ? 'video' : 'embed'; + if (type == 'video') { + attrs.controls = "controls"; + } + var html = '<' + type + ' '; + _each(attrs, function (key, val) { + html += key + '="' + val + '" '; + }); + html += '/>'; + return html; + } + + function _mediaImg(blankPath, attrs) { + var width = attrs.width, + height = attrs.height, + type = attrs.type || _mediaType(attrs.src), + srcTag = _mediaEmbed(attrs), + style = ''; + if (/\D/.test(width)) { + style += 'width:' + width + ';'; + } else if (width > 0) { + style += 'width:' + width + 'px;'; + } + if (/\D/.test(height)) { + style += 'height:' + height + ';'; + } else if (height > 0) { + style += 'height:' + height + 'px;'; + } + var html = ''; + return html; + } + + + function _tmpl(str, data) { + var fn = new Function("obj", + "var p=[],print=function(){p.push.apply(p,arguments);};" + + "with(obj){p.push('" + + str.replace(/[\r\t\n]/g, " ") + .split("<%").join("\t") + .replace(/((^|%>)[^\t]*)'/g, "$1\r") + .replace(/\t=(.*?)%>/g, "',$1,'") + .split("\t").join("');") + .split("%>").join("p.push('") + .split("\r").join("\\'") + "');}return p.join('');"); + return data ? fn(data) : fn; + } + + K.formatUrl = _formatUrl; + K.formatHtml = _formatHtml; + K.getCssList = _getCssList; + K.getAttrList = _getAttrList; + K.mediaType = _mediaType; + K.mediaAttrs = _mediaAttrs; + K.mediaEmbed = _mediaEmbed; + K.mediaImg = _mediaImg; + K.clearMsWord = _clearMsWord; + K.tmpl = _tmpl; + + + function _contains(nodeA, nodeB) { + if (nodeA.nodeType == 9 && nodeB.nodeType != 9) { + return true; + } + while ((nodeB = nodeB.parentNode)) { + if (nodeB == nodeA) { + return true; + } + } + return false; + } + + var _getSetAttrDiv = document.createElement('div'); + _getSetAttrDiv.setAttribute('className', 't'); + var _GET_SET_ATTRIBUTE = _getSetAttrDiv.className !== 't'; + + function _getAttr(el, key) { + key = key.toLowerCase(); + var val = null; + if (!_GET_SET_ATTRIBUTE && el.nodeName.toLowerCase() != 'script') { + var div = el.ownerDocument.createElement('div'); + div.appendChild(el.cloneNode(false)); + var list = _getAttrList(_unescape(div.innerHTML)); + if (key in list) { + val = list[key]; + } + } else { + try { + val = el.getAttribute(key, 2); + } catch (e) { + val = el.getAttribute(key, 1); + } + } + if (key === 'style' && val !== null) { + val = _formatCss(val); + } + return val; + } + + function _queryAll(expr, root) { + var exprList = expr.split(','); + if (exprList.length > 1) { + var mergedResults = []; + _each(exprList, function () { + _each(_queryAll(this, root), function () { + if (_inArray(this, mergedResults) < 0) { + mergedResults.push(this); + } + }); + }); + return mergedResults; + } + root = root || document; + + function escape(str) { + if (typeof str != 'string') { + return str; + } + return str.replace(/([^\w\-])/g, '\\$1'); + } + + function stripslashes(str) { + return str.replace(/\\/g, ''); + } + + function cmpTag(tagA, tagB) { + return tagA === '*' || tagA.toLowerCase() === escape(tagB.toLowerCase()); + } + + function byId(id, tag, root) { + var arr = [], + doc = root.ownerDocument || root, + el = doc.getElementById(stripslashes(id)); + if (el) { + if (cmpTag(tag, el.nodeName) && _contains(root, el)) { + arr.push(el); + } + } + return arr; + } + + function byClass(className, tag, root) { + var doc = root.ownerDocument || root, arr = [], els, i, len, el; + if (root.getElementsByClassName) { + els = root.getElementsByClassName(stripslashes(className)); + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (cmpTag(tag, el.nodeName)) { + arr.push(el); + } + } + } else if (doc.querySelectorAll) { + els = doc.querySelectorAll((root.nodeName !== '#document' ? root.nodeName + ' ' : '') + tag + '.' + className); + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (_contains(root, el)) { + arr.push(el); + } + } + } else { + els = root.getElementsByTagName(tag); + className = ' ' + className + ' '; + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + var cls = el.className; + if (cls && (' ' + cls + ' ').indexOf(className) > -1) { + arr.push(el); + } + } + } + } + return arr; + } + + function byName(name, tag, root) { + var arr = [], doc = root.ownerDocument || root, + els = doc.getElementsByName(stripslashes(name)), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (cmpTag(tag, el.nodeName) && _contains(root, el)) { + if (el.getAttribute('name') !== null) { + arr.push(el); + } + } + } + return arr; + } + + function byAttr(key, val, tag, root) { + var arr = [], els = root.getElementsByTagName(tag), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + if (val === null) { + if (_getAttr(el, key) !== null) { + arr.push(el); + } + } else { + if (val === escape(_getAttr(el, key))) { + arr.push(el); + } + } + } + } + return arr; + } + + function select(expr, root) { + var arr = [], matches; + matches = /^((?:\\.|[^.#\s\[<>])+)/.exec(expr); + var tag = matches ? matches[1] : '*'; + if ((matches = /#((?:[\w\-]|\\.)+)$/.exec(expr))) { + arr = byId(matches[1], tag, root); + } else if ((matches = /\.((?:[\w\-]|\\.)+)$/.exec(expr))) { + arr = byClass(matches[1], tag, root); + } else if ((matches = /\[((?:[\w\-]|\\.)+)\]/.exec(expr))) { + arr = byAttr(matches[1].toLowerCase(), null, tag, root); + } else if ((matches = /\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(expr))) { + var key = matches[1].toLowerCase(), val = matches[2]; + if (key === 'id') { + arr = byId(val, tag, root); + } else if (key === 'class') { + arr = byClass(val, tag, root); + } else if (key === 'name') { + arr = byName(val, tag, root); + } else { + arr = byAttr(key, val, tag, root); + } + } else { + var els = root.getElementsByTagName(tag), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + arr.push(el); + } + } + } + return arr; + } + + var parts = [], arr, re = /((?:\\.|[^\s>])+|[\s>])/g; + while ((arr = re.exec(expr))) { + if (arr[1] !== ' ') { + parts.push(arr[1]); + } + } + var results = []; + if (parts.length == 1) { + return select(parts[0], root); + } + var isChild = false, part, els, subResults, val, v, i, j, k, length, len, l; + for (i = 0, lenth = parts.length; i < lenth; i++) { + part = parts[i]; + if (part === '>') { + isChild = true; + continue; + } + if (i > 0) { + els = []; + for (j = 0, len = results.length; j < len; j++) { + val = results[j]; + subResults = select(part, val); + for (k = 0, l = subResults.length; k < l; k++) { + v = subResults[k]; + if (isChild) { + if (val === v.parentNode) { + els.push(v); + } + } else { + els.push(v); + } + } + } + results = els; + } else { + results = select(part, root); + } + if (results.length === 0) { + return []; + } + } + return results; + } + + function _query(expr, root) { + var arr = _queryAll(expr, root); + return arr.length > 0 ? arr[0] : null; + } + + K.query = _query; + K.queryAll = _queryAll; + + + function _get(val) { + return K(val)[0]; + } + + function _getDoc(node) { + if (!node) { + return document; + } + return node.ownerDocument || node.document || node; + } + + function _getWin(node) { + if (!node) { + return window; + } + var doc = _getDoc(node); + return doc.parentWindow || doc.defaultView; + } + + function _setHtml(el, html) { + if (el.nodeType != 1) { + return; + } + var doc = _getDoc(el); + try { + el.innerHTML = '' + html; + var temp = doc.getElementById('__kindeditor_temp_tag__'); + temp.parentNode.removeChild(temp); + } catch (e) { + K(el).empty(); + K('@' + html, doc).each(function () { + el.appendChild(this); + }); + } + } + + function _hasClass(el, cls) { + return _inString(cls, el.className, ' '); + } + + function _setAttr(el, key, val) { + if (_IE && _V < 8 && key.toLowerCase() == 'class') { + key = 'className'; + } + el.setAttribute(key, '' + val); + } + + function _removeAttr(el, key) { + if (_IE && _V < 8 && key.toLowerCase() == 'class') { + key = 'className'; + } + _setAttr(el, key, ''); + el.removeAttribute(key); + } + + function _getNodeName(node) { + if (!node || !node.nodeName) { + return ''; + } + return node.nodeName.toLowerCase(); + } + + function _computedCss(el, key) { + var self = this, win = _getWin(el), camelKey = _toCamel(key), val = ''; + if (win.getComputedStyle) { + var style = win.getComputedStyle(el, null); + val = style[camelKey] || style.getPropertyValue(key) || el.style[camelKey]; + } else if (el.currentStyle) { + val = el.currentStyle[camelKey] || el.style[camelKey]; + } + return val; + } + + function _hasVal(node) { + return !!_VALUE_TAG_MAP[_getNodeName(node)]; + } + + function _docElement(doc) { + doc = doc || document; + return _QUIRKS ? doc.body : doc.documentElement; + } + + function _docHeight(doc) { + var el = _docElement(doc); + return Math.max(el.scrollHeight, el.clientHeight); + } + + function _docWidth(doc) { + var el = _docElement(doc); + return Math.max(el.scrollWidth, el.clientWidth); + } + + function _getScrollPos(doc) { + doc = doc || document; + var x, y; + if (_IE || _NEWIE || _OPERA) { + x = _docElement(doc).scrollLeft; + y = _docElement(doc).scrollTop; + } else { + x = _getWin(doc).scrollX; + y = _getWin(doc).scrollY; + } + return {x: x, y: y}; + } + + + function KNode(node) { + this.init(node); + } + + _extend(KNode, { + init: function (node) { + var self = this; + node = _isArray(node) ? node : [node]; + var length = 0; + for (var i = 0, len = node.length; i < len; i++) { + if (node[i]) { + self[i] = node[i].constructor === KNode ? node[i][0] : node[i]; + length++; + } + } + self.length = length; + self.doc = _getDoc(self[0]); + self.name = _getNodeName(self[0]); + self.type = self.length > 0 ? self[0].nodeType : null; + self.win = _getWin(self[0]); + }, + each: function (fn) { + var self = this; + for (var i = 0; i < self.length; i++) { + if (fn.call(self[i], i, self[i]) === false) { + return self; + } + } + return self; + }, + bind: function (type, fn) { + this.each(function () { + _bind(this, type, fn); + }); + return this; + }, + unbind: function (type, fn) { + this.each(function () { + _unbind(this, type, fn); + }); + return this; + }, + fire: function (type) { + if (this.length < 1) { + return this; + } + _fire(this[0], type); + return this; + }, + hasAttr: function (key) { + if (this.length < 1) { + return false; + } + return !!_getAttr(this[0], key); + }, + attr: function (key, val) { + var self = this; + if (key === undefined) { + return _getAttrList(self.outer()); + } + if (typeof key === 'object') { + _each(key, function (k, v) { + self.attr(k, v); + }); + return self; + } + if (val === undefined) { + val = self.length < 1 ? null : _getAttr(self[0], key); + return val === null ? '' : val; + } + self.each(function () { + _setAttr(this, key, val); + }); + return self; + }, + removeAttr: function (key) { + this.each(function () { + _removeAttr(this, key); + }); + return this; + }, + get: function (i) { + if (this.length < 1) { + return null; + } + return this[i || 0]; + }, + eq: function (i) { + if (this.length < 1) { + return null; + } + return this[i] ? new KNode(this[i]) : null; + }, + hasClass: function (cls) { + if (this.length < 1) { + return false; + } + return _hasClass(this[0], cls); + }, + addClass: function (cls) { + this.each(function () { + if (!_hasClass(this, cls)) { + this.className = _trim(this.className + ' ' + cls); + } + }); + return this; + }, + removeClass: function (cls) { + this.each(function () { + if (_hasClass(this, cls)) { + this.className = _trim(this.className.replace(new RegExp('(^|\\s)' + cls + '(\\s|$)'), ' ')); + } + }); + return this; + }, + html: function (val) { + var self = this; + if (val === undefined) { + if (self.length < 1 || self.type != 1) { + return ''; + } + return _formatHtml(self[0].innerHTML); + } + self.each(function () { + _setHtml(this, val); + }); + return self; + }, + text: function () { + var self = this; + if (self.length < 1) { + return ''; + } + return _IE ? self[0].innerText : self[0].textContent; + }, + hasVal: function () { + if (this.length < 1) { + return false; + } + return _hasVal(this[0]); + }, + val: function (val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return ''; + } + return self.hasVal() ? self[0].value : self.attr('value'); + } else { + self.each(function () { + if (_hasVal(this)) { + this.value = val; + } else { + _setAttr(this, 'value', val); + } + }); + return self; + } + }, + css: function (key, val) { + var self = this; + if (key === undefined) { + return _getCssList(self.attr('style')); + } + if (typeof key === 'object') { + _each(key, function (k, v) { + self.css(k, v); + }); + return self; + } + if (val === undefined) { + if (self.length < 1) { + return ''; + } + return self[0].style[_toCamel(key)] || _computedCss(self[0], key) || ''; + } + self.each(function () { + this.style[_toCamel(key)] = val; + }); + return self; + }, + width: function (val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return 0; + } + return self[0].offsetWidth; + } + return self.css('width', _addUnit(val)); + }, + height: function (val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return 0; + } + return self[0].offsetHeight; + } + return self.css('height', _addUnit(val)); + }, + opacity: function (val) { + this.each(function () { + if (this.style.opacity === undefined) { + this.style.filter = val == 1 ? '' : 'alpha(opacity=' + (val * 100) + ')'; + } else { + this.style.opacity = val == 1 ? '' : val; + } + }); + return this; + }, + data: function (key, val) { + var self = this; + key = 'kindeditor_data_' + key; + if (val === undefined) { + if (self.length < 1) { + return null; + } + return self[0][key]; + } + this.each(function () { + this[key] = val; + }); + return self; + }, + pos: function () { + var self = this, node = self[0], x = 0, y = 0; + if (node) { + if (node.getBoundingClientRect) { + var box = node.getBoundingClientRect(), + pos = _getScrollPos(self.doc); + x = box.left + pos.x; + y = box.top + pos.y; + } else { + while (node) { + x += node.offsetLeft; + y += node.offsetTop; + node = node.offsetParent; + } + } + } + return {x: _round(x), y: _round(y)}; + }, + clone: function (bool) { + if (this.length < 1) { + return new KNode([]); + } + return new KNode(this[0].cloneNode(bool)); + }, + append: function (expr) { + this.each(function () { + if (this.appendChild) { + this.appendChild(_get(expr)); + } + }); + return this; + }, + appendTo: function (expr) { + this.each(function () { + _get(expr).appendChild(this); + }); + return this; + }, + before: function (expr) { + this.each(function () { + try { + this.parentNode.insertBefore(_get(expr), this); + } catch (e) { + } + }); + return this; + }, + after: function (expr) { + this.each(function () { + if (this.nextSibling) { + this.parentNode.insertBefore(_get(expr), this.nextSibling); + } else { + this.parentNode.appendChild(_get(expr)); + } + }); + return this; + }, + replaceWith: function (expr) { + var nodes = []; + this.each(function (i, node) { + _unbind(node); + var newNode = _get(expr); + node.parentNode.replaceChild(newNode, node); + nodes.push(newNode); + }); + return K(nodes); + }, + empty: function () { + var self = this; + self.each(function (i, node) { + var child = node.firstChild; + while (child) { + if (!node.parentNode) { + return; + } + var next = child.nextSibling; + child.parentNode.removeChild(child); + child = next; + } + }); + return self; + }, + remove: function (keepChilds) { + var self = this; + self.each(function (i, node) { + if (!node.parentNode) { + return; + } + _unbind(node); + if (keepChilds) { + var child = node.firstChild; + while (child) { + var next = child.nextSibling; + node.parentNode.insertBefore(child, node); + child = next; + } + } + node.parentNode.removeChild(node); + delete self[i]; + }); + self.length = 0; + return self; + }, + show: function (val) { + var self = this; + if (val === undefined) { + val = self._originDisplay || ''; + } + if (self.css('display') != 'none') { + return self; + } + return self.css('display', val); + }, + hide: function () { + var self = this; + if (self.length < 1) { + return self; + } + self._originDisplay = self[0].style.display; + return self.css('display', 'none'); + }, + outer: function () { + var self = this; + if (self.length < 1) { + return ''; + } + var div = self.doc.createElement('div'), html; + div.appendChild(self[0].cloneNode(true)); + html = _formatHtml(div.innerHTML); + div = null; + return html; + }, + isSingle: function () { + return !!_SINGLE_TAG_MAP[this.name]; + }, + isInline: function () { + return !!_INLINE_TAG_MAP[this.name]; + }, + isBlock: function () { + return !!_BLOCK_TAG_MAP[this.name]; + }, + isStyle: function () { + return !!_STYLE_TAG_MAP[this.name]; + }, + isControl: function () { + return !!_CONTROL_TAG_MAP[this.name]; + }, + contains: function (otherNode) { + if (this.length < 1) { + return false; + } + return _contains(this[0], _get(otherNode)); + }, + parent: function () { + if (this.length < 1) { + return null; + } + var node = this[0].parentNode; + return node ? new KNode(node) : null; + }, + children: function () { + if (this.length < 1) { + return new KNode([]); + } + var list = [], child = this[0].firstChild; + while (child) { + if (child.nodeType != 3 || _trim(child.nodeValue) !== '') { + list.push(child); + } + child = child.nextSibling; + } + return new KNode(list); + }, + first: function () { + var list = this.children(); + return list.length > 0 ? list.eq(0) : null; + }, + last: function () { + var list = this.children(); + return list.length > 0 ? list.eq(list.length - 1) : null; + }, + index: function () { + if (this.length < 1) { + return -1; + } + var i = -1, sibling = this[0]; + while (sibling) { + i++; + sibling = sibling.previousSibling; + } + return i; + }, + prev: function () { + if (this.length < 1) { + return null; + } + var node = this[0].previousSibling; + return node ? new KNode(node) : null; + }, + next: function () { + if (this.length < 1) { + return null; + } + var node = this[0].nextSibling; + return node ? new KNode(node) : null; + }, + scan: function (fn, order) { + if (this.length < 1) { + return; + } + order = (order === undefined) ? true : order; + + function walk(node) { + var n = order ? node.firstChild : node.lastChild; + while (n) { + var next = order ? n.nextSibling : n.previousSibling; + if (fn(n) === false) { + return false; + } + if (walk(n) === false) { + return false; + } + n = next; + } + } + + walk(this[0]); + return this; + } + }); + _each(('blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,' + + 'mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,' + + 'change,select,submit,keydown,keypress,keyup,error,contextmenu').split(','), function (i, type) { + KNode.prototype[type] = function (fn) { + return fn ? this.bind(type, fn) : this.fire(type); + }; + }); + var _K = K; + K = function (expr, root) { + if (expr === undefined || expr === null) { + return; + } + + function newNode(node) { + if (!node[0]) { + node = []; + } + return new KNode(node); + } + + if (typeof expr === 'string') { + if (root) { + root = _get(root); + } + var length = expr.length; + if (expr.charAt(0) === '@') { + expr = expr.substr(1); + } + if (expr.length !== length || /<.+>/.test(expr)) { + var doc = root ? root.ownerDocument || root : document, + div = doc.createElement('div'), list = []; + div.innerHTML = '' + expr; + for (var i = 0, len = div.childNodes.length; i < len; i++) { + var child = div.childNodes[i]; + if (child.id == '__kindeditor_temp_tag__') { + continue; + } + list.push(child); + } + return newNode(list); + } + return newNode(_queryAll(expr, root)); + } + if (expr && expr.constructor === KNode) { + return expr; + } + if (expr.toArray) { + expr = expr.toArray(); + } + if (_isArray(expr)) { + return newNode(expr); + } + return newNode(_toArray(arguments)); + }; + _each(_K, function (key, val) { + K[key] = val; + }); + K.NodeClass = KNode; + window.KindEditor = K; + + + var _START_TO_START = 0, + _START_TO_END = 1, + _END_TO_END = 2, + _END_TO_START = 3, + _BOOKMARK_ID = 0; + + function _updateCollapsed(range) { + range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset); + return range; + } + + function _copyAndDelete(range, isCopy, isDelete) { + var doc = range.doc, nodeList = []; + + function splitTextNode(node, startOffset, endOffset) { + var length = node.nodeValue.length, centerNode; + if (isCopy) { + var cloneNode = node.cloneNode(true); + if (startOffset > 0) { + centerNode = cloneNode.splitText(startOffset); + } else { + centerNode = cloneNode; + } + if (endOffset < length) { + centerNode.splitText(endOffset - startOffset); + } + } + if (isDelete) { + var center = node; + if (startOffset > 0) { + center = node.splitText(startOffset); + range.setStart(node, startOffset); + } + if (endOffset < length) { + var right = center.splitText(endOffset - startOffset); + range.setEnd(right, 0); + } + nodeList.push(center); + } + return centerNode; + } + + function removeNodes() { + if (isDelete) { + range.up().collapse(true); + } + for (var i = 0, len = nodeList.length; i < len; i++) { + var node = nodeList[i]; + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } + } + + var copyRange = range.cloneRange().down(); + var start = -1, incStart = -1, incEnd = -1, end = -1, + ancestor = range.commonAncestor(), frag = doc.createDocumentFragment(); + if (ancestor.nodeType == 3) { + var textNode = splitTextNode(ancestor, range.startOffset, range.endOffset); + if (isCopy) { + frag.appendChild(textNode); + } + removeNodes(); + return isCopy ? frag : range; + } + + function extractNodes(parent, frag) { + var node = parent.firstChild, nextNode; + while (node) { + var testRange = new KRange(doc).selectNode(node); + start = testRange.compareBoundaryPoints(_START_TO_END, range); + if (start >= 0 && incStart <= 0) { + incStart = testRange.compareBoundaryPoints(_START_TO_START, range); + } + if (incStart >= 0 && incEnd <= 0) { + incEnd = testRange.compareBoundaryPoints(_END_TO_END, range); + } + if (incEnd >= 0 && end <= 0) { + end = testRange.compareBoundaryPoints(_END_TO_START, range); + } + if (end >= 0) { + return false; + } + nextNode = node.nextSibling; + if (start > 0) { + if (node.nodeType == 1) { + if (incStart >= 0 && incEnd <= 0) { + if (isCopy) { + frag.appendChild(node.cloneNode(true)); + } + if (isDelete) { + nodeList.push(node); + } + } else { + var childFlag; + if (isCopy) { + childFlag = node.cloneNode(false); + frag.appendChild(childFlag); + } + if (extractNodes(node, childFlag) === false) { + return false; + } + } + } else if (node.nodeType == 3) { + var textNode; + if (node == copyRange.startContainer) { + textNode = splitTextNode(node, copyRange.startOffset, node.nodeValue.length); + } else if (node == copyRange.endContainer) { + textNode = splitTextNode(node, 0, copyRange.endOffset); + } else { + textNode = splitTextNode(node, 0, node.nodeValue.length); + } + if (isCopy) { + try { + frag.appendChild(textNode); + } catch (e) { + } + } + } + } + node = nextNode; + } + } + + extractNodes(ancestor, frag); + if (isDelete) { + range.up().collapse(true); + } + for (var i = 0, len = nodeList.length; i < len; i++) { + var node = nodeList[i]; + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } + return isCopy ? frag : range; + } + + function _moveToElementText(range, el) { + var node = el; + while (node) { + var knode = K(node); + if (knode.name == 'marquee' || knode.name == 'select') { + return; + } + node = node.parentNode; + } + try { + range.moveToElementText(el); + } catch (e) { + } + } + + function _getStartEnd(rng, isStart) { + var doc = rng.parentElement().ownerDocument, + pointRange = rng.duplicate(); + pointRange.collapse(isStart); + var parent = pointRange.parentElement(), + nodes = parent.childNodes; + if (nodes.length === 0) { + return {node: parent.parentNode, offset: K(parent).index()}; + } + var startNode = doc, startPos = 0, cmp = -1; + var testRange = rng.duplicate(); + _moveToElementText(testRange, parent); + for (var i = 0, len = nodes.length; i < len; i++) { + var node = nodes[i]; + cmp = testRange.compareEndPoints('StartToStart', pointRange); + if (cmp === 0) { + return {node: node.parentNode, offset: i}; + } + if (node.nodeType == 1) { + var nodeRange = rng.duplicate(), dummy, knode = K(node), newNode = node; + if (knode.isControl()) { + dummy = doc.createElement('span'); + knode.after(dummy); + newNode = dummy; + startPos += knode.text().replace(/\r\n|\n|\r/g, '').length; + } + _moveToElementText(nodeRange, newNode); + testRange.setEndPoint('StartToEnd', nodeRange); + if (cmp > 0) { + startPos += nodeRange.text.replace(/\r\n|\n|\r/g, '').length; + } else { + startPos = 0; + } + if (dummy) { + K(dummy).remove(); + } + } else if (node.nodeType == 3) { + testRange.moveStart('character', node.nodeValue.length); + startPos += node.nodeValue.length; + } + if (cmp < 0) { + startNode = node; + } + } + if (cmp < 0 && startNode.nodeType == 1) { + return {node: parent, offset: K(parent.lastChild).index() + 1}; + } + if (cmp > 0) { + while (startNode.nextSibling && startNode.nodeType == 1) { + startNode = startNode.nextSibling; + } + } + testRange = rng.duplicate(); + _moveToElementText(testRange, parent); + testRange.setEndPoint('StartToEnd', pointRange); + startPos -= testRange.text.replace(/\r\n|\n|\r/g, '').length; + if (cmp > 0 && startNode.nodeType == 3) { + var prevNode = startNode.previousSibling; + while (prevNode && prevNode.nodeType == 3) { + startPos -= prevNode.nodeValue.length; + prevNode = prevNode.previousSibling; + } + } + return {node: startNode, offset: startPos}; + } + + function _getEndRange(node, offset) { + var doc = node.ownerDocument || node, + range = doc.body.createTextRange(); + if (doc == node) { + range.collapse(true); + return range; + } + if (node.nodeType == 1 && node.childNodes.length > 0) { + var children = node.childNodes, isStart, child; + if (offset === 0) { + child = children[0]; + isStart = true; + } else { + child = children[offset - 1]; + isStart = false; + } + if (!child) { + return range; + } + if (K(child).name === 'head') { + if (offset === 1) { + isStart = true; + } + if (offset === 2) { + isStart = false; + } + range.collapse(isStart); + return range; + } + if (child.nodeType == 1) { + var kchild = K(child), span; + if (kchild.isControl()) { + span = doc.createElement('span'); + if (isStart) { + kchild.before(span); + } else { + kchild.after(span); + } + child = span; + } + _moveToElementText(range, child); + range.collapse(isStart); + if (span) { + K(span).remove(); + } + return range; + } + node = child; + offset = isStart ? 0 : child.nodeValue.length; + } + var dummy = doc.createElement('span'); + K(node).before(dummy); + _moveToElementText(range, dummy); + range.moveStart('character', offset); + K(dummy).remove(); + return range; + } + + function _toRange(rng) { + var doc, range; + + function tr2td(start) { + if (K(start.node).name == 'tr') { + start.node = start.node.cells[start.offset]; + start.offset = 0; + } + } + + if (_IERANGE) { + if (rng.item) { + doc = _getDoc(rng.item(0)); + range = new KRange(doc); + range.selectNode(rng.item(0)); + return range; + } + doc = rng.parentElement().ownerDocument; + var start = _getStartEnd(rng, true), + end = _getStartEnd(rng, false); + tr2td(start); + tr2td(end); + range = new KRange(doc); + range.setStart(start.node, start.offset); + range.setEnd(end.node, end.offset); + return range; + } + var startContainer = rng.startContainer; + doc = startContainer.ownerDocument || startContainer; + range = new KRange(doc); + range.setStart(startContainer, rng.startOffset); + range.setEnd(rng.endContainer, rng.endOffset); + return range; + } + + + function KRange(doc) { + this.init(doc); + } + + _extend(KRange, { + init: function (doc) { + var self = this; + self.startContainer = doc; + self.startOffset = 0; + self.endContainer = doc; + self.endOffset = 0; + self.collapsed = true; + self.doc = doc; + }, + commonAncestor: function () { + function getParents(node) { + var parents = []; + while (node) { + parents.push(node); + node = node.parentNode; + } + return parents; + } + + var parentsA = getParents(this.startContainer), + parentsB = getParents(this.endContainer), + i = 0, lenA = parentsA.length, lenB = parentsB.length, parentA, parentB; + while (++i) { + parentA = parentsA[lenA - i]; + parentB = parentsB[lenB - i]; + if (!parentA || !parentB || parentA !== parentB) { + break; + } + } + return parentsA[lenA - i + 1]; + }, + setStart: function (node, offset) { + var self = this, doc = self.doc; + self.startContainer = node; + self.startOffset = offset; + if (self.endContainer === doc) { + self.endContainer = node; + self.endOffset = offset; + } + return _updateCollapsed(this); + }, + setEnd: function (node, offset) { + var self = this, doc = self.doc; + self.endContainer = node; + self.endOffset = offset; + if (self.startContainer === doc) { + self.startContainer = node; + self.startOffset = offset; + } + return _updateCollapsed(this); + }, + setStartBefore: function (node) { + return this.setStart(node.parentNode || this.doc, K(node).index()); + }, + setStartAfter: function (node) { + return this.setStart(node.parentNode || this.doc, K(node).index() + 1); + }, + setEndBefore: function (node) { + return this.setEnd(node.parentNode || this.doc, K(node).index()); + }, + setEndAfter: function (node) { + return this.setEnd(node.parentNode || this.doc, K(node).index() + 1); + }, + selectNode: function (node) { + return this.setStartBefore(node).setEndAfter(node); + }, + selectNodeContents: function (node) { + var knode = K(node); + if (knode.type == 3 || knode.isSingle()) { + return this.selectNode(node); + } + var children = knode.children(); + if (children.length > 0) { + return this.setStartBefore(children[0]).setEndAfter(children[children.length - 1]); + } + return this.setStart(node, 0).setEnd(node, 0); + }, + collapse: function (toStart) { + if (toStart) { + return this.setEnd(this.startContainer, this.startOffset); + } + return this.setStart(this.endContainer, this.endOffset); + }, + compareBoundaryPoints: function (how, range) { + var rangeA = this.get(), rangeB = range.get(); + if (_IERANGE) { + var arr = {}; + arr[_START_TO_START] = 'StartToStart'; + arr[_START_TO_END] = 'EndToStart'; + arr[_END_TO_END] = 'EndToEnd'; + arr[_END_TO_START] = 'StartToEnd'; + var cmp = rangeA.compareEndPoints(arr[how], rangeB); + if (cmp !== 0) { + return cmp; + } + var nodeA, nodeB, nodeC, posA, posB; + if (how === _START_TO_START || how === _END_TO_START) { + nodeA = this.startContainer; + posA = this.startOffset; + } + if (how === _START_TO_END || how === _END_TO_END) { + nodeA = this.endContainer; + posA = this.endOffset; + } + if (how === _START_TO_START || how === _START_TO_END) { + nodeB = range.startContainer; + posB = range.startOffset; + } + if (how === _END_TO_END || how === _END_TO_START) { + nodeB = range.endContainer; + posB = range.endOffset; + } + if (nodeA === nodeB) { + var diff = posA - posB; + return diff > 0 ? 1 : (diff < 0 ? -1 : 0); + } + nodeC = nodeB; + while (nodeC && nodeC.parentNode !== nodeA) { + nodeC = nodeC.parentNode; + } + if (nodeC) { + return K(nodeC).index() >= posA ? -1 : 1; + } + nodeC = nodeA; + while (nodeC && nodeC.parentNode !== nodeB) { + nodeC = nodeC.parentNode; + } + if (nodeC) { + return K(nodeC).index() >= posB ? 1 : -1; + } + nodeC = K(nodeB).next(); + if (nodeC && nodeC.contains(nodeA)) { + return 1; + } + nodeC = K(nodeA).next(); + if (nodeC && nodeC.contains(nodeB)) { + return -1; + } + } else { + return rangeA.compareBoundaryPoints(how, rangeB); + } + }, + cloneRange: function () { + return new KRange(this.doc).setStart(this.startContainer, this.startOffset).setEnd(this.endContainer, this.endOffset); + }, + toString: function () { + var rng = this.get(), str = _IERANGE ? rng.text : rng.toString(); + return str.replace(/\r\n|\n|\r/g, ''); + }, + cloneContents: function () { + return _copyAndDelete(this, true, false); + }, + deleteContents: function () { + return _copyAndDelete(this, false, true); + }, + extractContents: function () { + return _copyAndDelete(this, true, true); + }, + insertNode: function (node) { + var self = this, + sc = self.startContainer, so = self.startOffset, + ec = self.endContainer, eo = self.endOffset, + firstChild, lastChild, c, nodeCount = 1; + if (node.nodeName.toLowerCase() === '#document-fragment') { + firstChild = node.firstChild; + lastChild = node.lastChild; + nodeCount = node.childNodes.length; + } + if (sc.nodeType == 1) { + c = sc.childNodes[so]; + if (c) { + sc.insertBefore(node, c); + if (sc === ec) { + eo += nodeCount; + } + } else { + sc.appendChild(node); + } + } else if (sc.nodeType == 3) { + if (so === 0) { + sc.parentNode.insertBefore(node, sc); + if (sc.parentNode === ec) { + eo += nodeCount; + } + } else if (so >= sc.nodeValue.length) { + if (sc.nextSibling) { + sc.parentNode.insertBefore(node, sc.nextSibling); + } else { + sc.parentNode.appendChild(node); + } + } else { + if (so > 0) { + c = sc.splitText(so); + } else { + c = sc; + } + sc.parentNode.insertBefore(node, c); + if (sc === ec) { + ec = c; + eo -= so; + } + } + } + if (firstChild) { + self.setStartBefore(firstChild).setEndAfter(lastChild); + } else { + self.selectNode(node); + } + if (self.compareBoundaryPoints(_END_TO_END, self.cloneRange().setEnd(ec, eo)) >= 1) { + return self; + } + return self.setEnd(ec, eo); + }, + surroundContents: function (node) { + node.appendChild(this.extractContents()); + return this.insertNode(node).selectNode(node); + }, + isControl: function () { + var self = this, + sc = self.startContainer, so = self.startOffset, + ec = self.endContainer, eo = self.endOffset, rng; + return sc.nodeType == 1 && sc === ec && so + 1 === eo && K(sc.childNodes[so]).isControl(); + }, + get: function (hasControlRange) { + var self = this, doc = self.doc, node, rng; + if (!_IERANGE) { + rng = doc.createRange(); + try { + rng.setStart(self.startContainer, self.startOffset); + rng.setEnd(self.endContainer, self.endOffset); + } catch (e) { + } + return rng; + } + if (hasControlRange && self.isControl()) { + rng = doc.body.createControlRange(); + rng.addElement(self.startContainer.childNodes[self.startOffset]); + return rng; + } + var range = self.cloneRange().down(); + rng = doc.body.createTextRange(); + rng.setEndPoint('StartToStart', _getEndRange(range.startContainer, range.startOffset)); + rng.setEndPoint('EndToStart', _getEndRange(range.endContainer, range.endOffset)); + return rng; + }, + html: function () { + return K(this.cloneContents()).outer(); + }, + down: function () { + var self = this; + + function downPos(node, pos, isStart) { + if (node.nodeType != 1) { + return; + } + var children = K(node).children(); + if (children.length === 0) { + return; + } + var left, right, child, offset; + if (pos > 0) { + left = children.eq(pos - 1); + } + if (pos < children.length) { + right = children.eq(pos); + } + if (left && left.type == 3) { + child = left[0]; + offset = child.nodeValue.length; + } + if (right && right.type == 3) { + child = right[0]; + offset = 0; + } + if (!child) { + return; + } + if (isStart) { + self.setStart(child, offset); + } else { + self.setEnd(child, offset); + } + } + + downPos(self.startContainer, self.startOffset, true); + downPos(self.endContainer, self.endOffset, false); + return self; + }, + up: function () { + var self = this; + + function upPos(node, pos, isStart) { + if (node.nodeType != 3) { + return; + } + if (pos === 0) { + if (isStart) { + self.setStartBefore(node); + } else { + self.setEndBefore(node); + } + } else if (pos == node.nodeValue.length) { + if (isStart) { + self.setStartAfter(node); + } else { + self.setEndAfter(node); + } + } + } + + upPos(self.startContainer, self.startOffset, true); + upPos(self.endContainer, self.endOffset, false); + return self; + }, + enlarge: function (toBlock) { + var self = this; + self.up(); + + function enlargePos(node, pos, isStart) { + var knode = K(node), parent; + if (knode.type == 3 || _NOSPLIT_TAG_MAP[knode.name] || !toBlock && knode.isBlock()) { + return; + } + if (pos === 0) { + while (!knode.prev()) { + parent = knode.parent(); + if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) { + break; + } + knode = parent; + } + if (isStart) { + self.setStartBefore(knode[0]); + } else { + self.setEndBefore(knode[0]); + } + } else if (pos == knode.children().length) { + while (!knode.next()) { + parent = knode.parent(); + if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) { + break; + } + knode = parent; + } + if (isStart) { + self.setStartAfter(knode[0]); + } else { + self.setEndAfter(knode[0]); + } + } + } + + enlargePos(self.startContainer, self.startOffset, true); + enlargePos(self.endContainer, self.endOffset, false); + return self; + }, + shrink: function () { + var self = this, child, collapsed = self.collapsed; + while (self.startContainer.nodeType == 1 && (child = self.startContainer.childNodes[self.startOffset]) && child.nodeType == 1 && !K(child).isSingle()) { + self.setStart(child, 0); + } + if (collapsed) { + return self.collapse(collapsed); + } + while (self.endContainer.nodeType == 1 && self.endOffset > 0 && (child = self.endContainer.childNodes[self.endOffset - 1]) && child.nodeType == 1 && !K(child).isSingle()) { + self.setEnd(child, child.childNodes.length); + } + return self; + }, + createBookmark: function (serialize) { + var self = this, doc = self.doc, endNode, + startNode = K('', doc)[0]; + startNode.id = '__kindeditor_bookmark_start_' + (_BOOKMARK_ID++) + '__'; + if (!self.collapsed) { + endNode = startNode.cloneNode(true); + endNode.id = '__kindeditor_bookmark_end_' + (_BOOKMARK_ID++) + '__'; + } + if (endNode) { + self.cloneRange().collapse(false).insertNode(endNode).setEndBefore(endNode); + } + self.insertNode(startNode).setStartAfter(startNode); + return { + start: serialize ? '#' + startNode.id : startNode, + end: endNode ? (serialize ? '#' + endNode.id : endNode) : null + }; + }, + moveToBookmark: function (bookmark) { + var self = this, doc = self.doc, + start = K(bookmark.start, doc), end = bookmark.end ? K(bookmark.end, doc) : null; + if (!start || start.length < 1) { + return self; + } + self.setStartBefore(start[0]); + start.remove(); + if (end && end.length > 0) { + self.setEndBefore(end[0]); + end.remove(); + } else { + self.collapse(true); + } + return self; + }, + dump: function () { + console.log('--------------------'); + console.log(this.startContainer.nodeType == 3 ? this.startContainer.nodeValue : this.startContainer, this.startOffset); + console.log(this.endContainer.nodeType == 3 ? this.endContainer.nodeValue : this.endContainer, this.endOffset); + } + }); + + function _range(mixed) { + if (!mixed.nodeName) { + return mixed.constructor === KRange ? mixed : _toRange(mixed); + } + return new KRange(mixed); + } + + K.RangeClass = KRange; + K.range = _range; + K.START_TO_START = _START_TO_START; + K.START_TO_END = _START_TO_END; + K.END_TO_END = _END_TO_END; + K.END_TO_START = _END_TO_START; + + + function _nativeCommand(doc, key, val) { + try { + doc.execCommand(key, false, val); + } catch (e) { + } + } + + function _nativeCommandValue(doc, key) { + var val = ''; + try { + val = doc.queryCommandValue(key); + } catch (e) { + } + if (typeof val !== 'string') { + val = ''; + } + return val; + } + + function _getSel(doc) { + var win = _getWin(doc); + return _IERANGE ? doc.selection : win.getSelection(); + } + + function _getRng(doc) { + var sel = _getSel(doc), rng; + try { + if (sel.rangeCount > 0) { + rng = sel.getRangeAt(0); + } else { + rng = sel.createRange(); + } + } catch (e) { + } + if (_IERANGE && (!rng || (!rng.item && rng.parentElement().ownerDocument !== doc))) { + return null; + } + return rng; + } + + function _singleKeyMap(map) { + var newMap = {}, arr, v; + _each(map, function (key, val) { + arr = key.split(','); + for (var i = 0, len = arr.length; i < len; i++) { + v = arr[i]; + newMap[v] = val; + } + }); + return newMap; + } + + function _hasAttrOrCss(knode, map) { + return _hasAttrOrCssByKey(knode, map, '*') || _hasAttrOrCssByKey(knode, map); + } + + function _hasAttrOrCssByKey(knode, map, mapKey) { + mapKey = mapKey || knode.name; + if (knode.type !== 1) { + return false; + } + var newMap = _singleKeyMap(map); + if (!newMap[mapKey]) { + return false; + } + var arr = newMap[mapKey].split(','); + for (var i = 0, len = arr.length; i < len; i++) { + var key = arr[i]; + if (key === '*') { + return true; + } + var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key); + var method = match[1] ? 'css' : 'attr'; + key = match[2]; + var val = match[3] || ''; + if (val === '' && knode[method](key) !== '') { + return true; + } + if (val !== '' && knode[method](key) === val) { + return true; + } + } + return false; + } + + function _removeAttrOrCss(knode, map) { + if (knode.type != 1) { + return; + } + _removeAttrOrCssByKey(knode, map, '*'); + _removeAttrOrCssByKey(knode, map); + } + + function _removeAttrOrCssByKey(knode, map, mapKey) { + mapKey = mapKey || knode.name; + if (knode.type !== 1) { + return; + } + var newMap = _singleKeyMap(map); + if (!newMap[mapKey]) { + return; + } + var arr = newMap[mapKey].split(','), allFlag = false; + for (var i = 0, len = arr.length; i < len; i++) { + var key = arr[i]; + if (key === '*') { + allFlag = true; + break; + } + var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key); + key = match[2]; + if (match[1]) { + key = _toCamel(key); + if (knode[0].style[key]) { + knode[0].style[key] = ''; + } + } else { + knode.removeAttr(key); + } + } + if (allFlag) { + knode.remove(true); + } + } + + function _getInnerNode(knode) { + var inner = knode; + while (inner.first()) { + inner = inner.first(); + } + return inner; + } + + function _isEmptyNode(knode) { + if (knode.type != 1 || knode.isSingle()) { + return false; + } + return knode.html().replace(/<[^>]+>/g, '') === ''; + } + + + function _mergeWrapper(a, b) { + a = a.clone(true); + var lastA = _getInnerNode(a), childA = a, merged = false; + while (b) { + while (childA) { + if (childA.name === b.name) { + _mergeAttrs(childA, b.attr(), b.css()); + merged = true; + } + childA = childA.first(); + } + if (!merged) { + lastA.append(b.clone(false)); + } + merged = false; + b = b.first(); + } + return a; + } + + function _wrapNode(knode, wrapper) { + wrapper = wrapper.clone(true); + if (knode.type == 3) { + _getInnerNode(wrapper).append(knode.clone(false)); + knode.replaceWith(wrapper); + return wrapper; + } + var nodeWrapper = knode, child; + while ((child = knode.first()) && child.children().length == 1) { + knode = child; + } + child = knode.first(); + var frag = knode.doc.createDocumentFragment(); + while (child) { + frag.appendChild(child[0]); + child = child.next(); + } + wrapper = _mergeWrapper(nodeWrapper, wrapper); + if (frag.firstChild) { + _getInnerNode(wrapper).append(frag); + } + nodeWrapper.replaceWith(wrapper); + return wrapper; + } + + function _mergeAttrs(knode, attrs, styles) { + _each(attrs, function (key, val) { + if (key !== 'style') { + knode.attr(key, val); + } + }); + _each(styles, function (key, val) { + knode.css(key, val); + }); + } + + function _inPreElement(knode) { + while (knode && knode.name != 'body') { + if (_PRE_TAG_MAP[knode.name] || knode.name == 'div' && knode.hasClass('ke-script')) { + return true; + } + knode = knode.parent(); + } + return false; + } + + function KCmd(range) { + this.init(range); + } + + _extend(KCmd, { + init: function (range) { + var self = this, doc = range.doc; + self.doc = doc; + self.win = _getWin(doc); + self.sel = _getSel(doc); + self.range = range; + }, + selection: function (forceReset) { + var self = this, doc = self.doc, rng = _getRng(doc); + self.sel = _getSel(doc); + if (rng) { + self.range = _range(rng); + if (K(self.range.startContainer).name == 'html') { + self.range.selectNodeContents(doc.body).collapse(false); + } + return self; + } + if (forceReset) { + self.range.selectNodeContents(doc.body).collapse(false); + } + return self; + }, + select: function (hasDummy) { + hasDummy = _undef(hasDummy, true); + var self = this, sel = self.sel, range = self.range.cloneRange().shrink(), + sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset, + doc = _getDoc(sc), win = self.win, rng, hasU200b = false; + if (hasDummy && sc.nodeType == 1 && range.collapsed) { + if (_IERANGE) { + var dummy = K(' ', doc); + range.insertNode(dummy[0]); + rng = doc.body.createTextRange(); + try { + rng.moveToElementText(dummy[0]); + } catch (ex) { + } + rng.collapse(false); + rng.select(); + dummy.remove(); + win.focus(); + return self; + } + if (_WEBKIT) { + var children = sc.childNodes; + if (K(sc).isInline() || so > 0 && K(children[so - 1]).isInline() || children[so] && K(children[so]).isInline()) { + range.insertNode(doc.createTextNode('\u200B')); + hasU200b = true; + } + } + } + if (_IERANGE) { + try { + rng = range.get(true); + rng.select(); + } catch (e) { + } + } else { + if (hasU200b) { + range.collapse(false); + } + rng = range.get(true); + sel.removeAllRanges(); + sel.addRange(rng); + if (doc !== document) { + var pos = K(rng.endContainer).pos(); + win.scrollTo(pos.x, pos.y); + } + } + win.focus(); + return self; + }, + wrap: function (val) { + var self = this, doc = self.doc, range = self.range, wrapper; + wrapper = K(val, doc); + if (range.collapsed) { + range.shrink(); + range.insertNode(wrapper[0]).selectNodeContents(wrapper[0]); + return self; + } + if (wrapper.isBlock()) { + var copyWrapper = wrapper.clone(true), child = copyWrapper; + while (child.first()) { + child = child.first(); + } + child.append(range.extractContents()); + range.insertNode(copyWrapper[0]).selectNode(copyWrapper[0]); + return self; + } + range.enlarge(); + var bookmark = range.createBookmark(), ancestor = range.commonAncestor(), isStart = false; + K(ancestor).scan(function (node) { + if (!isStart && node == bookmark.start) { + isStart = true; + return; + } + if (isStart) { + if (node == bookmark.end) { + return false; + } + var knode = K(node); + if (_inPreElement(knode)) { + return; + } + if (knode.type == 3 && _trim(node.nodeValue).length > 0) { + var parent; + while ((parent = knode.parent()) && parent.isStyle() && parent.children().length == 1) { + knode = parent; + } + _wrapNode(knode, wrapper); + } + } + }); + range.moveToBookmark(bookmark); + return self; + }, + split: function (isStart, map) { + var range = this.range, doc = range.doc; + var tempRange = range.cloneRange().collapse(isStart); + var node = tempRange.startContainer, pos = tempRange.startOffset, + parent = node.nodeType == 3 ? node.parentNode : node, + needSplit = false, knode; + while (parent && parent.parentNode) { + knode = K(parent); + if (map) { + if (!knode.isStyle()) { + break; + } + if (!_hasAttrOrCss(knode, map)) { + break; + } + } else { + if (_NOSPLIT_TAG_MAP[knode.name]) { + break; + } + } + needSplit = true; + parent = parent.parentNode; + } + if (needSplit) { + var dummy = doc.createElement('span'); + range.cloneRange().collapse(!isStart).insertNode(dummy); + if (isStart) { + tempRange.setStartBefore(parent.firstChild).setEnd(node, pos); + } else { + tempRange.setStart(node, pos).setEndAfter(parent.lastChild); + } + var frag = tempRange.extractContents(), + first = frag.firstChild, last = frag.lastChild; + if (isStart) { + tempRange.insertNode(frag); + range.setStartAfter(last).setEndBefore(dummy); + } else { + parent.appendChild(frag); + range.setStartBefore(dummy).setEndBefore(first); + } + var dummyParent = dummy.parentNode; + if (dummyParent == range.endContainer) { + var prev = K(dummy).prev(), next = K(dummy).next(); + if (prev && next && prev.type == 3 && next.type == 3) { + range.setEnd(prev[0], prev[0].nodeValue.length); + } else if (!isStart) { + range.setEnd(range.endContainer, range.endOffset - 1); + } + } + dummyParent.removeChild(dummy); + } + return this; + }, + remove: function (map) { + var self = this, doc = self.doc, range = self.range; + range.enlarge(); + if (range.startOffset === 0) { + var ksc = K(range.startContainer), parent; + while ((parent = ksc.parent()) && parent.isStyle() && parent.children().length == 1) { + ksc = parent; + } + range.setStart(ksc[0], 0); + ksc = K(range.startContainer); + if (ksc.isBlock()) { + _removeAttrOrCss(ksc, map); + } + var kscp = ksc.parent(); + if (kscp && kscp.isBlock()) { + _removeAttrOrCss(kscp, map); + } + } + var sc, so; + if (range.collapsed) { + self.split(true, map); + sc = range.startContainer; + so = range.startOffset; + if (so > 0) { + var sb = K(sc.childNodes[so - 1]); + if (sb && _isEmptyNode(sb)) { + sb.remove(); + range.setStart(sc, so - 1); + } + } + var sa = K(sc.childNodes[so]); + if (sa && _isEmptyNode(sa)) { + sa.remove(); + } + if (_isEmptyNode(sc)) { + range.startBefore(sc); + sc.remove(); + } + range.collapse(true); + return self; + } + self.split(true, map); + self.split(false, map); + var startDummy = doc.createElement('span'), endDummy = doc.createElement('span'); + range.cloneRange().collapse(false).insertNode(endDummy); + range.cloneRange().collapse(true).insertNode(startDummy); + var nodeList = [], cmpStart = false; + K(range.commonAncestor()).scan(function (node) { + if (!cmpStart && node == startDummy) { + cmpStart = true; + return; + } + if (node == endDummy) { + return false; + } + if (cmpStart) { + nodeList.push(node); + } + }); + K(startDummy).remove(); + K(endDummy).remove(); + sc = range.startContainer; + so = range.startOffset; + var ec = range.endContainer, eo = range.endOffset; + if (so > 0) { + var startBefore = K(sc.childNodes[so - 1]); + if (startBefore && _isEmptyNode(startBefore)) { + startBefore.remove(); + range.setStart(sc, so - 1); + if (sc == ec) { + range.setEnd(ec, eo - 1); + } + } + var startAfter = K(sc.childNodes[so]); + if (startAfter && _isEmptyNode(startAfter)) { + startAfter.remove(); + if (sc == ec) { + range.setEnd(ec, eo - 1); + } + } + } + var endAfter = K(ec.childNodes[range.endOffset]); + if (endAfter && _isEmptyNode(endAfter)) { + endAfter.remove(); + } + var bookmark = range.createBookmark(true); + _each(nodeList, function (i, node) { + _removeAttrOrCss(K(node), map); + }); + range.moveToBookmark(bookmark); + return self; + }, + commonNode: function (map) { + var range = this.range; + var ec = range.endContainer, eo = range.endOffset, + node = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1]; + + function find(node) { + var child = node, parent = node; + while (parent) { + if (_hasAttrOrCss(K(parent), map)) { + return K(parent); + } + parent = parent.parentNode; + } + while (child && (child = child.lastChild)) { + if (_hasAttrOrCss(K(child), map)) { + return K(child); + } + } + return null; + } + + var cNode = find(node); + if (cNode) { + return cNode; + } + if (node.nodeType == 1 || (ec.nodeType == 3 && eo === 0)) { + var prev = K(node).prev(); + if (prev) { + return find(prev); + } + } + return null; + }, + commonAncestor: function (tagName) { + var range = this.range, + sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset, + startNode = (sc.nodeType == 3 || so === 0) ? sc : sc.childNodes[so - 1], + endNode = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1]; + + function find(node) { + while (node) { + if (node.nodeType == 1) { + if (node.tagName.toLowerCase() === tagName) { + return node; + } + } + node = node.parentNode; + } + return null; + } + + var start = find(startNode), end = find(endNode); + if (start && end && start === end) { + return K(start); + } + return null; + }, + state: function (key) { + var self = this, doc = self.doc, bool = false; + try { + bool = doc.queryCommandState(key); + } catch (e) { + } + return bool; + }, + val: function (key) { + var self = this, doc = self.doc, range = self.range; + + function lc(val) { + return val.toLowerCase(); + } + + key = lc(key); + var val = '', knode; + if (key === 'fontfamily' || key === 'fontname') { + val = _nativeCommandValue(doc, 'fontname'); + val = val.replace(/['"]/g, ''); + return lc(val); + } + if (key === 'formatblock') { + val = _nativeCommandValue(doc, key); + if (val === '') { + knode = self.commonNode({'h1,h2,h3,h4,h5,h6,p,div,pre,address': '*'}); + if (knode) { + val = knode.name; + } + } + if (val === 'Normal') { + val = 'p'; + } + return lc(val); + } + if (key === 'fontsize') { + knode = self.commonNode({'*': '.font-size'}); + if (knode) { + val = knode.css('font-size'); + } + return lc(val); + } + if (key === 'forecolor') { + knode = self.commonNode({'*': '.color'}); + if (knode) { + val = knode.css('color'); + } + val = _toHex(val); + if (val === '') { + val = 'default'; + } + return lc(val); + } + if (key === 'hilitecolor') { + knode = self.commonNode({'*': '.background-color'}); + if (knode) { + val = knode.css('background-color'); + } + val = _toHex(val); + if (val === '') { + val = 'default'; + } + return lc(val); + } + return val; + }, + toggle: function (wrapper, map) { + var self = this; + if (self.commonNode(map)) { + self.remove(map); + } else { + self.wrap(wrapper); + } + return self.select(); + }, + bold: function () { + return this.toggle('', { + span: '.font-weight=bold', + strong: '*', + b: '*' + }); + }, + italic: function () { + return this.toggle('', { + span: '.font-style=italic', + em: '*', + i: '*' + }); + }, + underline: function () { + return this.toggle('', { + span: '.text-decoration=underline', + u: '*' + }); + }, + strikethrough: function () { + return this.toggle('', { + span: '.text-decoration=line-through', + s: '*' + }); + }, + forecolor: function (val) { + return this.wrap('').select(); + }, + hilitecolor: function (val) { + return this.wrap('').select(); + }, + fontsize: function (val) { + return this.wrap('').select(); + }, + fontname: function (val) { + return this.fontfamily(val); + }, + fontfamily: function (val) { + return this.wrap('').select(); + }, + removeformat: function () { + var map = { + '*': '.font-weight,.font-style,.text-decoration,.color,.background-color,.font-size,.font-family,.text-indent' + }, + tags = _STYLE_TAG_MAP; + _each(tags, function (key, val) { + map[key] = '*'; + }); + this.remove(map); + return this.select(); + }, + inserthtml: function (val, quickMode) { + var self = this, range = self.range; + if (val === '') { + return self; + } + + function pasteHtml(range, val) { + val = '' + val; + var rng = range.get(); + if (rng.item) { + rng.item(0).outerHTML = val; + } else { + rng.pasteHTML(val); + } + var temp = range.doc.getElementById('__kindeditor_temp_tag__'); + temp.parentNode.removeChild(temp); + var newRange = _toRange(rng); + range.setEnd(newRange.endContainer, newRange.endOffset); + range.collapse(false); + self.select(false); + } + + function insertHtml(range, val) { + var doc = range.doc, + frag = doc.createDocumentFragment(); + K('@' + val, doc).each(function () { + frag.appendChild(this); + }); + range.deleteContents(); + range.insertNode(frag); + range.collapse(false); + self.select(false); + } + + if (_IERANGE && quickMode) { + try { + pasteHtml(range, val); + } catch (e) { + insertHtml(range, val); + } + return self; + } + insertHtml(range, val); + return self; + }, + hr: function () { + return this.inserthtml('
'); + }, + print: function () { + this.win.print(); + return this; + }, + insertimage: function (url, title, width, height, border, align) { + title = _undef(title, ''); + border = _undef(border, 0); + var html = ''; + return self.inserthtml(html); + } + if (range.isControl()) { + var node = K(range.startContainer.childNodes[range.startOffset]); + html += '>'; + node.after(K(html, doc)); + node.next().append(node); + range.selectNode(node[0]); + return self.select(); + } + + function setAttr(node, url, type) { + K(node).attr('href', url).attr('data-ke-src', url); + if (type) { + K(node).attr('target', type); + } else { + K(node).removeAttr('target'); + } + } + + var sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset; + if (sc.nodeType == 1 && sc === ec && so + 1 === eo) { + var child = sc.childNodes[so]; + if (child.nodeName.toLowerCase() == 'a') { + setAttr(child, url, type); + return self; + } + } + _nativeCommand(doc, 'createlink', '__kindeditor_temp_url__'); + K('a[href="__kindeditor_temp_url__"]', doc).each(function () { + setAttr(this, url, type); + }); + return self; + }, + unlink: function () { + var self = this, doc = self.doc, range = self.range; + self.select(); + if (range.collapsed) { + var a = self.commonNode({a: '*'}); + if (a) { + range.selectNode(a.get()); + self.select(); + } + _nativeCommand(doc, 'unlink', null); + if (_WEBKIT && K(range.startContainer).name === 'img') { + var parent = K(range.startContainer).parent(); + if (parent.name === 'a') { + parent.remove(true); + } + } + } else { + _nativeCommand(doc, 'unlink', null); + } + return self; + } + }); + _each(('formatblock,selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' + + 'insertunorderedlist,indent,outdent,subscript,superscript').split(','), function (i, name) { + KCmd.prototype[name] = function (val) { + var self = this; + self.select(); + _nativeCommand(self.doc, name, val); + if (_IERANGE && _inArray(name, 'justifyleft,justifycenter,justifyright,justifyfull'.split(',')) >= 0) { + self.selection(); + } + if (!_IERANGE || _inArray(name, 'formatblock,selectall,insertorderedlist,insertunorderedlist'.split(',')) >= 0) { + self.selection(); + } + return self; + }; + }); + _each('cut,copy,paste'.split(','), function (i, name) { + KCmd.prototype[name] = function () { + var self = this; + if (!self.doc.queryCommandSupported(name)) { + throw 'not supported'; + } + self.select(); + _nativeCommand(self.doc, name, null); + return self; + }; + }); + + function _cmd(mixed) { + if (mixed.nodeName) { + var doc = _getDoc(mixed); + mixed = _range(doc).selectNodeContents(doc.body).collapse(false); + } + return new KCmd(mixed); + } + + K.CmdClass = KCmd; + K.cmd = _cmd; + + + function _drag(options) { + var moveEl = options.moveEl, + moveFn = options.moveFn, + clickEl = options.clickEl || moveEl, + beforeDrag = options.beforeDrag, + iframeFix = options.iframeFix === undefined ? true : options.iframeFix; + var docs = [document]; + if (iframeFix) { + K('iframe').each(function () { + var src = _formatUrl(this.src || '', 'absolute'); + if (/^https?:\/\//.test(src)) { + return; + } + var doc; + try { + doc = _iframeDoc(this); + } catch (e) { + } + if (doc) { + var pos = K(this).pos(); + K(doc).data('pos-x', pos.x); + K(doc).data('pos-y', pos.y); + docs.push(doc); + } + }); + } + clickEl.mousedown(function (e) { + if (e.button !== 0 && e.button !== 1) { + return; + } + e.stopPropagation(); + var self = clickEl.get(), + x = _removeUnit(moveEl.css('left')), + y = _removeUnit(moveEl.css('top')), + width = moveEl.width(), + height = moveEl.height(), + pageX = e.pageX, + pageY = e.pageY; + if (beforeDrag) { + beforeDrag(); + } + + function moveListener(e) { + e.preventDefault(); + var kdoc = K(_getDoc(e.target)); + var diffX = _round((kdoc.data('pos-x') || 0) + e.pageX - pageX); + var diffY = _round((kdoc.data('pos-y') || 0) + e.pageY - pageY); + moveFn.call(clickEl, x, y, width, height, diffX, diffY); + } + + function selectListener(e) { + e.preventDefault(); + } + + function upListener(e) { + e.preventDefault(); + K(docs).unbind('mousemove', moveListener) + .unbind('mouseup', upListener) + .unbind('selectstart', selectListener); + if (self.releaseCapture) { + self.releaseCapture(); + } + } + + K(docs).mousemove(moveListener) + .mouseup(upListener) + .bind('selectstart', selectListener); + if (self.setCapture) { + self.setCapture(); + } + }); + } + + + function KWidget(options) { + this.init(options); + } + + _extend(KWidget, { + init: function (options) { + var self = this; + self.name = options.name || ''; + self.doc = options.doc || document; + self.win = _getWin(self.doc); + self.x = _addUnit(options.x); + self.y = _addUnit(options.y); + self.z = options.z; + self.width = _addUnit(options.width); + self.height = _addUnit(options.height); + self.div = K('
'); + self.options = options; + self._alignEl = options.alignEl; + if (self.width) { + self.div.css('width', self.width); + } + if (self.height) { + self.div.css('height', self.height); + } + if (self.z) { + self.div.css({ + position: 'absolute', + left: self.x, + top: self.y, + 'z-index': self.z + }); + } + if (self.z && (self.x === undefined || self.y === undefined)) { + self.autoPos(self.width, self.height); + } + if (options.cls) { + self.div.addClass(options.cls); + } + if (options.shadowMode) { + self.div.addClass('ke-shadow'); + } + if (options.css) { + self.div.css(options.css); + } + if (options.src) { + K(options.src).replaceWith(self.div); + } else { + K(self.doc.body).append(self.div); + } + if (options.html) { + self.div.html(options.html); + } + if (options.autoScroll) { + if (_IE && _V < 7 || _QUIRKS) { + var scrollPos = _getScrollPos(); + K(self.win).bind('scroll', function (e) { + var pos = _getScrollPos(), + diffX = pos.x - scrollPos.x, + diffY = pos.y - scrollPos.y; + self.pos(_removeUnit(self.x) + diffX, _removeUnit(self.y) + diffY, false); + }); + } else { + self.div.css('position', 'fixed'); + } + } + }, + pos: function (x, y, updateProp) { + var self = this; + updateProp = _undef(updateProp, true); + if (x !== null) { + x = x < 0 ? 0 : _addUnit(x); + self.div.css('left', x); + if (updateProp) { + self.x = x; + } + } + if (y !== null) { + y = y < 0 ? 0 : _addUnit(y); + self.div.css('top', y); + if (updateProp) { + self.y = y; + } + } + return self; + }, + autoPos: function (width, height) { + var x, y, self = this, + w = _removeUnit(width) || 0, + h = _removeUnit(height) || 0, + scrollPos = _getScrollPos(); + if (self._alignEl) { + var knode = K(self._alignEl), + pos = knode.pos(), + diffX = _round(knode[0].clientWidth / 2 - w / 2), + diffY = _round(knode[0].clientHeight / 2 - h / 2); + x = diffX < 0 ? pos.x : pos.x + diffX; + } else { + var docEl = _docElement(self.doc); + x = _round(scrollPos.x + (docEl.clientWidth - w) / 2); + y = _round(scrollPos.y + (docEl.clientHeight - h) / 2); + } + if (K.options.dialogOffset > 0) { + y = scrollPos.y + 20; + } + if (!(_IE && _V < 7 || _QUIRKS)) { + x -= scrollPos.x; + y -= scrollPos.y; + } + return self.pos(x, y); + }, + remove: function () { + var self = this; + if (_IE && _V < 7 || _QUIRKS) { + K(self.win).unbind('scroll'); + } + self.div.remove(); + _each(self, function (i) { + self[i] = null; + }); + return this; + }, + show: function () { + this.div.show(); + return this; + }, + hide: function () { + this.div.hide(); + return this; + }, + draggable: function (options) { + var self = this; + options = options || {}; + options.moveEl = self.div; + options.moveFn = function (x, y, width, height, diffX, diffY) { + if ((x = x + diffX) < 0) { + x = 0; + } + if ((y = y + diffY) < 0) { + y = 0; + } + self.pos(x, y); + }; + _drag(options); + return self; + } + }); + + function _widget(options) { + return new KWidget(options); + } + + K.WidgetClass = KWidget; + K.widget = _widget; + + + function _iframeDoc(iframe) { + iframe = _get(iframe); + return iframe.contentDocument || iframe.contentWindow.document; + } + + var html, _direction = ''; + if ((html = document.getElementsByTagName('html'))) { + _direction = html[0].dir; + } + + function _getInitHtml(options) { + var themesPath = _undef(options.themesPath, ''), + bodyClass = options.bodyClass, + cssPath = options.cssPath, + jsPath = options.jsPath, + cssData = options.cssData; + var arr = [ + (_direction === '' ? '' : ''), + '', + ''); + if (!_isArray(cssPath)) { + cssPath = [cssPath]; + } + if (_inArray(K.basePath + 'themes/app.css', cssPath) < 0) { + cssPath.push(K.basePath + 'themes/app.css'); + } + _each(cssPath, function (i, path) { + if (path) { + arr.push(''); + } + }); + if (cssData) { + arr.push(''); + } + arr.push(''); + if (!_isArray(jsPath)) { + jsPath = [jsPath]; + } + _each(jsPath, function (i, path) { + if (path) { + arr.push(''); + } + }); + arr.push(''); + return arr.join('\n'); + } + + function _elementVal(knode, val) { + if (knode.hasVal()) { + if (val === undefined) { + var html = knode.val(); + html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, ''); + return html; + } + return knode.val(val); + } + return knode.html(val); + } + + + function KEdit(options) { + this.init(options); + } + + _extend(KEdit, KWidget, { + init: function (options) { + var self = this; + KEdit.parent.init.call(self, options); + self.srcElement = K(options.srcElement); + self.div.addClass('ke-edit'); + self.designMode = _undef(options.designMode, true); + self.beforeGetHtml = options.beforeGetHtml; + self.beforeSetHtml = options.beforeSetHtml; + self.afterSetHtml = options.afterSetHtml; + var isDocumentDomain = location.protocol != 'res:' && location.host.replace(/:\d+/, '') !== document.domain, + srcScript = ('document.open();' + + (isDocumentDomain ? 'document.domain="' + document.domain + '";' : '') + + 'document.close();'), + iframeSrc = _IE ? ' src="javascript:void(function(){' + encodeURIComponent(srcScript) + '}())"' : ''; + self.iframe = K('').css('width', '100%'); + self.textarea = K('').css('width', '100%'); + self.tabIndex = isNaN(parseInt(options.tabIndex, 10)) ? self.srcElement.attr('tabindex') : parseInt(options.tabIndex, 10); + self.iframe.attr('tabindex', self.tabIndex); + self.textarea.attr('tabindex', self.tabIndex); + if (self.width) { + self.setWidth(self.width); + } + if (self.height) { + self.setHeight(self.height); + } + if (self.designMode) { + self.textarea.hide(); + } else { + self.iframe.hide(); + } + + function ready() { + var doc = _iframeDoc(self.iframe); + doc.open(); + if (isDocumentDomain) { + doc.domain = document.domain; + } + doc.write(_getInitHtml(self.options)); + doc.close(); + self.win = self.iframe[0].contentWindow; + self.doc = doc; + var cmd = _cmd(doc); + self.afterChange(function (e) { + cmd.selection(); + }); + if (_WEBKIT) { + K(doc).click(function (e) { + if (K(e.target).name === 'img') { + cmd.selection(true); + cmd.range.selectNode(e.target); + cmd.select(); + } + }); + } + if (_IE) { + self._mousedownHandler = function () { + var newRange = cmd.range.cloneRange(); + newRange.shrink(); + if (newRange.isControl()) { + self.blur(); + } + }; + K(document).mousedown(self._mousedownHandler); + K(doc).keydown(function (e) { + if (e.which == 8) { + cmd.selection(); + var rng = cmd.range; + if (rng.isControl()) { + rng.collapse(true); + K(rng.startContainer.childNodes[rng.startOffset]).remove(); + e.preventDefault(); + } + } + }); + } + self.cmd = cmd; + self.html(_elementVal(self.srcElement)); + if (_IE) { + doc.body.disabled = true; + doc.body.contentEditable = true; + doc.body.removeAttribute('disabled'); + } else { + doc.designMode = 'on'; + } + if (options.afterCreate) { + options.afterCreate.call(self); + } + } + + if (isDocumentDomain) { + self.iframe.bind('load', function (e) { + self.iframe.unbind('load'); + if (_IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + } + self.div.append(self.iframe); + self.div.append(self.textarea); + self.srcElement.hide(); + !isDocumentDomain && ready(); + }, + setWidth: function (val) { + var self = this; + val = _addUnit(val); + self.width = val; + self.div.css('width', val); + return self; + }, + setHeight: function (val) { + var self = this; + val = _addUnit(val); + self.height = val; + self.div.css('height', val); + self.iframe.css('height', val); + if ((_IE && _V < 8) || _QUIRKS) { + val = _addUnit(_removeUnit(val) - 2); + } + self.textarea.css('height', val); + return self; + }, + remove: function () { + var self = this, doc = self.doc; + K(doc.body).unbind(); + K(doc).unbind(); + K(self.win).unbind(); + if (self._mousedownHandler) { + K(document).unbind('mousedown', self._mousedownHandler); + } + _elementVal(self.srcElement, self.html()); + self.srcElement.show(); + self.iframe.unbind(); + self.textarea.unbind(); + KEdit.parent.remove.call(self); + }, + html: function (val, isFull) { + var self = this, doc = self.doc; + if (self.designMode) { + var body = doc.body; + if (val === undefined) { + if (isFull) { + val = '' + body.parentNode.innerHTML + ''; + } else { + val = body.innerHTML; + } + if (self.beforeGetHtml) { + val = self.beforeGetHtml(val); + } + if (_GECKO && val == '
') { + val = ''; + } + return val; + } + if (self.beforeSetHtml) { + val = self.beforeSetHtml(val); + } + if (_IE && _V >= 9) { + val = val.replace(/(<.*?checked=")checked(".*>)/ig, '$1$2'); + } + K(body).html(val); + if (self.afterSetHtml) { + self.afterSetHtml(); + } + return self; + } + if (val === undefined) { + return self.textarea.val(); + } + self.textarea.val(val); + return self; + }, + design: function (bool) { + var self = this, val; + if (bool === undefined ? !self.designMode : bool) { + if (!self.designMode) { + val = self.html(); + self.designMode = true; + self.textarea.hide(); + self.html(val); + var iframe = self.iframe; + var height = _removeUnit(self.height); + iframe.height(height - 2); + iframe.show(); + setTimeout(function () { + iframe.height(height); + }, 0); + } + } else { + if (self.designMode) { + val = self.html(); + self.designMode = false; + self.html(val); + self.iframe.hide(); + self.textarea.show(); + } + } + return self.focus(); + }, + focus: function () { + var self = this; + self.designMode ? self.win.focus() : self.textarea[0].focus(); + return self; + }, + blur: function () { + var self = this; + if (_IE) { + var input = K('', self.div); + self.div.append(input); + input[0].focus(); + input.remove(); + } else { + self.designMode ? self.win.blur() : self.textarea[0].blur(); + } + return self; + }, + afterChange: function (fn) { + var self = this, doc = self.doc, body = doc.body; + K(doc).keyup(function (e) { + if (!e.ctrlKey && !e.altKey && _CHANGE_KEY_MAP[e.which]) { + fn(e); + } + }); + K(doc).mouseup(fn).contextmenu(fn); + K(self.win).blur(fn); + + function timeoutHandler(e) { + setTimeout(function () { + fn(e); + }, 1); + } + + K(body).bind('paste', timeoutHandler); + K(body).bind('cut', timeoutHandler); + return self; + } + }); + + function _edit(options) { + return new KEdit(options); + } + + K.EditClass = KEdit; + K.edit = _edit; + K.iframeDoc = _iframeDoc; + + + function _selectToolbar(name, fn) { + var self = this, + knode = self.get(name); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + fn(knode); + } + } + + + function KToolbar(options) { + this.init(options); + } + + _extend(KToolbar, KWidget, { + init: function (options) { + var self = this; + KToolbar.parent.init.call(self, options); + self.disableMode = _undef(options.disableMode, false); + self.noDisableItemMap = _toMap(_undef(options.noDisableItems, [])); + self._itemMap = {}; + self.div.addClass('ke-toolbar').bind('contextmenu,mousedown,mousemove', function (e) { + e.preventDefault(); + }).attr('unselectable', 'on'); + + function find(target) { + var knode = K(target); + if (knode.hasClass('ke-outline')) { + return knode; + } + if (knode.hasClass('ke-toolbar-icon')) { + return knode.parent(); + } + } + + function hover(e, method) { + var knode = find(e.target); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + if (knode.hasClass('ke-selected')) { + return; + } + knode[method]('ke-on'); + } + } + + self.div.mouseover(function (e) { + hover(e, 'addClass'); + }) + .mouseout(function (e) { + hover(e, 'removeClass'); + }) + .click(function (e) { + var knode = find(e.target); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + self.options.click.call(this, e, knode.attr('data-name')); + } + }); + }, + get: function (name) { + if (this._itemMap[name]) { + return this._itemMap[name]; + } + return (this._itemMap[name] = K('span.ke-icon-' + name, this.div).parent()); + }, + select: function (name) { + _selectToolbar.call(this, name, function (knode) { + knode.addClass('ke-selected'); + }); + return self; + }, + unselect: function (name) { + _selectToolbar.call(this, name, function (knode) { + knode.removeClass('ke-selected').removeClass('ke-on'); + }); + return self; + }, + enable: function (name) { + var self = this, + knode = name.get ? name : self.get(name); + if (knode) { + knode.removeClass('ke-disabled'); + knode.opacity(1); + } + return self; + }, + disable: function (name) { + var self = this, + knode = name.get ? name : self.get(name); + if (knode) { + knode.removeClass('ke-selected').addClass('ke-disabled'); + knode.opacity(0.5); + } + return self; + }, + disableAll: function (bool, noDisableItems) { + var self = this, map = self.noDisableItemMap, item; + if (noDisableItems) { + map = _toMap(noDisableItems); + } + if (bool === undefined ? !self.disableMode : bool) { + K('span.ke-outline', self.div).each(function () { + var knode = K(this), + name = knode[0].getAttribute('data-name', 2); + if (!map[name]) { + self.disable(knode); + } + }); + self.disableMode = true; + } else { + K('span.ke-outline', self.div).each(function () { + var knode = K(this), + name = knode[0].getAttribute('data-name', 2); + if (!map[name]) { + self.enable(knode); + } + }); + self.disableMode = false; + } + return self; + } + }); + + function _toolbar(options) { + return new KToolbar(options); + } + + K.ToolbarClass = KToolbar; + K.toolbar = _toolbar; + + + function KMenu(options) { + this.init(options); + } + + _extend(KMenu, KWidget, { + init: function (options) { + var self = this; + options.z = options.z || 811213; + KMenu.parent.init.call(self, options); + self.centerLineMode = _undef(options.centerLineMode, true); + self.div.addClass('ke-menu ke-menu-' + options.themeType).bind('click,mousedown', function (e) { + e.stopPropagation(); + }).attr('unselectable', 'on'); + }, + addItem: function (item) { + var self = this; + if (item.title === '-') { + self.div.append(K('
')); + return; + } + var itemDiv = K('
'), + leftDiv = K('
'), + rightDiv = K('
'), + height = _addUnit(item.height), + iconClass = _undef(item.iconClass, ''); + self.div.append(itemDiv); + if (height) { + itemDiv.css('height', height); + rightDiv.css('line-height', height); + } + var centerDiv; + if (self.centerLineMode) { + centerDiv = K('
'); + if (height) { + centerDiv.css('height', height); + } + } + itemDiv.mouseover(function (e) { + K(this).addClass('ke-menu-item-on'); + if (centerDiv) { + centerDiv.addClass('ke-menu-item-center-on'); + } + }) + .mouseout(function (e) { + K(this).removeClass('ke-menu-item-on'); + if (centerDiv) { + centerDiv.removeClass('ke-menu-item-center-on'); + } + }) + .click(function (e) { + item.click.call(K(this)); + e.stopPropagation(); + }) + .append(leftDiv); + if (centerDiv) { + itemDiv.append(centerDiv); + } + itemDiv.append(rightDiv); + if (item.checked) { + iconClass = 'ke-icon-checked'; + } + if (iconClass !== '') { + leftDiv.html(''); + } + rightDiv.html(item.title); + return self; + }, + remove: function () { + var self = this; + if (self.options.beforeRemove) { + self.options.beforeRemove.call(self); + } + K('.ke-menu-item', self.div[0]).unbind(); + KMenu.parent.remove.call(self); + return self; + } + }); + + function _menu(options) { + return new KMenu(options); + } + + K.MenuClass = KMenu; + K.menu = _menu; + + + function KColorPicker(options) { + this.init(options); + } + + _extend(KColorPicker, KWidget, { + init: function (options) { + var self = this; + options.z = options.z || 811213; + KColorPicker.parent.init.call(self, options); + var colors = options.colors || [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] + ]; + self.selectedColor = (options.selectedColor || '').toLowerCase(); + self._cells = []; + self.div.addClass('ke-colorpicker').bind('click,mousedown', function (e) { + e.stopPropagation(); + }).attr('unselectable', 'on'); + var table = self.doc.createElement('table'); + self.div.append(table); + table.className = 'ke-colorpicker-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var row = table.insertRow(0), cell = row.insertCell(0); + cell.colSpan = colors[0].length; + self._addAttr(cell, '', 'ke-colorpicker-cell-top'); + for (var i = 0; i < colors.length; i++) { + row = table.insertRow(i + 1); + for (var j = 0; j < colors[i].length; j++) { + cell = row.insertCell(j); + self._addAttr(cell, colors[i][j], 'ke-colorpicker-cell'); + } + } + }, + _addAttr: function (cell, color, cls) { + var self = this; + cell = K(cell).addClass(cls); + if (self.selectedColor === color.toLowerCase()) { + cell.addClass('ke-colorpicker-cell-selected'); + } + cell.attr('title', color || self.options.noColor); + cell.mouseover(function (e) { + K(this).addClass('ke-colorpicker-cell-on'); + }); + cell.mouseout(function (e) { + K(this).removeClass('ke-colorpicker-cell-on'); + }); + cell.click(function (e) { + e.stop(); + self.options.click.call(K(this), color); + }); + if (color) { + cell.append(K('
').css('background-color', color)); + } else { + cell.html(self.options.noColor); + } + K(cell).attr('unselectable', 'on'); + self._cells.push(cell); + }, + remove: function () { + var self = this; + _each(self._cells, function () { + this.unbind(); + }); + KColorPicker.parent.remove.call(self); + return self; + } + }); + + function _colorpicker(options) { + return new KColorPicker(options); + } + + K.ColorPickerClass = KColorPicker; + K.colorpicker = _colorpicker; + + + function KUploadButton(options) { + this.init(options); + } + + _extend(KUploadButton, { + init: function (options) { + var self = this, + button = K(options.button), + fieldName = options.fieldName || 'file', + url = options.url || '', + title = button.val(), + extraParams = options.extraParams || {}, + cls = button[0].className || '', + target = options.target || 'kindeditor_upload_iframe_' + new Date().getTime(); + options.afterError = options.afterError || function (str) { + K.options.errorMsgHandler(str, "error"); + }; + var hiddenElements = []; + for (var k in extraParams) { + hiddenElements.push(''); + } + var html = [ + '
', + (options.target ? '' : ''), + (options.form ? '
' : '
'), + '', + hiddenElements.join(''), + '', + '', + '', + (options.form ? '
' : ''), + '
'].join(''); + var div = K(html, button.doc); + button.hide(); + button.before(div); + self.div = div; + self.button = button; + self.iframe = options.target ? K('iframe[name="' + target + '"]') : K('iframe', div); + self.form = options.form ? K(options.form) : K('form', div); + self.fileBox = K('.ke-upload-file', div); + var width = options.width || K('.ke-button-common', div).width(); + K('.ke-upload-area', div).width(width); + self.options = options; + }, + submit: function () { + var self = this, + iframe = self.iframe; + if (typeof self.options.beforeUpload == 'function') { + var result = self.options.beforeUpload.call(self); + if (!result) { + return false; + } + } + iframe.bind('load', function () { + iframe.unbind(); + var tempForm = document.createElement('form'); + self.fileBox.before(tempForm); + K(tempForm).append(self.fileBox); + tempForm.reset(); + K(tempForm).remove(true); + var doc = K.iframeDoc(iframe), + pre = doc.getElementsByTagName('pre')[0], + str = '', data; + if (pre) { + str = pre.innerHTML; + } else { + str = doc.body.innerHTML; + } + str = _unescape(str); + iframe[0].src = 'javascript:false'; + try { + data = K.json(str); + } catch (e) { + self.options.afterError.call(self, '' + doc.body.parentNode.innerHTML + ''); + } + if (data) { + self.options.afterUpload.call(self, data); + } + }); + self.form[0].submit(); + return self; + }, + remove: function () { + var self = this; + if (self.fileBox) { + self.fileBox.unbind(); + } + self.iframe.remove(); + self.div.remove(); + self.button.show(); + return self; + } + }); + + function _uploadbutton(options) { + return new KUploadButton(options); + } + + K.UploadButtonClass = KUploadButton; + K.uploadbutton = _uploadbutton; + + + function _createButton(arg) { + arg = arg || {}; + var name = arg.name || '', + btn = K('' + name + ''); + if (arg.click) { + btn.click(arg.click); + } + return btn; + } + + + function KDialog(options) { + this.init(options); + } + + _extend(KDialog, KWidget, { + init: function (options) { + var self = this; + options.z = options.z || 811213; + options.shadowMode = false; + options.autoScroll = _undef(options.autoScroll, true); + KDialog.parent.init.call(self, options); + var title = options.title, + body = K(options.body, self.doc), + previewBtn = options.previewBtn, + yesBtn = options.yesBtn, + noBtn = options.noBtn, + closeBtn = options.closeBtn, + showMask = _undef(options.showMask, true); + self.div.addClass('ke-dialog ke-animated').bind('click,mousedown', function (e) { + e.stopPropagation(); + }); + var contentDiv = K('
').appendTo(self.div); + var headerDiv = K('
'); + contentDiv.append(headerDiv); + headerDiv.html(title); + self.closeIcon = K('').click(closeBtn.click); + headerDiv.append(self.closeIcon); + self.draggable({ + clickEl: headerDiv, + beforeDrag: options.beforeDrag + }); + var bodyDiv = K('
'); + contentDiv.append(bodyDiv); + bodyDiv.append(body); + var footerDiv = K(''); + if (previewBtn || yesBtn || noBtn) { + self.div.append(footerDiv); + contentDiv.height(self.div.height() - footerDiv.height()); + } + _each([ + {btn: previewBtn, name: 'preview'}, + {btn: yesBtn, name: 'yes'}, + {btn: noBtn, name: 'no'} + ], function () { + if (this.btn) { + var button = _createButton(this.btn); + button.addClass('ke-dialog-' + this.name); + footerDiv.append(button); + } + }); + if (self.height) { + bodyDiv.height(_removeUnit(self.height) - headerDiv.height() - footerDiv.height()); + } + self.div.width(self.div.width()); + self.div.height(self.div.height()); + self.mask = null; + if (showMask) { + var docEl = _docElement(self.doc), + docWidth = Math.max(docEl.scrollWidth, docEl.clientWidth), + docHeight = Math.max(docEl.scrollHeight, docEl.clientHeight); + self.mask = _widget({ + x: 0, + y: 0, + z: self.z - 1, + cls: 'ke-dialog-mask', + width: docWidth, + height: docHeight + }); + } + self.autoPos(self.div.width(), self.div.height()); + self.footerDiv = footerDiv; + self.bodyDiv = bodyDiv; + self.headerDiv = headerDiv; + self.isLoading = false; + }, + setMaskIndex: function (z) { + var self = this; + self.mask.div.css('z-index', z); + }, + showLoading: function (msg) { + msg = _undef(msg, ''); + var self = this, body = self.bodyDiv; + self.loading = K('
' + msg + '
') + .width(body.width()).height(body.height()) + .css('top', self.headerDiv.height() + 'px'); + body.css('visibility', 'hidden').after(self.loading); + self.isLoading = true; + return self; + }, + hideLoading: function () { + this.loading && this.loading.remove(); + this.bodyDiv.css('visibility', 'visible'); + this.isLoading = false; + return this; + }, + remove: function () { + var self = this; + if (self.options.beforeRemove) { + self.options.beforeRemove.call(self); + } + self.mask && self.mask.remove(); + self.iframeMask && self.iframeMask.remove(); + self.closeIcon.unbind(); + K('input', self.div).unbind(); + K('button', self.div).unbind(); + self.footerDiv.unbind(); + self.bodyDiv.unbind(); + self.headerDiv.unbind(); + K('iframe', self.div).each(function () { + K(this).remove(); + }); + KDialog.parent.remove.call(self); + return self; + } + }); + + function _dialog(options) { + return new KDialog(options); + } + + K.DialogClass = KDialog; + K.dialog = _dialog; + + + function _tabs(options) { + var self = _widget(options), + remove = self.remove, + afterSelect = options.afterSelect, + div = self.div, + liList = []; + div.addClass('ke-tabs') + .bind('contextmenu,mousedown,mousemove', function (e) { + e.preventDefault(); + }); + var ul = K('
    '); + div.append(ul); + self.add = function (tab) { + var li = K('
  • ' + tab.title + '
  • '); + li.data('tab', tab); + liList.push(li); + ul.append(li); + }; + self.selectedIndex = 0; + self.select = function (index) { + self.selectedIndex = index; + _each(liList, function (i, li) { + li.unbind(); + if (i === index) { + li.addClass('ke-tabs-li-selected'); + K(li.data('tab').panel).show(''); + } else { + li.removeClass('ke-tabs-li-selected').removeClass('ke-tabs-li-on') + .mouseover(function () { + K(this).addClass('ke-tabs-li-on'); + }) + .mouseout(function () { + K(this).removeClass('ke-tabs-li-on'); + }) + .click(function () { + self.select(i); + }); + K(li.data('tab').panel).hide(); + } + }); + if (afterSelect) { + afterSelect.call(self, index); + } + }; + self.remove = function () { + _each(liList, function () { + this.remove(); + }); + ul.remove(); + remove.call(self); + }; + return self; + } + + K.tabs = _tabs; + + + function _loadScript(url, fn) { + if (K.options.resLoadCache[url]) { + return; + } + var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement), + script = document.createElement('script'); + head.appendChild(script); + K.options.resLoadCache[url] = 1; + script.src = url; + script.charset = 'utf-8'; + script.onload = script.onreadystatechange = function () { + if (!this.readyState || this.readyState === 'loaded') { + if (fn) { + fn(); + } + script.onload = script.onreadystatechange = null; + head.removeChild(script); + } + }; + } + + + function _chopQuery(url) { + var index = url.indexOf('?'); + return index > 0 ? url.substr(0, index) : url; + } + + function _loadStyle(url) { + if (K.options.resLoadCache[url]) { + return; + } + var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement), + link = document.createElement('link'), + absoluteUrl = _chopQuery(_formatUrl(url, 'absolute')); + var links = K('link[rel="stylesheet"]', head); + for (var i = 0, len = links.length; i < len; i++) { + if (_chopQuery(_formatUrl(links[i].href, 'absolute')) === absoluteUrl) { + return; + } + } + head.appendChild(link); + K.options.resLoadCache[url] = 1; + link.href = url; + link.rel = 'stylesheet'; + } + + function _ajax(url, fn, method, param, dataType) { + method = method || 'GET'; + dataType = dataType || 'json'; + var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); + xhr.open(method, url, true); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4 && xhr.status == 200) { + if (fn) { + var data = _trim(xhr.responseText); + if (dataType == 'json') { + data = _json(data); + } + fn(data); + } + } + }; + if (method == 'POST') { + var params = []; + _each(param, function (key, val) { + params.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); + }); + try { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + } catch (e) { + } + xhr.send(params.join('&')); + } else { + xhr.send(null); + } + } + + K.loadScript = _loadScript; + K.loadStyle = _loadStyle; + K.ajax = _ajax; + + + var _plugins = {}; + + function _plugin(name, fn) { + if (name === undefined) { + return _plugins; + } + if (!fn) { + return _plugins[name]; + } + _plugins[name] = fn; + } + + var _language = {}; + + function _parseLangKey(key) { + var match, ns = 'core'; + if ((match = /^(\w+)\.(\w+)$/.exec(key))) { + ns = match[1]; + key = match[2]; + } + return {ns: ns, key: key}; + } + + function _lang(mixed, langType) { + langType = langType === undefined ? K.options.langType : langType; + if (typeof mixed === 'string') { + if (!_language[langType]) { + return 'no language'; + } + var pos = mixed.length - 1; + if (mixed.substr(pos) === '.') { + return _language[langType][mixed.substr(0, pos)]; + } + var obj = _parseLangKey(mixed); + return _language[langType][obj.ns][obj.key]; + } + _each(mixed, function (key, val) { + var obj = _parseLangKey(key); + if (!_language[langType]) { + _language[langType] = {}; + } + if (!_language[langType][obj.ns]) { + _language[langType][obj.ns] = {}; + } + _language[langType][obj.ns][obj.key] = val; + }); + } + + + function _getImageFromRange(range, fn) { + if (range.collapsed) { + return; + } + range = range.cloneRange().up(); + var sc = range.startContainer, so = range.startOffset; + if (!_WEBKIT && !range.isControl()) { + return; + } + var img = K(sc.childNodes[so]); + if (!img || img.name != 'img') { + return; + } + if (fn(img)) { + return img; + } + } + + function _bindContextmenuEvent() { + var self = this, doc = self.edit.doc; + K(doc).contextmenu(function (e) { + if (self.menu) { + self.hideMenu(); + } + if (!self.useContextmenu) { + e.preventDefault(); + return; + } + if (self._contextmenus.length === 0) { + return; + } + var maxWidth = 0, items = []; + _each(self._contextmenus, function () { + if (this.title == '-') { + items.push(this); + return; + } + if (this.cond && this.cond()) { + items.push(this); + if (this.width && this.width > maxWidth) { + maxWidth = this.width; + } + } + }); + while (items.length > 0 && items[0].title == '-') { + items.shift(); + } + while (items.length > 0 && items[items.length - 1].title == '-') { + items.pop(); + } + var prevItem = null; + _each(items, function (i) { + if (this.title == '-' && prevItem.title == '-') { + delete items[i]; + } + prevItem = this; + }); + if (items.length > 0) { + e.preventDefault(); + var pos = K(self.edit.iframe).pos(), + menu = _menu({ + x: pos.x + e.clientX, + themeType: self.themeType, + y: pos.y + e.clientY, + width: maxWidth, + css: {visibility: 'hidden'}, + shadowMode: self.shadowMode + }); + _each(items, function () { + if (this.title) { + menu.addItem(this); + } + }); + var docEl = _docElement(menu.doc), + menuHeight = menu.div.height(); + if (e.clientY + menuHeight >= docEl.clientHeight - 100) { + menu.pos(menu.x, _removeUnit(menu.y) - menuHeight); + } + menu.div.css('visibility', 'visible'); + self.menu = menu; + } + }); + } + + function _bindNewlineEvent() { + var self = this, doc = self.edit.doc, newlineTag = self.newlineTag; + if (_IE && newlineTag !== 'br') { + return; + } + if (_GECKO && _V < 3 && newlineTag !== 'p') { + return; + } + if (_OPERA && _V < 9) { + return; + } + var brSkipTagMap = _toMap('h1,h2,h3,h4,h5,h6,pre,li'), + pSkipTagMap = _toMap('p,h1,h2,h3,h4,h5,h6,pre,li,blockquote'); + + function getAncestorTagName(range) { + var ancestor = K(range.commonAncestor()); + while (ancestor) { + if (ancestor.type == 1 && !ancestor.isStyle()) { + break; + } + ancestor = ancestor.parent(); + } + return ancestor.name; + } + + K(doc).keydown(function (e) { + if (e.which == 39) { + if (self.__startOffset == self.cmd.range.startOffset) { + var tagName = getAncestorTagName(self.cmd.range); + if (tagName != 'body') { + self.appendHtml('
    ') + } + } else { + self.__startOffset = self.cmd.range.startOffset + } + return; + } + if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) { + return; + } + self.cmd.selection(); + var tagName = getAncestorTagName(self.cmd.range); + if (tagName == 'marquee' || tagName == 'select') { + return; + } + if (newlineTag === 'br' && !brSkipTagMap[tagName]) { + e.preventDefault(); + self.insertHtml('
    ' + (_IE && _V < 9 ? '' : '\u200B')); + return; + } + if (!pSkipTagMap[tagName]) { + _nativeCommand(doc, 'formatblock', '

    '); + } + }); + K(doc).keyup(function (e) { + if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) { + return; + } + if (newlineTag == 'br') { + return; + } + if (_GECKO) { + var root = self.cmd.commonAncestor('p'); + var a = self.cmd.commonAncestor('a'); + if (a && a.text() == '') { + a.remove(true); + self.cmd.range.selectNodeContents(root[0]).collapse(true); + self.cmd.select(); + } + return; + } + self.cmd.selection(); + var tagName = getAncestorTagName(self.cmd.range); + if (tagName == 'marquee' || tagName == 'select') { + return; + } + if (!pSkipTagMap[tagName]) { + _nativeCommand(doc, 'formatblock', '

    '); + } + var div = self.cmd.commonAncestor('div'); + if (div) { + var p = K('

    '), + child = div[0].firstChild; + while (child) { + var next = child.nextSibling; + p.append(child); + child = next; + } + div.before(p); + div.remove(); + self.cmd.range.selectNodeContents(p[0]); + self.cmd.select(); + } + }); + } + + function _bindTabEvent() { + var self = this, doc = self.edit.doc; + K(doc).keydown(function (e) { + if (e.which == 9) { + e.preventDefault(); + if (self.afterTab) { + self.afterTab.call(self, e); + return; + } + var cmd = self.cmd, range = cmd.range; + range.shrink(); + if (range.collapsed && range.startContainer.nodeType == 1) { + range.insertNode(K('@ ', doc)[0]); + cmd.select(); + } + self.insertHtml('    '); + } + }); + } + + function _bindFocusEvent() { + var self = this; + K(self.edit.textarea[0], self.edit.win).focus(function (e) { + if (self.afterFocus) { + self.afterFocus.call(self, e); + } + }).blur(function (e) { + if (self.afterBlur) { + self.afterBlur.call(self, e); + } + }); + } + + function _removeBookmarkTag(html) { + return _trim(html.replace(/]*id="?__kindeditor_bookmark_\w+_\d+__"?[^>]*><\/span>/ig, '')); + } + + function _removeTempTag(html) { + return html.replace(/]+class="?__kindeditor_paste__"?[^>]*>[\s\S]*?<\/div>/ig, ''); + } + + function _addBookmarkToStack(stack, bookmark) { + if (stack.length === 0) { + stack.push(bookmark); + return; + } + var prev = stack[stack.length - 1]; + if (_removeBookmarkTag(bookmark.html) !== _removeBookmarkTag(prev.html)) { + stack.push(bookmark); + } + } + + + function _undoToRedo(fromStack, toStack) { + var self = this, edit = self.edit, + body = edit.doc.body, + range, bookmark; + if (fromStack.length === 0) { + return self; + } + if (edit.designMode) { + range = self.cmd.range; + bookmark = range.createBookmark(true); + bookmark.html = body.innerHTML; + } else { + bookmark = { + html: body.innerHTML + }; + } + _addBookmarkToStack(toStack, bookmark); + var prev = fromStack.pop(); + if (_removeBookmarkTag(bookmark.html) === _removeBookmarkTag(prev.html) && fromStack.length > 0) { + prev = fromStack.pop(); + } + if (edit.designMode) { + edit.html(prev.html); + if (prev.start) { + range.moveToBookmark(prev); + self.select(); + } + } else { + K(body).html(_removeBookmarkTag(prev.html)); + } + return self; + } + + function KEditor(options) { + var self = this; + self.options = {}; + + function setOption(key, val) { + if (KEditor.prototype[key] === undefined) { + self[key] = val; + } + self.options[key] = val; + } + + _each(options, function (key, val) { + setOption(key, options[key]); + }); + _each(K.options, function (key, val) { + if (self[key] === undefined) { + setOption(key, val); + } + }); + var se = K(self.srcElement || '', + ''].join(''), + dialog = self.createDialog({ + name: name, + width: 450, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var type = K('.ke-select', dialog.div).val(), + code = textarea.val(), + cls = type === '' ? '' : 'language-' + type, + html = '
    ' + K.escape(code) + '

    '; + if (K.trim(code) === '') { + K.options.errorMsgHandler(lang.pleaseInput, "error"); + textarea[0].focus(); + return; + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('emoticons', function (K) { + var self = this, name = 'emoticons', + path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'), + allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons, + currentPageNum = 1; + self.clickToolbar(name, function () { + var rows = 5, cols = 9, total = 135, startNum = 0, + cells = rows * cols, pages = Math.ceil(total / cells), + colsHalf = Math.floor(cols / 2), + wrapperDiv = K('
    '), + elements = [], + menu = self.createMenu({ + name: name, + beforeRemove: function () { + removeEvent(); + } + }); + menu.div.append(wrapperDiv); + var previewDiv, previewImg; + if (allowPreview) { + previewDiv = K('
    ').css('right', 0); + previewImg = K(''); + wrapperDiv.append(previewDiv); + previewDiv.append(previewImg); + } + + function bindCellEvent(cell, j, num) { + if (previewDiv) { + cell.mouseover(function () { + if (j > colsHalf) { + previewDiv.css('left', 0); + previewDiv.css('right', ''); + } else { + previewDiv.css('left', ''); + previewDiv.css('right', 0); + } + previewImg.attr('src', path + num + '.gif'); + K(this).addClass('ke-on'); + }); + } else { + cell.mouseover(function () { + K(this).addClass('ke-on'); + }); + } + cell.mouseout(function () { + K(this).removeClass('ke-on'); + }); + cell.click(function (e) { + self.insertHtml('').hideMenu().focus(); + e.stop(); + }); + } + + function createEmoticonsTable(pageNum, parentDiv) { + var table = document.createElement('table'); + parentDiv.append(table); + if (previewDiv) { + K(table).mouseover(function () { + previewDiv.show('block'); + }); + K(table).mouseout(function () { + previewDiv.hide(); + }); + elements.push(K(table)); + } + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var num = (pageNum - 1) * cells + startNum; + for (var i = 0; i < rows; i++) { + var row = table.insertRow(i); + for (var j = 0; j < cols; j++) { + var cell = K(row.insertCell(j)); + cell.addClass('ke-cell'); + bindCellEvent(cell, j, num); + var span = K('') + .css('background-position', '-' + (24 * num) + 'px 0px') + .css('background-image', 'url(' + path + 'static.gif)'); + cell.append(span); + elements.push(cell); + num++; + } + } + return table; + } + + var table = createEmoticonsTable(currentPageNum, wrapperDiv); + + function removeEvent() { + K.each(elements, function () { + this.unbind(); + }); + } + + var pageDiv; + + function bindPageEvent(el, pageNum) { + el.click(function (e) { + removeEvent(); + table.parentNode.removeChild(table); + pageDiv.remove(); + table = createEmoticonsTable(pageNum, wrapperDiv); + createPageTable(pageNum); + currentPageNum = pageNum; + e.stop(); + }); + } + + function createPageTable(currentPageNum) { + pageDiv = K('
    '); + wrapperDiv.append(pageDiv); + for (var pageNum = 1; pageNum <= pages; pageNum++) { + if (currentPageNum !== pageNum) { + var a = K('[' + pageNum + ']'); + bindPageEvent(a, pageNum); + pageDiv.append(a); + elements.push(a); + } else { + pageDiv.append(K('@[' + pageNum + ']')); + } + pageDiv.append(K('@ ')); + } + } + + createPageTable(currentPageNum); + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('flash', function (K) { + var self = this, name = 'flash', lang = self.lang(name + '.'), + allowFlashUpload = K.undef(self.allowFlashUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.flash = { + edit: function () { + var html = [ + '
    ', + '
    ', + '', + '
    ', + '  ', + '  ', + '', + '', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + ' ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + ' ', + '
    ', + '
    ', + '
    ' + ].join(''); + var dialog = self.createDialog({ + name: name, + width: 450, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + K.options.errorMsgHandler(self.lang('invalidUrl'), "error"); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + K.options.errorMsgHandler(self.lang('invalidWidth'), "error"); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + K.options.errorMsgHandler(self.lang('invalidHeight'), "error"); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src: url, + type: K.mediaType('.swf'), + width: width, + height: height, + quality: 'high' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div); + urlBox.val('http://'); + if (allowFlashUpload) { + var callback = function (data) { + dialog.hideLoading(); + if (data.code === "000") { + var url = data.data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + //K.options.errorMsgHandler(self.lang('uploadSuccess'), "ok"); + } else { + K.options.errorMsgHandler(data.message, "error"); + } + }; + var uploadbutton = K.uploadbutton({ + button: K('.ke-upload-button', div)[0], + fieldName: filePostName, + extraParams: extraParams, + url: K.addParam(uploadJson, 'fileType=flash'), + beforeUpload: function () { + if (typeof self.beforeUpload == 'function') { + self.beforeUpload.call(this, callback); + return false; + } else { + return true; + } + }, + afterUpload: function (data) { + callback(data); + }, + afterError: function (html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function (e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function (e) { + self.loadPlugin('filemanager', function () { + self.plugin.filemanagerDialog({ + dirName: 'flash', + clickFn: function (url) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + } + }); + }); + }); + } else { + K('[name="url"]').css("width", "250px"); + viewServerBtn.hide(); + } + var img = self.plugin.getSelectedFlash(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete': function () { + self.plugin.getSelectedFlash().remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.flash.edit); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('image', function (K) { + var self = this, name = 'image', + allowImageUpload = K.undef(self.allowImageUpload, true), + allowImageRemote = K.undef(self.allowImageRemote, true), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + allowFileManager = K.undef(self.allowFileManager, false), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imageTabIndex = K.undef(self.imageTabIndex, 0), + imgPath = self.pluginsPath + 'image/images/', + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + fillDescAfterUploadImage = K.undef(self.fillDescAfterUploadImage, false), + lang = self.lang(name + '.'); + self.plugin.imageDialog = function (options) { + var imageUrl = options.imageUrl, + imageWidth = K.undef(options.imageWidth, ''), + imageHeight = K.undef(options.imageHeight, ''), + imageTitle = K.undef(options.imageTitle, ''), + imageAlign = K.undef(options.imageAlign, ''), + showRemote = K.undef(options.showRemote, true), + showLocal = K.undef(options.showLocal, true), + tabIndex = K.undef(options.tabIndex, 0), + clickFn = options.clickFn; + var target = 'kindeditor_upload_iframe_' + new Date().getTime(); + var hiddenElements = []; + for (var k in extraParams) { + hiddenElements.push(''); + } + var html = [ + '
    ', + '
    ', + '', + '', + '
    ' + ].join(''); + var dialogWidth = showLocal || allowFileManager ? 450 : 400, + dialogHeight = showLocal && showRemote ? 310 : 260; + var dialog = self.createDialog({ + name: name, + width: dialogWidth, + height: dialogHeight, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + if (dialog.isLoading) { + return; + } + if (showLocal && showRemote && tabs && tabs.selectedIndex === 1 || !showRemote) { + if (uploadbutton.fileBox.val() == '') { + K.options.errorMsgHandler(self.lang('pleaseSelectFile'), "error"); + return; + } + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + localUrlBox.val(''); + return; + } + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(), + title = titleBox.val(), + align = ''; + alignBox.each(function () { + if (this.checked) { + align = this.value; + return false; + } + }); + if (url == 'http://' || K.invalidUrl(url)) { + K.options.errorMsgHandler(self.lang('invalidUrl'), "error"); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + K.options.errorMsgHandler(self.lang('invalidWidth'), "error"); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + K.options.errorMsgHandler(self.lang('invalidHeight'), "error"); + heightBox[0].focus(); + return; + } + clickFn.call(self, url, title, width, height, 0, align); + } + }, + beforeRemove: function () { + viewServerBtn.unbind(); + widthBox.unbind(); + heightBox.unbind(); + refreshBtn.unbind(); + } + }), + div = dialog.div; + var urlBox = K('[name="url"]', div), + localUrlBox = K('[name="localUrl"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('.tab1 [name="width"]', div), + heightBox = K('.tab1 [name="height"]', div), + refreshBtn = K('.ke-refresh-btn', div), + titleBox = K('.tab1 [name="title"]', div), + alignBox = K('.tab1 [name="align"]', div); + var tabs; + if (showRemote && showLocal) { + tabs = K.tabs({ + src: K('.tabs', div), + afterSelect: function (i) { + } + }); + tabs.add({ + title: lang.remoteImage, + panel: K('.tab1', div) + }); + tabs.add({ + title: lang.localImage, + panel: K('.tab2', div) + }); + tabs.select(tabIndex); + } else if (showRemote) { + K('.tab1', div).show(); + } else if (showLocal) { + K('.tab2', div).show(); + } + var callback = function (data) { + if (data.code == "000") { + dialog.hideLoading(); + //K.options.errorMsgHandler(self.lang('uploadSuccess'), "ok"); + var url = data.data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + if (!fillDescAfterUploadImage) { + clickFn.call(self, url, data.title, data.width, data.height, data.border, data.align); + } else { + K(".ke-dialog-row #remoteUrl", div).val(url); + K(".ke-tabs-li", div)[0].click(); + K(".ke-refresh-btn", div).click(); + } + } else { + K.options.errorMsgHandler(data.message, "error"); + } + }; + var uploadbutton = K.uploadbutton({ + button: K('.ke-upload-button', div)[0], + fieldName: filePostName, + form: K('.ke-form', div), + target: target, + width: 60, + beforeUpload: function () { + if (typeof self.beforeUpload == 'function') { + self.beforeUpload.call(this, callback); + return false; + } else { + return true; + } + }, + afterUpload: function (data) { + callback(data); + }, + afterError: function (html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function (e) { + localUrlBox.val(uploadbutton.fileBox.val()); + }); + if (allowFileManager) { + viewServerBtn.click(function (e) { + self.loadPlugin('filemanager', function () { + self.plugin.filemanagerDialog({ + dirName: 'image', + clickFn: function (url) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var originalWidth = 0, originalHeight = 0; + + function setSize(width, height) { + widthBox.val(width); + heightBox.val(height); + originalWidth = width; + originalHeight = height; + } + + refreshBtn.click(function (e) { + var tempImg = K('', document).css({ + position: 'absolute', + visibility: 'hidden', + top: 0, + left: '-1000px' + }); + tempImg.bind('load', function () { + setSize(tempImg.width(), tempImg.height()); + tempImg.remove(); + }); + K(document.body).append(tempImg); + }); + widthBox.change(function (e) { + if (originalWidth > 0) { + heightBox.val(Math.round(originalHeight / originalWidth * parseInt(this.value, 10))); + } + }); + heightBox.change(function (e) { + if (originalHeight > 0) { + widthBox.val(Math.round(originalWidth / originalHeight * parseInt(this.value, 10))); + } + }); + urlBox.val(options.imageUrl); + setSize(options.imageWidth, options.imageHeight); + titleBox.val(options.imageTitle); + alignBox.each(function () { + if (this.value === options.imageAlign) { + this.checked = true; + return false; + } + }); + if (showRemote && tabIndex === 0) { + urlBox[0].focus(); + urlBox[0].select(); + } + return dialog; + }; + self.plugin.image = { + edit: function () { + var img = self.plugin.getSelectedImage(); + self.plugin.imageDialog({ + imageUrl: img ? img.attr('data-ke-src') : 'http://', + imageWidth: img ? img.width() : '', + imageHeight: img ? img.height() : '', + imageTitle: img ? img.attr('title') : '', + imageAlign: img ? img.attr('align') : '', + showRemote: allowImageRemote, + showLocal: allowImageUpload, + tabIndex: img ? 0 : imageTabIndex, + clickFn: function (url, title, width, height, border, align) { + if (img) { + img.attr('src', url); + img.attr('data-ke-src', url); + img.attr('width', width); + img.attr('height', height); + img.attr('title', title); + img.attr('align', align); + img.attr('alt', title); + } else { + self.exec('insertimage', url, title, width, height, border, align); + } + setTimeout(function () { + self.hideDialog().focus(); + }, 0); + } + }); + }, + 'delete': function () { + var target = self.plugin.getSelectedImage(); + if (target.parent().name == 'a') { + target = target.parent(); + } + target.remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.image.edit); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('insertfile', function (K) { + var self = this, name = 'insertfile', + allowFileUpload = K.undef(self.allowFileUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + self.plugin.fileDialog = function (options) { + var fileUrl = K.undef(options.fileUrl, 'http://'), + fileTitle = K.undef(options.fileTitle, ''), + clickFn = options.clickFn; + var html = [ + '
    ', + '
    ', + '', + '
    ', + '  ', + '  ', + '', + '', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '', + '' + ].join(''); + var dialog = self.createDialog({ + name: name, + width: 450, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var url = K.trim(urlBox.val()), + title = titleBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + K.options.errorMsgHandler(self.lang('invalidUrl'), "error"); + urlBox[0].focus(); + return; + } + if (K.trim(title) === '') { + title = url; + } + clickFn.call(self, url, title); + } + } + }), + div = dialog.div; + var urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + titleBox = K('[name="title"]', div); + if (allowFileUpload) { + var callback = function (data) { + dialog.hideLoading(); + if (data.code === "000") { + var url = data.data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + //K.options.errorMsgHandler(self.lang('uploadSuccess'), "ok"); + } else { + K.options.errorMsgHandler(data.message, "error"); + } + }; + var uploadbutton = K.uploadbutton({ + button: K('.ke-upload-button', div)[0], + fieldName: filePostName, + url: K.addParam(uploadJson, 'fileType=file'), + extraParams: extraParams, + beforeUpload: function () { + if (typeof self.beforeUpload == 'function') { + self.beforeUpload.call(this, callback); + return false; + } else { + return true; + } + }, + afterUpload: function (data) { + callback(data); + }, + afterError: function (html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function (e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function (e) { + self.loadPlugin('filemanager', function () { + self.plugin.filemanagerDialog({ + viewType: 'LIST', + dirName: 'file', + clickFn: function (url) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + } + }); + }); + }); + } else { + K("#keUrl").css("width", "250px"); + viewServerBtn.hide(); + } + urlBox.val(fileUrl); + titleBox.val(fileTitle); + urlBox[0].focus(); + urlBox[0].select(); + }; + self.clickToolbar(name, function () { + self.plugin.fileDialog({ + clickFn: function (url, title) { + var html = '' + title + ''; + self.insertHtml(html).hideDialog().focus(); + } + }); + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('lineheight', function (K) { + var self = this, name = 'lineheight', lang = self.lang(name + '.'); + self.clickToolbar(name, function () { + var curVal = '', commonNode = self.cmd.commonNode({'*': '.line-height'}); + if (commonNode) { + curVal = commonNode.css('line-height'); + } + var menu = self.createMenu({ + name: name, + width: 150 + }); + K.each(lang.lineHeight, function (i, row) { + K.each(row, function (key, val) { + menu.addItem({ + title: val, + checked: curVal === key, + click: function () { + self.cmd.toggle('', { + span: '.line-height=' + key + }); + self.updateState(); + self.addBookmark(); + self.hideMenu(); + } + }); + }); + }); + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('link', function (K) { + var self = this, name = 'link'; + self.plugin.link = { + edit: function () { + var lang = self.lang(name + '.'), + html = ['
    ', + '
    ', + '', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '', + '
    ', + '
    ', + '
    '].join(""), + dialog = self.createDialog({ + name: name, + width: 450, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var url = K.trim(urlBox.val()); + if (url == 'http://' || K.invalidUrl(url)) { + K.options.errorMsgHandler(self.lang('invalidUrl'), "error"); + urlBox[0].focus(); + return; + } + self.exec('createlink', url, typeBox.val()).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('input[name="url"]', div), + typeBox = K('select[name="type"]', div); + urlBox.val('http://'); + typeBox[0].options[0] = new Option(lang.newWindow, '_blank'); + typeBox[0].options[1] = new Option(lang.selfWindow, ''); + self.cmd.selection(); + var a = self.plugin.getSelectedLink(); + if (a) { + self.cmd.range.selectNode(a[0]); + self.cmd.select(); + urlBox.val(a.attr('data-ke-src')); + typeBox.val(a.attr('target')); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete': function () { + self.exec('unlink', null); + } + }; + self.clickToolbar(name, self.plugin.link.edit); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('media', function (K) { + var self = this, name = 'media', lang = self.lang(name + '.'), + allowMediaUpload = K.undef(self.allowMediaUpload, false), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.media = { + edit: function () { + var html = [ + '
    ', + '
    ', + '', + '
    ', + '  ', + '  ', + '', + '', + '', + '
    支持优酷、爱奇艺、腾讯视频等视频网站【通用代码】', + '
    ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + ' ', + '
    ', + '
    ', + '
    ' + ].join(''); + var dialog = self.createDialog({ + name: name, + width: 450, + height: 260, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + var match = url.match(/^'; + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div), + autostartBox = K('[name="autostart"]', div); + urlBox.val('http://'); + if (allowMediaUpload) { + var callback = function (data) { + dialog.hideLoading(); + if (data.code == "000") { + var url = data.data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + //K.options.errorMsgHandler(self.lang('uploadSuccess'), "ok"); + } else { + K.options.errorMsgHandler(data.message, "error", "error"); + } + }; + var uploadbutton = K.uploadbutton({ + button: K('.ke-upload-button', div)[0], + fieldName: filePostName, + extraParams: extraParams, + url: K.addParam(uploadJson, 'fileType=media'), + beforeUpload: function () { + if (typeof self.beforeUpload == 'function') { + self.beforeUpload.call(this, callback); + return false; + } else { + return true; + } + }, + afterUpload: function (data) { + callback(data); + }, + afterError: function (html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function (e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowMediaUpload && allowFileManager) { + viewServerBtn.click(function (e) { + self.loadPlugin('filemanager', function () { + self.plugin.filemanagerDialog({ + dirName: 'media', + clickFn: function (url) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + } + }); + }); + }); + } else { + K("#keUrl").css("width", "250px"); + viewServerBtn.hide(); + } + var img = self.plugin.getSelectedMedia(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + autostartBox[0].checked = (attrs.autostart === 'true'); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete': function () { + self.plugin.getSelectedMedia().remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.media.edit); +}); + +KindEditor.plugin('multiimage', function (K) { + var self = this, name = 'multiimage', + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'), + imageSizeLimit = K.undef(self.imageSizeLimit, 2048), + imageFileTypes = K.undef(self.imageFileTypes, 'jpg|png|gif|jpeg'), + imageUploadLimit = K.undef(self.imageUploadLimit, 20), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + if (typeof jQuery == 'undefined') { + K.options.errorMsgHandler(lang.depJQueryError, "error"); + return; + } else { + K.loadScript(K.options.pluginsPath + name + "/BUpload.js"); + K.loadStyle(K.options.pluginsPath + name + "/css/upload.css"); + } + K.locker = function () { + var docWidth = Math.max(document.documentElement.clientWidth, document.body.clientWidth); + var docHeight = Math.max(document.documentElement.clientHeight, document.body.clientHeight, $(document).height()) + document.documentElement.scrollTop; + return K.widget({ + x: 0, + y: 0, + cls: 'ke-dialog-lock', + width: docWidth, + height: docHeight + }); + } + self.plugin.multiImageDialog = function (options) { + + var clickFn = options.clickFn; + var locker = K.locker(); + locker.show(); + var dialog = new BUpload({ + src: filePostName, + upload_url: uploadJson, + list_url: fileManagerJson, + max_filesize: imageSizeLimit, + max_filenum: imageUploadLimit, + ext_allow: imageFileTypes, + lang: lang, + top: self.dialogOffset, + fileType: "image", + errorHandler: K.options.errorMsgHandler, + callback: function (data) { + clickFn.call(this, data); + }, + close: function () { + locker.remove(); + } + }); + return dialog; + }; + self.clickToolbar(name, function () { + self.plugin.multiImageDialog({ + clickFn: function (urlList) { + if (urlList.length === 0) { + return; + } + K.each(urlList, function (i, data) { + if (self.afterUpload) { + self.afterUpload.call(self, data, data, 'multiimage'); + } + self.exec('insertimage', data); + }); + setTimeout(function () { + self.hideDialog().focus(); + }, 0); + } + }); + }); +}); + + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('graft', function (K) { + var self = this, name = 'graft', + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + allowUploadGraft = K.undef(self.allowUploadGraft, true), + lang = self.lang(name + '.'); + if (typeof jQuery == 'undefined') { + K.options.errorMsgHandler(lang.depJQueryError, "error"); + return; + } else { + K.loadStyle(K.options.pluginsPath + "graft/css/scrawl.css"); + K.loadScript(K.options.pluginsPath + "graft/scrawl.js"); + } + self.plugin.graftDialog = function (options) { + var clickFn = options.clickFn; + var html = [ + '
    ', + '
    ', + '
    ', + '你的浏览器不支持 canvas 绘图', + '
    ', + '
    ', + '
    ', + '', + '', + '', + '
    ', + '
    ', + '
    ', + '
    ', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '
    ', + '
    ', + '', + '1', + '3', + '5', + '7', + '
    ', + '
    ', + '', + '5', + '10', + '15', + '20', + '
    ', + '
    ', + '', + '2', + '4', + '6', + '8', + '
    ', + '
    ', + '', + '', + '初始化设置', + '', + '
    ', + '
    ', + '
    ', + '', + '添加背景', + '', + '
    ', + '
    ', + '
    ', + '', + '', + '删除背景', + '', + '
    ', + '
    ' + ].join(''); + var dataURLtoFile = function (dataurl, filename) { + var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], + bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new File([u8arr], filename, {type: mime}); + }; + var dialog = self.createDialog({ + name: name, + width: 750, + height: 440, + title: self.lang(name), + body: html, + yesBtn: { + name: lang.btnText, + click: function (e) { + if (dialog.isLoading) { + return; + } + if (canvas.isEmpty()) { + K.options.errorMsgHandler(lang.empty, "error"); + return; + } + canvas.save(function (data) { + if (allowUploadGraft) { + var callback = function (res) { + dialog.hideLoading(); + if (res.code == "000") { + //K.options.errorMsgHandler(lang.uploadSuccess, "ok"); + clickFn.call(self, res.data.url); + self.hideDialog().focus(); + } else { + K.options.errorMsgHandler(lang.uploadFaild, "error"); + } + }; + dialog.showLoading(self.lang('uploadLoading')); + if (typeof self.beforeUpload == 'function') { + var file = dataURLtoFile(data, "graft.png"); + self.beforeUpload.call(this, callback, file); + } else { + $.post(uploadJson, { + img_base64_data: data, + fileType: "image", + base64: 1 + }, function (res) { + callback(res); + }, "json"); + } + } else { + clickFn.call(self, data); + self.hideDialog().focus(); + } + }); + } + } + }); + var canvas = new Canvas({ + canvasId: "canvas-borad", + width: 600, + height: 320 + }); + }; + self.clickToolbar(name, function () { + self.plugin.graftDialog({ + clickFn: function (url) { + self.exec('insertimage', url); + } + }); + }); +}); +/** + * 文件服务器管理 + * @author yangjian + * @since v4.1.12(2017-09-12) + * @site http://git.oschina.net/blackfox/kindeditor + */ +KindEditor.plugin('filemanager', function (K) { + var self = this; + var fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'); + var lang = self.lang('filemanager.'); + if (typeof jQuery == 'undefined') { + K.options.errorMsgHandler(lang.depJQueryError, "error"); + return; + } else { + K.loadScript(K.options.pluginsPath + "filemanager/FManager.js"); + K.loadStyle(K.options.pluginsPath + "multiimage/css/upload.css"); + } + + self.plugin.filemanagerDialog = function (options) { + + var clickFn = options.clickFn; + new FManager({ + list_url: fileManagerJson, //图片列表数据获取url + lang: lang, //语言包 + fileType: options.dirName, + top: self.dialogOffset, + multiple: options.multiple ? true : false, + callback: function (data) { + clickFn.call(this, options.multiple ? data : data[0]); + } + }); + //return dialog; + } + +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('pagebreak', function (K) { + var self = this; + var name = 'pagebreak'; + var pagebreakHtml = K.undef(self.pagebreakHtml, '
    '); + self.clickToolbar(name, function () { + var cmd = self.cmd, range = cmd.range; + self.focus(); + var tail = self.newlineTag == 'br' || K.WEBKIT ? '' : ''; + self.insertHtml(pagebreakHtml + tail); + if (tail !== '') { + var p = K('#__kindeditor_tail_tag__', self.edit.doc); + range.selectNodeContents(p[0]); + p.removeAttr('id'); + cmd.select(); + } + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('plainpaste', function (K) { + var self = this, name = 'plainpaste'; + self.clickToolbar(name, function () { + var lang = self.lang(name + '.'), + html = '
    ' + + '
    ' + lang.comment + '
    ' + + '' + + '
    ', + dialog = self.createDialog({ + name: name, + width: 450, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var html = textarea.val(); + html = K.escape(html); + html = html.replace(/ {2}/g, '  '); + if (self.newlineTag == 'p') { + html = html.replace(/^/, '

    ').replace(/$/, '

    ').replace(/\n/g, '

    '); + } else { + html = html.replace(/\n/g, '
    $&'); + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('preview', function (K) { + var self = this, name = 'preview', undefined; + self.clickToolbar(name, function () { + var lang = self.lang(name + '.'), + width = document.documentElement.clientWidth * 0.9, + height = document.documentElement.clientHeight - 160, + html = '

    ' + + '' + + '
    ', + dialog = self.createDialog({ + name: name, + width: width, + title: self.lang(name), + body: html + }), + iframe = K('iframe', dialog.div), + doc = K.iframeDoc(iframe); + doc.open(); + var cssPath = self.options.cssPath; + var jsPath = self.options.jsPath; + var arr = [ + '', + '', + ''); + if (!K.isArray(cssPath)) { + cssPath = [cssPath]; + } + if (K.inArray(self.options.pluginsPath + 'code/prism.css', cssPath) < 0) { + cssPath.push(self.options.pluginsPath + 'code/prism.css'); + } + K.each(cssPath, function (i, path) { + if (path) { + arr.push(''); + } + }); + if (self.options.cssData) { + arr.push(''); + } + arr.push(''); + arr.push(self.fullHtml()); + if (!K.isArray(jsPath)) { + jsPath = [jsPath]; + } + if (K.inArray(self.options.pluginsPath + 'code/prism.js', jsPath) < 0) { + jsPath.push(self.options.pluginsPath + 'code/prism.js'); + } + K.each(jsPath, function (i, path) { + if (path) { + arr.push(''); + } + }); + arr.push(''); + doc.write(arr.join('\n')); + doc.close(); + K(doc.body).css('background-color', '#FFF'); + iframe[0].contentWindow.focus(); + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('quickformat', function (K) { + var self = this, name = 'quickformat', + blockMap = K.toMap('blockquote,center,div,h1,h2,h3,h4,h5,h6,p'); + + function getFirstChild(knode) { + var child = knode.first(); + while (child && child.first()) { + child = child.first(); + } + return child; + } + + self.clickToolbar(name, function () { + self.focus(); + var doc = self.edit.doc, + range = self.cmd.range, + child = K(doc.body).first(), next, + nodeList = [], subList = [], + bookmark = range.createBookmark(true); + while (child) { + next = child.next(); + var firstChild = getFirstChild(child); + if (!firstChild || firstChild.name != 'img') { + if (blockMap[child.name]) { + child.html(child.html().replace(/^(\s| | )+/ig, '')); + child.css('text-indent', '2em'); + } else { + subList.push(child); + } + if (!next || (blockMap[next.name] || blockMap[child.name] && !blockMap[next.name])) { + if (subList.length > 0) { + nodeList.push(subList); + } + subList = []; + } + } + child = next; + } + K.each(nodeList, function (i, subList) { + var wrapper = K('

    ', doc); + subList[0].before(wrapper); + K.each(subList, function (i, knode) { + wrapper.append(knode); + }); + }); + range.moveToBookmark(bookmark); + self.addBookmark(); + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('table', function (K) { + var self = this, name = 'table', lang = self.lang(name + '.'), zeroborder = 'ke-zeroborder'; + var borderColor = K.undef(self.options.tableBorderColor, '#cccccc'); + + function _setColor(box, color) { + color = color.toUpperCase(); + box.css('background-color', color); + box.css('color', color === '#000000' ? '#FFFFFF' : '#000000'); + box.html(color); + } + + var pickerList = []; + + function _initColorPicker(dialogDiv, colorBox) { + colorBox.bind('click,mousedown', function (e) { + e.stopPropagation(); + }); + + function removePicker() { + K.each(pickerList, function () { + this.remove(); + }); + pickerList = []; + K(document).unbind('click,mousedown', removePicker); + dialogDiv.unbind('click,mousedown', removePicker); + } + + colorBox.click(function (e) { + removePicker(); + var box = K(this), + pos = box.pos(); + var picker = K.colorpicker({ + x: pos.x, + y: pos.y + box.height(), + z: 811214, + selectedColor: K(this).html(), + colors: self.colorTable, + noColor: self.lang('noColor'), + shadowMode: self.shadowMode, + click: function (color) { + _setColor(box, color); + removePicker(); + } + }); + pickerList.push(picker); + K(document).bind('click,mousedown', removePicker); + dialogDiv.bind('click,mousedown', removePicker); + }); + } + + function _getCellIndex(table, row, cell) { + var rowSpanCount = 0; + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i] == cell) { + break; + } + rowSpanCount += row.cells[i].rowSpan - 1; + } + return cell.cellIndex - rowSpanCount; + } + + self.plugin.table = { + prop: function (isInsert) { + var html = [ + '
    ', + '
    ', + '', + '
    ', + lang.rows + '   ', + lang.cols + ' ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + lang.width + '   ', + '   ', + lang.height + '   ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + lang.padding + '   ', + lang.spacing + ' ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + lang.borderWidth + '   ', + lang.borderColor + ' ', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '', + '
    ', + '
    ', + '
    ' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name: name, + width: 500, + title: self.lang(name), + body: html, + beforeRemove: function () { + colorBox.unbind(); + }, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var rows = rowsBox.val(), + cols = colsBox.val(), + width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + align = alignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (rows == 0 || !/^\d+$/.test(rows)) { + K.options.errorMsgHandler(self.lang('invalidRows'), "error"); + rowsBox[0].focus(); + return; + } + if (cols == 0 || !/^\d+$/.test(cols)) { + K.options.errorMsgHandler(self.lang('invalidRows'), "error"); + colsBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + K.options.errorMsgHandler(self.lang('invalidWidth'), "error"); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + K.options.errorMsgHandler(self.lang('invalidHeight'), "error"); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(padding)) { + K.options.errorMsgHandler(self.lang('invalidPadding'), "error"); + paddingBox[0].focus(); + return; + } + if (!/^\d*$/.test(spacing)) { + K.options.errorMsgHandler(self.lang('invalidSpacing'), "error"); + spacingBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + K.options.errorMsgHandler(self.lang('invalidBorder'), "error"); + borderBox[0].focus(); + return; + } + if (table) { + if (width !== '') { + table.width(width + widthType); + } else { + table.css('width', ''); + } + if (table[0].width !== undefined) { + table.removeAttr('width'); + } + if (height !== '') { + table.height(height + heightType); + } else { + table.css('height', ''); + } + if (table[0].height !== undefined) { + table.removeAttr('height'); + } + table.css('background-color', bgColor); + if (table[0].bgColor !== undefined) { + table.removeAttr('bgColor'); + } + if (padding !== '') { + table[0].cellPadding = padding; + } else { + table.removeAttr('cellPadding'); + } + if (spacing !== '') { + table[0].cellSpacing = spacing; + } else { + table.removeAttr('cellSpacing'); + } + if (align !== '') { + table[0].align = align; + } else { + table.removeAttr('align'); + } + if (border !== '') { + table.attr('border', border); + } else { + table.removeAttr('border'); + } + if (border === '' || border === '0') { + table.addClass(zeroborder); + } else { + table.removeClass(zeroborder); + } + if (borderColor !== '') { + table.attr('borderColor', borderColor); + } else { + table.removeAttr('borderColor'); + } + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + return; + } + var style = ''; + if (width !== '') { + style += 'width:' + width + widthType + ';'; + } + if (height !== '') { + style += 'height:' + height + heightType + ';'; + } + if (bgColor !== '') { + style += 'background-color:' + bgColor + ';'; + } + var html = '') + ''; + } + html += ''; + } + html += '
    '; + if (!K.IE) { + html += '
    '; + } + + function getAncestorTag(range) { + var ancestor = K(range.commonAncestor()); + while (ancestor) { + if (ancestor.type == 1 && !ancestor.isStyle()) { + break; + } + ancestor = ancestor.parent(); + } + return ancestor; + } + + var tag = getAncestorTag(self.cmd.range); + if (tag.name == 'p') { + tag.before(K(html)); + tag.remove(); + self.cmd.selection(); + self.insertHtml('
    '); + self.select().hideDialog().focus(); + } else { + self.insertHtml(html); + self.select().hideDialog().focus(); + self.addBookmark(); + } + } + } + }), + div = dialog.div, + rowsBox = K('[name="rows"]', div).val(3), + colsBox = K('[name="cols"]', div).val(2), + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(0), + spacingBox = K('[name="spacing"]', div).val(0), + alignBox = K('[name="align"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(1), ''); + rowsBox[0].focus(); + rowsBox[0].select(); + var table; + if (isInsert) { + return; + } + table = self.plugin.getSelectedTable(); + if (table) { + rowsBox.val(table[0].rows.length); + colsBox.val(table[0].rows.length > 0 ? table[0].rows[0].cells.length : 0); + rowsBox.attr('disabled', true); + colsBox.attr('disabled', true); + var match, + tableWidth = table[0].style.width || table[0].width, + tableHeight = table[0].style.height || table[0].height; + if (tableWidth !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if (tableHeight !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + paddingBox.val(table[0].cellPadding || ''); + spacingBox.val(table[0].cellSpacing || ''); + alignBox.val(table[0].align || ''); + borderBox.val(table[0].border === undefined ? '' : table[0].border); + _setColor(colorBox.eq(0), K.toHex(table.attr('borderColor') || '')); + _setColor(colorBox.eq(1), K.toHex(table[0].style.backgroundColor || table[0].bgColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + } + }, + cellprop: function () { + var html = [ + '
    ', + '
    ', + '', + lang.width + '   ', + '   ', + lang.height + '   ', + '', + '
    ', + '
    ', + '', + lang.textAlign + ' ', + lang.verticalAlign + ' ', + '
    ', + '
    ', + '', + lang.borderWidth + '   ', + lang.borderColor + ' ', + '
    ', + '
    ', + '', + '', + '
    ', + '
    ' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name: name, + width: 500, + title: self.lang('tablecell'), + body: html, + beforeRemove: function () { + colorBox.unbind(); + }, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + textAlign = textAlignBox.val(), + verticalAlign = verticalAlignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (!/^\d*$/.test(width)) { + K.options.errorMsgHandler(self.lang('invalidWidth'), "error"); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + K.options.errorMsgHandler(self.lang('invalidHeight'), "error"); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + K.options.errorMsgHandler(self.lang('invalidBorder'), "error"); + borderBox[0].focus(); + return; + } + cell.css({ + width: width !== '' ? (width + widthType) : '', + height: height !== '' ? (height + heightType) : '', + 'background-color': bgColor, + 'text-align': textAlign, + 'vertical-align': verticalAlign, + 'border-width': border, + 'border-style': border !== '' ? 'solid' : '', + 'border-color': borderColor + }); + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + } + } + }), + div = dialog.div, + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(0), + spacingBox = K('[name="spacing"]', div).val(0), + textAlignBox = K('[name="textAlign"]', div), + verticalAlignBox = K('[name="verticalAlign"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(1), ''); + widthBox[0].focus(); + widthBox[0].select(); + var cell = self.plugin.getSelectedCell(); + var match, + cellWidth = cell[0].style.width || cell[0].width || '', + cellHeight = cell[0].style.height || cell[0].height || ''; + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + textAlignBox.val(cell[0].style.textAlign || ''); + verticalAlignBox.val(cell[0].style.verticalAlign || ''); + var border = cell[0].style.borderWidth || ''; + if (border) { + border = parseInt(border); + } + borderBox.val(border); + _setColor(colorBox.eq(0), K.toHex(cell[0].style.borderColor || '')); + _setColor(colorBox.eq(1), K.toHex(cell[0].style.backgroundColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + }, + insert: function () { + this.prop(true); + }, + 'delete': function () { + var table = self.plugin.getSelectedTable(); + self.cmd.range.setStartBefore(table[0]).collapse(true); + self.cmd.select(); + table.remove(); + self.addBookmark(); + }, + colinsert: function (offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex + offset; + index += table.rows[0].cells.length - row.cells.length; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.insertCell(index); + newCell.innerHTML = K.IE ? '' : '
    '; + index = _getCellIndex(table, newRow, newCell); + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colinsertleft: function () { + this.colinsert(0); + }, + colinsertright: function () { + this.colinsert(1); + }, + rowinsert: function (offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0]; + var rowIndex = row.rowIndex; + if (offset === 1) { + rowIndex = row.rowIndex + (cell.rowSpan - 1) + offset; + } + var newRow = table.insertRow(rowIndex); + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i].rowSpan > 1) { + len -= row.cells[i].rowSpan - 1; + } + var newCell = newRow.insertCell(i); + if (offset === 1 && row.cells[i].colSpan > 1) { + newCell.colSpan = row.cells[i].colSpan; + } + newCell.innerHTML = K.IE ? '' : '
    '; + } + for (var j = rowIndex; j >= 0; j--) { + var cells = table.rows[j].cells; + if (cells.length > i) { + for (var k = cell.cellIndex; k >= 0; k--) { + if (cells[k].rowSpan > 1) { + cells[k].rowSpan += 1; + } + } + break; + } + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowinsertabove: function () { + this.rowinsert(0); + }, + rowinsertbelow: function () { + this.rowinsert(1); + }, + rowmerge: function () { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, + nextRowIndex = rowIndex + cell.rowSpan, + nextRow = table.rows[nextRowIndex]; + if (table.rows.length <= nextRowIndex) { + return; + } + var cellIndex = cell.cellIndex; + if (nextRow.cells.length <= cellIndex) { + return; + } + var nextCell = nextRow.cells[cellIndex]; + if (cell.colSpan !== nextCell.colSpan) { + return; + } + cell.rowSpan += nextCell.rowSpan; + nextRow.deleteCell(cellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colmerge: function () { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, + cellIndex = cell.cellIndex, + nextCellIndex = cellIndex + 1; + if (row.cells.length <= nextCellIndex) { + return; + } + var nextCell = row.cells[nextCellIndex]; + if (cell.rowSpan !== nextCell.rowSpan) { + return; + } + cell.colSpan += nextCell.colSpan; + row.deleteCell(nextCellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowsplit: function () { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + if (cell.rowSpan === 1) { + return; + } + var cellIndex = _getCellIndex(table, row, cell); + for (var i = 1, len = cell.rowSpan; i < len; i++) { + var newRow = table.rows[rowIndex + i], + newCell = newRow.insertCell(cellIndex); + if (cell.colSpan > 1) { + newCell.colSpan = cell.colSpan; + } + newCell.innerHTML = K.IE ? '' : '
    '; + cellIndex = _getCellIndex(table, newRow, newCell); + } + K(cell).removeAttr('rowSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colsplit: function () { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + cellIndex = cell.cellIndex; + if (cell.colSpan === 1) { + return; + } + for (var i = 1, len = cell.colSpan; i < len; i++) { + var newCell = row.insertCell(cellIndex + i); + if (cell.rowSpan > 1) { + newCell.rowSpan = cell.rowSpan; + } + newCell.innerHTML = K.IE ? '' : '
    '; + } + K(cell).removeAttr('colSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + coldelete: function () { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.cells[index]; + if (newCell.colSpan > 1) { + newCell.colSpan -= 1; + if (newCell.colSpan === 1) { + K(newCell).removeAttr('colSpan'); + } + } else { + newRow.deleteCell(index); + } + if (newCell.rowSpan > 1) { + i += newCell.rowSpan - 1; + } + } + if (row.cells.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + }, + rowdelete: function () { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + for (var i = cell.rowSpan - 1; i >= 0; i--) { + table.deleteRow(rowIndex + i); + } + if (table.rows.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.table.prop); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('template', function (K) { + var self = this, name = 'template', lang = self.lang(name + '.'), + htmlPath = self.pluginsPath + name + '/html/'; + + function getFilePath(fileName) { + return htmlPath + fileName + '?ver=' + encodeURIComponent(K.DEBUG ? K.TIME : K.VERSION); + } + + self.clickToolbar(name, function () { + var lang = self.lang(name + '.'), + arr = ['
    ', + '
    ', + '
    ', + lang.selectTemplate + ' ', + ' ', + '
    ', + '
    ', + '', + '
    '].join(''); + var dialog = self.createDialog({ + name: name, + width: 500, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var doc = K.iframeDoc(iframe); + self[checkbox[0].checked ? 'html' : 'insertHtml'](doc.body.innerHTML).hideDialog().focus(); + } + } + }); + var selectBox = K('select', dialog.div), + checkbox = K('[name="replaceFlag"]', dialog.div), + iframe = K('iframe', dialog.div); + checkbox[0].checked = true; + iframe.attr('src', getFilePath(selectBox.val())); + selectBox.change(function () { + iframe.attr('src', getFilePath(this.value)); + }); + }); +}); + +/******************************************************************************* + * KindEditor - WYSIWYG HTML Editor for Internet + * Copyright (C) 2006-2011 kindsoft.net + * + * @author Roddy + * @site http://www.kindsoft.net/ + * @licence http://www.kindsoft.net/license.php + *******************************************************************************/ +KindEditor.plugin('wordpaste', function (K) { + var self = this, name = 'wordpaste'; + self.clickToolbar(name, function () { + var lang = self.lang(name + '.'), + html = '
    ' + + '
    ' + lang.comment + '
    ' + + '' + + '
    ', + dialog = self.createDialog({ + name: name, + width: 450, + title: self.lang(name), + body: html, + yesBtn: { + name: self.lang('yes'), + click: function (e) { + var str = doc.body.innerHTML; + str = K.clearMsWord(str, self.filterMode ? self.htmlTags : K.options.htmlTags); + self.insertHtml(str).hideDialog().focus(); + } + } + }), + div = dialog.div, + iframe = K('iframe', div), + doc = K.iframeDoc(iframe); + if (!K.IE) { + doc.designMode = 'on'; + } + doc.open(); + doc.write('WordPaste'); + doc.write(''); + if (!K.IE) { + doc.write('
    '); + } + doc.write(''); + doc.close(); + if (K.IE) { + doc.body.contentEditable = 'true'; + } + iframe[0].contentWindow.focus(); + }); +}); + + +KindEditor.plugin('fixtoolbar', function (K) { + var self = this; + if (!self.fixToolBar) { + return; + } + + function init() { + var toolbar = K('.ke-toolbar'); + var originY = toolbar.pos().y; + K(window).bind('scroll', function () { + if (toolbar.css('position') == 'fixed') { + if (document.body.scrollTop - originY < 0) { + toolbar.css('position', 'static'); + toolbar.css('top', 'auto'); + } + } else { + if (toolbar.pos().y - document.body.scrollTop < 0) { + toolbar.css('position', 'fixed'); + toolbar.css('top', 0); + } + } + }); + } + + if (self.isCreated) { + init(); + } else { + self.afterCreate(init); + } +}); diff --git a/addons/nkeditor/assets/nkeditor.min.js b/addons/nkeditor/assets/nkeditor.min.js new file mode 100644 index 0000000000000000000000000000000000000000..5f174951995d14a0e2c673ec852ad2515be6751e --- /dev/null +++ b/addons/nkeditor/assets/nkeditor.min.js @@ -0,0 +1 @@ +(function(window,undefined){if(window.KindEditor){return}if(!window.console){window.console={}}if(!console.log){console.log=function(){}}var _VERSION="5.0.3 (2018-10-25)",_ua=navigator.userAgent.toLowerCase(),_IE=_ua.indexOf("msie")>-1&&_ua.indexOf("opera")==-1,_NEWIE=_ua.indexOf("msie")==-1&&_ua.indexOf("trident")>-1,_GECKO=_ua.indexOf("gecko")>-1&&_ua.indexOf("khtml")==-1,_WEBKIT=_ua.indexOf("applewebkit")>-1,_OPERA=_ua.indexOf("opera")>-1,_MOBILE=_ua.indexOf("mobile")>-1,_IOS=/ipad|iphone|ipod/.test(_ua),_QUIRKS=document.compatMode!="CSS1Compat",_IERANGE=!window.getSelection,_matches=/(?:msie|firefox|webkit|opera)[\/:\s](\d+)/.exec(_ua),_V=_matches?_matches[1]:"0",_TIME=(new Date).getTime();function _isArray(val){if(!val){return false}return Object.prototype.toString.call(val)==="[object Array]"}function _isFunction(val){if(!val){return false}return Object.prototype.toString.call(val)==="[object Function]"}function _inArray(val,arr){for(var i=0,len=arr.length;i=0}function _addUnit(val,unit){unit=unit||"px";return val&&/^-?\d+(?:\.\d+)?$/.test(val)?val+unit:val}function _removeUnit(val){var match;return val&&(match=/(\d+)/.exec(val))?parseInt(match[1],10):0}function _escape(val){return val.replace(/&/g,"&").replace(//g,">").replace(/"/g,""")}function _unescape(val){return val.replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/&/g,"&")}function _toCamel(str){var arr=str.split("-");str="";_each(arr,function(key,val){str+=key>0?val.charAt(0).toUpperCase()+val.substr(1):val});return str}function _toHex(val){function hex(d){var s=parseInt(d,10).toString(16).toUpperCase();return s.length>1?s:"0"+s}return val.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/gi,function($0,$1,$2,$3){return"#"+hex($1)+hex($2)+hex($3)})}function _toMap(val,delimiter){delimiter=delimiter===undefined?",":delimiter;var map={},arr=_isArray(val)?val:val.split(delimiter),match;_each(arr,function(key,val){if(match=/^(\d+)\.\.(\d+)$/.exec(val)){for(var i=parseInt(match[1],10);i<=parseInt(match[2],10);i++){map[i.toString()]=true}}else{map[val]=true}});return map}function _toArray(obj,offset){return Array.prototype.slice.call(obj,offset||0)}function _undef(val,defaultVal){return val===undefined?defaultVal:val}function _invalidUrl(url){return!url||/[<>"]/.test(url)}function _addParam(url,param){return url.indexOf("?")>=0?url+"&"+param:url+"?"+param}function _extend(child,parent,proto){if(!proto){proto=parent;parent=null}var childProto;if(parent){var fn=function(){};fn.prototype=parent.prototype;childProto=new fn;_each(proto,function(key,val){childProto[key]=val})}else{childProto=proto}childProto.constructor=child;child.prototype=childProto;child.parent=parent?parent.prototype:null}function _json(text){var match;if(match=/\{[\s\S]*\}|\[[\s\S]*\]/.exec(text)){text=match[0]}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){return eval("("+text+")")}throw"JSON parse error"}function _merge(distObj,obj){for(var name in distObj){obj[name]=distObj[name]}return obj}var _round=Math.round;var K={DEBUG:false,VERSION:_VERSION,IE:_IE,GECKO:_GECKO,WEBKIT:_WEBKIT,OPERA:_OPERA,V:_V,TIME:_TIME,each:_each,isArray:_isArray,isFunction:_isFunction,inArray:_inArray,inString:_inString,trim:_trim,addUnit:_addUnit,removeUnit:_removeUnit,escape:_escape,unescape:_unescape,toCamel:_toCamel,toHex:_toHex,toMap:_toMap,toArray:_toArray,undef:_undef,invalidUrl:_invalidUrl,addParam:_addParam,extend:_extend,merge:_merge,json:_json};var _INLINE_TAG_MAP=_toMap("a,abbr,acronym,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,img,input,ins,kbd,label,map,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"),_BLOCK_TAG_MAP=_toMap("address,applet,blockquote,body,center,dd,dir,div,dl,dt,fieldset,form,frameset,h1,h2,h3,h4,h5,h6,head,hr,html,iframe,ins,isindex,li,map,menu,meta,noframes,noscript,object,ol,p,pre,script,style,table,tbody,td,tfoot,th,thead,title,tr,ul"),_SINGLE_TAG_MAP=_toMap("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed"),_STYLE_TAG_MAP=_toMap("b,basefont,big,del,em,font,i,s,small,span,strike,strong,sub,sup,u"),_CONTROL_TAG_MAP=_toMap("img,table,input,textarea,button"),_PRE_TAG_MAP=_toMap("pre,style,script"),_NOSPLIT_TAG_MAP=_toMap("html,head,body,td,tr,table,ol,ul,li"),_AUTOCLOSE_TAG_MAP=_toMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr"),_FILL_ATTR_MAP=_toMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"),_VALUE_TAG_MAP=_toMap("input,button,textarea,select");function _getBasePath(){var els=document.getElementsByTagName("script"),src;for(var i=0,len=els.length;i
    ',afterBlur:function(){this.sync()},errorMsgHandler:function(message,type){console.log(message);console.log(type);alert(message)},dialogOffset:0,allowUploadGraft:true,resLoadCache:{},tableBorderColor:"#cccccc"};var _useCapture=false;var _INPUT_KEY_MAP=_toMap("8,9,13,32,46,48..57,59,61,65..90,106,109..111,188,190..192,219..222");var _CURSORMOVE_KEY_MAP=_toMap("33..40");var _CHANGE_KEY_MAP={};_each(_INPUT_KEY_MAP,function(key,val){_CHANGE_KEY_MAP[key]=val});_each(_CURSORMOVE_KEY_MAP,function(key,val){_CHANGE_KEY_MAP[key]=val});function _bindEvent(el,type,fn){if(el.addEventListener){el.addEventListener(type,fn,_useCapture)}else if(el.attachEvent){el.attachEvent("on"+type,fn)}}function _unbindEvent(el,type,fn){if(el.removeEventListener){el.removeEventListener(type,fn,_useCapture)}else if(el.detachEvent){el.detachEvent("on"+type,fn)}}var _EVENT_PROPS=("altKey,attrChange,attrName,bubbles,button,cancelable,charCode,clientX,clientY,ctrlKey,currentTarget,"+"data,detail,eventPhase,fromElement,handler,keyCode,metaKey,newValue,offsetX,offsetY,originalTarget,pageX,"+"pageY,prevValue,relatedNode,relatedTarget,screenX,screenY,shiftKey,srcElement,target,toElement,view,wheelDelta,which").split(",");function KEvent(el,event){this.init(el,event)}_extend(KEvent,{init:function(el,event){var self=this,doc=el.ownerDocument||el.document||el;self.event=event;_each(_EVENT_PROPS,function(key,val){self[val]=event[val]});if(!self.target){self.target=self.srcElement||doc}if(self.target.nodeType===3){self.target=self.target.parentNode}if(!self.relatedTarget&&self.fromElement){self.relatedTarget=self.fromElement===self.target?self.toElement:self.fromElement}if(self.pageX==null&&self.clientX!=null){var d=doc.documentElement,body=doc.body;self.pageX=self.clientX+(d&&d.scrollLeft||body&&body.scrollLeft||0)-(d&&d.clientLeft||body&&body.clientLeft||0);self.pageY=self.clientY+(d&&d.scrollTop||body&&body.scrollTop||0)-(d&&d.clientTop||body&&body.clientTop||0)}if(!self.which&&(self.charCode||self.charCode===0?self.charCode:self.keyCode)){self.which=self.charCode||self.keyCode}if(!self.metaKey&&self.ctrlKey){self.metaKey=self.ctrlKey}if(!self.which&&self.button!==undefined){self.which=self.button&1?1:self.button&2?3:self.button&4?2:0}switch(self.which){case 186:self.which=59;break;case 187:case 107:case 43:self.which=61;break;case 189:case 45:self.which=109;break;case 42:self.which=106;break;case 47:self.which=111;break;case 78:self.which=110;break}if(self.which>=96&&self.which<=105){self.which-=48}},preventDefault:function(){var ev=this.event;if(ev.preventDefault){ev.preventDefault()}else{ev.returnValue=false}},stopPropagation:function(){var ev=this.event;if(ev.stopPropagation){ev.stopPropagation()}else{ev.cancelBubble=true}},stop:function(){this.preventDefault();this.stopPropagation()}});var _eventExpendo="kindeditor_"+_TIME,_eventId=0,_eventData={};function _getId(el){return el[_eventExpendo]||null}function _setId(el){el[_eventExpendo]=++_eventId;return _eventId}function _removeId(el){try{delete el[_eventExpendo]}catch(e){if(el.removeAttribute){el.removeAttribute(_eventExpendo)}}}function _bind(el,type,fn){if(type.indexOf(",")>=0){_each(type.split(","),function(){_bind(el,this,fn)});return}var id=_getId(el);if(!id){id=_setId(el)}if(_eventData[id]===undefined){_eventData[id]={}}var events=_eventData[id][type];if(events&&events.length>0){_unbindEvent(el,type,events[0])}else{_eventData[id][type]=[];_eventData[id].el=el}events=_eventData[id][type];if(events.length===0){events[0]=function(e){var kevent=e?new KEvent(el,e):undefined;_each(events,function(i,event){if(i>0&&event){event.call(el,kevent)}})}}if(_inArray(fn,events)<0){events.push(fn)}_bindEvent(el,type,events[0])}function _unbind(el,type,fn){if(type&&type.indexOf(",")>=0){_each(type.split(","),function(){_unbind(el,this,fn)});return}var id=_getId(el);if(!id){return}if(type===undefined){if(id in _eventData){_each(_eventData[id],function(key,events){if(key!="el"&&events.length>0){_unbindEvent(el,key,events[0])}});delete _eventData[id];_removeId(el)}return}if(!_eventData[id]){return}var events=_eventData[id][type];if(events&&events.length>0){if(fn===undefined){_unbindEvent(el,type,events[0]);delete _eventData[id][type]}else{_each(events,function(i,event){if(i>0&&event===fn){events.splice(i,1)}});if(events.length==1){_unbindEvent(el,type,events[0]);delete _eventData[id][type]}}var count=0;_each(_eventData[id],function(){count++});if(count<2){delete _eventData[id];_removeId(el)}}}function _fire(el,type){if(type.indexOf(",")>=0){_each(type.split(","),function(){_fire(el,this)});return}var id=_getId(el);if(!id){return}var events=_eventData[id][type];if(_eventData[id]&&events&&events.length>0){events[0]()}}function _ctrl(el,key,fn){var self=this;key=/^\d{2,}$/.test(key)?key:key.toUpperCase().charCodeAt(0);_bind(el,"keydown",function(e){if(e.ctrlKey&&e.which==key&&!e.shiftKey&&!e.altKey){fn.call(el);e.stop()}})}var _readyFinished=false;function _ready(fn){if(_readyFinished){fn(KindEditor);return}var loaded=false;function readyFunc(){if(!loaded){loaded=true;fn(KindEditor);_readyFinished=true}}function ieReadyFunc(){if(!loaded){try{document.documentElement.doScroll("left")}catch(e){setTimeout(ieReadyFunc,100);return}readyFunc()}}function ieReadyStateFunc(){if(document.readyState==="complete"){readyFunc()}}if(document.addEventListener){_bind(document,"DOMContentLoaded",readyFunc)}else if(document.attachEvent){_bind(document,"readystatechange",ieReadyStateFunc);var toplevel=false;try{toplevel=window.frameElement==null}catch(e){}if(document.documentElement.doScroll&&toplevel){ieReadyFunc()}}_bind(window,"load",readyFunc)}if(window.attachEvent){window.attachEvent("onunload",function(){_each(_eventData,function(key,events){if(events.el){_unbind(events.el)}})})}K.ctrl=_ctrl;K.ready=_ready;function _getCssList(css){css=css.replace(/"/g,'"');var list={},reg=/\s*([\w\-]+)\s*:([^;]*)(;|$)/g,match;while(match=reg.exec(css)){var key=_trim(match[1].toLowerCase()),val=_trim(_toHex(match[2]));list[key]=val}return list}function _getAttrList(tag){var list={},reg=/\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g,match;while(match=reg.exec(tag)){var key=(match[1]||match[2]||match[4]||match[6]).toLowerCase(),val=(match[2]?match[3]:match[4]?match[5]:match[7])||"";list[key]=val}return list}function _addClassToTag(tag,className){if(/\s+class\s*=/.test(tag)){tag=tag.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/,function($0,$1,$2,$3){if((" "+$2+" ").indexOf(" "+className+" ")<0){return $2===""?$1+className+$3:$1+$2+" "+className+$3}else{return $0}})}else{tag=tag.substr(0,tag.length-1)+' class="'+className+'">'}return tag}function _formatCss(css){var str="";_each(_getCssList(css),function(key,val){str+=key+":"+val+";"});return str}function _formatUrl(url,mode,host,pathname){mode=_undef(mode,"").toLowerCase();if(url.substr(0,5)!="data:"){url=url.replace(/([^:])\/\//g,"$1/")}if(_inArray(mode,["absolute","relative","domain"])<0){return url}host=host||location.protocol+"//"+location.host;if(pathname===undefined){var m=location.pathname.match(/^(\/.*)\//);pathname=m?m[1]:""}var match;if(match=/^(\w+:\/\/[^\/]*)/.exec(url)){if(match[1]!==host){return url}}else if(/^\w+:/.test(url)){return url}function getRealPath(path){var parts=path.split("/"),paths=[];for(var i=0,len=parts.length;i0){paths.pop()}}else if(part!==""&&part!="."){paths.push(part)}}return"/"+paths.join("/")}if(/^\//.test(url)){url=host+getRealPath(url.substr(1))}else if(!/^\w+:\/\//.test(url)){url=host+getRealPath(pathname+"/"+url)}function getRelativePath(path,depth){if(url.substr(0,path.length)===path){var arr=[];for(var i=0;i0){prefix+="/"+arr.join("/")}if(pathname=="/"){prefix+="/"}return prefix+url.substr(path.length)}else{if(match=/^(.*)\//.exec(path)){return getRelativePath(match[1],++depth)}}}if(mode==="relative"){url=getRelativePath(host+pathname,0).substr(2)}else if(mode==="absolute"){if(url.substr(0,host.length)===host){url=url.substr(host.length)}}return url}function _formatHtml(html,htmlTags,urlType,wellFormatted,indentChar){if(html==null){html=""}urlType=urlType||"";wellFormatted=_undef(wellFormatted,false);indentChar=_undef(indentChar,"\t");var fontSizeList="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");html=html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/gi,function($0,$1,$2,$3){return $1+$2.replace(/<(?:br|br\s[^>]*)>/gi,"\n")+$3});html=html.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/gi,"

    ");html=html.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/gi,"$1
    $2");html=html.replace(/\u200B/g,"");html=html.replace(/\u00A9/g,"©");html=html.replace(/\u00AE/g,"®");html=html.replace(/\u2003/g," ");html=html.replace(/\u3000/g," ");html=html.replace(/<[^>]+/g,function($0){return $0.replace(/\s+/g," ")});var htmlTagMap={};if(htmlTags){_each(htmlTags,function(key,val){var arr=key.split(",");for(var i=0,len=arr.length;i]*)>)([\s\S]*?)(<\/script>)/gi,"")}if(!htmlTagMap.style){html=html.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/gi,"")}}var re=/(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>(\s*)/g;var tagStack=[];html=html.replace(re,function($0,$1,$2,$3,$4,$5,$6){var full=$0,startNewline=$1||"",startSlash=$2||"",tagName=$3.toLowerCase(),attr=$4||"",endSlash=$5?" "+$5:"",endNewline=$6||"";if(tagName=="code"){return full}if(htmlTags&&!htmlTagMap[tagName]){return""}if(endSlash===""&&_SINGLE_TAG_MAP[tagName]){endSlash=" /"}if(_INLINE_TAG_MAP[tagName]){if(startNewline){startNewline=" "}if(endNewline){endNewline=" "}}if(_PRE_TAG_MAP[tagName]){if(startSlash){endNewline="\n"}else{startNewline="\n"}}if(wellFormatted&&tagName=="br"){endNewline="\n"}if(_BLOCK_TAG_MAP[tagName]&&!_PRE_TAG_MAP[tagName]){if(wellFormatted){if(startSlash&&tagStack.length>0&&tagStack[tagStack.length-1]===tagName){tagStack.pop()}else{tagStack.push(tagName)}startNewline="\n";endNewline="\n";for(var i=0,len=startSlash?tagStack.length:tagStack.length-1;i=0){attrMap[key]=_formatUrl(val,urlType)}if(htmlTags&&key!=="style"&&!htmlTagMap[tagName]["*"]&&!htmlTagMap[tagName][key]||tagName==="body"&&key==="contenteditable"||/^kindeditor_\d+$/.test(key)){delete attrMap[key]}if(key==="style"&&val!==""){var styleMap=_getCssList(val);_each(styleMap,function(k,v){if(htmlTags&&!htmlTagMap[tagName].style&&!htmlTagMap[tagName]["."+k]){delete styleMap[k]}});var style="";_each(styleMap,function(k,v){style+=k+":"+v+";"});attrMap.style=style}});attr="";_each(attrMap,function(key,val){if(key==="style"&&val===""){return}val=val.replace(/"/g,""");attr+=" "+key+'="'+val+'"'})}if(tagName==="font"){tagName="span"}return startNewline+"<"+startSlash+tagName+attr+endSlash+">"+endNewline});html=html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/gi,function($0,$1,$2,$3){return $1+$2.replace(/\n/g,'\n')+$3});html=html.replace(/\n\s*\n/g,"\n");html=html.replace(/\n/g,"\n");return _trim(html)}function _clearMsWord(html,htmlTags){html=html.replace(//gi,"").replace(//gi,"").replace(/]*>[\s\S]*?<\/style>/gi,"").replace(/]*>[\s\S]*?<\/script>/gi,"").replace(/]+>[\s\S]*?<\/w:[^>]+>/gi,"").replace(/]+>[\s\S]*?<\/o:[^>]+>/gi,"").replace(/[\s\S]*?<\/xml>/gi,"").replace(/<(?:table|td)[^>]*>/gi,function(full){return full.replace(/border-bottom:([#\w\s]+)/gi,"border:$1")});return _formatHtml(html,htmlTags)}function _mediaType(src){if(/\.(rm|rmvb)(\?|$)/i.test(src)){return"audio/x-pn-realaudio-plugin"}if(/\.(mp4)(\?|$)/i.test(src)){return"video/mpeg4"}if(/\.(swf|flv)(\?|$)/i.test(src)){return"application/x-shockwave-flash"}return"video/x-ms-asf-plugin"}function _mediaClass(type){if(/realaudio/i.test(type)){return"ke-rm"}if(/flash/i.test(type)){return"ke-flash"}return"ke-media"}function _mediaAttrs(srcTag){return _getAttrList(unescape(srcTag))}function _mediaEmbed(attrs){var type=attrs.type=="video/mpeg4"?"video":"embed";if(type=="video"){attrs.controls="controls"}var html="<"+type+" ";_each(attrs,function(key,val){html+=key+'="'+val+'" '});html+="/>";return html}function _mediaImg(blankPath,attrs){var width=attrs.width,height=attrs.height,type=attrs.type||_mediaType(attrs.src),srcTag=_mediaEmbed(attrs),style="";if(/\D/.test(width)){style+="width:"+width+";"}else if(width>0){style+="width:"+width+"px;"}if(/\D/.test(height)){style+="height:"+height+";"}else if(height>0){style+="height:"+height+"px;"}var html='';return html}function _tmpl(str,data){var fn=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};"+"with(obj){p.push('"+str.replace(/[\r\t\n]/g," ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return data?fn(data):fn}K.formatUrl=_formatUrl;K.formatHtml=_formatHtml;K.getCssList=_getCssList;K.getAttrList=_getAttrList;K.mediaType=_mediaType;K.mediaAttrs=_mediaAttrs;K.mediaEmbed=_mediaEmbed;K.mediaImg=_mediaImg;K.clearMsWord=_clearMsWord;K.tmpl=_tmpl;function _contains(nodeA,nodeB){if(nodeA.nodeType==9&&nodeB.nodeType!=9){return true}while(nodeB=nodeB.parentNode){if(nodeB==nodeA){return true}}return false}var _getSetAttrDiv=document.createElement("div");_getSetAttrDiv.setAttribute("className","t");var _GET_SET_ATTRIBUTE=_getSetAttrDiv.className!=="t";function _getAttr(el,key){key=key.toLowerCase();var val=null;if(!_GET_SET_ATTRIBUTE&&el.nodeName.toLowerCase()!="script"){var div=el.ownerDocument.createElement("div");div.appendChild(el.cloneNode(false));var list=_getAttrList(_unescape(div.innerHTML));if(key in list){val=list[key]}}else{try{val=el.getAttribute(key,2)}catch(e){val=el.getAttribute(key,1)}}if(key==="style"&&val!==null){val=_formatCss(val)}return val}function _queryAll(expr,root){var exprList=expr.split(",");if(exprList.length>1){var mergedResults=[];_each(exprList,function(){_each(_queryAll(this,root),function(){if(_inArray(this,mergedResults)<0){mergedResults.push(this)}})});return mergedResults}root=root||document;function escape(str){if(typeof str!="string"){return str}return str.replace(/([^\w\-])/g,"\\$1")}function stripslashes(str){return str.replace(/\\/g,"")}function cmpTag(tagA,tagB){return tagA==="*"||tagA.toLowerCase()===escape(tagB.toLowerCase())}function byId(id,tag,root){var arr=[],doc=root.ownerDocument||root,el=doc.getElementById(stripslashes(id));if(el){if(cmpTag(tag,el.nodeName)&&_contains(root,el)){arr.push(el)}}return arr}function byClass(className,tag,root){var doc=root.ownerDocument||root,arr=[],els,i,len,el;if(root.getElementsByClassName){els=root.getElementsByClassName(stripslashes(className));for(i=0,len=els.length;i-1){arr.push(el)}}}}return arr}function byName(name,tag,root){var arr=[],doc=root.ownerDocument||root,els=doc.getElementsByName(stripslashes(name)),el;for(var i=0,len=els.length;i])+)/.exec(expr);var tag=matches?matches[1]:"*";if(matches=/#((?:[\w\-]|\\.)+)$/.exec(expr)){arr=byId(matches[1],tag,root)}else if(matches=/\.((?:[\w\-]|\\.)+)$/.exec(expr)){arr=byClass(matches[1],tag,root)}else if(matches=/\[((?:[\w\-]|\\.)+)\]/.exec(expr)){arr=byAttr(matches[1].toLowerCase(),null,tag,root)}else if(matches=/\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(expr)){var key=matches[1].toLowerCase(),val=matches[2];if(key==="id"){arr=byId(val,tag,root)}else if(key==="class"){arr=byClass(val,tag,root)}else if(key==="name"){arr=byName(val,tag,root)}else{arr=byAttr(key,val,tag,root)}}else{var els=root.getElementsByTagName(tag),el;for(var i=0,len=els.length;i])+|[\s>])/g;while(arr=re.exec(expr)){if(arr[1]!==" "){parts.push(arr[1])}}var results=[];if(parts.length==1){return select(parts[0],root)}var isChild=false,part,els,subResults,val,v,i,j,k,length,len,l;for(i=0,lenth=parts.length;i"){isChild=true;continue}if(i>0){els=[];for(j=0,len=results.length;j0?arr[0]:null}K.query=_query;K.queryAll=_queryAll;function _get(val){return K(val)[0]}function _getDoc(node){if(!node){return document}return node.ownerDocument||node.document||node}function _getWin(node){if(!node){return window}var doc=_getDoc(node);return doc.parentWindow||doc.defaultView}function _setHtml(el,html){if(el.nodeType!=1){return}var doc=_getDoc(el);try{el.innerHTML=''+html;var temp=doc.getElementById("__kindeditor_temp_tag__");temp.parentNode.removeChild(temp)}catch(e){K(el).empty();K("@"+html,doc).each(function(){el.appendChild(this)})}}function _hasClass(el,cls){return _inString(cls,el.className," ")}function _setAttr(el,key,val){if(_IE&&_V<8&&key.toLowerCase()=="class"){key="className"}el.setAttribute(key,""+val)}function _removeAttr(el,key){if(_IE&&_V<8&&key.toLowerCase()=="class"){key="className"}_setAttr(el,key,"");el.removeAttribute(key)}function _getNodeName(node){if(!node||!node.nodeName){return""}return node.nodeName.toLowerCase()}function _computedCss(el,key){var self=this,win=_getWin(el),camelKey=_toCamel(key),val="";if(win.getComputedStyle){var style=win.getComputedStyle(el,null);val=style[camelKey]||style.getPropertyValue(key)||el.style[camelKey]}else if(el.currentStyle){val=el.currentStyle[camelKey]||el.style[camelKey]}return val}function _hasVal(node){return!!_VALUE_TAG_MAP[_getNodeName(node)]}function _docElement(doc){doc=doc||document;return _QUIRKS?doc.body:doc.documentElement}function _docHeight(doc){var el=_docElement(doc);return Math.max(el.scrollHeight,el.clientHeight)}function _docWidth(doc){var el=_docElement(doc);return Math.max(el.scrollWidth,el.clientWidth)}function _getScrollPos(doc){doc=doc||document;var x,y;if(_IE||_NEWIE||_OPERA){x=_docElement(doc).scrollLeft;y=_docElement(doc).scrollTop}else{x=_getWin(doc).scrollX;y=_getWin(doc).scrollY}return{x:x,y:y}}function KNode(node){this.init(node)}_extend(KNode,{init:function(node){var self=this;node=_isArray(node)?node:[node];var length=0;for(var i=0,len=node.length;i0?self[0].nodeType:null;self.win=_getWin(self[0])},each:function(fn){var self=this;for(var i=0;i0?list.eq(0):null},last:function(){var list=this.children();return list.length>0?list.eq(list.length-1):null},index:function(){if(this.length<1){return-1}var i=-1,sibling=this[0];while(sibling){i++;sibling=sibling.previousSibling}return i},prev:function(){if(this.length<1){return null}var node=this[0].previousSibling;return node?new KNode(node):null},next:function(){if(this.length<1){return null}var node=this[0].nextSibling;return node?new KNode(node):null},scan:function(fn,order){if(this.length<1){return}order=order===undefined?true:order;function walk(node){var n=order?node.firstChild:node.lastChild;while(n){var next=order?n.nextSibling:n.previousSibling;if(fn(n)===false){return false}if(walk(n)===false){return false}n=next}}walk(this[0]);return this}});_each(("blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,"+"change,select,submit,keydown,keypress,keyup,error,contextmenu").split(","),function(i,type){KNode.prototype[type]=function(fn){return fn?this.bind(type,fn):this.fire(type)}});var _K=K;K=function(expr,root){if(expr===undefined||expr===null){return}function newNode(node){if(!node[0]){node=[]}return new KNode(node)}if(typeof expr==="string"){if(root){root=_get(root)}var length=expr.length;if(expr.charAt(0)==="@"){expr=expr.substr(1)}if(expr.length!==length||/<.+>/.test(expr)){var doc=root?root.ownerDocument||root:document,div=doc.createElement("div"),list=[];div.innerHTML=''+expr;for(var i=0,len=div.childNodes.length;i0){centerNode=cloneNode.splitText(startOffset)}else{centerNode=cloneNode}if(endOffset0){center=node.splitText(startOffset);range.setStart(node,startOffset)}if(endOffset=0&&incStart<=0){incStart=testRange.compareBoundaryPoints(_START_TO_START,range)}if(incStart>=0&&incEnd<=0){incEnd=testRange.compareBoundaryPoints(_END_TO_END,range)}if(incEnd>=0&&end<=0){end=testRange.compareBoundaryPoints(_END_TO_START,range)}if(end>=0){return false}nextNode=node.nextSibling;if(start>0){if(node.nodeType==1){if(incStart>=0&&incEnd<=0){if(isCopy){frag.appendChild(node.cloneNode(true))}if(isDelete){nodeList.push(node)}}else{var childFlag;if(isCopy){childFlag=node.cloneNode(false);frag.appendChild(childFlag)}if(extractNodes(node,childFlag)===false){return false}}}else if(node.nodeType==3){var textNode;if(node==copyRange.startContainer){textNode=splitTextNode(node,copyRange.startOffset,node.nodeValue.length)}else if(node==copyRange.endContainer){textNode=splitTextNode(node,0,copyRange.endOffset)}else{textNode=splitTextNode(node,0,node.nodeValue.length)}if(isCopy){try{frag.appendChild(textNode)}catch(e){}}}}node=nextNode}}extractNodes(ancestor,frag);if(isDelete){range.up().collapse(true)}for(var i=0,len=nodeList.length;i0){startPos+=nodeRange.text.replace(/\r\n|\n|\r/g,"").length}else{startPos=0}if(dummy){K(dummy).remove()}}else if(node.nodeType==3){testRange.moveStart("character",node.nodeValue.length);startPos+=node.nodeValue.length}if(cmp<0){startNode=node}}if(cmp<0&&startNode.nodeType==1){return{node:parent,offset:K(parent.lastChild).index()+1}}if(cmp>0){while(startNode.nextSibling&&startNode.nodeType==1){startNode=startNode.nextSibling}}testRange=rng.duplicate();_moveToElementText(testRange,parent);testRange.setEndPoint("StartToEnd",pointRange);startPos-=testRange.text.replace(/\r\n|\n|\r/g,"").length;if(cmp>0&&startNode.nodeType==3){var prevNode=startNode.previousSibling;while(prevNode&&prevNode.nodeType==3){startPos-=prevNode.nodeValue.length;prevNode=prevNode.previousSibling}}return{node:startNode,offset:startPos}}function _getEndRange(node,offset){var doc=node.ownerDocument||node,range=doc.body.createTextRange();if(doc==node){range.collapse(true);return range}if(node.nodeType==1&&node.childNodes.length>0){var children=node.childNodes,isStart,child;if(offset===0){child=children[0];isStart=true}else{child=children[offset-1];isStart=false}if(!child){return range}if(K(child).name==="head"){if(offset===1){isStart=true}if(offset===2){isStart=false}range.collapse(isStart);return range}if(child.nodeType==1){var kchild=K(child),span;if(kchild.isControl()){span=doc.createElement("span");if(isStart){kchild.before(span)}else{kchild.after(span)}child=span}_moveToElementText(range,child);range.collapse(isStart);if(span){K(span).remove()}return range}node=child;offset=isStart?0:child.nodeValue.length}var dummy=doc.createElement("span");K(node).before(dummy);_moveToElementText(range,dummy);range.moveStart("character",offset);K(dummy).remove();return range}function _toRange(rng){var doc,range;function tr2td(start){if(K(start.node).name=="tr"){start.node=start.node.cells[start.offset];start.offset=0}}if(_IERANGE){if(rng.item){doc=_getDoc(rng.item(0));range=new KRange(doc);range.selectNode(rng.item(0));return range}doc=rng.parentElement().ownerDocument;var start=_getStartEnd(rng,true),end=_getStartEnd(rng,false);tr2td(start);tr2td(end);range=new KRange(doc);range.setStart(start.node,start.offset);range.setEnd(end.node,end.offset);return range}var startContainer=rng.startContainer;doc=startContainer.ownerDocument||startContainer;range=new KRange(doc);range.setStart(startContainer,rng.startOffset);range.setEnd(rng.endContainer,rng.endOffset);return range}function KRange(doc){this.init(doc)}_extend(KRange,{init:function(doc){var self=this;self.startContainer=doc;self.startOffset=0;self.endContainer=doc;self.endOffset=0;self.collapsed=true;self.doc=doc},commonAncestor:function(){function getParents(node){var parents=[];while(node){parents.push(node);node=node.parentNode}return parents}var parentsA=getParents(this.startContainer),parentsB=getParents(this.endContainer),i=0,lenA=parentsA.length,lenB=parentsB.length,parentA,parentB;while(++i){parentA=parentsA[lenA-i];parentB=parentsB[lenB-i];if(!parentA||!parentB||parentA!==parentB){break}}return parentsA[lenA-i+1]},setStart:function(node,offset){var self=this,doc=self.doc;self.startContainer=node;self.startOffset=offset;if(self.endContainer===doc){self.endContainer=node;self.endOffset=offset}return _updateCollapsed(this)},setEnd:function(node,offset){var self=this,doc=self.doc;self.endContainer=node;self.endOffset=offset;if(self.startContainer===doc){self.startContainer=node;self.startOffset=offset}return _updateCollapsed(this)},setStartBefore:function(node){return this.setStart(node.parentNode||this.doc,K(node).index())},setStartAfter:function(node){return this.setStart(node.parentNode||this.doc,K(node).index()+1)},setEndBefore:function(node){return this.setEnd(node.parentNode||this.doc,K(node).index())},setEndAfter:function(node){return this.setEnd(node.parentNode||this.doc,K(node).index()+1)},selectNode:function(node){return this.setStartBefore(node).setEndAfter(node)},selectNodeContents:function(node){var knode=K(node);if(knode.type==3||knode.isSingle()){return this.selectNode(node)}var children=knode.children();if(children.length>0){return this.setStartBefore(children[0]).setEndAfter(children[children.length-1])}return this.setStart(node,0).setEnd(node,0)},collapse:function(toStart){if(toStart){return this.setEnd(this.startContainer,this.startOffset)}return this.setStart(this.endContainer,this.endOffset)},compareBoundaryPoints:function(how,range){var rangeA=this.get(),rangeB=range.get();if(_IERANGE){var arr={};arr[_START_TO_START]="StartToStart";arr[_START_TO_END]="EndToStart";arr[_END_TO_END]="EndToEnd";arr[_END_TO_START]="StartToEnd";var cmp=rangeA.compareEndPoints(arr[how],rangeB);if(cmp!==0){return cmp}var nodeA,nodeB,nodeC,posA,posB;if(how===_START_TO_START||how===_END_TO_START){nodeA=this.startContainer;posA=this.startOffset}if(how===_START_TO_END||how===_END_TO_END){nodeA=this.endContainer;posA=this.endOffset}if(how===_START_TO_START||how===_START_TO_END){nodeB=range.startContainer;posB=range.startOffset}if(how===_END_TO_END||how===_END_TO_START){nodeB=range.endContainer;posB=range.endOffset}if(nodeA===nodeB){var diff=posA-posB;return diff>0?1:diff<0?-1:0}nodeC=nodeB;while(nodeC&&nodeC.parentNode!==nodeA){nodeC=nodeC.parentNode}if(nodeC){return K(nodeC).index()>=posA?-1:1}nodeC=nodeA;while(nodeC&&nodeC.parentNode!==nodeB){nodeC=nodeC.parentNode}if(nodeC){return K(nodeC).index()>=posB?1:-1}nodeC=K(nodeB).next();if(nodeC&&nodeC.contains(nodeA)){return 1}nodeC=K(nodeA).next();if(nodeC&&nodeC.contains(nodeB)){return-1}}else{return rangeA.compareBoundaryPoints(how,rangeB)}},cloneRange:function(){return new KRange(this.doc).setStart(this.startContainer,this.startOffset).setEnd(this.endContainer,this.endOffset)},toString:function(){var rng=this.get(),str=_IERANGE?rng.text:rng.toString();return str.replace(/\r\n|\n|\r/g,"")},cloneContents:function(){return _copyAndDelete(this,true,false)},deleteContents:function(){return _copyAndDelete(this,false,true)},extractContents:function(){return _copyAndDelete(this,true,true)},insertNode:function(node){var self=this,sc=self.startContainer,so=self.startOffset,ec=self.endContainer,eo=self.endOffset,firstChild,lastChild,c,nodeCount=1;if(node.nodeName.toLowerCase()==="#document-fragment"){firstChild=node.firstChild;lastChild=node.lastChild;nodeCount=node.childNodes.length}if(sc.nodeType==1){c=sc.childNodes[so];if(c){sc.insertBefore(node,c);if(sc===ec){eo+=nodeCount}}else{sc.appendChild(node)}}else if(sc.nodeType==3){if(so===0){sc.parentNode.insertBefore(node,sc);if(sc.parentNode===ec){eo+=nodeCount}}else if(so>=sc.nodeValue.length){if(sc.nextSibling){sc.parentNode.insertBefore(node,sc.nextSibling)}else{sc.parentNode.appendChild(node)}}else{if(so>0){c=sc.splitText(so)}else{c=sc}sc.parentNode.insertBefore(node,c);if(sc===ec){ec=c;eo-=so}}}if(firstChild){self.setStartBefore(firstChild).setEndAfter(lastChild)}else{self.selectNode(node)}if(self.compareBoundaryPoints(_END_TO_END,self.cloneRange().setEnd(ec,eo))>=1){return self}return self.setEnd(ec,eo)},surroundContents:function(node){node.appendChild(this.extractContents());return this.insertNode(node).selectNode(node)},isControl:function(){var self=this,sc=self.startContainer,so=self.startOffset,ec=self.endContainer,eo=self.endOffset,rng;return sc.nodeType==1&&sc===ec&&so+1===eo&&K(sc.childNodes[so]).isControl()},get:function(hasControlRange){var self=this,doc=self.doc,node,rng;if(!_IERANGE){rng=doc.createRange();try{rng.setStart(self.startContainer,self.startOffset);rng.setEnd(self.endContainer,self.endOffset)}catch(e){}return rng}if(hasControlRange&&self.isControl()){rng=doc.body.createControlRange();rng.addElement(self.startContainer.childNodes[self.startOffset]);return rng}var range=self.cloneRange().down();rng=doc.body.createTextRange();rng.setEndPoint("StartToStart",_getEndRange(range.startContainer,range.startOffset));rng.setEndPoint("EndToStart",_getEndRange(range.endContainer,range.endOffset));return rng},html:function(){return K(this.cloneContents()).outer()},down:function(){var self=this;function downPos(node,pos,isStart){if(node.nodeType!=1){return}var children=K(node).children();if(children.length===0){return}var left,right,child,offset;if(pos>0){left=children.eq(pos-1)}if(pos0&&(child=self.endContainer.childNodes[self.endOffset-1])&&child.nodeType==1&&!K(child).isSingle()){self.setEnd(child,child.childNodes.length)}return self},createBookmark:function(serialize){var self=this,doc=self.doc,endNode,startNode=K('',doc)[0];startNode.id="__kindeditor_bookmark_start_"+_BOOKMARK_ID+++"__";if(!self.collapsed){endNode=startNode.cloneNode(true);endNode.id="__kindeditor_bookmark_end_"+_BOOKMARK_ID+++"__"}if(endNode){self.cloneRange().collapse(false).insertNode(endNode).setEndBefore(endNode)}self.insertNode(startNode).setStartAfter(startNode);return{start:serialize?"#"+startNode.id:startNode,end:endNode?serialize?"#"+endNode.id:endNode:null}},moveToBookmark:function(bookmark){var self=this,doc=self.doc,start=K(bookmark.start,doc),end=bookmark.end?K(bookmark.end,doc):null;if(!start||start.length<1){return self}self.setStartBefore(start[0]);start.remove();if(end&&end.length>0){self.setEndBefore(end[0]);end.remove()}else{self.collapse(true)}return self},dump:function(){console.log("--------------------");console.log(this.startContainer.nodeType==3?this.startContainer.nodeValue:this.startContainer,this.startOffset);console.log(this.endContainer.nodeType==3?this.endContainer.nodeValue:this.endContainer,this.endOffset)}});function _range(mixed){if(!mixed.nodeName){return mixed.constructor===KRange?mixed:_toRange(mixed)}return new KRange(mixed)}K.RangeClass=KRange;K.range=_range;K.START_TO_START=_START_TO_START;K.START_TO_END=_START_TO_END;K.END_TO_END=_END_TO_END;K.END_TO_START=_END_TO_START;function _nativeCommand(doc,key,val){try{doc.execCommand(key,false,val)}catch(e){}}function _nativeCommandValue(doc,key){var val="";try{val=doc.queryCommandValue(key)}catch(e){}if(typeof val!=="string"){val=""}return val}function _getSel(doc){var win=_getWin(doc);return _IERANGE?doc.selection:win.getSelection()}function _getRng(doc){var sel=_getSel(doc),rng;try{if(sel.rangeCount>0){rng=sel.getRangeAt(0)}else{rng=sel.createRange()}}catch(e){}if(_IERANGE&&(!rng||!rng.item&&rng.parentElement().ownerDocument!==doc)){return null}return rng}function _singleKeyMap(map){var newMap={},arr,v;_each(map,function(key,val){arr=key.split(",");for(var i=0,len=arr.length;i]+>/g,"")===""}function _mergeWrapper(a,b){a=a.clone(true);var lastA=_getInnerNode(a),childA=a,merged=false;while(b){while(childA){if(childA.name===b.name){_mergeAttrs(childA,b.attr(),b.css());merged=true}childA=childA.first()}if(!merged){lastA.append(b.clone(false))}merged=false;b=b.first()}return a}function _wrapNode(knode,wrapper){wrapper=wrapper.clone(true);if(knode.type==3){_getInnerNode(wrapper).append(knode.clone(false));knode.replaceWith(wrapper);return wrapper}var nodeWrapper=knode,child;while((child=knode.first())&&child.children().length==1){knode=child}child=knode.first();var frag=knode.doc.createDocumentFragment();while(child){frag.appendChild(child[0]);child=child.next()}wrapper=_mergeWrapper(nodeWrapper,wrapper);if(frag.firstChild){_getInnerNode(wrapper).append(frag)}nodeWrapper.replaceWith(wrapper);return wrapper}function _mergeAttrs(knode,attrs,styles){_each(attrs,function(key,val){if(key!=="style"){knode.attr(key,val)}});_each(styles,function(key,val){knode.css(key,val)})}function _inPreElement(knode){while(knode&&knode.name!="body"){if(_PRE_TAG_MAP[knode.name]||knode.name=="div"&&knode.hasClass("ke-script")){return true}knode=knode.parent()}return false}function KCmd(range){this.init(range)}_extend(KCmd,{init:function(range){var self=this,doc=range.doc;self.doc=doc;self.win=_getWin(doc);self.sel=_getSel(doc);self.range=range},selection:function(forceReset){var self=this,doc=self.doc,rng=_getRng(doc);self.sel=_getSel(doc);if(rng){self.range=_range(rng);if(K(self.range.startContainer).name=="html"){self.range.selectNodeContents(doc.body).collapse(false)}return self}if(forceReset){self.range.selectNodeContents(doc.body).collapse(false)}return self},select:function(hasDummy){hasDummy=_undef(hasDummy,true);var self=this,sel=self.sel,range=self.range.cloneRange().shrink(),sc=range.startContainer,so=range.startOffset,ec=range.endContainer,eo=range.endOffset,doc=_getDoc(sc),win=self.win,rng,hasU200b=false;if(hasDummy&&sc.nodeType==1&&range.collapsed){if(_IERANGE){var dummy=K(" ",doc);range.insertNode(dummy[0]);rng=doc.body.createTextRange();try{rng.moveToElementText(dummy[0])}catch(ex){}rng.collapse(false);rng.select();dummy.remove();win.focus();return self}if(_WEBKIT){var children=sc.childNodes;if(K(sc).isInline()||so>0&&K(children[so-1]).isInline()||children[so]&&K(children[so]).isInline()){range.insertNode(doc.createTextNode("​"));hasU200b=true}}}if(_IERANGE){try{rng=range.get(true);rng.select()}catch(e){}}else{if(hasU200b){range.collapse(false)}rng=range.get(true);sel.removeAllRanges();sel.addRange(rng);if(doc!==document){var pos=K(rng.endContainer).pos();win.scrollTo(pos.x,pos.y)}}win.focus();return self},wrap:function(val){var self=this,doc=self.doc,range=self.range,wrapper;wrapper=K(val,doc);if(range.collapsed){range.shrink();range.insertNode(wrapper[0]).selectNodeContents(wrapper[0]);return self}if(wrapper.isBlock()){var copyWrapper=wrapper.clone(true),child=copyWrapper;while(child.first()){child=child.first()}child.append(range.extractContents());range.insertNode(copyWrapper[0]).selectNode(copyWrapper[0]);return self}range.enlarge();var bookmark=range.createBookmark(),ancestor=range.commonAncestor(),isStart=false;K(ancestor).scan(function(node){if(!isStart&&node==bookmark.start){isStart=true;return}if(isStart){if(node==bookmark.end){return false}var knode=K(node);if(_inPreElement(knode)){return}if(knode.type==3&&_trim(node.nodeValue).length>0){var parent;while((parent=knode.parent())&&parent.isStyle()&&parent.children().length==1){knode=parent}_wrapNode(knode,wrapper)}}});range.moveToBookmark(bookmark);return self},split:function(isStart,map){var range=this.range,doc=range.doc;var tempRange=range.cloneRange().collapse(isStart);var node=tempRange.startContainer,pos=tempRange.startOffset,parent=node.nodeType==3?node.parentNode:node,needSplit=false,knode;while(parent&&parent.parentNode){knode=K(parent);if(map){if(!knode.isStyle()){break}if(!_hasAttrOrCss(knode,map)){break}}else{if(_NOSPLIT_TAG_MAP[knode.name]){break}}needSplit=true;parent=parent.parentNode}if(needSplit){var dummy=doc.createElement("span");range.cloneRange().collapse(!isStart).insertNode(dummy);if(isStart){tempRange.setStartBefore(parent.firstChild).setEnd(node,pos)}else{tempRange.setStart(node,pos).setEndAfter(parent.lastChild)}var frag=tempRange.extractContents(),first=frag.firstChild,last=frag.lastChild;if(isStart){tempRange.insertNode(frag);range.setStartAfter(last).setEndBefore(dummy)}else{parent.appendChild(frag);range.setStartBefore(dummy).setEndBefore(first)}var dummyParent=dummy.parentNode;if(dummyParent==range.endContainer){var prev=K(dummy).prev(),next=K(dummy).next();if(prev&&next&&prev.type==3&&next.type==3){range.setEnd(prev[0],prev[0].nodeValue.length)}else if(!isStart){range.setEnd(range.endContainer,range.endOffset-1)}}dummyParent.removeChild(dummy)}return this},remove:function(map){var self=this,doc=self.doc,range=self.range;range.enlarge();if(range.startOffset===0){var ksc=K(range.startContainer),parent;while((parent=ksc.parent())&&parent.isStyle()&&parent.children().length==1){ksc=parent}range.setStart(ksc[0],0);ksc=K(range.startContainer);if(ksc.isBlock()){_removeAttrOrCss(ksc,map)}var kscp=ksc.parent();if(kscp&&kscp.isBlock()){_removeAttrOrCss(kscp,map)}}var sc,so;if(range.collapsed){self.split(true,map);sc=range.startContainer;so=range.startOffset;if(so>0){var sb=K(sc.childNodes[so-1]);if(sb&&_isEmptyNode(sb)){sb.remove();range.setStart(sc,so-1)}}var sa=K(sc.childNodes[so]);if(sa&&_isEmptyNode(sa)){sa.remove()}if(_isEmptyNode(sc)){range.startBefore(sc);sc.remove()}range.collapse(true);return self}self.split(true,map);self.split(false,map);var startDummy=doc.createElement("span"),endDummy=doc.createElement("span");range.cloneRange().collapse(false).insertNode(endDummy);range.cloneRange().collapse(true).insertNode(startDummy);var nodeList=[],cmpStart=false;K(range.commonAncestor()).scan(function(node){if(!cmpStart&&node==startDummy){cmpStart=true;return}if(node==endDummy){return false}if(cmpStart){nodeList.push(node)}});K(startDummy).remove();K(endDummy).remove();sc=range.startContainer;so=range.startOffset;var ec=range.endContainer,eo=range.endOffset;if(so>0){var startBefore=K(sc.childNodes[so-1]);if(startBefore&&_isEmptyNode(startBefore)){startBefore.remove();range.setStart(sc,so-1);if(sc==ec){range.setEnd(ec,eo-1)}}var startAfter=K(sc.childNodes[so]);if(startAfter&&_isEmptyNode(startAfter)){startAfter.remove();if(sc==ec){range.setEnd(ec,eo-1)}}}var endAfter=K(ec.childNodes[range.endOffset]);if(endAfter&&_isEmptyNode(endAfter)){endAfter.remove()}var bookmark=range.createBookmark(true);_each(nodeList,function(i,node){_removeAttrOrCss(K(node),map)});range.moveToBookmark(bookmark);return self},commonNode:function(map){var range=this.range;var ec=range.endContainer,eo=range.endOffset,node=ec.nodeType==3||eo===0?ec:ec.childNodes[eo-1];function find(node){var child=node,parent=node;while(parent){if(_hasAttrOrCss(K(parent),map)){return K(parent)}parent=parent.parentNode}while(child&&(child=child.lastChild)){if(_hasAttrOrCss(K(child),map)){return K(child)}}return null}var cNode=find(node);if(cNode){return cNode}if(node.nodeType==1||ec.nodeType==3&&eo===0){var prev=K(node).prev();if(prev){return find(prev)}}return null},commonAncestor:function(tagName){var range=this.range,sc=range.startContainer,so=range.startOffset,ec=range.endContainer,eo=range.endOffset,startNode=sc.nodeType==3||so===0?sc:sc.childNodes[so-1],endNode=ec.nodeType==3||eo===0?ec:ec.childNodes[eo-1];function find(node){while(node){if(node.nodeType==1){if(node.tagName.toLowerCase()===tagName){return node}}node=node.parentNode}return null}var start=find(startNode),end=find(endNode);if(start&&end&&start===end){return K(start)}return null},state:function(key){var self=this,doc=self.doc,bool=false;try{bool=doc.queryCommandState(key)}catch(e){}return bool},val:function(key){var self=this,doc=self.doc,range=self.range;function lc(val){return val.toLowerCase()}key=lc(key);var val="",knode;if(key==="fontfamily"||key==="fontname"){val=_nativeCommandValue(doc,"fontname");val=val.replace(/['"]/g,"");return lc(val)}if(key==="formatblock"){val=_nativeCommandValue(doc,key);if(val===""){knode=self.commonNode({"h1,h2,h3,h4,h5,h6,p,div,pre,address":"*"});if(knode){val=knode.name}}if(val==="Normal"){val="p"}return lc(val)}if(key==="fontsize"){knode=self.commonNode({"*":".font-size"});if(knode){val=knode.css("font-size")}return lc(val)}if(key==="forecolor"){knode=self.commonNode({"*":".color"});if(knode){val=knode.css("color")}val=_toHex(val);if(val===""){val="default"}return lc(val)}if(key==="hilitecolor"){knode=self.commonNode({"*":".background-color"});if(knode){val=knode.css("background-color")}val=_toHex(val);if(val===""){val="default"}return lc(val)}return val},toggle:function(wrapper,map){var self=this;if(self.commonNode(map)){self.remove(map)}else{self.wrap(wrapper)}return self.select()},bold:function(){return this.toggle("",{span:".font-weight=bold",strong:"*",b:"*"})},italic:function(){return this.toggle("",{span:".font-style=italic",em:"*",i:"*"})},underline:function(){return this.toggle("",{span:".text-decoration=underline",u:"*"})},strikethrough:function(){return this.toggle("",{span:".text-decoration=line-through",s:"*"})},forecolor:function(val){return this.wrap('').select()},hilitecolor:function(val){return this.wrap('').select()},fontsize:function(val){return this.wrap('').select()},fontname:function(val){return this.fontfamily(val)},fontfamily:function(val){return this.wrap('').select()},removeformat:function(){var map={"*":".font-weight,.font-style,.text-decoration,.color,.background-color,.font-size,.font-family,.text-indent"},tags=_STYLE_TAG_MAP;_each(tags,function(key,val){map[key]="*"});this.remove(map);return this.select()},inserthtml:function(val,quickMode){var self=this,range=self.range;if(val===""){return self}function pasteHtml(range,val){val=''+val;var rng=range.get();if(rng.item){rng.item(0).outerHTML=val}else{rng.pasteHTML(val)}var temp=range.doc.getElementById("__kindeditor_temp_tag__");temp.parentNode.removeChild(temp);var newRange=_toRange(rng);range.setEnd(newRange.endContainer,newRange.endOffset);range.collapse(false);self.select(false)}function insertHtml(range,val){var doc=range.doc,frag=doc.createDocumentFragment();K("@"+val,doc).each(function(){frag.appendChild(this)});range.deleteContents();range.insertNode(frag);range.collapse(false);self.select(false)}if(_IERANGE&&quickMode){try{pasteHtml(range,val)}catch(e){insertHtml(range,val)}return self}insertHtml(range,val);return self},hr:function(){return this.inserthtml("
    ")},print:function(){this.win.print();return this},insertimage:function(url,title,width,height,border,align){title=_undef(title,"");border=_undef(border,0);var html='";return self.inserthtml(html)}if(range.isControl()){var node=K(range.startContainer.childNodes[range.startOffset]);html+=">";node.after(K(html,doc));node.next().append(node);range.selectNode(node[0]);return self.select()}function setAttr(node,url,type){K(node).attr("href",url).attr("data-ke-src",url);if(type){K(node).attr("target",type)}else{K(node).removeAttr("target")}}var sc=range.startContainer,so=range.startOffset,ec=range.endContainer,eo=range.endOffset;if(sc.nodeType==1&&sc===ec&&so+1===eo){var child=sc.childNodes[so];if(child.nodeName.toLowerCase()=="a"){setAttr(child,url,type);return self}}_nativeCommand(doc,"createlink","__kindeditor_temp_url__");K('a[href="__kindeditor_temp_url__"]',doc).each(function(){setAttr(this,url,type)});return self},unlink:function(){var self=this,doc=self.doc,range=self.range;self.select();if(range.collapsed){var a=self.commonNode({a:"*"});if(a){range.selectNode(a.get());self.select()}_nativeCommand(doc,"unlink",null);if(_WEBKIT&&K(range.startContainer).name==="img"){var parent=K(range.startContainer).parent();if(parent.name==="a"){parent.remove(true)}}}else{_nativeCommand(doc,"unlink",null)}return self}});_each(("formatblock,selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,"+"insertunorderedlist,indent,outdent,subscript,superscript").split(","),function(i,name){KCmd.prototype[name]=function(val){var self=this;self.select();_nativeCommand(self.doc,name,val);if(_IERANGE&&_inArray(name,"justifyleft,justifycenter,justifyright,justifyfull".split(","))>=0){self.selection()}if(!_IERANGE||_inArray(name,"formatblock,selectall,insertorderedlist,insertunorderedlist".split(","))>=0){self.selection()}return self}});_each("cut,copy,paste".split(","),function(i,name){KCmd.prototype[name]=function(){var self=this;if(!self.doc.queryCommandSupported(name)){throw"not supported"}self.select();_nativeCommand(self.doc,name,null);return self}});function _cmd(mixed){if(mixed.nodeName){var doc=_getDoc(mixed);mixed=_range(doc).selectNodeContents(doc.body).collapse(false)}return new KCmd(mixed)}K.CmdClass=KCmd;K.cmd=_cmd;function _drag(options){var moveEl=options.moveEl,moveFn=options.moveFn,clickEl=options.clickEl||moveEl,beforeDrag=options.beforeDrag,iframeFix=options.iframeFix===undefined?true:options.iframeFix;var docs=[document];if(iframeFix){K("iframe").each(function(){var src=_formatUrl(this.src||"","absolute");if(/^https?:\/\//.test(src)){return}var doc;try{doc=_iframeDoc(this)}catch(e){}if(doc){var pos=K(this).pos();K(doc).data("pos-x",pos.x);K(doc).data("pos-y",pos.y);docs.push(doc)}})}clickEl.mousedown(function(e){if(e.button!==0&&e.button!==1){return}e.stopPropagation();var self=clickEl.get(),x=_removeUnit(moveEl.css("left")),y=_removeUnit(moveEl.css("top")),width=moveEl.width(),height=moveEl.height(),pageX=e.pageX,pageY=e.pageY;if(beforeDrag){beforeDrag()}function moveListener(e){e.preventDefault();var kdoc=K(_getDoc(e.target));var diffX=_round((kdoc.data("pos-x")||0)+e.pageX-pageX);var diffY=_round((kdoc.data("pos-y")||0)+e.pageY-pageY);moveFn.call(clickEl,x,y,width,height,diffX,diffY)}function selectListener(e){e.preventDefault()}function upListener(e){e.preventDefault();K(docs).unbind("mousemove",moveListener).unbind("mouseup",upListener).unbind("selectstart",selectListener);if(self.releaseCapture){self.releaseCapture()}}K(docs).mousemove(moveListener).mouseup(upListener).bind("selectstart",selectListener);if(self.setCapture){self.setCapture()}})}function KWidget(options){this.init(options)}_extend(KWidget,{init:function(options){var self=this;self.name=options.name||"";self.doc=options.doc||document;self.win=_getWin(self.doc);self.x=_addUnit(options.x);self.y=_addUnit(options.y);self.z=options.z;self.width=_addUnit(options.width);self.height=_addUnit(options.height);self.div=K('
    ');self.options=options;self._alignEl=options.alignEl;if(self.width){self.div.css("width",self.width)}if(self.height){self.div.css("height",self.height)}if(self.z){self.div.css({position:"absolute",left:self.x,top:self.y,"z-index":self.z})}if(self.z&&(self.x===undefined||self.y===undefined)){self.autoPos(self.width,self.height)}if(options.cls){self.div.addClass(options.cls)}if(options.shadowMode){self.div.addClass("ke-shadow")}if(options.css){self.div.css(options.css)}if(options.src){K(options.src).replaceWith(self.div)}else{K(self.doc.body).append(self.div)}if(options.html){self.div.html(options.html)}if(options.autoScroll){if(_IE&&_V<7||_QUIRKS){var scrollPos=_getScrollPos();K(self.win).bind("scroll",function(e){var pos=_getScrollPos(),diffX=pos.x-scrollPos.x,diffY=pos.y-scrollPos.y;self.pos(_removeUnit(self.x)+diffX,_removeUnit(self.y)+diffY,false)})}else{self.div.css("position","fixed")}}},pos:function(x,y,updateProp){var self=this;updateProp=_undef(updateProp,true);if(x!==null){x=x<0?0:_addUnit(x);self.div.css("left",x);if(updateProp){self.x=x}}if(y!==null){y=y<0?0:_addUnit(y);self.div.css("top",y);if(updateProp){self.y=y}}return self},autoPos:function(width,height){var x,y,self=this,w=_removeUnit(width)||0,h=_removeUnit(height)||0,scrollPos=_getScrollPos();if(self._alignEl){var knode=K(self._alignEl),pos=knode.pos(),diffX=_round(knode[0].clientWidth/2-w/2),diffY=_round(knode[0].clientHeight/2-h/2);x=diffX<0?pos.x:pos.x+diffX}else{var docEl=_docElement(self.doc);x=_round(scrollPos.x+(docEl.clientWidth-w)/2);y=_round(scrollPos.y+(docEl.clientHeight-h)/2)}if(K.options.dialogOffset>0){y=scrollPos.y+20}if(!(_IE&&_V<7||_QUIRKS)){x-=scrollPos.x;y-=scrollPos.y}return self.pos(x,y)},remove:function(){var self=this;if(_IE&&_V<7||_QUIRKS){K(self.win).unbind("scroll")}self.div.remove();_each(self,function(i){self[i]=null});return this},show:function(){this.div.show();return this},hide:function(){this.div.hide();return this},draggable:function(options){var self=this;options=options||{};options.moveEl=self.div;options.moveFn=function(x,y,width,height,diffX,diffY){if((x=x+diffX)<0){x=0}if((y=y+diffY)<0){y=0}self.pos(x,y)};_drag(options);return self}});function _widget(options){return new KWidget(options)}K.WidgetClass=KWidget;K.widget=_widget;function _iframeDoc(iframe){iframe=_get(iframe);return iframe.contentDocument||iframe.contentWindow.document}var html,_direction="";if(html=document.getElementsByTagName("html")){_direction=html[0].dir}function _getInitHtml(options){var themesPath=_undef(options.themesPath,""),bodyClass=options.bodyClass,cssPath=options.cssPath,jsPath=options.jsPath,cssData=options.cssData;var arr=[_direction===""?"":'','',"");if(!_isArray(cssPath)){cssPath=[cssPath]}if(_inArray(K.basePath+"themes/app.css",cssPath)<0){cssPath.push(K.basePath+"themes/app.css")}_each(cssPath,function(i,path){if(path){arr.push('')}});if(cssData){arr.push("")}arr.push("");if(!_isArray(jsPath)){jsPath=[jsPath]}_each(jsPath,function(i,path){if(path){arr.push(' + + + + +
    + + + \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/baidumap/map.html b/addons/nkeditor/assets/plugins/baidumap/map.html new file mode 100644 index 0000000000000000000000000000000000000000..6810c15885f0205b73bc81cca824d4634a25e717 --- /dev/null +++ b/addons/nkeditor/assets/plugins/baidumap/map.html @@ -0,0 +1,53 @@ + + + + + Baidu Maps + + + + + +
    + + diff --git a/addons/nkeditor/assets/plugins/clearhtml/clearhtml.js b/addons/nkeditor/assets/plugins/clearhtml/clearhtml.js new file mode 100644 index 0000000000000000000000000000000000000000..1bf0e5dcad91a42d114b7e3acc426332357e1e5f --- /dev/null +++ b/addons/nkeditor/assets/plugins/clearhtml/clearhtml.js @@ -0,0 +1,29 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('clearhtml', function(K) { + var self = this, name = 'clearhtml'; + self.clickToolbar(name, function() { + self.focus(); + var html = self.html(); + html = html.replace(/(]*>)([\s\S]*?)(<\/script>)/ig, ''); + html = html.replace(/(]*>)([\s\S]*?)(<\/style>)/ig, ''); + html = K.formatHtml(html, { + a : ['href', 'target'], + embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'], + img : ['src', 'width', 'height', 'border', 'alt', 'title', '.width', '.height'], + table : ['border'], + 'td,th' : ['rowspan', 'colspan'], + 'div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [] + }); + self.html(html); + self.cmd.selection(true); + self.addBookmark(); + }); +}); diff --git a/addons/nkeditor/assets/plugins/code/code.js b/addons/nkeditor/assets/plugins/code/code.js new file mode 100644 index 0000000000000000000000000000000000000000..67bd09d3f5e394a7c3dcf5ea6467a955b3bd7947 --- /dev/null +++ b/addons/nkeditor/assets/plugins/code/code.js @@ -0,0 +1,64 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +// google code prettify: http://google-code-prettify.googlecode.com/ +// http://google-code-prettify.googlecode.com/ + +KindEditor.plugin('code', function(K) { + var self = this, name = 'code'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = ['
    ', + '
    ', + '', + '
    ', + '', + '
    '].join(''), + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var type = K('.ke-select', dialog.div).val(), + code = textarea.val(), + cls = type === '' ? '' : 'language-' + type, + html = '
    ' + K.escape(code) + '

    '; + if (K.trim(code) === '') { + K.options.errorMsgHandler(lang.pleaseInput, "error"); + textarea[0].focus(); + return; + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); diff --git a/addons/nkeditor/assets/plugins/code/pretty.js b/addons/nkeditor/assets/plugins/code/pretty.js new file mode 100644 index 0000000000000000000000000000000000000000..ec84da943b6c2d980fcb9c01ea658a344dbb1eac --- /dev/null +++ b/addons/nkeditor/assets/plugins/code/pretty.js @@ -0,0 +1,18 @@ +/** + * @author yangjian + * @since 18-9-11 下午9:02. + */ + +// function _bindEvent(el, type, fn) { +// if (el.addEventListener){ +// el.addEventListener(type, fn); +// } else if (el.attachEvent){ +// el.attachEvent('on' + type, fn); +// } +// } +// _bindEvent(document.body, "DOMNodeInserted", function(e) { +// var className = e.target.className; +// if (className && className.indexOf("language-") != -1) { +// Prism.highlightElement(e.target); +// } +// }) diff --git a/addons/nkeditor/assets/plugins/code/prism.css b/addons/nkeditor/assets/plugins/code/prism.css new file mode 100644 index 0000000000000000000000000000000000000000..f88adbcf6a51a138ab92e170ee2447fe2ea9284a --- /dev/null +++ b/addons/nkeditor/assets/plugins/code/prism.css @@ -0,0 +1,292 @@ +/* PrismJS 1.15.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+csharp+bash+cpp+aspnet+ruby+markup-templating+go+markdown+php+python+sass+yaml&plugins=line-highlight+line-numbers+toolbar+highlight-keywords+show-language+copy-to-clipboard */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #9a6e3a; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function, +.token.class-name { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + +pre[data-line] { + position: relative; + padding: 1em 0 1em 3em; +} + +.line-highlight { + position: absolute; + left: 0; + right: 0; + padding: inherit 0; + margin-top: 1em; /* Same as .prism’s padding-top */ + + background: hsla(24, 20%, 50%,.08); + background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0)); + + pointer-events: none; + + line-height: inherit; + white-space: pre; +} + + .line-highlight:before, + .line-highlight[data-end]:after { + content: attr(data-start); + position: absolute; + top: .4em; + left: .6em; + min-width: 1em; + padding: 0 .5em; + background-color: hsla(24, 20%, 50%,.4); + color: hsl(24, 20%, 95%); + font: bold 65%/1.5 sans-serif; + text-align: center; + vertical-align: .3em; + border-radius: 999px; + text-shadow: none; + box-shadow: 0 1px white; + } + + .line-highlight[data-end]:after { + content: attr(data-end); + top: auto; + bottom: .4em; + } + +.line-numbers .line-highlight:before, +.line-numbers .line-highlight:after { + content: none; +} + +pre[class*="language-"].line-numbers { + position: relative; + padding-left: 3.8em; + counter-reset: linenumber; +} + +pre[class*="language-"].line-numbers > code { + position: relative; + white-space: inherit; +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + letter-spacing: -1px; + border-right: 1px solid #999; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} + + .line-numbers-rows > span { + pointer-events: none; + display: block; + counter-increment: linenumber; + } + + .line-numbers-rows > span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: 0.8em; + text-align: right; + } + +div.code-toolbar { + position: relative; +} + +div.code-toolbar > .toolbar { + position: absolute; + top: .3em; + right: .2em; + transition: opacity 0.3s ease-in-out; + opacity: 0; +} + +div.code-toolbar:hover > .toolbar { + opacity: 1; +} + +div.code-toolbar > .toolbar .toolbar-item { + display: inline-block; +} + +div.code-toolbar > .toolbar a { + cursor: pointer; +} + +div.code-toolbar > .toolbar button { + background: none; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + padding: 0; + -webkit-user-select: none; /* for button */ + -moz-user-select: none; + -ms-user-select: none; +} + +div.code-toolbar > .toolbar a, +div.code-toolbar > .toolbar button, +div.code-toolbar > .toolbar span { + color: #bbb; + font-size: .8em; + padding: 0 .5em; + background: #f5f2f0; + background: rgba(224, 224, 224, 0.2); + box-shadow: 0 2px 0 0 rgba(0,0,0,0.2); + border-radius: .5em; +} + +div.code-toolbar > .toolbar a:hover, +div.code-toolbar > .toolbar a:focus, +div.code-toolbar > .toolbar button:hover, +div.code-toolbar > .toolbar button:focus, +div.code-toolbar > .toolbar span:hover, +div.code-toolbar > .toolbar span:focus { + color: inherit; + text-decoration: none; +} + diff --git a/addons/nkeditor/assets/plugins/code/prism.js b/addons/nkeditor/assets/plugins/code/prism.js new file mode 100644 index 0000000000000000000000000000000000000000..0f748e715048ae964dcd762836531ef4c63020d4 --- /dev/null +++ b/addons/nkeditor/assets/plugins/code/prism.js @@ -0,0 +1,26 @@ +/* PrismJS 1.15.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+csharp+bash+cpp+aspnet+ruby+markup-templating+go+markdown+php+python+sass+yaml&plugins=line-highlight+line-numbers+toolbar+highlight-keywords+show-language+copy-to-clipboard */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-([\w-]+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,disableWorkerMessageHandler:_self.Prism&&_self.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof r?new r(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(w instanceof s)){if(m&&b!=t.length-1){h.lastIndex=k;var _=h.exec(e);if(!_)break;for(var j=_.index+(d?_[1].length:0),P=_.index+_[0].length,A=b,x=k,O=t.length;O>A&&(P>x||!t[A].type&&!t[A-1].greedy);++A)x+=t[A].length,j>=x&&(++b,k=x);if(t[b]instanceof s)continue;I=A-b,w=e.slice(k,x),_.index-=k}else{h.lastIndex=0;var _=h.exec(w),I=1}if(_){d&&(p=_[1]?_[1].length:0);var j=_.index+p,_=_[0].slice(p),P=j+_.length,N=w.slice(0,j),S=w.slice(P),C=[b,I];N&&(++b,k+=N.length,C.push(N));var E=new s(u,f?n.tokenize(_,f):_,y,_,m);if(C.push(E),S&&C.push(S),Array.prototype.splice.apply(t,C),1!=I&&n.matchGrammar(e,t,r,b,k,!0,u),i)break}else if(i)break}}}}},tokenize:function(e,t){var r=[e],a=t.rest;if(a){for(var l in a)t[l]=a[l];delete t.rest}return n.matchGrammar(e,r,t,0,0,!1),r},hooks:{all:{},add:function(e,t){var r=n.hooks.all;r[e]=r[e]||[],r[e].push(t)},run:function(e,t){var r=n.hooks.all[e];if(r&&r.length)for(var a,l=0;a=r[l++];)a(t)}}},r=n.Token=function(e,t,n,r,a){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length,this.greedy=!!a};if(r.stringify=function(e,t,a){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return r.stringify(n,t,e)}).join("");var l={type:e.type,content:r.stringify(e.content,t,a),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:a};if(e.alias){var i="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run("wrap",l);var o=Object.keys(l.attributes).map(function(e){return e+'="'+(l.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+l.tag+' class="'+l.classes.join(" ")+'"'+(o?" "+o:"")+">"+l.content+""},!_self.document)return _self.addEventListener?(n.disableWorkerMessageHandler||_self.addEventListener("message",function(e){var t=JSON.parse(e.data),r=t.language,a=t.code,l=t.immediateClose;_self.postMessage(n.highlight(a,n.languages[r],r)),l&&_self.close()},!1),_self.Prism):_self.Prism;var a=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return a&&(n.filename=a.src,n.manual||a.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/(^|[^\\])["']/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup; +Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.languages.css,Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/()[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css",greedy:!0}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(?:true|false)\b/,"function":/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},/\b(?:as|async|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/],number:/\b(?:(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+)n?|\d+n|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,"function":/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\(|\.(?:apply|bind|call)\()/,operator:/-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[[^\]\r\n]+]|\\.|[^\/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,alias:"function"},constant:/\b[A-Z][A-Z\d_]*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\${[^}]+}/,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/()[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript",greedy:!0}}),Prism.languages.js=Prism.languages.javascript; +Prism.languages.c=Prism.languages.extend("clike",{keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*\/%&|^!=<>]=?/,number:/(?:\b0x[\da-f]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,alias:"property",inside:{string:{pattern:/(#\s*include\s*)(?:<.+?>|("|')(?:\\?.)+?\2)/,lookbehind:!0},directive:{pattern:/(#\s*)\b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,lookbehind:!0,alias:"keyword"}}},constant:/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete Prism.languages.c["class-name"],delete Prism.languages.c["boolean"]; +Prism.languages.csharp=Prism.languages.extend("clike",{keyword:/\b(?:abstract|add|alias|as|ascending|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|descending|do|double|dynamic|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|from|get|global|goto|group|if|implicit|in|int|interface|internal|into|is|join|let|lock|long|namespace|new|null|object|operator|orderby|out|override|params|partial|private|protected|public|readonly|ref|remove|return|sbyte|sealed|select|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|value|var|virtual|void|volatile|where|while|yield)\b/,string:[{pattern:/@("|')(?:\1\1|\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0},{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*?\1/,greedy:!0}],"class-name":[{pattern:/\b[A-Z]\w*(?:\.\w+)*\b(?=\s+\w+)/,inside:{punctuation:/\./}},{pattern:/(\[)[A-Z]\w*(?:\.\w+)*\b/,lookbehind:!0,inside:{punctuation:/\./}},{pattern:/(\b(?:class|interface)\s+[A-Z]\w*(?:\.\w+)*\s*:\s*)[A-Z]\w*(?:\.\w+)*\b/,lookbehind:!0,inside:{punctuation:/\./}},{pattern:/((?:\b(?:class|interface|new)\s+)|(?:catch\s+\())[A-Z]\w*(?:\.\w+)*\b/,lookbehind:!0,inside:{punctuation:/\./}}],number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)f?/i}),Prism.languages.insertBefore("csharp","class-name",{"generic-method":{pattern:/\w+\s*<[^>\r\n]+?>\s*(?=\()/,inside:{"function":/^\w+/,"class-name":{pattern:/\b[A-Z]\w*(?:\.\w+)*\b/,inside:{punctuation:/\./}},keyword:Prism.languages.csharp.keyword,punctuation:/[<>(),.:]/}},preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(\s*#)\b(?:define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}}),Prism.languages.dotnet=Prism.languages.csharp; +!function(e){var t={variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\([^)]+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},/\$(?:[\w#?*!@]+|\{[^}]+\})/i]};e.languages.bash={shebang:{pattern:/^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/,alias:"important"},comment:{pattern:/(^|[^"{\\])#.*/,lookbehind:!0},string:[{pattern:/((?:^|[^<])<<\s*)["']?(\w+?)["']?\s*\r?\n(?:[\s\S])*?\r?\n\2/,lookbehind:!0,greedy:!0,inside:t},{pattern:/(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/,greedy:!0,inside:t}],variable:t.variable,"function":{pattern:/(^|[\s;|&])(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|[\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&])(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|[\s;|&])/,lookbehind:!0},"boolean":{pattern:/(^|[\s;|&])(?:true|false)(?=$|[\s;|&])/,lookbehind:!0},operator:/&&?|\|\|?|==?|!=?|<<>|<=?|>=?|=~/,punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];]/};var a=t.variable[1].inside;a.string=e.languages.bash.string,a["function"]=e.languages.bash["function"],a.keyword=e.languages.bash.keyword,a["boolean"]=e.languages.bash["boolean"],a.operator=e.languages.bash.operator,a.punctuation=e.languages.bash.punctuation,e.languages.shell=e.languages.bash}(Prism); +Prism.languages.cpp=Prism.languages.extend("c",{keyword:/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(?:true|false)\b/,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*\/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),Prism.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)\w+/i,lookbehind:!0}}),Prism.languages.insertBefore("cpp","string",{"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}); +Prism.languages.aspnet=Prism.languages.extend("markup",{"page-directive tag":{pattern:/<%\s*@.*%>/i,inside:{"page-directive tag":/<%\s*@\s*(?:Assembly|Control|Implements|Import|Master(?:Type)?|OutputCache|Page|PreviousPageType|Reference|Register)?|%>/i,rest:Prism.languages.markup.tag.inside}},"directive tag":{pattern:/<%.*%>/i,inside:{"directive tag":/<%\s*?[$=%#:]{0,2}|%>/i,rest:Prism.languages.csharp}}}),Prism.languages.aspnet.tag.pattern=/<(?!%)\/?[^\s>\/]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,Prism.languages.insertBefore("inside","punctuation",{"directive tag":Prism.languages.aspnet["directive tag"]},Prism.languages.aspnet.tag.inside["attr-value"]),Prism.languages.insertBefore("aspnet","comment",{"asp comment":/<%--[\s\S]*?--%>/}),Prism.languages.insertBefore("aspnet",Prism.languages.javascript?"script":"tag",{"asp script":{pattern:/()[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.csharp||{}}}); +!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m,greedy:!0}],keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:n}}]}(Prism); +Prism.languages["markup-templating"]={},Object.defineProperties(Prism.languages["markup-templating"],{buildPlaceholders:{value:function(e,t,n,a){e.language===t&&(e.tokenStack=[],e.code=e.code.replace(n,function(n){if("function"==typeof a&&!a(n))return n;for(var r=e.tokenStack.length;-1!==e.code.indexOf("___"+t.toUpperCase()+r+"___");)++r;return e.tokenStack[r]=n,"___"+t.toUpperCase()+r+"___"}),e.grammar=Prism.languages.markup)}},tokenizePlaceholders:{value:function(e,t){if(e.language===t&&e.tokenStack){e.grammar=Prism.languages[t];var n=0,a=Object.keys(e.tokenStack),r=function(o){if(!(n>=a.length))for(var i=0;i-1){++n;var f,u=l.substring(0,p),_=new Prism.Token(t,Prism.tokenize(s,e.grammar,t),"language-"+t,s),k=l.substring(p+("___"+t.toUpperCase()+c+"___").length);if(u||k?(f=[u,_,k].filter(function(e){return!!e}),r(f)):f=_,"string"==typeof g?Array.prototype.splice.apply(o,[i,1].concat(f)):g.content=f,n>=a.length)break}}else g.content&&"string"!=typeof g.content&&r(g.content)}};r(e.tokens)}}}}); +Prism.languages.go=Prism.languages.extend("clike",{keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,builtin:/\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/,"boolean":/\b(?:_|iota|nil|true|false)\b/,operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,number:/(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,string:{pattern:/(["'`])(\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0}}),delete Prism.languages.go["class-name"]; +Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},code:[{pattern:/^(?: {4}|\t).+/m,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*(?:\r?\n|\r)(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*$|__$/}},italic:{pattern:/(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.languages.markdown.url,Prism.languages.markdown.italic.inside.url=Prism.languages.markdown.url,Prism.languages.markdown.bold.inside.italic=Prism.languages.markdown.italic,Prism.languages.markdown.italic.inside.bold=Prism.languages.markdown.bold; +!function(e){e.languages.php=e.languages.extend("clike",{keyword:/\b(?:and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0}}),e.languages.insertBefore("php","string",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),e.languages.insertBefore("php","keyword",{delimiter:{pattern:/\?>|<\?(?:php|=)?/i,alias:"important"},variable:/\$+(?:\w+\b|(?={))/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),e.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}});var n={pattern:/{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/,lookbehind:!0,inside:{rest:e.languages.php}};e.languages.insertBefore("php","string",{"nowdoc-string":{pattern:/<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/,greedy:!0,alias:"string",inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},"heredoc-string":{pattern:/<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i,greedy:!0,alias:"string",inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:n}},"single-quoted-string":{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0,alias:"string"},"double-quoted-string":{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,alias:"string",inside:{interpolation:n}}}),delete e.languages.php.string,e.hooks.add("before-tokenize",function(n){if(/(?:<\?php|<\?)/gi.test(n.code)){var t=/(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/gi;e.languages["markup-templating"].buildPlaceholders(n,"php",t)}}),e.hooks.add("after-tokenize",function(n){e.languages["markup-templating"].tokenizePlaceholders(n,"php")})}(Prism); +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},"triple-quoted-string":{pattern:/("""|''')[\s\S]+?\1/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},"function":{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},keyword:/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,"boolean":/\b(?:True|False|None)\b/,number:/(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,punctuation:/[{}[\];(),.:]/}; +!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var a=/\$[-\w]+|#\{\$[-\w]+\}/,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:a,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:a,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,delete e.languages.sass.selector,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism); +Prism.languages.yaml={scalar:{pattern:/([\-:]\s*(?:![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/,lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:/(\s*(?:^|[:\-,[{\r\n?])[ \t]*(?:![^\s]+)?[ \t]*)[^\r\n{[\]},#\s]+?(?=\s*:\s)/,lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?)(?=[ \t]*(?:$|,|]|}))/m,lookbehind:!0,alias:"number"},"boolean":{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:true|false)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},"null":{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:null|~)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},string:{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)("|')(?:(?!\2)[^\\\r\n]|\\.)*\2(?=[ \t]*(?:$|,|]|}))/m,lookbehind:!0,greedy:!0},number:{pattern:/([:\-,[{]\s*(?:![^\s]+)?[ \t]*)[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,lookbehind:!0},tag:/![^\s]+/,important:/[&*][\w]+/,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./}; +!function(){function e(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function t(e,t){return t=" "+t+" ",(" "+e.className+" ").replace(/[\n\t]/g," ").indexOf(t)>-1}function n(e,n,i){n="string"==typeof n?n:e.getAttribute("data-line");for(var o,l=n.replace(/\s+/g,"").split(","),a=+e.getAttribute("data-line-offset")||0,s=r()?parseInt:parseFloat,d=s(getComputedStyle(e).lineHeight),u=t(e,"line-numbers"),c=0;o=l[c++];){var p=o.split("-"),m=+p[0],f=+p[1]||m,h=e.querySelector('.line-highlight[data-range="'+o+'"]')||document.createElement("div");if(h.setAttribute("aria-hidden","true"),h.setAttribute("data-range",o),h.className=(i||"")+" line-highlight",u&&Prism.plugins.lineNumbers){var g=Prism.plugins.lineNumbers.getLine(e,m),y=Prism.plugins.lineNumbers.getLine(e,f);g&&(h.style.top=g.offsetTop+"px"),y&&(h.style.height=y.offsetTop-g.offsetTop+y.offsetHeight+"px")}else h.setAttribute("data-start",m),f>m&&h.setAttribute("data-end",f),h.style.top=(m-a-1)*d+"px",h.textContent=new Array(f-m+2).join(" \n");u?e.appendChild(h):(e.querySelector("code")||e).appendChild(h)}}function i(){var t=location.hash.slice(1);e(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var i=(t.match(/\.([\d,-]+)$/)||[,""])[1];if(i&&!document.getElementById(t)){var r=t.slice(0,t.lastIndexOf(".")),o=document.getElementById(r);o&&(o.hasAttribute("data-line")||o.setAttribute("data-line",""),n(o,i,"temporary "),document.querySelector(".temporary.line-highlight").scrollIntoView())}}if("undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector){var r=function(){var e;return function(){if("undefined"==typeof e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding=0,t.style.border=0,t.innerHTML=" 
     ",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e}}(),o=0;Prism.hooks.add("before-sanity-check",function(t){var n=t.element.parentNode,i=n&&n.getAttribute("data-line");if(n&&i&&/pre/i.test(n.nodeName)){var r=0;e(".line-highlight",n).forEach(function(e){r+=e.textContent.length,e.parentNode.removeChild(e)}),r&&/^( \n)+$/.test(t.code.slice(-r))&&(t.code=t.code.slice(0,-r))}}),Prism.hooks.add("complete",function l(e){var r=e.element.parentNode,a=r&&r.getAttribute("data-line");if(r&&a&&/pre/i.test(r.nodeName)){clearTimeout(o);var s=Prism.plugins.lineNumbers,d=e.plugins&&e.plugins.lineNumbers;t(r,"line-numbers")&&s&&!d?Prism.hooks.add("line-numbers",l):(n(r,a),o=setTimeout(i,1))}}),window.addEventListener("hashchange",i),window.addEventListener("resize",function(){var e=document.querySelectorAll("pre[data-line]");Array.prototype.forEach.call(e,function(e){n(e)})})}}(); +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var e="line-numbers",t=/\n(?!$)/g,n=function(e){var n=r(e),s=n["white-space"];if("pre-wrap"===s||"pre-line"===s){var l=e.querySelector("code"),i=e.querySelector(".line-numbers-rows"),a=e.querySelector(".line-numbers-sizer"),o=l.textContent.split(t);a||(a=document.createElement("span"),a.className="line-numbers-sizer",l.appendChild(a)),a.style.display="block",o.forEach(function(e,t){a.textContent=e||"\n";var n=a.getBoundingClientRect().height;i.children[t].style.height=n+"px"}),a.textContent="",a.style.display="none"}},r=function(e){return e?window.getComputedStyle?getComputedStyle(e):e.currentStyle||null:null};window.addEventListener("resize",function(){Array.prototype.forEach.call(document.querySelectorAll("pre."+e),n)}),Prism.hooks.add("complete",function(e){if(e.code){var r=e.element.parentNode,s=/\s*\bline-numbers\b\s*/;if(r&&/pre/i.test(r.nodeName)&&(s.test(r.className)||s.test(e.element.className))&&!e.element.querySelector(".line-numbers-rows")){s.test(e.element.className)&&(e.element.className=e.element.className.replace(s," ")),s.test(r.className)||(r.className+=" line-numbers");var l,i=e.code.match(t),a=i?i.length+1:1,o=new Array(a+1);o=o.join(""),l=document.createElement("span"),l.setAttribute("aria-hidden","true"),l.className="line-numbers-rows",l.innerHTML=o,r.hasAttribute("data-start")&&(r.style.counterReset="linenumber "+(parseInt(r.getAttribute("data-start"),10)-1)),e.element.appendChild(l),n(r),Prism.hooks.run("line-numbers",e)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0}),Prism.plugins.lineNumbers={getLine:function(t,n){if("PRE"===t.tagName&&t.classList.contains(e)){var r=t.querySelector(".line-numbers-rows"),s=parseInt(t.getAttribute("data-start"),10)||1,l=s+(r.children.length-1);s>n&&(n=s),n>l&&(n=l);var i=n-s;return r.children[i]}}}}}(); +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var t=[],e={},n=function(){};Prism.plugins.toolbar={};var a=Prism.plugins.toolbar.registerButton=function(n,a){var o;o="function"==typeof a?a:function(t){var e;return"function"==typeof a.onClick?(e=document.createElement("button"),e.type="button",e.addEventListener("click",function(){a.onClick.call(this,t)})):"string"==typeof a.url?(e=document.createElement("a"),e.href=a.url):e=document.createElement("span"),e.textContent=a.text,e},t.push(e[n]=o)},o=Prism.plugins.toolbar.hook=function(a){var o=a.element.parentNode;if(o&&/pre/i.test(o.nodeName)&&!o.parentNode.classList.contains("code-toolbar")){var r=document.createElement("div");r.classList.add("code-toolbar"),o.parentNode.insertBefore(r,o),r.appendChild(o);var i=document.createElement("div");i.classList.add("toolbar"),document.body.hasAttribute("data-toolbar-order")&&(t=document.body.getAttribute("data-toolbar-order").split(",").map(function(t){return e[t]||n})),t.forEach(function(t){var e=t(a);if(e){var n=document.createElement("div");n.classList.add("toolbar-item"),n.appendChild(e),i.appendChild(n)}}),r.appendChild(i)}};a("label",function(t){var e=t.element.parentNode;if(e&&/pre/i.test(e.nodeName)&&e.hasAttribute("data-label")){var n,a,o=e.getAttribute("data-label");try{a=document.querySelector("template#"+o)}catch(r){}return a?n=a.content:(e.hasAttribute("data-url")?(n=document.createElement("a"),n.href=e.getAttribute("data-url")):n=document.createElement("span"),n.textContent=o),n}}),Prism.hooks.add("complete",o)}}(); +!function(){"undefined"!=typeof self&&!self.Prism||"undefined"!=typeof global&&!global.Prism||Prism.hooks.add("wrap",function(e){"keyword"===e.type&&e.classes.push("keyword-"+e.content)})}(); +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){if(!Prism.plugins.toolbar)return console.warn("Show Languages plugin loaded before Toolbar plugin."),void 0;var e={html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",css:"CSS",clike:"C-like",javascript:"JavaScript",abap:"ABAP",actionscript:"ActionScript",apacheconf:"Apache Configuration",apl:"APL",applescript:"AppleScript",arff:"ARFF",asciidoc:"AsciiDoc",asm6502:"6502 Assembly",aspnet:"ASP.NET (C#)",autohotkey:"AutoHotkey",autoit:"AutoIt",shell:"Shell",basic:"BASIC",csharp:"C#",cpp:"C++",coffeescript:"CoffeeScript",csp:"Content-Security-Policy","css-extras":"CSS Extras",django:"Django/Jinja2",erb:"ERB",fsharp:"F#",gedcom:"GEDCOM",glsl:"GLSL",graphql:"GraphQL",http:"HTTP",hpkp:"HTTP Public-Key-Pins",hsts:"HTTP Strict-Transport-Security",ichigojam:"IchigoJam",inform7:"Inform 7",json:"JSON",jsonp:"JSONP",latex:"LaTeX",livescript:"LiveScript",lolcode:"LOLCODE","markup-templating":"Markup templating",matlab:"MATLAB",mel:"MEL",n4js:"N4JS",nasm:"NASM",nginx:"nginx",nsis:"NSIS",objectivec:"Objective-C",ocaml:"OCaml",opencl:"OpenCL",parigp:"PARI/GP",objectpascal:"Object Pascal",php:"PHP","php-extras":"PHP Extras",plsql:"PL/SQL",powershell:"PowerShell",properties:".properties",protobuf:"Protocol Buffers",q:"Q (kdb+ database)",jsx:"React JSX",tsx:"React TSX",renpy:"Ren'py",rest:"reST (reStructuredText)",sas:"SAS",sass:"Sass (Sass)",scss:"Sass (Scss)",sql:"SQL",soy:"Soy (Closure Template)",tap:"TAP",tt2:"Template Toolkit 2",typescript:"TypeScript",vbnet:"VB.Net",vhdl:"VHDL",vim:"vim","visual-basic":"Visual Basic",wasm:"WebAssembly",wiki:"Wiki markup",xeoracube:"XeoraCube",xojo:"Xojo (REALbasic)",xquery:"XQuery",yaml:"YAML"};Prism.plugins.toolbar.registerButton("show-language",function(a){var t=a.element.parentNode;if(t&&/pre/i.test(t.nodeName)){var s=t.getAttribute("data-language")||e[a.language]||a.language&&a.language.substring(0,1).toUpperCase()+a.language.substring(1);if(s){var i=document.createElement("span");return i.textContent=s,i}}})}}(); +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){if(!Prism.plugins.toolbar)return console.warn("Copy to Clipboard plugin loaded before Toolbar plugin."),void 0;var o=window.ClipboardJS||void 0;o||"function"!=typeof require||(o=require("clipboard"));var e=[];if(!o){var t=document.createElement("script"),n=document.querySelector("head");t.onload=function(){if(o=window.ClipboardJS)for(;e.length;)e.pop()()},t.src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js",n.appendChild(t)}Prism.plugins.toolbar.registerButton("copy-to-clipboard",function(t){function n(){var e=new o(i,{text:function(){return t.code}});e.on("success",function(){i.textContent="Copied!",r()}),e.on("error",function(){i.textContent="Press Ctrl+C to copy",r()})}function r(){setTimeout(function(){i.textContent="Copy"},5e3)}var i=document.createElement("a");return i.textContent="Copy",o?n():e.push(n),i})}}(); diff --git a/addons/nkeditor/assets/plugins/emoticons/emoticons.js b/addons/nkeditor/assets/plugins/emoticons/emoticons.js new file mode 100644 index 0000000000000000000000000000000000000000..a9900668b97356f0b291e3feb7c7331ef18a0eab --- /dev/null +++ b/addons/nkeditor/assets/plugins/emoticons/emoticons.js @@ -0,0 +1,129 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('emoticons', function(K) { + var self = this, name = 'emoticons', + path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'), + allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons, + currentPageNum = 1; + self.clickToolbar(name, function() { + var rows = 5, cols = 9, total = 135, startNum = 0, + cells = rows * cols, pages = Math.ceil(total / cells), + colsHalf = Math.floor(cols / 2), + wrapperDiv = K('
    '), + elements = [], + menu = self.createMenu({ + name : name, + beforeRemove : function() { + removeEvent(); + } + }); + menu.div.append(wrapperDiv); + var previewDiv, previewImg; + if (allowPreview) { + previewDiv = K('
    ').css('right', 0); + previewImg = K(''); + wrapperDiv.append(previewDiv); + previewDiv.append(previewImg); + } + function bindCellEvent(cell, j, num) { + if (previewDiv) { + cell.mouseover(function() { + if (j > colsHalf) { + previewDiv.css('left', 0); + previewDiv.css('right', ''); + } else { + previewDiv.css('left', ''); + previewDiv.css('right', 0); + } + previewImg.attr('src', path + num + '.gif'); + K(this).addClass('ke-on'); + }); + } else { + cell.mouseover(function() { + K(this).addClass('ke-on'); + }); + } + cell.mouseout(function() { + K(this).removeClass('ke-on'); + }); + cell.click(function(e) { + self.insertHtml('').hideMenu().focus(); + e.stop(); + }); + } + function createEmoticonsTable(pageNum, parentDiv) { + var table = document.createElement('table'); + parentDiv.append(table); + if (previewDiv) { + K(table).mouseover(function() { + previewDiv.show('block'); + }); + K(table).mouseout(function() { + previewDiv.hide(); + }); + elements.push(K(table)); + } + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var num = (pageNum - 1) * cells + startNum; + for (var i = 0; i < rows; i++) { + var row = table.insertRow(i); + for (var j = 0; j < cols; j++) { + var cell = K(row.insertCell(j)); + cell.addClass('ke-cell'); + bindCellEvent(cell, j, num); + var span = K('') + .css('background-position', '-' + (24 * num) + 'px 0px') + .css('background-image', 'url(' + path + 'static.gif)'); + cell.append(span); + elements.push(cell); + num++; + } + } + return table; + } + var table = createEmoticonsTable(currentPageNum, wrapperDiv); + function removeEvent() { + K.each(elements, function() { + this.unbind(); + }); + } + var pageDiv; + function bindPageEvent(el, pageNum) { + el.click(function(e) { + removeEvent(); + table.parentNode.removeChild(table); + pageDiv.remove(); + table = createEmoticonsTable(pageNum, wrapperDiv); + createPageTable(pageNum); + currentPageNum = pageNum; + e.stop(); + }); + } + function createPageTable(currentPageNum) { + pageDiv = K('
    '); + wrapperDiv.append(pageDiv); + for (var pageNum = 1; pageNum <= pages; pageNum++) { + if (currentPageNum !== pageNum) { + var a = K('[' + pageNum + ']'); + bindPageEvent(a, pageNum); + pageDiv.append(a); + elements.push(a); + } else { + pageDiv.append(K('@[' + pageNum + ']')); + } + pageDiv.append(K('@ ')); + } + } + createPageTable(currentPageNum); + }); +}); diff --git a/addons/nkeditor/assets/plugins/emoticons/images/0.gif b/addons/nkeditor/assets/plugins/emoticons/images/0.gif new file mode 100644 index 0000000000000000000000000000000000000000..5be27cb0ecf9a21240e151962f59f94a2ce361ad Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/0.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/1.gif b/addons/nkeditor/assets/plugins/emoticons/images/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..a2644a9ee85fd75515d8368633118e5df1a1bb3b Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/1.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/10.gif b/addons/nkeditor/assets/plugins/emoticons/images/10.gif new file mode 100644 index 0000000000000000000000000000000000000000..905c15be3cee3fca3e8f0e48f0ffcfeb911def34 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/10.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/100.gif b/addons/nkeditor/assets/plugins/emoticons/images/100.gif new file mode 100644 index 0000000000000000000000000000000000000000..92ad35d2bf72018f7b5bec0b607625ccd29f42bd Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/100.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/101.gif b/addons/nkeditor/assets/plugins/emoticons/images/101.gif new file mode 100644 index 0000000000000000000000000000000000000000..1f27663ae037c9be9646c26703aad9c0aa90c57b Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/101.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/102.gif b/addons/nkeditor/assets/plugins/emoticons/images/102.gif new file mode 100644 index 0000000000000000000000000000000000000000..748ded1ac4351e1ee26715098281d70099355c20 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/102.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/103.gif b/addons/nkeditor/assets/plugins/emoticons/images/103.gif new file mode 100644 index 0000000000000000000000000000000000000000..be9eaa05445ef7dbb0c709fbca695bbf06c47ec3 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/103.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/104.gif b/addons/nkeditor/assets/plugins/emoticons/images/104.gif new file mode 100644 index 0000000000000000000000000000000000000000..d7c2066316bacf3736264353fcbf79a5e5d5f4d4 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/104.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/105.gif b/addons/nkeditor/assets/plugins/emoticons/images/105.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f353cadc85e447155e636b50ab392a99b36f664 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/105.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/106.gif b/addons/nkeditor/assets/plugins/emoticons/images/106.gif new file mode 100644 index 0000000000000000000000000000000000000000..51935349b48efeac0e0d50a2cc809817015d32b8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/106.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/107.gif b/addons/nkeditor/assets/plugins/emoticons/images/107.gif new file mode 100644 index 0000000000000000000000000000000000000000..70d38d3bb278969ef82a3c666c5e85192ad65948 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/107.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/108.gif b/addons/nkeditor/assets/plugins/emoticons/images/108.gif new file mode 100644 index 0000000000000000000000000000000000000000..749d500830dfca329998faa17603870723402469 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/108.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/109.gif b/addons/nkeditor/assets/plugins/emoticons/images/109.gif new file mode 100644 index 0000000000000000000000000000000000000000..6f57d5642f1e3ae11479f04d3558b6e9714f07d2 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/109.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/11.gif b/addons/nkeditor/assets/plugins/emoticons/images/11.gif new file mode 100644 index 0000000000000000000000000000000000000000..b512dd5da196b15a6fa31115da13cb24730c14ef Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/11.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/110.gif b/addons/nkeditor/assets/plugins/emoticons/images/110.gif new file mode 100644 index 0000000000000000000000000000000000000000..e253abcff6a046ec78559c5403e2e617a268ecb7 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/110.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/111.gif b/addons/nkeditor/assets/plugins/emoticons/images/111.gif new file mode 100644 index 0000000000000000000000000000000000000000..0c567233d0b370a84f638df0825064ad8d82645e Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/111.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/112.gif b/addons/nkeditor/assets/plugins/emoticons/images/112.gif new file mode 100644 index 0000000000000000000000000000000000000000..c8ddce88a45b7fe4703a663ef2e6a7044c977601 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/112.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/113.gif b/addons/nkeditor/assets/plugins/emoticons/images/113.gif new file mode 100644 index 0000000000000000000000000000000000000000..272710453f6b8f6fc9b6c34192c52dfe5a538293 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/113.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/114.gif b/addons/nkeditor/assets/plugins/emoticons/images/114.gif new file mode 100644 index 0000000000000000000000000000000000000000..53918e2ae600a026da6e13bd2c26cb49c309f026 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/114.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/115.gif b/addons/nkeditor/assets/plugins/emoticons/images/115.gif new file mode 100644 index 0000000000000000000000000000000000000000..4db33697339ec31270ead8d928986ad0d6a13685 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/115.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/116.gif b/addons/nkeditor/assets/plugins/emoticons/images/116.gif new file mode 100644 index 0000000000000000000000000000000000000000..57326bd2fd865df3a6d418f636e10f1b8d10a50f Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/116.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/117.gif b/addons/nkeditor/assets/plugins/emoticons/images/117.gif new file mode 100644 index 0000000000000000000000000000000000000000..14611b6ef950a82aaf12e5c183b7c4f0edc7c243 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/117.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/118.gif b/addons/nkeditor/assets/plugins/emoticons/images/118.gif new file mode 100644 index 0000000000000000000000000000000000000000..8c255004ceea385e7d193d36f9791885db5de933 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/118.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/119.gif b/addons/nkeditor/assets/plugins/emoticons/images/119.gif new file mode 100644 index 0000000000000000000000000000000000000000..65bb468b950af19bb195dbfdc7f13c07d1006ae1 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/119.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/12.gif b/addons/nkeditor/assets/plugins/emoticons/images/12.gif new file mode 100644 index 0000000000000000000000000000000000000000..547529cab6ec7ccc19719487e644b132b40f9d9c Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/12.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/120.gif b/addons/nkeditor/assets/plugins/emoticons/images/120.gif new file mode 100644 index 0000000000000000000000000000000000000000..5ce77c05f0a63219bbc4623ae223c5b8cd6942c6 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/120.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/121.gif b/addons/nkeditor/assets/plugins/emoticons/images/121.gif new file mode 100644 index 0000000000000000000000000000000000000000..a021abaa6d811cf0562ff82ccb24fa76bb9508df Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/121.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/122.gif b/addons/nkeditor/assets/plugins/emoticons/images/122.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a79e111c4884ad613e3778ea862c02d7de0c46d Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/122.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/123.gif b/addons/nkeditor/assets/plugins/emoticons/images/123.gif new file mode 100644 index 0000000000000000000000000000000000000000..b9480be25497315da11e549ef9e000fc9dc1df2e Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/123.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/124.gif b/addons/nkeditor/assets/plugins/emoticons/images/124.gif new file mode 100644 index 0000000000000000000000000000000000000000..7fed47728048476cde5365750a27699a67a6cfc0 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/124.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/125.gif b/addons/nkeditor/assets/plugins/emoticons/images/125.gif new file mode 100644 index 0000000000000000000000000000000000000000..e2c3c11c92c14fa76e5ae842af7e4b51a4cdec70 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/125.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/126.gif b/addons/nkeditor/assets/plugins/emoticons/images/126.gif new file mode 100644 index 0000000000000000000000000000000000000000..24105c988898cc03bf21c4ef26df1f7fb6f34824 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/126.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/127.gif b/addons/nkeditor/assets/plugins/emoticons/images/127.gif new file mode 100644 index 0000000000000000000000000000000000000000..0cead364a05f031b024181e7c778f8b206763312 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/127.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/128.gif b/addons/nkeditor/assets/plugins/emoticons/images/128.gif new file mode 100644 index 0000000000000000000000000000000000000000..3185861818bab566315b08e4484ebe313322d779 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/128.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/129.gif b/addons/nkeditor/assets/plugins/emoticons/images/129.gif new file mode 100644 index 0000000000000000000000000000000000000000..ffd7c6ba331d56153f3366f181bd8ac78c845e98 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/129.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/13.gif b/addons/nkeditor/assets/plugins/emoticons/images/13.gif new file mode 100644 index 0000000000000000000000000000000000000000..34753001ef80a38a08e8a75f23482f528313fd1b Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/13.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/130.gif b/addons/nkeditor/assets/plugins/emoticons/images/130.gif new file mode 100644 index 0000000000000000000000000000000000000000..d828e3da103099151b00c5e700302d8d9c69f6a7 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/130.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/131.gif b/addons/nkeditor/assets/plugins/emoticons/images/131.gif new file mode 100644 index 0000000000000000000000000000000000000000..dcb096f0dab7daf71a3347e0b04c2e5fa3ff33ba Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/131.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/132.gif b/addons/nkeditor/assets/plugins/emoticons/images/132.gif new file mode 100644 index 0000000000000000000000000000000000000000..1b272a690b6740b94956037d021a9f0aa7136b64 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/132.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/133.gif b/addons/nkeditor/assets/plugins/emoticons/images/133.gif new file mode 100644 index 0000000000000000000000000000000000000000..0d0e864264353800e362f1e7b160d9be9980a7b3 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/133.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/134.gif b/addons/nkeditor/assets/plugins/emoticons/images/134.gif new file mode 100644 index 0000000000000000000000000000000000000000..cf48356e334edfac6890439290f2b5d8f109b594 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/134.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/14.gif b/addons/nkeditor/assets/plugins/emoticons/images/14.gif new file mode 100644 index 0000000000000000000000000000000000000000..6a788f8be067976a32bf37c13482a2d41d367ba6 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/14.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/15.gif b/addons/nkeditor/assets/plugins/emoticons/images/15.gif new file mode 100644 index 0000000000000000000000000000000000000000..debab8ed082d3e38ac6a824193311c20f9584a45 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/15.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/16.gif b/addons/nkeditor/assets/plugins/emoticons/images/16.gif new file mode 100644 index 0000000000000000000000000000000000000000..ed5d29f428799b04d07715ccec87fd504d5325b8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/16.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/17.gif b/addons/nkeditor/assets/plugins/emoticons/images/17.gif new file mode 100644 index 0000000000000000000000000000000000000000..85886fef9d4aab3f4b73d2d24866c444319c69f2 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/17.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/18.gif b/addons/nkeditor/assets/plugins/emoticons/images/18.gif new file mode 100644 index 0000000000000000000000000000000000000000..b6af2189c8c6e5edaee66142a76d2ca56b45e8bc Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/18.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/19.gif b/addons/nkeditor/assets/plugins/emoticons/images/19.gif new file mode 100644 index 0000000000000000000000000000000000000000..e045ff2af252ee7a3abbc468442ef7bd98ab16f9 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/19.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/2.gif b/addons/nkeditor/assets/plugins/emoticons/images/2.gif new file mode 100644 index 0000000000000000000000000000000000000000..40cfda436f3087c561bbf0dfe60d2591f8f11e71 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/2.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/20.gif b/addons/nkeditor/assets/plugins/emoticons/images/20.gif new file mode 100644 index 0000000000000000000000000000000000000000..efd650f5598c031ec3a205351c95d9d83bada14b Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/20.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/21.gif b/addons/nkeditor/assets/plugins/emoticons/images/21.gif new file mode 100644 index 0000000000000000000000000000000000000000..cb8cf6d2a19857f6f6a13a16ce84b907da7b8500 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/21.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/22.gif b/addons/nkeditor/assets/plugins/emoticons/images/22.gif new file mode 100644 index 0000000000000000000000000000000000000000..96b04df8652f771d110da55677ef188701433a42 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/22.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/23.gif b/addons/nkeditor/assets/plugins/emoticons/images/23.gif new file mode 100644 index 0000000000000000000000000000000000000000..96516b8d9368ae6562b4da1541b41390d56e4931 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/23.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/24.gif b/addons/nkeditor/assets/plugins/emoticons/images/24.gif new file mode 100644 index 0000000000000000000000000000000000000000..5f925c7bc15698964c943551584ed856aafada3c Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/24.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/25.gif b/addons/nkeditor/assets/plugins/emoticons/images/25.gif new file mode 100644 index 0000000000000000000000000000000000000000..97f8b1afabd2f68e61cad14aca71204148f2b1e8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/25.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/26.gif b/addons/nkeditor/assets/plugins/emoticons/images/26.gif new file mode 100644 index 0000000000000000000000000000000000000000..a7cded731266f64589777db82e8072d73cb51c35 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/26.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/27.gif b/addons/nkeditor/assets/plugins/emoticons/images/27.gif new file mode 100644 index 0000000000000000000000000000000000000000..bb468901e4a9412da4f5fc0c4edeaa73b3acf570 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/27.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/28.gif b/addons/nkeditor/assets/plugins/emoticons/images/28.gif new file mode 100644 index 0000000000000000000000000000000000000000..f59dd58257545068f230bb6515c053a38f47d5ae Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/28.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/29.gif b/addons/nkeditor/assets/plugins/emoticons/images/29.gif new file mode 100644 index 0000000000000000000000000000000000000000..3c5227e8e7796fcbfdfb8aece35232df864f5f00 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/29.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/3.gif b/addons/nkeditor/assets/plugins/emoticons/images/3.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d6f7629968d979878a2defb2d66ece81bdc2af2 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/3.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/30.gif b/addons/nkeditor/assets/plugins/emoticons/images/30.gif new file mode 100644 index 0000000000000000000000000000000000000000..e24a1801c48d9d149c96ea5bf449697c1ceac93c Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/30.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/31.gif b/addons/nkeditor/assets/plugins/emoticons/images/31.gif new file mode 100644 index 0000000000000000000000000000000000000000..073e743ce5f5611321cb04f9e6266024db0070e2 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/31.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/32.gif b/addons/nkeditor/assets/plugins/emoticons/images/32.gif new file mode 100644 index 0000000000000000000000000000000000000000..772eff23e345569189e0dd16516733f20d7b4442 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/32.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/33.gif b/addons/nkeditor/assets/plugins/emoticons/images/33.gif new file mode 100644 index 0000000000000000000000000000000000000000..217c1c581013f2e88905ad0451c0f12b8186ef91 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/33.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/34.gif b/addons/nkeditor/assets/plugins/emoticons/images/34.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9d42131a9bdb8556647e91fa3915425ab730102 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/34.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/35.gif b/addons/nkeditor/assets/plugins/emoticons/images/35.gif new file mode 100644 index 0000000000000000000000000000000000000000..d6da2c33ab4139ac5ec7becbb7221008e0805034 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/35.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/36.gif b/addons/nkeditor/assets/plugins/emoticons/images/36.gif new file mode 100644 index 0000000000000000000000000000000000000000..c1e6ac913b33ee0c0637c4d4e70cb5f7b007a4b8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/36.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/37.gif b/addons/nkeditor/assets/plugins/emoticons/images/37.gif new file mode 100644 index 0000000000000000000000000000000000000000..92efec6ae180c7e685512017cfd06f75c36afa39 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/37.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/38.gif b/addons/nkeditor/assets/plugins/emoticons/images/38.gif new file mode 100644 index 0000000000000000000000000000000000000000..489f0f948d665ef36d803efd512e4727ef673c38 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/38.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/39.gif b/addons/nkeditor/assets/plugins/emoticons/images/39.gif new file mode 100644 index 0000000000000000000000000000000000000000..734f6d82eb95a917d07f6c9fa17a1a178bb168aa Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/39.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/4.gif b/addons/nkeditor/assets/plugins/emoticons/images/4.gif new file mode 100644 index 0000000000000000000000000000000000000000..6ccdaa2c9cf1cb656c0306f6a396f1f765d01786 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/4.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/40.gif b/addons/nkeditor/assets/plugins/emoticons/images/40.gif new file mode 100644 index 0000000000000000000000000000000000000000..24a8eb69149cc1b139e24d3ada04246c42e05c71 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/40.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/41.gif b/addons/nkeditor/assets/plugins/emoticons/images/41.gif new file mode 100644 index 0000000000000000000000000000000000000000..99139e1d1ebbb9123de502b7b8bc0127dc55334f Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/41.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/42.gif b/addons/nkeditor/assets/plugins/emoticons/images/42.gif new file mode 100644 index 0000000000000000000000000000000000000000..f60897e40b26a3cc6529cb4ab5c2de8cd35a15c5 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/42.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/43.gif b/addons/nkeditor/assets/plugins/emoticons/images/43.gif new file mode 100644 index 0000000000000000000000000000000000000000..43504910020ead31098a489ea1e2b6fa51e8314a Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/43.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/44.gif b/addons/nkeditor/assets/plugins/emoticons/images/44.gif new file mode 100644 index 0000000000000000000000000000000000000000..650d3dd84026c33b31712f94d1c189db2b3e7295 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/44.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/45.gif b/addons/nkeditor/assets/plugins/emoticons/images/45.gif new file mode 100644 index 0000000000000000000000000000000000000000..5c8e071815a3cfd3a38f1dd477a305010dd8e239 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/45.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/46.gif b/addons/nkeditor/assets/plugins/emoticons/images/46.gif new file mode 100644 index 0000000000000000000000000000000000000000..f3cb0742d7f2c12475b1fdfca98a46ce3d1dffbc Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/46.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/47.gif b/addons/nkeditor/assets/plugins/emoticons/images/47.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b3057ab7eceb885238c9308a9591b118213703a Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/47.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/48.gif b/addons/nkeditor/assets/plugins/emoticons/images/48.gif new file mode 100644 index 0000000000000000000000000000000000000000..27a30c15c7b6ae395763d9dd900c9806cc702fa4 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/48.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/49.gif b/addons/nkeditor/assets/plugins/emoticons/images/49.gif new file mode 100644 index 0000000000000000000000000000000000000000..dcfa48af01be5b1e2170e7e0f64a65cc5cd70a6a Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/49.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/5.gif b/addons/nkeditor/assets/plugins/emoticons/images/5.gif new file mode 100644 index 0000000000000000000000000000000000000000..ab0b81ba4dd535bbfe38ddd6bc5b35ed85d22a0f Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/5.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/50.gif b/addons/nkeditor/assets/plugins/emoticons/images/50.gif new file mode 100644 index 0000000000000000000000000000000000000000..029cf0feab9660a39b25111936e9b85835bb2a8d Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/50.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/51.gif b/addons/nkeditor/assets/plugins/emoticons/images/51.gif new file mode 100644 index 0000000000000000000000000000000000000000..69f183f043a276acaf62658536b0c4561492578a Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/51.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/52.gif b/addons/nkeditor/assets/plugins/emoticons/images/52.gif new file mode 100644 index 0000000000000000000000000000000000000000..d41e8aab1e210fbdf7cb54247a38b05f086c3072 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/52.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/53.gif b/addons/nkeditor/assets/plugins/emoticons/images/53.gif new file mode 100644 index 0000000000000000000000000000000000000000..56352dde46f7f530c7f4e9cc71a49a8db2e5d525 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/53.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/54.gif b/addons/nkeditor/assets/plugins/emoticons/images/54.gif new file mode 100644 index 0000000000000000000000000000000000000000..b28d8481ea3077ae4d04ab9817273ca46ecc6619 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/54.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/55.gif b/addons/nkeditor/assets/plugins/emoticons/images/55.gif new file mode 100644 index 0000000000000000000000000000000000000000..e18da84c6e550fea8f3cc25d7d64188816f641fd Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/55.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/56.gif b/addons/nkeditor/assets/plugins/emoticons/images/56.gif new file mode 100644 index 0000000000000000000000000000000000000000..edf96f0a63e79e6eb80e22a0774137dab2852e5d Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/56.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/57.gif b/addons/nkeditor/assets/plugins/emoticons/images/57.gif new file mode 100644 index 0000000000000000000000000000000000000000..3f0e2b9af46c46a72bb935137f139294f16ab7eb Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/57.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/58.gif b/addons/nkeditor/assets/plugins/emoticons/images/58.gif new file mode 100644 index 0000000000000000000000000000000000000000..47b1aaa34eb04db3c8cf8420c4401e25bbab2479 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/58.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/59.gif b/addons/nkeditor/assets/plugins/emoticons/images/59.gif new file mode 100644 index 0000000000000000000000000000000000000000..918288b007a2b32426fdc06ab03f5567bea96e1f Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/59.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/6.gif b/addons/nkeditor/assets/plugins/emoticons/images/6.gif new file mode 100644 index 0000000000000000000000000000000000000000..ceab12242b28bf9746b67d7babfca3d5909985f8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/6.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/60.gif b/addons/nkeditor/assets/plugins/emoticons/images/60.gif new file mode 100644 index 0000000000000000000000000000000000000000..66d21136de8dc3e26949cd6447d1ac9881e1a2b5 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/60.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/61.gif b/addons/nkeditor/assets/plugins/emoticons/images/61.gif new file mode 100644 index 0000000000000000000000000000000000000000..034933ec3e3fed2ac2df7b7370289ec2e8feeb13 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/61.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/62.gif b/addons/nkeditor/assets/plugins/emoticons/images/62.gif new file mode 100644 index 0000000000000000000000000000000000000000..8d5c4fd39a08d0315c14c963336f079fef8fb380 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/62.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/63.gif b/addons/nkeditor/assets/plugins/emoticons/images/63.gif new file mode 100644 index 0000000000000000000000000000000000000000..d58fcf671bdb51457baa9a88c599e5d4ae9be4e9 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/63.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/64.gif b/addons/nkeditor/assets/plugins/emoticons/images/64.gif new file mode 100644 index 0000000000000000000000000000000000000000..c4e00bdfda09412d7aa977d227ceef4f4464f288 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/64.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/65.gif b/addons/nkeditor/assets/plugins/emoticons/images/65.gif new file mode 100644 index 0000000000000000000000000000000000000000..da23bfaac75af2b450692e93890435fde4225efb Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/65.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/66.gif b/addons/nkeditor/assets/plugins/emoticons/images/66.gif new file mode 100644 index 0000000000000000000000000000000000000000..310ec65f1090ed879101d6a739bd41c14b4c2745 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/66.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/67.gif b/addons/nkeditor/assets/plugins/emoticons/images/67.gif new file mode 100644 index 0000000000000000000000000000000000000000..51761ba4561e87023eae9d1f5296bf9b663c6a75 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/67.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/68.gif b/addons/nkeditor/assets/plugins/emoticons/images/68.gif new file mode 100644 index 0000000000000000000000000000000000000000..345cb439104d5227534ae2188471176cdff04264 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/68.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/69.gif b/addons/nkeditor/assets/plugins/emoticons/images/69.gif new file mode 100644 index 0000000000000000000000000000000000000000..e0f28a0736509c3e339f72c7f582db36bd52ad70 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/69.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/7.gif b/addons/nkeditor/assets/plugins/emoticons/images/7.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f4539998426e7cbc4114eb8809b680566a70129 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/7.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/70.gif b/addons/nkeditor/assets/plugins/emoticons/images/70.gif new file mode 100644 index 0000000000000000000000000000000000000000..24284cf39d84e7e70e1633199579330ac996e598 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/70.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/71.gif b/addons/nkeditor/assets/plugins/emoticons/images/71.gif new file mode 100644 index 0000000000000000000000000000000000000000..a0ccf2edf5f3c1760323012456f57ddd8e31afd7 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/71.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/72.gif b/addons/nkeditor/assets/plugins/emoticons/images/72.gif new file mode 100644 index 0000000000000000000000000000000000000000..7e113eead2a7258acf539d1a6ee140df28f001b6 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/72.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/73.gif b/addons/nkeditor/assets/plugins/emoticons/images/73.gif new file mode 100644 index 0000000000000000000000000000000000000000..c0293c3ab0750b5a1f654fcd1851c5565dfd1199 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/73.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/74.gif b/addons/nkeditor/assets/plugins/emoticons/images/74.gif new file mode 100644 index 0000000000000000000000000000000000000000..1c52bde9ccd7a6de0be87a2469a8b7a9401810a7 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/74.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/75.gif b/addons/nkeditor/assets/plugins/emoticons/images/75.gif new file mode 100644 index 0000000000000000000000000000000000000000..9cb9aa7961f87230f198c3f85dbd14e5999af3ea Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/75.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/76.gif b/addons/nkeditor/assets/plugins/emoticons/images/76.gif new file mode 100644 index 0000000000000000000000000000000000000000..27019f8ff85d7520cd36fa6f67c6311996228217 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/76.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/77.gif b/addons/nkeditor/assets/plugins/emoticons/images/77.gif new file mode 100644 index 0000000000000000000000000000000000000000..8f882f53173bb627b3d1660f950acd25ef2771d8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/77.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/78.gif b/addons/nkeditor/assets/plugins/emoticons/images/78.gif new file mode 100644 index 0000000000000000000000000000000000000000..d0d0856045d240cd96871afa4fca7c48d8d152d9 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/78.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/79.gif b/addons/nkeditor/assets/plugins/emoticons/images/79.gif new file mode 100644 index 0000000000000000000000000000000000000000..61652a71687509883c73273bce1bee24d49721f7 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/79.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/8.gif b/addons/nkeditor/assets/plugins/emoticons/images/8.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6c883447ca373fecdb60210e27c858844add470 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/8.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/80.gif b/addons/nkeditor/assets/plugins/emoticons/images/80.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a779364b3381afe3c1faf86bf94a29825a43db0 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/80.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/81.gif b/addons/nkeditor/assets/plugins/emoticons/images/81.gif new file mode 100644 index 0000000000000000000000000000000000000000..2329101a71efc84d76fcdc0e0acab11fa4b832fd Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/81.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/82.gif b/addons/nkeditor/assets/plugins/emoticons/images/82.gif new file mode 100644 index 0000000000000000000000000000000000000000..644748a96ca06c8518ed8618b9df99265748558b Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/82.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/83.gif b/addons/nkeditor/assets/plugins/emoticons/images/83.gif new file mode 100644 index 0000000000000000000000000000000000000000..fbf275ba500778d06fb2709e0e5556ae8afddc16 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/83.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/84.gif b/addons/nkeditor/assets/plugins/emoticons/images/84.gif new file mode 100644 index 0000000000000000000000000000000000000000..076f0c65cf7162d9244e3ebf86ca56d6b6f05ddb Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/84.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/85.gif b/addons/nkeditor/assets/plugins/emoticons/images/85.gif new file mode 100644 index 0000000000000000000000000000000000000000..d254af44216ecbbc9cbece9ea5588a15bbb36ac6 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/85.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/86.gif b/addons/nkeditor/assets/plugins/emoticons/images/86.gif new file mode 100644 index 0000000000000000000000000000000000000000..8f09d336a30070add12af16be11397ac97436234 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/86.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/87.gif b/addons/nkeditor/assets/plugins/emoticons/images/87.gif new file mode 100644 index 0000000000000000000000000000000000000000..df70756f0c74d0aa64c84efe026966e941f40aab Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/87.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/88.gif b/addons/nkeditor/assets/plugins/emoticons/images/88.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d8b15e7e625ddb98838f58ca001f3163c5fad45 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/88.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/89.gif b/addons/nkeditor/assets/plugins/emoticons/images/89.gif new file mode 100644 index 0000000000000000000000000000000000000000..05726dc4abb26afda444aa8b059006bff0af1bec Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/89.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/9.gif b/addons/nkeditor/assets/plugins/emoticons/images/9.gif new file mode 100644 index 0000000000000000000000000000000000000000..c2d84507528f0aadfd63e466bd31e3b2bd9a7f05 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/9.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/90.gif b/addons/nkeditor/assets/plugins/emoticons/images/90.gif new file mode 100644 index 0000000000000000000000000000000000000000..adaf20e8bbdf42f907448d691c8af19333838b9f Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/90.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/91.gif b/addons/nkeditor/assets/plugins/emoticons/images/91.gif new file mode 100644 index 0000000000000000000000000000000000000000..608d0ad87c31a4e2ac8a28529c7af1a08a0abbbc Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/91.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/92.gif b/addons/nkeditor/assets/plugins/emoticons/images/92.gif new file mode 100644 index 0000000000000000000000000000000000000000..b909e16a89ccfdccdd75cb7d67cfa5dcef7c10d5 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/92.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/93.gif b/addons/nkeditor/assets/plugins/emoticons/images/93.gif new file mode 100644 index 0000000000000000000000000000000000000000..7f71a8c94cde07ca85f7e7880732cb41f02c053b Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/93.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/94.gif b/addons/nkeditor/assets/plugins/emoticons/images/94.gif new file mode 100644 index 0000000000000000000000000000000000000000..4f26d7d734f5a92178a96f81a7b409e9eca9bcc7 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/94.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/95.gif b/addons/nkeditor/assets/plugins/emoticons/images/95.gif new file mode 100644 index 0000000000000000000000000000000000000000..5ef6d3823c78c7e46781c7c06e448d3e1673640f Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/95.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/96.gif b/addons/nkeditor/assets/plugins/emoticons/images/96.gif new file mode 100644 index 0000000000000000000000000000000000000000..2b709e15bade2f707632e1a4bdc2b7e97521b4d8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/96.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/97.gif b/addons/nkeditor/assets/plugins/emoticons/images/97.gif new file mode 100644 index 0000000000000000000000000000000000000000..cf29be87c890a6633eda84dacba996a29183c09e Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/97.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/98.gif b/addons/nkeditor/assets/plugins/emoticons/images/98.gif new file mode 100644 index 0000000000000000000000000000000000000000..c70e7d339fca9d0d12b9e66a1fbb6a68f4c6f4b4 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/98.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/99.gif b/addons/nkeditor/assets/plugins/emoticons/images/99.gif new file mode 100644 index 0000000000000000000000000000000000000000..05c18635da1b3258e044e30de4f7a72058bfd6c8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/99.gif differ diff --git a/addons/nkeditor/assets/plugins/emoticons/images/static.gif b/addons/nkeditor/assets/plugins/emoticons/images/static.gif new file mode 100644 index 0000000000000000000000000000000000000000..b8c444b5a2e0e25d8bbc988d8d72d1582e15e904 Binary files /dev/null and b/addons/nkeditor/assets/plugins/emoticons/images/static.gif differ diff --git a/addons/nkeditor/assets/plugins/filemanager/FManager.js b/addons/nkeditor/assets/plugins/filemanager/FManager.js new file mode 100644 index 0000000000000000000000000000000000000000..ad8a8f870466a100872efef2d177ac8bc11aee42 --- /dev/null +++ b/addons/nkeditor/assets/plugins/filemanager/FManager.js @@ -0,0 +1,307 @@ +/** + * HTML5上传插件 + * @author yangjian + * @version 1.0.1 + * @site https://git.oschina.net/blackfox/ajaxUpload + */ +(function ($) { + + //判断浏览器是否支持html5 + // if ( !window.applicationCache ) + // throw new Error("您当前的浏览器不支持HTML5,请先升级浏览器才能使用该上传插件!"); + + //image crop + $.fn.imageCrop = function (__width, __height) { + $(this).on("load", function () { + + var width, height, left, top; + var orgRate = this.width / this.height; + var cropRate = __width / __height; + if (orgRate >= cropRate) { + height = __height; + width = __width * orgRate; + top = 0; + left = (width - __width) / 2; + } else { + width = __width; + height = __height / orgRate; + left = 0; + //top = (height - __height)/2; + top = 0; + } + $(this).css({ + "position": "absolute", + top: -top + "px", + left: -left + "px", + width: width + "px", + height: height + "px" + }); + }); + } + + //make element draggable + $.fn.draggable = function (options) { + var defaults = { + handler: null + } + options = $.extend(defaults, options); + var __self = this; + $(options.handler).mousedown(function (e) { + var offsetLeft = e.pageX - $(__self).position().left; + var offsetTop = e.pageY - $(__self).position().top; + $(document).mousemove(function (e) { + //清除拖动鼠标的时候选择文本 + window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); + $(__self).css({ + 'top': e.pageY - offsetTop + 'px', + 'left': e.pageX - offsetLeft + 'px' + }); + }); + + }).mouseup(function () { + $(document).unbind('mousemove'); + }); + + } + + if (Array.prototype.remove == undefined) { + Array.prototype.remove = function (item) { + for (var i = 0; i < this.length; i++) { + if (this[i] == item) { + this.splice(i, 1); + break; + } + } + } + } + if (Array.prototype.uinque == undefined) { + Array.prototype.uinque = function () { + var result = [], hash = {}; + for (var i = 0, item; (item = this[i]) != null; i++) { + if (!hash[item]) { + result.push(item); + hash[item] = true; + } + } + return result; + } + } + + window.FManager = function (options) { + options = $.extend({ + lang: {}, + list_url: null, + data_type: "json", + fileType: "image", //文件类型,默认是图片,可选flash,media,file + top: 20, + multiple: false, + callback: function (data) { + console.log(data); + } + }, options); + + var o = {}; + o.dialog = null; + o.selectedList = new Array(); //the file queue upload successfully + o.page = 1; //服务器图片列表页码 + o.marker = null, //七牛云上传的分页标识 + o.noRecord = false; + + //close the dialog + o.close = function () { + o.dialog.remove(); + try { + JDialog.lock.hide(); + } catch (e) { + } + if (typeof options.close == 'function') { + options.close(); + } + } + + //create dialog + function createDialog() { + + var builder = new StringBuilder(); + builder.append('
    '); + builder.append('
    ' + options.lang.title + '
    '); + builder.append('
    '); + builder.append('
      '); + builder.append('
      '); + builder.append('
      ' + options.lang.loadMoreData + '
      ') + builder.append('' + options.lang.confirmBtnText + '') + builder.append('' + options.lang.cancelBtnText + '
      '); + + o.dialog = $(builder.toString()); + $("body").append(o.dialog); + if (options.top == 0) { + options.top = ($(window).height() - o.dialog.height()) / 2; + } + o.dialog.css({ + left: ($(window).width() - o.dialog.width()) / 2 + "px", + top: options.top + "px" + }); + //给对话框添加拖拽事件 + o.dialog.draggable({handler: o.dialog.find(".ued_title")}); + loadFilesFromServer(); + + } + + //绑定元素事件 + function bindEvent() { + + //关闭对话框 + G(".close_btn").on("click", function () { + o.close(); + }); + + //点击确认|取消按钮事件 + G(".btn-confirm").on("click", function () { + options.callback(o.selectedList); + o.close(); + }); + G(".btn-cancel").on("click", function () { + o.close(); + }); + + //当滚动条滚到底部时自动去加载图片 + G(".imagelist").on("scroll", function () { + + if (this.scrollTop + this.clientHeight >= this.scrollHeight) { + loadFilesFromServer(); + } + }); + + } + + //query + function G(query) { + return o.dialog.find(query); + } + + //从服务器上获取图片地址 + function loadFilesFromServer() { + if (!options.list_url) { + G(".online .no-data").html('' + options.lang.noListUrl + '').show(); + return false; + } + if (o.noRecord) return false; + + G(".loading-icon").show(); //显示加载图标 + $.get(options.list_url, { + page: o.page, + marker: o.marker, + fileType: options.fileType + }, function (res) { + + G(".loading-icon").hide(); //隐藏加载图标 + if (res.code == "000") { + if (!res.data[0]) { + G(".online .no-data").html(options.lang.noDataText).show(); + return; + } + o.page++; + o.marker = res.extra; //存储marker + appendFiles(res.data); + } else { + G(".online .no-data").text(options.lang.noDataText).show(); + o.noRecord = true; + } + + }, "json"); + } + + //追加元素到图片列表 + function appendFiles(data) { + + $.each(data, function (idx, item) { + + var builder = new StringBuilder(); + builder.append('
    • '); + var extension = getFileExt(item.thumbURL); + if (extension == '') extension = "default"; + extension = extension.toLowerCase(); + //如果不是图片,则根据文件的后缀名去加载对应的缩略图 + var imgSize = item.width + 'x' + item.height; //图片尺寸 + if ("jpg|jpeg|gif|png|bmp".indexOf(extension) == -1) { + imgSize = formatFileSize(item.filesize); //如果是文件则显示文件大小 + builder.append(''); + } else { + builder.append(''); + } + + builder.append('' + imgSize + '
    • '); + var $image = $(builder.toString()); + + //绑定选择图片事件 + $image.find(".ic").on("click", function () { + var src = $(this).prev().attr("data-src"); + var oldSrc = $('.selected:eq(0)').prev().attr("data-src"); + if (options.multiple) { + //多选 + if ($(this).hasClass("selected")) { + $(this).removeClass("selected"); + o.selectedList.remove(src); + } else { + $(this).addClass("selected"); + o.selectedList.push(src); + } + } else { + //这里暂时改成单选 + $('.selected:eq(0)').removeClass("selected"); //移除之前的选中的图片 + o.selectedList.remove(oldSrc); + $(this).addClass("selected"); + o.selectedList.push(src); + } + //console.log(o.selectedList); + }); + //裁剪显示图片 + $image.find("img").imageCrop(113, 113); + G(".imagelist .list").append($image); + }); + + } + + //获取文件后缀名 + function getFileExt(filename) { + if (!filename) return false; + var position = filename.lastIndexOf('.') + if (position != -1) { + return filename.substr(position + 1).toLowerCase(); + } + return false; + } + + //format file size(格式化文件大小) + function formatFileSize(size) { + + if (size / 1048576 > 1) { + return (size / 1048576).toFixed(2) + "MB"; + } else { + return (size / 1024).toFixed(2) + "KB"; + } + + } + + //initialize dialog + createDialog(); + bindEvent(); + return o; + }; //end of JUpload + + //string builder + var StringBuilder = function () { + + var buffer = new Array(); + StringBuilder.prototype.append = function (str) { + buffer.push(str); + } + + StringBuilder.prototype.toString = function () { + return buffer.join(""); + } + + } + + +})(jQuery); \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/filemanager/FManager.min.js b/addons/nkeditor/assets/plugins/filemanager/FManager.min.js new file mode 100644 index 0000000000000000000000000000000000000000..508bf23de9578162582699c27e36009b07e3a2d2 --- /dev/null +++ b/addons/nkeditor/assets/plugins/filemanager/FManager.min.js @@ -0,0 +1,2 @@ +/* NKeditor 5.0.3 (2018-10-25), Copyright (C) r9it.com,*/ +!function(a){if(!window.applicationCache)throw new Error("您当前的浏览器不支持HTML5,请先升级浏览器才能使用该上传插件!");a.fn.imageCrop=function(b,c){a(this).on("load",function(){var d,e,f,g,h=this.width/this.height,i=b/c;h>=i?(e=c,d=b*h,g=0,f=(d-b)/2):(d=b,e=c/h,f=0,g=0),a(this).css({position:"absolute",top:-g+"px",left:-f+"px",width:d+"px",height:e+"px"})})},a.fn.draggable=function(b){var c={handler:null};b=a.extend(c,b);var d=this;a(b.handler).mousedown(function(b){var c=b.pageX-a(d).position().left,e=b.pageY-a(d).position().top;a(document).mousemove(function(b){window.getSelection?window.getSelection().removeAllRanges():document.selection.empty(),a(d).css({top:b.pageY-e+"px",left:b.pageX-c+"px"})})}).mouseup(function(){a(document).unbind("mousemove")})},void 0==Array.prototype.remove&&(Array.prototype.remove=function(a){for(var b=0;b
      '),d.append('
      '+c.lang.title+'
      '),d.append('
      '),d.append('
        '),d.append('
        '),d.append('
        '+c.lang.loadMoreData+"
        "),d.append(''+c.lang.confirmBtnText+""),d.append(''+c.lang.cancelBtnText+"
        "),k.dialog=a(d.toString()),a("body").append(k.dialog),0==c.top&&(c.top=(a(window).height()-k.dialog.height())/2),k.dialog.css({left:(a(window).width()-k.dialog.width())/2+"px",top:c.top+"px"}),k.dialog.draggable({handler:k.dialog.find(".ued_title")}),g()}function e(){f(".close_btn").on("click",function(){k.close()}),f(".btn-confirm").on("click",function(){c.callback(k.selectedList),k.close()}),f(".btn-cancel").on("click",function(){k.close()}),f(".imagelist").on("scroll",function(){this.scrollTop+this.clientHeight>=this.scrollHeight&&g()})}function f(a){return k.dialog.find(a)}function g(){return c.list_url?k.noRecord?!1:(f(".loading-icon").show(),void a.get(c.list_url,{page:k.page,marker:k.marker,fileType:c.fileType},function(a){if(f(".loading-icon").hide(),"000"==a.code){if(!a.data[0])return void f(".online .no-data").html(c.lang.noDataText).show();k.page++,k.marker=a.extra,h(a.data)}else f(".online .no-data").text(c.lang.noDataText).show(),k.noRecord=!0},"json")):(f(".online .no-data").html(''+c.lang.noListUrl+"").show(),!1)}function h(c){a.each(c,function(c,d){var e=new b;e.append("
      • ");var g=i(d.thumbURL);""==g&&(g="default"),g=g.toLowerCase();var h=d.width+"x"+d.height;-1=="jpg|jpeg|gif|png|bmp".indexOf(g)?(h=j(d.filesize),e.append('')):e.append(''),e.append(''+h+"
      • ");var l=a(e.toString());l.find(".ic").on("click",function(){var b=a(this).prev().attr("data-src"),c=a(".selected:eq(0)").prev().attr("data-src");a(".selected:eq(0)").removeClass("selected"),k.selectedList.remove(c),a(this).addClass("selected"),k.selectedList.push(b)}),l.find("img").imageCrop(113,113),f(".imagelist .list").append(l)})}function i(a){if(!a)return!1;var b=a.lastIndexOf(".");return-1!=b?a.substr(b+1).toLowerCase():!1}function j(a){return a/1048576>1?(a/1048576).toFixed(2)+"MB":(a/1024).toFixed(2)+"KB"}c=a.extend({lang:{},list_url:null,data_type:"json",fileType:"image",top:20,callback:function(a){console.log(a)}},c);var k={};return k.dialog=null,k.selectedList=new Array,k.page=1,k.marker=null,k.noRecord=!1,k.close=function(){k.dialog.remove();try{JDialog.lock.hide()}catch(a){}"function"==typeof c.close&&c.close()},d(),e(),k};var b=function(){var a=new Array;b.prototype.append=function(b){a.push(b)},b.prototype.toString=function(){return a.join("")}}}(jQuery); \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/filemanager/css/filemanager.min.css b/addons/nkeditor/assets/plugins/filemanager/css/filemanager.min.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/addons/nkeditor/assets/plugins/filemanager/filemanager.js b/addons/nkeditor/assets/plugins/filemanager/filemanager.js new file mode 100644 index 0000000000000000000000000000000000000000..9f740f86ceb6f642b428ea09b821856317b4186a --- /dev/null +++ b/addons/nkeditor/assets/plugins/filemanager/filemanager.js @@ -0,0 +1,35 @@ +/** + * 文件服务器管理 + * @author yangjian + * @since v4.1.12(2017-09-12) + * @site http://git.oschina.net/blackfox/kindeditor + */ +KindEditor.plugin('filemanager', function(K) { + var self = this; + var fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'); + var lang = self.lang('filemanager.'); + if(typeof jQuery == 'undefined') { + K.options.errorMsgHandler(lang.depJQueryError, "error"); + return; + } else { + K.loadScript(K.options.pluginsPath+"filemanager/FManager.js"); + K.loadStyle(K.options.pluginsPath+"multiimage/css/upload.css"); + } + + self.plugin.filemanagerDialog = function(options) { + + var clickFn = options.clickFn; + new FManager({ + list_url : fileManagerJson, //图片列表数据获取url + lang : lang, //语言包 + fileType : options.dirName, + top : self.dialogOffset, + callback : function(data) { + //console.log(data); + clickFn.call(this, data[0]); + } + }); + //return dialog; + } + +}); diff --git a/addons/nkeditor/assets/plugins/fixtoolbar/fixtoolbar.js b/addons/nkeditor/assets/plugins/fixtoolbar/fixtoolbar.js new file mode 100644 index 0000000000000000000000000000000000000000..7a16fca078fba2eecde5a4998bb945394d740f8a --- /dev/null +++ b/addons/nkeditor/assets/plugins/fixtoolbar/fixtoolbar.js @@ -0,0 +1,35 @@ +/** + * Created by chenyihong on 14/12/4. + */ + +KindEditor.plugin('fixtoolbar', function (K) { + var self = this; + if (!self.fixToolBar) { + return; + } + + function init() { + var toolbar = K('.ke-toolbar'); + var originY = toolbar.pos().y; + K(window).bind('scroll', function () { + if (toolbar.css('position') == 'fixed') { + if(document.body.scrollTop - originY < 0){ + toolbar.css('position', 'static'); + toolbar.css('top', 'auto'); + } + } else { + if (toolbar.pos().y - document.body.scrollTop < 0) { + toolbar.css('position', 'fixed'); + toolbar.css('top', 0); + } + } + }); + } + + if (self.isCreated) { + init(); + } else { + self.afterCreate(init); + } + +}); diff --git a/addons/nkeditor/assets/plugins/flash/flash.js b/addons/nkeditor/assets/plugins/flash/flash.js new file mode 100644 index 0000000000000000000000000000000000000000..f26eaf32edaf3fa721aff83fd980df958fa16c52 --- /dev/null +++ b/addons/nkeditor/assets/plugins/flash/flash.js @@ -0,0 +1,165 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('flash', function(K) { + var self = this, name = 'flash', lang = self.lang(name + '.'), + allowFlashUpload = K.undef(self.allowFlashUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.flash = { + edit : function() { + var html = [ + '
        ', + //url + '
        ', + '', + '
        ', + '  ', + '  ', + '', + '', + '', + '
        ', + '
        ', + //width + '
        ', + '', + '
        ', + ' ', + '
        ', + '
        ', + //height + '
        ', + '', + '
        ', + ' ', + '
        ', + '
        ', + '
        ' + ].join(''); + + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + K.options.errorMsgHandler(self.lang('invalidUrl'), "error"); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + K.options.errorMsgHandler(self.lang('invalidWidth'), "error"); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + K.options.errorMsgHandler(self.lang('invalidHeight'), "error"); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType('.swf'), + width : width, + height : height, + quality : 'high' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div); + urlBox.val('http://'); + + if (allowFlashUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'fileType=flash'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.code === "000") { + var url = data.data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + K.options.errorMsgHandler(self.lang('uploadSuccess'), "ok"); + } else { + K.options.errorMsgHandler(data.message, "error"); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + dirName : 'flash', + clickFn : function(url) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + } + }); + }); + }); + } else { + K('[name="url"]').css("width", "250px"); + viewServerBtn.hide(); + } + + var img = self.plugin.getSelectedFlash(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedFlash().remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.flash.edit); +}); diff --git a/addons/nkeditor/assets/plugins/graft/css/images/addimg.png b/addons/nkeditor/assets/plugins/graft/css/images/addimg.png new file mode 100644 index 0000000000000000000000000000000000000000..03a87135bab65fa2633156789ed0f4a906d6c48b Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/addimg.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/blur.png b/addons/nkeditor/assets/plugins/graft/css/images/blur.png new file mode 100644 index 0000000000000000000000000000000000000000..6307d27916eea5a147d5ba1c1c3fd8f4882c2cc0 Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/blur.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/brush.png b/addons/nkeditor/assets/plugins/graft/css/images/brush.png new file mode 100644 index 0000000000000000000000000000000000000000..efa6fdb01a8e5cf161dc62bfb20894689a1730bd Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/brush.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/delimg.png b/addons/nkeditor/assets/plugins/graft/css/images/delimg.png new file mode 100644 index 0000000000000000000000000000000000000000..5a892e40ad3257f632b34a873b517dd5d590cc9f Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/delimg.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/delimgH.png b/addons/nkeditor/assets/plugins/graft/css/images/delimgH.png new file mode 100644 index 0000000000000000000000000000000000000000..2f0c5c9de33a431d1c8e50cd12da74505921ad7e Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/delimgH.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/empty.png b/addons/nkeditor/assets/plugins/graft/css/images/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..0375196257ac3c859373b3ebebbabe6f16105587 Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/empty.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/emptyH.png b/addons/nkeditor/assets/plugins/graft/css/images/emptyH.png new file mode 100644 index 0000000000000000000000000000000000000000..838ca723119499465f29e881a745f4d8a051e22c Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/emptyH.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/eraser.png b/addons/nkeditor/assets/plugins/graft/css/images/eraser.png new file mode 100644 index 0000000000000000000000000000000000000000..63e87cecb90ed3ac0e4acbc257c6dddae5311e09 Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/eraser.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/init.png b/addons/nkeditor/assets/plugins/graft/css/images/init.png new file mode 100644 index 0000000000000000000000000000000000000000..c2eb7bed91e964de1390a3218125ba7c874ad2e4 Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/init.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/redo.png b/addons/nkeditor/assets/plugins/graft/css/images/redo.png new file mode 100644 index 0000000000000000000000000000000000000000..12cd9bbefc637c7c0a394d00e9d70333ac0f6ea5 Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/redo.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/redoH.png b/addons/nkeditor/assets/plugins/graft/css/images/redoH.png new file mode 100644 index 0000000000000000000000000000000000000000..d9f33d38a3d11ce10447830ce409a0890ecad264 Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/redoH.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/save.png b/addons/nkeditor/assets/plugins/graft/css/images/save.png new file mode 100644 index 0000000000000000000000000000000000000000..2ab611e0277aedf2f82f5bff5d81a90380ce4184 Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/save.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/scale.png b/addons/nkeditor/assets/plugins/graft/css/images/scale.png new file mode 100644 index 0000000000000000000000000000000000000000..935a3f3e1eee04b8a3aa6f70681376298d11e22a Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/scale.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/scaleH.png b/addons/nkeditor/assets/plugins/graft/css/images/scaleH.png new file mode 100644 index 0000000000000000000000000000000000000000..72e64a9d0f3ef081ffda153c755600dc4a758e5b Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/scaleH.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/size.png b/addons/nkeditor/assets/plugins/graft/css/images/size.png new file mode 100644 index 0000000000000000000000000000000000000000..8366845059c94089aef92aa3aeeee79e242732eb Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/size.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/undo.png b/addons/nkeditor/assets/plugins/graft/css/images/undo.png new file mode 100644 index 0000000000000000000000000000000000000000..084c7cc73f4058c8084e5ea3ab4e51fd105b7991 Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/undo.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/images/undoH.png b/addons/nkeditor/assets/plugins/graft/css/images/undoH.png new file mode 100644 index 0000000000000000000000000000000000000000..fde7eb3c2e8080be0224b603f65c3fa5552418be Binary files /dev/null and b/addons/nkeditor/assets/plugins/graft/css/images/undoH.png differ diff --git a/addons/nkeditor/assets/plugins/graft/css/scrawl.css b/addons/nkeditor/assets/plugins/graft/css/scrawl.css new file mode 100644 index 0000000000000000000000000000000000000000..f53a5d7a223fe58201848c58611f6290642e8f93 --- /dev/null +++ b/addons/nkeditor/assets/plugins/graft/css/scrawl.css @@ -0,0 +1,204 @@ +/*common +*/ +body { + margin: 0; } + body a { + text-decoration: none; } + body em { + font-style: normal; } + body .border_style { + border: 1px solid #ccc; + border-radius: 5px; + box-shadow: 2px 2px 5px #d3d6da; } + body em { + font-style: normal; } + body .ke-dialog-body { + padding-top: 8px; } + body .scrawl-main { + padding: 0px 8px; + zoom: 1; + overflow: hidden; + max-width: 1000px; } + body .scrawl-main .hot { + float: left; } + body .scrawl-main .hot .drawBoard { + position: relative; + cursor: crosshair; } + body .scrawl-main .hot .drawBoard .brushBorad { + position: absolute; + left: 0; + top: 0; + z-index: 998; } + body .scrawl-main .hot .drawBoard .picBoard { + border: none; + text-align: center; + cursor: default; } + body .scrawl-main .hot .operateBar { + margin-top: 10px; + font-size: 12px; + text-align: center; } + body .scrawl-main .hot .operateBar span { + margin-left: 10px; } + body .scrawl-main .hot .operateBar button { + background: #e1e1e1; + border: 1px solid #cccccc; + margin: 0px 5px; + cursor: default; } + body .scrawl-main .hot .operateBar .prevStep .icon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/undo.png"); } + body .scrawl-main .hot .operateBar .prevStep.active { + cursor: pointer; + background: #FFFFFF; + border-color: #56CCCC; } + body .scrawl-main .hot .operateBar .prevStep.active .icon { + background-image: url("images/undoH.png"); } + body .scrawl-main .hot .operateBar .nextStep .icon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/redo.png"); } + body .scrawl-main .hot .operateBar .nextStep.active { + cursor: pointer; + background: #FFFFFF; + border-color: #56CCCC; } + body .scrawl-main .hot .operateBar .nextStep.active .icon { + background-image: url("images/redoH.png"); } + body .scrawl-main .hot .operateBar .clearBoard { + cursor: default; } + body .scrawl-main .hot .operateBar .clearBoard .icon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/empty.png"); } + body .scrawl-main .hot .operateBar .clearBoard.active { + cursor: pointer; + background: #FFFFFF; + border-color: #56CCCC; } + body .scrawl-main .hot .operateBar .clearBoard.active .icon { + background-image: url("images/emptyH.png"); } + body .scrawl-main .hot .operateBar .scaleBoard .icon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/scale.png"); + cursor: default; } + body .scrawl-main .hot .operateBar .scaleBoard .iconH { + background-image: url("images/scaleH.png"); } + body .scrawl-main .hot .operateBar .scaleBoard .text { + color: #ccc; + cursor: default; } + body .scrawl-main .drawToolbar { + float: right; + width: 110px; + height: 320px; + overflow: hidden; } + body .scrawl-main .drawToolbar .brushIcon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/brush.png"); } + body .scrawl-main .drawToolbar .eraserIcon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/eraser.png"); } + body .scrawl-main .drawToolbar .blurIcon { + display: inline-block; + width: 16px; + height: 16px; + background: url(images/blur.png) -2px -2px; + background-size: 22px 20px; } + body .scrawl-main .drawToolbar .colorBar { + margin-top: 10px; + font-size: 12px; + text-align: center; + zoom: 1; + overflow: hidden; } + body .scrawl-main .drawToolbar .colorBar span { + float: left; + margin: 2px 3px; + width: 10px; + height: 10px; + border: 1px solid #c1c1c1; + border-radius: 3px; + cursor: pointer; } + body .scrawl-main .drawToolbar .colorBar .active { + border-color: #FF0000; + box-shadow: 2px 2px 5px #d3d6da; } + body .scrawl-main .drawToolbar .sectionBar { + margin-top: 15px; + font-size: 12px; + text-align: center; } + body .scrawl-main .drawToolbar .sectionBar a { + display: inline-block; + width: 10px; + height: 12px; + color: #888; + text-indent: -999px; + opacity: 0.3; } + body .scrawl-main .drawToolbar .sectionBar .size1 { + background: url("images/size.png") 1px center no-repeat; } + body .scrawl-main .drawToolbar .sectionBar .size2 { + background: url("images/size.png") -10px center no-repeat; } + body .scrawl-main .drawToolbar .sectionBar .size3 { + background: url("images/size.png") -22px center no-repeat; } + body .scrawl-main .drawToolbar .sectionBar .size4 { + background: url("images/size.png") -35px center no-repeat; } + body .scrawl-main .drawToolbar .sectionBar .icon { + position: relative; + top: 3px; } + body .scrawl-main .drawToolbar .sectionBar .clearSetting .icon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/init.png"); + background-size: 16px 16px; } + body .scrawl-main .drawToolbar .sectionBar .addImgH { + position: relative; } + body .scrawl-main .drawToolbar .sectionBar .addImgH .icon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/addimg.png"); + cursor: default; } + body .scrawl-main .drawToolbar .sectionBar .addImgH .upload { + position: absolute; + left: 18px; + top: -1px; + width: 75px; + height: 21px; + opacity: 0; + cursor: pointer; + opacity: 0; } + body .scrawl-main .drawToolbar .sectionBar .removeImg .icon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/delimg.png"); + cursor: default; } + body .scrawl-main .drawToolbar .sectionBar .removeImg .text { + color: #ccc; + cursor: default; } + body .scrawl-main .drawToolbar .sectionBar .removeImg.active { + cursor: pointer; } + body .scrawl-main .drawToolbar .sectionBar .removeImg.active .icon { + background-image: url("images/delimgH.png"); } + body .scrawl-main .drawToolbar .sectionBar .removeImg.active .text { + color: #000; + cursor: default; } + body .scrawl-main .drawToolbar .sectionBar .saveImg { + cursor: pointer; } + body .scrawl-main .drawToolbar .sectionBar .saveImg .icon { + display: inline-block; + width: 16px; + height: 16px; + background-image: url("images/save.png"); + background-size: 18px 18px; + cursor: default; } + body .scrawl-main .drawToolbar #clearSetting { + cursor: pointer; } + +/*# sourceMappingURL=scrawl.css.map */ diff --git a/addons/nkeditor/assets/plugins/graft/css/scrawl.scss b/addons/nkeditor/assets/plugins/graft/css/scrawl.scss new file mode 100644 index 0000000000000000000000000000000000000000..fc23a3e4ed4054cca2360e14ed31e0ee9c23d56c --- /dev/null +++ b/addons/nkeditor/assets/plugins/graft/css/scrawl.scss @@ -0,0 +1,284 @@ +/*common +*/ +body { + + margin: 0; + a{text-decoration: none;} + em{font-style: normal;} + + .border_style{ + border: 1px solid #ccc; + border-radius: 5px; + box-shadow:2px 2px 5px #d3d6da; + } + em {font-style: normal;} + + .ke-dialog-body { + padding-top: 8px; + } + .scrawl-main { + padding: 0px 8px; + zoom: 1; + overflow: hidden; + max-width: 1000px; + + + // 绘图区域 + .hot { + float:left; + + .drawBoard{ + position: relative; + cursor: crosshair; + + .brushBorad{ + position: absolute; + left:0; + top:0; + z-index: 998; + } + + .picBoard{ + border: none; + text-align: center; + cursor: default; + } + } + + .operateBar{ + margin-top:10px; + font-size:12px; + text-align: center; + + span {margin-left: 10px;} + + button { + background:#e1e1e1; + border: 1px solid #cccccc; + margin: 0px 5px; + cursor:default; + } + + .prevStep { + .icon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/undo.png'); + } + } + + .prevStep.active { + cursor: pointer; + background: #FFFFFF; + border-color: #56CCCC; + + .icon { + background-image: url('images/undoH.png'); + } + + } + + .nextStep { + .icon { + display: inline-block; + width:16px; + height:16px; + background-image: url('images/redo.png'); + } + } + + .nextStep.active { + cursor: pointer; + background: #FFFFFF; + border-color: #56CCCC; + + .icon { + background-image: url('images/redoH.png'); + } + } + + .clearBoard { + cursor: default; + + .icon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/empty.png'); + } + + } + + .clearBoard.active { + cursor: pointer; + background: #FFFFFF; + border-color: #56CCCC; + + .icon { + background-image: url('images/emptyH.png'); + } + } + + .scaleBoard { + .icon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/scale.png'); + cursor:default;} + + .iconH { + background-image: url('images/scaleH.png'); + } + + .text{ + color:#ccc; + cursor:default;} + } + + + } + } + + // 绘图工具 + .drawToolbar { + float:right; + width:110px; + height:320px; + overflow: hidden; + + .brushIcon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/brush.png')} + + .eraserIcon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/eraser.png')} + + .blurIcon { + display: inline-block; + width:16px;height:16px; + background: url(images/blur.png) -2px -2px; + background-size: 22px 20px; + } + + .colorBar { + margin-top:10px; + font-size: 12px; + text-align: center; + zoom: 1; + overflow: hidden; + + span { + float: left; + margin: 2px 3px; + width: 10px; + height: 10px; + border:1px solid #c1c1c1; + border-radius: 3px; + cursor: pointer; + } + + .active { + border-color: #FF0000; + box-shadow:2px 2px 5px #d3d6da; + } + } + + .sectionBar { + margin-top:15px; + font-size: 12px; + text-align: center; + + a { + display:inline-block; + width:10px; + height:12px; + color: #888; + text-indent: -999px; + opacity: 0.3 + } + + .size1 {background: url('images/size.png') 1px center no-repeat ;} + .size2 {background: url('images/size.png') -10px center no-repeat;} + .size3 {background: url('images/size.png') -22px center no-repeat;} + .size4 {background: url('images/size.png') -35px center no-repeat;} + + .icon { + position: relative; + top:3px; + } + .clearSetting { + .icon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/init.png'); + background-size: 16px 16px; + } + } + + .addImgH { + position: relative; + + .icon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/addimg.png'); + cursor:default; + } + + .upload { + position: absolute; + left: 18px;top: -1px; + width: 75px; + height: 21px; + opacity: 0; + cursor: pointer; + opacity: 0; + } + } + + .removeImg { + .icon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/delimg.png'); + cursor:default; + } + + .text{color:#ccc;cursor:default;} + } //end removeImg + + .removeImg.active { + cursor: pointer; + + .icon { + background-image: url('images/delimgH.png'); + } + + .text{color:#000;cursor:default;} + } //end removeImg + + //保存图片 + .saveImg { + cursor: pointer; + + .icon { + display: inline-block; + width:16px;height:16px; + background-image: url('images/save.png'); + background-size: 18px 18px; + cursor:default; + } + } + + } + + #clearSetting {cursor: pointer;} + } + } + + +} + + diff --git a/addons/nkeditor/assets/plugins/graft/graft.js b/addons/nkeditor/assets/plugins/graft/graft.js new file mode 100644 index 0000000000000000000000000000000000000000..0102a88f9757a6ef527c4a6ccef0db1bc5af4665 --- /dev/null +++ b/addons/nkeditor/assets/plugins/graft/graft.js @@ -0,0 +1,189 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('graft', function(K) { + var self = this, name = 'graft', + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + allowUploadGraft = K.undef(self.allowUploadGraft, true), + lang = self.lang(name + '.'); + + if(typeof jQuery == 'undefined') { + K.options.errorMsgHandler(lang.depJQueryError, "error"); + return; + } else { + K.loadStyle(K.options.pluginsPath+"graft/css/scrawl.css"); + K.loadScript(K.options.pluginsPath+"graft/scrawl.js"); + } + + self.plugin.graftDialog = function(options) { + var clickFn = options.clickFn; + var html = [ + '
        ', + //绘图区域 + '
        ', + '
        ', + '你的浏览器不支持 canvas 绘图', + '
        ', + '
        ', + '
        ', + '', + '', + '', + '
        ', + '
        ', + //绘图区域 end + + //工具栏 + '
        ', + '
        ', + '', + '', + '', + '', + '', + '', + + '', + '', + '', + '', + '', + '', + + '', + '', + '', + '', + '', + '', + '
        ', + + //笔刷设置 + '
        ', + '', + '1', + '3', + '5', + '7', + '
        ', + '
        ', + '', + '5', + '10', + '15', + '20', + '
        ', + '
        ', + '', + '2', + '4', + '6', + '8', + '
        ', + //end 笔刷设置 + '
        ', + '', + '', + '初始化设置', + '', + '
        ', + '
        ', + '
        ', + '', + '添加背景', + '', + '
        ', + '
        ', + '
        ', + '', + '', + '删除背景', + '', + '
        ', + '
        ' + ].join(''); + + var dialog = self.createDialog({ + name : name, + width : 750, + height : 440, + title : self.lang(name), + body : html, + yesBtn : { + name : lang.btnText, + click : function(e) { + + if (dialog.isLoading) { + return; + } + if (canvas.isEmpty()) { + K.options.errorMsgHandler(lang.empty, "error"); + return; + } + canvas.save(function(data) { + //上传涂鸦到服务器 + if (allowUploadGraft) { + dialog.showLoading(self.lang('uploadLoading')); + $.post(uploadJson, { + img_base64_data : data, + fileType : "image", + base64 : 1 + }, function(res) { + + dialog.hideLoading(); + if (res.code == "000") { + K.options.errorMsgHandler(lang.uploadSuccess, "ok"); + clickFn.call(self, res.data.url); + self.hideDialog().focus(); + } else { + K.options.errorMsgHandler(lang.uploadFaild, "error"); + } + + }, "json"); + + } else { + clickFn.call(self, data); + self.hideDialog().focus(); + } + + }); + + } + } + }); + //console.log(div); + + //var urlBox = K('[name="url"]', div), + // viewServerBtn = K('[name="viewServer"]', div), + // titleBox = K('[name="title"]', div); + + var canvas = new Canvas({ + canvasId : "canvas-borad", + width : 600, + height : 320 + }); + + + + }; + + self.clickToolbar(name, function() { + self.plugin.graftDialog({ + clickFn : function(url) { + self.exec('insertimage', url); + } + }); + }); +}); diff --git a/addons/nkeditor/assets/plugins/graft/index.html b/addons/nkeditor/assets/plugins/graft/index.html new file mode 100644 index 0000000000000000000000000000000000000000..9b684f97d1bfb8a2846b95de1398e0b492eca55c --- /dev/null +++ b/addons/nkeditor/assets/plugins/graft/index.html @@ -0,0 +1,134 @@ + + + + 在线涂鸦工具 + + + + + +
        +
        +
        + 你的浏览器不支持 canvas 绘图 +
        +
        +
        + + + + + + + +
        +
        +
        +
        + + + + + + + + + + + + + + + + + + + + +
        + +
        + + 1 + 3 + 5 + 7 +
        +
        + + 5 + 10 + 15 + 20 +
        + +
        + + 2 + 4 + 6 + 8 +
        + +
        + + + 初始化设置 + +
        + +
        +
        + + 添加背景 + + +
        +
        + +
        + + + 删除背景 + +
        + +
        + + + 保存图片 + +
        + +
        +
        + + + + + + + \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/graft/scrawl.js b/addons/nkeditor/assets/plugins/graft/scrawl.js new file mode 100644 index 0000000000000000000000000000000000000000..fe13f079658748fad462030ad3fd18eee02f0216 --- /dev/null +++ b/addons/nkeditor/assets/plugins/graft/scrawl.js @@ -0,0 +1,262 @@ +/** + * Created by yangjian on 17-9-18. + */ +(function($) { + + // 设置元素可用状态 + $.fn.enable = function() { + $(this).addClass("active"); + $(this).removeAttr("disabled"); + } + + // 设置元素不可用状态 + $.fn.disable = function() { + $(this).removeClass("active"); + $(this).attr("disabled", true); + } + + var Canvas = function(options) { + + var configs = { + width : 360, + height : 300 + }; //默认配置 + options = options || {}; + $.extend(configs, options); + + var canvas = $("#"+configs.canvasId)[0]; //画布 + canvas.width = configs.width; + canvas.height = configs.height; + var context = canvas.getContext("2d"); //绘图环境 + context.lineCap = "round"; //设置线条两端为圆弧 + context.lineJoin = "round"; //设置线条转折为圆弧 + //设置默认颜色 + setColor(); + var $prevBtn = $("#J_prevStep"); //上一步 + var $nextBtn = $("#J_nextStep"); //下一步 + var $clearBtn = $("#J_clearBoard"); //清空画板 + var drawing = false; //是否正在绘制 + var erasering = false; //是否正在擦除 + var prevSteps = []; //返回上一步操作集合 + var nextSteps = []; //恢复下一步操作集合 + var o = {}; + + $("#picBoard").css({ + width : configs.width + "px", + height : configs.height + "px" + }); + + // 事件绑定 + canvas.onmousedown = startDrawing; + canvas.onmouseup = stopDrawing; + canvas.onmouseout = stopDrawing; + canvas.onmousemove = doDrawing; + $prevBtn.on("click", gotoPrevStep); + $nextBtn.on("click", gotoNextStep); + $clearBtn.on("click", clearBoard); + + // 清空设置 + $("#clearSetting").on("click", function() { + context.lineWidth = 1; + setColor($(".colorBar span:first").data("color")); + context.shadowBlur = 0; + alert("画笔已重新初始化,请重新配置画笔。"); + }); + + //上传背景图片 + $("#J_canvas_bg").on("change", function() { + + if ($("#picBoard img").length > 0) { + $("#picBoard img:eq(0)").attr("src", window.URL.createObjectURL(this.files[0])); + return; + } + var $img = ''; + $("#picBoard").append($img); + + // 激活删除背景按钮 + $("#J_removeImg").enable(); + + }); + + // 删除背景图片 + $("#J_removeImg").on("click", function() { + $("#picBoard").empty(); + $(this).disable(); + }); + + //保存图片 + $('#J_saveImg').on("click", saveImage); + + // 设置笔刷大小 + $("#scrawl-main .brush-size").on("click", function() { + + context.restore(); //恢复到canvas的上一个状态 + context.lineWidth = parseInt($(this).text()); + erasering = false; + + }); + + // 设置笔触虚化 + $("#scrawl-main .blur-size").on("click", function() { + context.shadowBlur = parseInt($(this).text()); + }); + + // 橡皮擦功能 + $("#scrawl-main .eraser-size").on("click", function() { + + if (erasering == true) { + return; + } + erasering = true; + context.save(); //保存canvas状态 + context.lineCap = "round"; //设置线条两端为圆弧 + context.lineJoin = "round"; //设置线条转折为圆弧 + context.lineWidth = 10; + context.globalCompositeOperation = "destination-out"; + + }); + + //设置颜色 + $("#scrawl-main .colorBar span").on("click",function() { + + $("#scrawl-main .colorBar .active").removeClass("active"); + $(this).addClass("active"); + setColor($(this).data("color")); + }); + + // 开始绘制 + function startDrawing(e) { + drawing = true; + //记录上一步的数据 + prevSteps.push(context.getImageData(0, 0, configs.width, configs.height)); + // 创建一个新的绘图路径 + context.beginPath(); + // 把画笔移动到鼠标位置 + var offset = $(canvas).offset(); + context.moveTo(e.pageX - offset.left, e.pageY - offset.top); + } + + // 停止绘制 + function stopDrawing() { + + drawing = false; + //清空下一步的数据集合,从新开始记录 + nextSteps = []; + $nextBtn.disable(); + if (prevSteps.length == 1) { + $prevBtn.enable(); + $clearBtn.enable(); + } + } + + //绘制图像 + function doDrawing(e) { + if (drawing) { + // 找到鼠标最新位置 + var offset = $(canvas).offset(); + var x = e.pageX - offset.left; + var y = e.pageY - offset.top; + // 画一条直线到鼠标最新位置 + context.lineTo(x, y); + context.stroke(); + } + } + + /** + * 返回上一步操作 + */ + function gotoPrevStep() { + if (prevSteps.length > 0) { + //保存当前状态到下一步的操作历史库 + nextSteps.push(context.getImageData(0, 0, configs.width, configs.height)); + var popData = prevSteps.pop(); + context.putImageData(popData, 0, 0); + $nextBtn.enable(); + + if (prevSteps.length == 0) { + $prevBtn.disable(); + } + } + } + + /** + * 恢复下一步操作 + */ + function gotoNextStep() { + if (nextSteps.length > 0) { + //保存当前状态到上一步的操作历史库 + prevSteps.push(context.getImageData(0, 0, configs.width, configs.height)); + var imgData = nextSteps.pop(); + context.putImageData(imgData, 0, 0); + $prevBtn.enable(); + + if (nextSteps.length == 0) { + $nextBtn.disable(); + } + } + } + + /** + * 清空画板 + */ + function clearBoard() { + context.clearRect(0, 0, context.canvas.width, context.canvas.height); + prevSteps = []; + nextSteps = []; + + $prevBtn.disable(); + $nextBtn.disable(); + $clearBtn.disable(); + } + + /** + * 设置画笔颜色 + * @param color + */ + function setColor(color) { + if (!color) { + color = $(".colorBar .active:eq(0)").data("color"); + } + context.strokeStyle = color; + context.shadowColor = color; + } + + /** + * 获取图片 base64 编码 + */ + function saveImage(callback) { + + if ($("#picBoard img").length > 0) { + var image = new Image(); + image.src = $("#picBoard img:eq(0)").attr("src"); + image.onload = function() { + context.save(); + context.shadowBlur = 0; + context.shadowColor = '#FFF'; + context.globalCompositeOperation = "destination-atop"; + context.drawImage(this, 0, 0, configs.width, configs.height); + context.restore(); + + callback(canvas.toDataURL("image/png")); + } + + } else { + callback(canvas.toDataURL("image/png")); + } + } + + + //要导出的API + o.nextStep = gotoNextStep; + o.prevStep = gotoNextStep; + o.setColor = setColor; + o.save = saveImage; + o.isEmpty = function() { + return prevSteps.length == 0; + } + return o; + } + + + window.Canvas = Canvas; +})(jQuery); \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/image/image.js b/addons/nkeditor/assets/plugins/image/image.js new file mode 100644 index 0000000000000000000000000000000000000000..dc4848a48e17c14ef30f023645b47bc5a4915c54 --- /dev/null +++ b/addons/nkeditor/assets/plugins/image/image.js @@ -0,0 +1,340 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('image', function(K) { + var self = this, name = 'image', + allowImageUpload = K.undef(self.allowImageUpload, true), + allowImageRemote = K.undef(self.allowImageRemote, true), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + allowFileManager = K.undef(self.allowFileManager, false), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imageTabIndex = K.undef(self.imageTabIndex, 0), + imgPath = self.pluginsPath + 'image/images/', + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + fillDescAfterUploadImage = K.undef(self.fillDescAfterUploadImage, false), + lang = self.lang(name + '.'); + + self.plugin.imageDialog = function(options) { + var imageUrl = options.imageUrl, + imageWidth = K.undef(options.imageWidth, ''), + imageHeight = K.undef(options.imageHeight, ''), + imageTitle = K.undef(options.imageTitle, ''), + imageAlign = K.undef(options.imageAlign, ''), + showRemote = K.undef(options.showRemote, true), + showLocal = K.undef(options.showLocal, true), + tabIndex = K.undef(options.tabIndex, 0), + clickFn = options.clickFn; + var target = 'kindeditor_upload_iframe_' + new Date().getTime(); + var hiddenElements = []; + for(var k in extraParams){ + hiddenElements.push(''); + } + var html = [ + '
        ', + //tabs + '
        ', + //remote image - start + '', + //remote image - end + //local upload - start + '', + //local upload - end + '
        ' + ].join(''); + + var dialogWidth = showLocal || allowFileManager ? 450 : 400, + dialogHeight = showLocal && showRemote ? 310 : 260; + var dialog = self.createDialog({ + name : name, + width : dialogWidth, + height : dialogHeight, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + // Bugfix: http://code.google.com/p/kindeditor/issues/detail?id=319 + if (dialog.isLoading) { + return; + } + // insert local image + if (showLocal && showRemote && tabs && tabs.selectedIndex === 1 || !showRemote) { + if (uploadbutton.fileBox.val() == '') { + K.options.errorMsgHandler(self.lang('pleaseSelectFile'), "error"); + return; + } + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + localUrlBox.val(''); + return; + } + // insert remote image + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(), + title = titleBox.val(), + align = ''; + alignBox.each(function() { + if (this.checked) { + align = this.value; + return false; + } + }); + if (url == 'http://' || K.invalidUrl(url)) { + K.options.errorMsgHandler(self.lang('invalidUrl'), "error"); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + K.options.errorMsgHandler(self.lang('invalidWidth'), "error"); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + K.options.errorMsgHandler(self.lang('invalidHeight'), "error"); + heightBox[0].focus(); + return; + } + clickFn.call(self, url, title, width, height, 0, align); + } + }, + beforeRemove : function() { + viewServerBtn.unbind(); + widthBox.unbind(); + heightBox.unbind(); + refreshBtn.unbind(); + } + }), + div = dialog.div; + + var urlBox = K('[name="url"]', div), + localUrlBox = K('[name="localUrl"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('.tab1 [name="width"]', div), + heightBox = K('.tab1 [name="height"]', div), + refreshBtn = K('.ke-refresh-btn', div), + titleBox = K('.tab1 [name="title"]', div), + alignBox = K('.tab1 [name="align"]', div); + + var tabs; + if (showRemote && showLocal) { + tabs = K.tabs({ + src : K('.tabs', div), + afterSelect : function(i) {} + }); + tabs.add({ + title : lang.remoteImage, + panel : K('.tab1', div) + }); + tabs.add({ + title : lang.localImage, + panel : K('.tab2', div) + }); + tabs.select(tabIndex); + } else if (showRemote) { + K('.tab1', div).show(); + } else if (showLocal) { + K('.tab2', div).show(); + } + + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + form : K('.ke-form', div), + target : target, + width: 60, + afterUpload : function(data) { + + dialog.hideLoading(); + if (data.code == "000") { + + K.options.errorMsgHandler(self.lang('uploadSuccess'), "ok"); + + var url = data.data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + if (!fillDescAfterUploadImage) { + clickFn.call(self, url, data.title, data.width, data.height, data.border, data.align); + } else { + K(".ke-dialog-row ke-clearfix #remoteUrl", div).val(url); + K(".ke-tabs-li", div)[0].click(); + K(".ke-refresh-btn", div).click(); + } + } else { + K.options.errorMsgHandler(data.message, "error"); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + localUrlBox.val(uploadbutton.fileBox.val()); + }); + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + dirName : 'image', + clickFn : function(url) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var originalWidth = 0, originalHeight = 0; + function setSize(width, height) { + widthBox.val(width); + heightBox.val(height); + originalWidth = width; + originalHeight = height; + } + refreshBtn.click(function(e) { + var tempImg = K('', document).css({ + position : 'absolute', + visibility : 'hidden', + top : 0, + left : '-1000px' + }); + tempImg.bind('load', function() { + setSize(tempImg.width(), tempImg.height()); + tempImg.remove(); + }); + K(document.body).append(tempImg); + }); + widthBox.change(function(e) { + if (originalWidth > 0) { + heightBox.val(Math.round(originalHeight / originalWidth * parseInt(this.value, 10))); + } + }); + heightBox.change(function(e) { + if (originalHeight > 0) { + widthBox.val(Math.round(originalWidth / originalHeight * parseInt(this.value, 10))); + } + }); + urlBox.val(options.imageUrl); + setSize(options.imageWidth, options.imageHeight); + titleBox.val(options.imageTitle); + alignBox.each(function() { + if (this.value === options.imageAlign) { + this.checked = true; + return false; + } + }); + if (showRemote && tabIndex === 0) { + urlBox[0].focus(); + urlBox[0].select(); + } + return dialog; + }; + self.plugin.image = { + edit : function() { + var img = self.plugin.getSelectedImage(); + self.plugin.imageDialog({ + imageUrl : img ? img.attr('data-ke-src') : 'http://', + imageWidth : img ? img.width() : '', + imageHeight : img ? img.height() : '', + imageTitle : img ? img.attr('title') : '', + imageAlign : img ? img.attr('align') : '', + showRemote : allowImageRemote, + showLocal : allowImageUpload, + tabIndex: img ? 0 : imageTabIndex, + clickFn : function(url, title, width, height, border, align) { + if (img) { + img.attr('src', url); + img.attr('data-ke-src', url); + img.attr('width', width); + img.attr('height', height); + img.attr('title', title); + img.attr('align', align); + img.attr('alt', title); + } else { + self.exec('insertimage', url, title, width, height, border, align); + } + // Bugfix: [Firefox] 上传图片后,总是出现正在加载的样式,需要延迟执行hideDialog + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }, + 'delete' : function() { + var target = self.plugin.getSelectedImage(); + if (target.parent().name == 'a') { + target = target.parent(); + } + target.remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.image.edit); +}); diff --git a/addons/nkeditor/assets/plugins/image/images/align_left.gif b/addons/nkeditor/assets/plugins/image/images/align_left.gif new file mode 100644 index 0000000000000000000000000000000000000000..ab17f56797aa3d6e54901251faa46a1d6a82ecc2 Binary files /dev/null and b/addons/nkeditor/assets/plugins/image/images/align_left.gif differ diff --git a/addons/nkeditor/assets/plugins/image/images/align_right.gif b/addons/nkeditor/assets/plugins/image/images/align_right.gif new file mode 100644 index 0000000000000000000000000000000000000000..e8ebe6a6367b8f2abe19eab1e888f62b31ebcafa Binary files /dev/null and b/addons/nkeditor/assets/plugins/image/images/align_right.gif differ diff --git a/addons/nkeditor/assets/plugins/image/images/align_top.gif b/addons/nkeditor/assets/plugins/image/images/align_top.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8826a5bce1462216379abff027077225394620d Binary files /dev/null and b/addons/nkeditor/assets/plugins/image/images/align_top.gif differ diff --git a/addons/nkeditor/assets/plugins/image/images/refresh.png b/addons/nkeditor/assets/plugins/image/images/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..77e12d1c6acb7ad8defd5410e695d603097fba04 Binary files /dev/null and b/addons/nkeditor/assets/plugins/image/images/refresh.png differ diff --git a/addons/nkeditor/assets/plugins/insertfile/insertfile.js b/addons/nkeditor/assets/plugins/insertfile/insertfile.js new file mode 100644 index 0000000000000000000000000000000000000000..12d6e278ecb446af3245877763c12a3dc26d2750 --- /dev/null +++ b/addons/nkeditor/assets/plugins/insertfile/insertfile.js @@ -0,0 +1,141 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('insertfile', function(K) { + var self = this, name = 'insertfile', + allowFileUpload = K.undef(self.allowFileUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + self.plugin.fileDialog = function(options) { + var fileUrl = K.undef(options.fileUrl, 'http://'), + fileTitle = K.undef(options.fileTitle, ''), + clickFn = options.clickFn; + var html = [ + '
        ', + '
        ', + '', + '
        ', + '  ', + '  ', + '', + '', + '', + '
        ', + '
        ', + //title + '
        ', + '', + '
        ', + '
        ', + '
        ', + '
        ', + //form end + '', + '
        ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + title = titleBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + K.options.errorMsgHandler(self.lang('invalidUrl'), "error"); + urlBox[0].focus(); + return; + } + if (K.trim(title) === '') { + title = url; + } + clickFn.call(self, url, title); + } + } + }), + div = dialog.div; + + var urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + titleBox = K('[name="title"]', div); + + if (allowFileUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + url : K.addParam(uploadJson, 'fileType=file'), + extraParams : extraParams, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.code === "000") { + var url = data.data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + K.options.errorMsgHandler(self.lang('uploadSuccess'), "ok"); + } else { + K.options.errorMsgHandler(data.message, "error"); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'file', + clickFn : function(url) { + //console.log(url); + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + } + }); + }); + }); + } else { + K("#keUrl").css("width", "250px"); + viewServerBtn.hide(); + } + urlBox.val(fileUrl); + titleBox.val(fileTitle); + urlBox[0].focus(); + urlBox[0].select(); + }; + self.clickToolbar(name, function() { + self.plugin.fileDialog({ + clickFn : function(url, title) { + var html = '' + title + ''; + self.insertHtml(html).hideDialog().focus(); + } + }); + }); +}); diff --git a/addons/nkeditor/assets/plugins/lineheight/lineheight.js b/addons/nkeditor/assets/plugins/lineheight/lineheight.js new file mode 100644 index 0000000000000000000000000000000000000000..ae679d788372f53e7dabdd63e88e5915e00f0693 --- /dev/null +++ b/addons/nkeditor/assets/plugins/lineheight/lineheight.js @@ -0,0 +1,38 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('lineheight', function(K) { + var self = this, name = 'lineheight', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var curVal = '', commonNode = self.cmd.commonNode({'*' : '.line-height'}); + if (commonNode) { + curVal = commonNode.css('line-height'); + } + var menu = self.createMenu({ + name : name, + width : 150 + }); + K.each(lang.lineHeight, function(i, row) { + K.each(row, function(key, val) { + menu.addItem({ + title : val, + checked : curVal === key, + click : function() { + self.cmd.toggle('', { + span : '.line-height=' + key + }); + self.updateState(); + self.addBookmark(); + self.hideMenu(); + } + }); + }); + }); + }); +}); diff --git a/addons/nkeditor/assets/plugins/link/link.js b/addons/nkeditor/assets/plugins/link/link.js new file mode 100644 index 0000000000000000000000000000000000000000..9a42fbdacfcabf92902424f2ace246151a2bbba0 --- /dev/null +++ b/addons/nkeditor/assets/plugins/link/link.js @@ -0,0 +1,71 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('link', function(K) { + var self = this, name = 'link'; + self.plugin.link = { + edit : function() { + var lang = self.lang(name + '.'), + html = ['
        ', + //url + '
        ', + '', + '
        ', + '', + '
        ', + '
        ', + //type + '
        ', + '', + '
        ', + '', + '
        ', + '
        ', + '
        '].join(""), + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()); + if (url == 'http://' || K.invalidUrl(url)) { + K.options.errorMsgHandler(self.lang('invalidUrl'), "error"); + urlBox[0].focus(); + return; + } + self.exec('createlink', url, typeBox.val()).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('input[name="url"]', div), + typeBox = K('select[name="type"]', div); + urlBox.val('http://'); + typeBox[0].options[0] = new Option(lang.newWindow, '_blank'); + typeBox[0].options[1] = new Option(lang.selfWindow, ''); + self.cmd.selection(); + var a = self.plugin.getSelectedLink(); + if (a) { + self.cmd.range.selectNode(a[0]); + self.cmd.select(); + urlBox.val(a.attr('data-ke-src')); + typeBox.val(a.attr('target')); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.exec('unlink', null); + } + }; + self.clickToolbar(name, self.plugin.link.edit); +}); diff --git a/addons/nkeditor/assets/plugins/map/map.html b/addons/nkeditor/assets/plugins/map/map.html new file mode 100644 index 0000000000000000000000000000000000000000..fb275550011d7817adc78dbc2d15aa5636a4b8cb --- /dev/null +++ b/addons/nkeditor/assets/plugins/map/map.html @@ -0,0 +1,57 @@ + + + + + + + + + +
        + + \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/map/map.js b/addons/nkeditor/assets/plugins/map/map.js new file mode 100644 index 0000000000000000000000000000000000000000..52908752515c319c03916d5e4c1b275baf2c5817 --- /dev/null +++ b/addons/nkeditor/assets/plugins/map/map.js @@ -0,0 +1,137 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +// Google Maps: http://code.google.com/apis/maps/index.html + +KindEditor.plugin('map', function(K) { + var self = this, name = 'map', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var html = ['
        ', + '
        ', + lang.address + ' ', + '', + '', + '', + '
        ', + '
        ', + '
        '].join(''); + var dialog = self.createDialog({ + name : name, + width : 600, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var geocoder = win.geocoder, + map = win.map, + center = map.getCenter().lat() + ',' + map.getCenter().lng(), + zoom = map.getZoom(), + maptype = map.getMapTypeId(), + url = 'http://maps.googleapis.com/maps/api/staticmap'; + url += '?center=' + encodeURIComponent(center); + url += '&zoom=' + encodeURIComponent(zoom); + url += '&size=558x360'; + url += '&maptype=' + encodeURIComponent(maptype); + url += '&markers=' + encodeURIComponent(center); + url += '&language=' + self.langType; + url += '&sensor=false'; + self.exec('insertimage', url).hideDialog().focus(); + } + }, + beforeRemove : function() { + searchBtn.remove(); + if (doc) { + doc.write(''); + } + iframe.remove(); + } + }); + var div = dialog.div, + addressBox = K('[name="address"]', div), + searchBtn = K('[name="searchBtn"]', div), + win, doc; + var iframeHtml = ['', + '', + '', + '', + '', + '', + '', + '
        ', + ''].join('\n'); + // TODO:用doc.write(iframeHtml)方式加载时,在IE6上第一次加载报错,暂时使用src方式 + var iframe = K(''); + function ready() { + win = iframe[0].contentWindow; + doc = K.iframeDoc(iframe); + //doc.open(); + //doc.write(iframeHtml); + //doc.close(); + } + iframe.bind('load', function() { + iframe.unbind('load'); + if (K.IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + K('.ke-map', div).replaceWith(iframe); + // search map + searchBtn.click(function() { + win.search(addressBox.val()); + }); + }); +}); diff --git a/addons/nkeditor/assets/plugins/media/media.js b/addons/nkeditor/assets/plugins/media/media.js new file mode 100644 index 0000000000000000000000000000000000000000..fab7faa669969a401de6f43873daa919d642c246 --- /dev/null +++ b/addons/nkeditor/assets/plugins/media/media.js @@ -0,0 +1,186 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('media', function(K) { + var self = this, name = 'media', lang = self.lang(name + '.'), + allowMediaUpload = K.undef(self.allowMediaUpload, false), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + + self.plugin.media = { + edit : function() { + var html = [ + '
        ', + //url + '
        ', + '', + '
        ', + '  ', + '  ', + '', + '', + '', + '
        支持优酷、爱奇艺、土豆、腾讯视频、56等视频网站【通用代码】', + '
        ', + '
        ', + '
        ', + //width + '
        ', + '', + '
        ', + '', + '
        ', + '
        ', + //height + '
        ', + '', + '
        ', + '', + '
        ', + '
        ', + //autostart + '
        ', + '', + '
        ', + ' ', + '
        ', + '
        ', + '
        ' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + height : 260, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + var match = url.match(/^'; + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div), + autostartBox = K('[name="autostart"]', div); + urlBox.val('http://'); + + if (allowMediaUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'fileType=media'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.code == "000") { + var url = data.data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + K.options.errorMsgHandler(self.lang('uploadSuccess'), "ok"); + } else { + K.options.errorMsgHandler(data.message, "error", "error"); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + + if (allowMediaUpload && allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + dirName : 'media', + clickFn : function(url) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + } + }); + }); + }); + } else { + K("#keUrl").css("width", "280px"); + viewServerBtn.hide(); + } + + var img = self.plugin.getSelectedMedia(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + autostartBox[0].checked = (attrs.autostart === 'true'); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedMedia().remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.media.edit); +}); diff --git a/addons/nkeditor/assets/plugins/multiimage/BUpload.js b/addons/nkeditor/assets/plugins/multiimage/BUpload.js new file mode 100644 index 0000000000000000000000000000000000000000..a314e0cf23611a4493ec47508a483fc6a8b2bc0f --- /dev/null +++ b/addons/nkeditor/assets/plugins/multiimage/BUpload.js @@ -0,0 +1,625 @@ +/** + * HTML5上传插件 + * @site https://git.oschina.net/blackfox/ajaxUpload + * @author yangjian + * @version 1.0.1 + */ +(function($) { + + //判断浏览器是否支持html5 + // if ( !window.applicationCache ) + // throw new Error("您当前的浏览器不支持HTML5,请先升级浏览器才能使用该上传插件!"); + + //image crop + $.fn.imageCrop = function(__width, __height) { + $(this).on("load", function () { + + var width, height, left, top; + var orgRate = this.width/this.height; + var cropRate = __width/__height; + if ( orgRate >= cropRate ) { + height = __height; + width = __width * orgRate; + top = 0; + left = (width - __width)/2; + } else { + width = __width; + height = __height / orgRate; + left = 0; + //top = (height - __height)/2; + top = 0; + } + $(this).css({ + "position" : "absolute", + top : -top + "px", + left : -left + "px", + width : width + "px", + height : height + "px" + }); + }); + } + + //make element draggable + $.fn.draggable = function(options) { + var defaults = { + handler : null + } + options = $.extend(defaults, options); + var __self = this; + $(options.handler).mousedown(function(e) { + var offsetLeft = e.pageX - $(__self).position().left; + var offsetTop = e.pageY - $(__self).position().top; + $(document).mousemove(function(e) { + //清除拖动鼠标的时候选择文本 + window.getSelection ? window.getSelection().removeAllRanges():document.selection.empty(); + $(__self).css({ + 'top' : e.pageY-offsetTop + 'px', + 'left' : e.pageX-offsetLeft + 'px' + }); + }); + + }).mouseup(function() { + $(document).unbind('mousemove'); + }); + + } + + if ( Array.prototype.remove == undefined ) { + Array.prototype.remove = function(item) { + for ( var i = 0; i < this.length; i++ ) { + if ( this[i] == item ) { + this.splice(i, 1); + break; + } + } + } + } + if ( Array.prototype.uinque == undefined ) { + Array.prototype.uinque = function() { + var result = [], hash = {}; + for ( var i = 0, item; (item = this[i]) != null; i++ ) { + if ( !hash[item] ) { + result.push(item); + hash[item] = true; + } + } + return result; + } + } + + window.BUpload = function(options) { + + options = $.extend({ + src : "src", + upload_url : null, + list_url : null, + data_type : "json", + top : 20, + fileType : "image", //文件类型,默认是图片,可选flash,media,file + max_filesize : 2048, //unit:KB + max_filenum : 20, + no_data_text : "(⊙o⊙)亲,没有多数据了。", + ext_allow : "jpg|png|gif|jpeg", + ext_refuse : "exe|txt", + errorHandler : function(messsage, type) { + alert(messsage); + }, + callback : function(data) { + console.log(data); + } + }, options); + + //错误代码和提示消息 + var codeMessageMap = { + '000' : '文件上传成功', + '001' : '文件上传失败', + '003' : '文件大小超出限制', + '004' : '非法文件名后缀' + }; + + var mimeType = { + "3gpp":"audio/3gpp, video/3gpp", + "ac3":"audio/ac3", + "asf":"allpication/vnd.ms-asf", + "au":"audio/basic", + "css":"text/css", + "csv":"text/csv", + "doc":"application/msword", + "dot":"application/msword", + "dtd":"application/xml-dtd", + "dwg":"image/vnd.dwg", + "dxf":"image/vnd.dxf", + "gif":"image/gif", + "htm":"text/html", + "html":"text/html", + "jp2":"image/jp2", + "jpe":"image/jpeg", + "jpeg":"image/jpeg", + "jpg":"image/jpeg", + "js":"text/javascript, application/javascript", + "json":"application/json", + "mp2":"audio/mpeg, video/mpeg", + "mp3":"audio/mpeg", + "mp4":"audio/mp4, video/mp4", + "mpeg":"video/mpeg", + "mpg":"video/mpeg", + "mpp":"application/vnd.ms-project", + "ogg":"application/ogg, audio/ogg", + "pdf":"application/pdf", + "png":"image/png", + "pot":"application/vnd.ms-powerpoint", + "pps":"application/vnd.ms-powerpoint", + "ppt":"application/vnd.ms-powerpoint", + "rtf":"application/rtf, text/rtf", + "svf":"image/vnd.svf", + "tif":"image/tiff", + "tiff":"image/tiff", + "txt":"text/plain", + "wdb":"application/vnd.ms-works", + "wps":"application/vnd.ms-works", + "xhtml":"application/xhtml+xml", + "xlc":"application/vnd.ms-excel", + "xlm":"application/vnd.ms-excel", + "xls":"application/vnd.ms-excel", + "xlt":"application/vnd.ms-excel", + "xlw":"application/vnd.ms-excel", + "xml":"text/xml, application/xml", + "zip":"aplication/zip", + "xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + } + + var o = {}; + o.dialog = null; + o.todoList = new Array(); //the file queue to be uploaded + o.uploadSuccessNum = 0; //已经上传成功的图片数量 + o.selectedList = new Array(); //the file queue upload successfully + o.addedFileNumber = 0; //the numbers of files that has added + o.totalFilesize = 0; //total file size + o.uploadLock = false; //upload thread lock + o.page = 1; //服务器图片列表页码 + o.marker = null, //七牛云上传的分页标识 + o.noRecord = false; + var dialogSCode = Math.ceil(Math.random() * 1000000000000); //对话框的令牌,如果创建多个BUpload上传对象用来保持唯一性 + + //close the dialog + o.close = function () { + o.dialog.remove(); + if (typeof options.close == 'function') { + options.close(); + } + } + + //create dialog + function createDialog() { + + var builder = new StringBuilder(); + builder.append('
        '); + builder.append('
        '+options.lang.title+'
        '); + builder.append('
        '+options.lang.localUpload+''); + if ( options.list_url != null ) { + builder.append(''+options.lang.fileServer+''); + } + builder.append('
        '); + builder.append('
        '+options.lang.selectFile+'
        '); + builder.append('
          '); + builder.append('
          '+options.lang.confirmBtnText+''); + builder.append(''+options.lang.cancelBtnText+'
          '); + + o.dialog = $(builder.toString()); + $("body").append(o.dialog); + if (options.top == 0) { + options.top = ($(window).height() - o.dialog.height())/2; + } + o.dialog.css({ + left : ($(window).width() - o.dialog.width())/2 + "px", + top : options.top + "px" + }); + //给对话框添加拖拽事件 + o.dialog.draggable({handler : o.dialog.find(".ued_title")}) + + } + + //绑定元素事件 + function bindEvent() { + + //选项卡事件 + G(".tab").on("click", function() { + var tab = $(this).attr("tab"); + G(".tab-panel").hide(); + G("."+tab).show(); + G(".tab").removeClass("focus"); + $(this).addClass("focus"); + }); + + //关闭对话框 + G(".close_btn").on("click", function() { + o.close(); + }); + + //选择文件事件 + G(".webuploader-element-invisible").on("change", function() { + addFiles(this); + }); + + //弹出上传文件选择框 + G(".image-select").on("click", function() { + G(".webuploader-element-invisible").trigger("click"); + }); + G(".btn-continue-add").on("click", function() { + G(".webuploader-element-invisible").trigger("click"); + }); + + //开始上传按钮事件 + G(".btn-start-upload").on("click", function() { + if ( o.uploadLock ) return; + + if ( o.todoList.length == 0 ) { + options.errorHandler(options.lang.noFileAdded, "error"); + return false; + } + $(this).addClass("disabled").text(options.lang.uploading); + uploadFile(o.todoList.shift()); + }); + + //点击确认|取消按钮事件 + G(".btn-confirm").on("click", function() { + if ( o.todoList.length > 0 ) { + options.errorHandler(options.lang.fileNotUpload, "error"); + return false; + } + if (o.selectedList.length == 0) { + options.errorHandler(options.lang.noFileSelected, "error"); + return false; + } + options.callback(o.selectedList); + o.close(); + + }); + G(".btn-cancel").on("click", function() { + o.close(); + }); + + //从服务器加载文件 + G(".tab-online").on("click", function() { + + if ( G(".imagelist .list").children().length == 0 ) { + loadFilesFromServer() + } + + }); + + //当滚动条滚到底部时自动去加载图片 + G(".imagelist").on("scroll", function() { + + if ( this.scrollTop + this.clientHeight >= this.scrollHeight ) { + loadFilesFromServer(); + } + }); + } + + //add file to upload list + function addFiles(input) { + + var files = input.files; + var totalFileNum = o.todoList.length + o.uploadSuccessNum + files.length; //本次上传文件总数 + for ( var i = o.addedFileNumber; i < o.addedFileNumber+files.length; i++ ) { + + if ( totalFileNum > options.max_filenum ) { + options.errorHandler(KindEditor.tmpl(options.lang.uploadLimit, {uploadLimit: options.max_filenum}), "error"); + return; + } + var builder = new StringBuilder(); + var tempFile = files[i- o.addedFileNumber]; + builder.append('
        • '); + + //如果上传的不是图片,则通过判断文件后缀来显示不同的图标 + var extension = getFileExt(tempFile.name); + if ( extension == '' ) extension = "default"; + extension = extension.toLowerCase(); + if ( "jpg|jpeg|gif|png|bmp".indexOf(extension) == -1 ) { + builder.append(''); + } else { + builder.append(''); + } + + builder.append('
          '+options.lang.remove+''+options.lang.rotateRight+''); + builder.append(''+options.lang.rotateLeft+'
          '); + builder.append('
        • '); + + var $image = $(builder.toString()); + //bind onelele event + $image.find(".remove").on("click", function() { + $(this).parents("li").remove(); //remove element + //remove file from todoList + var index = $(this).attr("index"); + for ( var i = 0; i < o.todoList.length; i++ ) { + if ( o.todoList[i].index == index ) { + o.totalFilesize -= o.todoList[i].file.size; + updateInfoText(o.uploadSuccessNum + o.todoList.length-1, o.totalFilesize); + o.todoList.splice(i, 1); + break; + } + } + if (G(".filelist li").length == 0) { + G(".image-list-box").hide(); + G(".wra_pla").show(); + } + }); + $image.on("mouseover", function() { + $(this).find(".file-opt-box").show(); + }).on("mouseout", function() { + $(this).find(".file-opt-box").hide(); + }); + + G(".wra_pla").hide(); + G(".image-list-box").show(); + G(".filelist").append($image); + + o.todoList.push({index:i, file:tempFile}); + o.totalFilesize += tempFile.size; + + //console.log(tempFile); + } + o.addedFileNumber += files.length; + updateInfoText(o.uploadSuccessNum + o.todoList.length, o.totalFilesize); + + //缩放并裁剪图片 + $(".imgWrap img").imageCrop(113,113); + + } + + /** + * upload file function(文件上传主函数) + * @param node 数据节点 + */ + function uploadFile(node) { + + if ( !fileCheckHandler(node) ) { + uploadNextFile(); //skip the file and upload the next file + return; + } + + // prepare XMLHttpRequest + var xhr = new XMLHttpRequest(); + xhr.open('POST', options.upload_url); + //upload successfully + xhr.addEventListener('load',function(e) { + + if ( options.data_type == "json" ) { + //console.log(e); + var data = $.parseJSON(e.target.responseText); + if ( data.code == "000" ) { + o.selectedList.push(data.data.url); //添加文件到上传文件列表 + o.uploadSuccessNum++; + $("#img-comtainer-"+dialogSCode+ node.index).find(".file-opt-box").remove(); + $("#img-comtainer-"+dialogSCode+ node.index).find(".progress").remove(); + $("#img-comtainer-"+dialogSCode+ node.index).find(".success").show(); + } else { + __error__(codeMessageMap[data.code], node); + } + } + + }, false); + + // file upload complete + xhr.addEventListener('loadend', function () { + uploadNextFile(); //upload the next file + }, false); + + //上传失败 + xhr.addEventListener('error', function() { + __error__(options.lang.uploadFail, node); + }, false); + + xhr.upload.addEventListener('progress', function(e) { + updateProgress(e, node); + }, false); + + // prepare FormData + var formData = new FormData(); + formData.append(options.src, node.file); + xhr.send(formData); + + } + + //upload next file(上传下一个文件) + function uploadNextFile() { + + if ( o.todoList.length ) { + var nextFile = o.todoList.shift(); + uploadFile(nextFile); + } else { + o.uploadLock = false; //release the upload lock + G(".btn-start-upload").removeClass("disabled").text(options.lang.startUpload); + //console.log(o.selectedList); + } + } + + // progress handler(文件上传进度控制) + function updateProgress(e, node) { + if ( e.lengthComputable ) { + $("#img-comtainer-"+dialogSCode+ node.index).find(".progress span").css({"width" : (e.loaded/e.total)*100+'%', "display":"block"}); + } + } + + //update file info text + function updateInfoText(filenum, filesize) { + var text = KindEditor.tmpl(options.lang.uploadDesc, {numSelect:filenum, totalSize:formatFileSize(filesize), numLeft:(options.max_filenum - filenum)}); + G(".info").text(text); + } + + //format file size(格式化文件大小) + function formatFileSize(size) { + + if ( size/1048576 > 1 ) { + return (size/1048576).toFixed(2)+"MB"; + } else { + return (size/1024).toFixed(2)+"KB"; + } + + } + + //file check handler(文件检测处理函数) + function fileCheckHandler(node) { + + //检查文件大小 + var maxsize = options.max_filesize * 1024; + if ( maxsize > 0 && node.file.size > maxsize ) { + __error__(KindEditor.tmpl(options.lang.sizeLimit, {sizeLimit:options.max_filesize}), node); + return false; + } + + //检查文件后缀名 + var ext = getFileExt(node.file.name); + if ( ext && options.ext_allow.indexOf(ext) != -1 + && options.ext_refuse.indexOf(ext) == -1 ) { + return true; + } else { + __error__(KindEditor.tmpl(options.lang.invalidExt, {invalidExt:ext}), node); + return false; + } + + } + + //获取文件后缀名 + function getFileExt(filename) { + if ( !filename ) return false; + var position = filename.lastIndexOf('.') + if ( position != -1 ) { + return filename.substr(position+1).toLowerCase(); + } + return false; + } + + //获取可接受的文件后缀 + function getAccept() { + var extensions = options.ext_allow.split("|"); + var accept = []; + $.each(extensions, function(idx, item) { + accept.push(mimeType[item]); + }); + if ( accept.length > 1 ) { + return accept.uinque().join(","); + } + return "*"; + } + + //显示上传错误信息 + function __error__(message, node) { + G("#img-comtainer-"+dialogSCode+ node.index).find(".error").show().text(message); + } + + //query + function G(query) { + return o.dialog.find(query); + } + + //从服务器上获取图片地址 + function loadFilesFromServer() { + if ( !options.list_url ) { + G(".online .no-data").html(''+options.lang.noListUrl+'').show(); + return false; + } + if ( o.noRecord ) return false; + + G(".loading-icon").show(); //显示加载图标 + $.get(options.list_url, { + page : o.page, + marker : o.marker, + fileType : options.fileType, + }, function(res) { + + G(".loading-icon").hide(); //隐藏加载图标 + if ( res.code == "000" ) { + + if (!res.data[0]) { //没有加载到数据 + G(".online .no-data").text(options.lang.noDataText).show(); + return; + } + o.marker = res.extra; //存储marker + o.page++; + appendFiles(res.data, "online"); + } else { + G(".online .no-data").text(options.lang.noDataText).show(); + o.noRecord = true; + } + + }, "json"); + } + + //追加元素到图片列表 + function appendFiles(data, module) { + + $.each(data, function(idx, item) { + + var builder = new StringBuilder(); + builder.append('
        • '); + var extension = getFileExt(item.thumbURL); + if ( extension == '' ) extension = "default"; + extension = extension.toLowerCase(); + //如果不是图片,则根据文件的后缀名去加载对应的缩略图 + var imgSize = item.width+'x'+item.height; //图片尺寸 + if ( "jpg|jpeg|gif|png|bmp".indexOf(extension) == -1 ) { + imgSize = formatFileSize(item.filesize); //如果是文件则显示文件大小 + builder.append(''); + } else { + builder.append(''); + } + + builder.append(''+imgSize+'
        • '); + var $image = $(builder.toString()); + + //绑定选择图片事件 + $image.find(".ic").on("click", function() { + var src = $(this).prev().data("src"); + var module = $(this).data("module"); + if ( $(this).hasClass("selected") ) { + $(this).removeClass("selected"); + } else { + $(this).addClass("selected"); + o.selectedList.push(src); + } + //console.log(o.selectedList); + }); + //裁剪显示图片 + $image.find("img").imageCrop(113, 113); + if ( module == "online" ) { + G(".imagelist .list").append($image); + } else if ( module == "search" ) { + G(".search-imagelist-box .search-list").append($image); + } + }); + + } + + //initialize dialog + createDialog(); + bindEvent(); + return o; + }; //end of JUpload + + //string builder + var StringBuilder = function() { + + var buffer = new Array(); + StringBuilder.prototype.append = function(str) { + buffer.push(str); + } + + StringBuilder.prototype.toString = function () { + return buffer.join(""); + } + + } + + +})(jQuery); \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/multiimage/BUpload.min.js b/addons/nkeditor/assets/plugins/multiimage/BUpload.min.js new file mode 100644 index 0000000000000000000000000000000000000000..182c6faaf46372168c077afda926e2299564515b --- /dev/null +++ b/addons/nkeditor/assets/plugins/multiimage/BUpload.min.js @@ -0,0 +1,2 @@ +/* NKeditor 5.0.3 (2018-10-25), Copyright (C) r9it.com,*/ +!function(a){if(!window.applicationCache)throw new Error("您当前的浏览器不支持HTML5,请先升级浏览器才能使用该上传插件!");a.fn.imageCrop=function(b,c){a(this).on("load",function(){var d,e,f,g,h=this.width/this.height,i=b/c;h>=i?(e=c,d=b*h,g=0,f=(d-b)/2):(d=b,e=c/h,f=0,g=0),a(this).css({position:"absolute",top:-g+"px",left:-f+"px",width:d+"px",height:e+"px"})})},a.fn.draggable=function(b){var c={handler:null};b=a.extend(c,b);var d=this;a(b.handler).mousedown(function(b){var c=b.pageX-a(d).position().left,e=b.pageY-a(d).position().top;a(document).mousemove(function(b){window.getSelection?window.getSelection().removeAllRanges():document.selection.empty(),a(d).css({top:b.pageY-e+"px",left:b.pageX-c+"px"})})}).mouseup(function(){a(document).unbind("mousemove")})},void 0==Array.prototype.remove&&(Array.prototype.remove=function(a){for(var b=0;b
          '),d.append('
          '+c.lang.title+'
          '),d.append('
          '+c.lang.localUpload+""),null!=c.list_url&&d.append(''+c.lang.fileServer+""),d.append('
          '),d.append('
          '+c.lang.selectFile+'
          '),d.append('
            '),d.append('
            '+c.lang.confirmBtnText+""),d.append(''+c.lang.cancelBtnText+"
            "),u.dialog=a(d.toString()),a("body").append(u.dialog),0==c.top&&(c.top=(a(window).height()-u.dialog.height())/2),u.dialog.css({left:(a(window).width()-u.dialog.width())/2+"px",top:c.top+"px"}),u.dialog.draggable({handler:u.dialog.find(".ued_title")})}function e(){p(".tab").on("click",function(){var b=a(this).attr("tab");p(".tab-panel").hide(),p("."+b).show(),p(".tab").removeClass("focus"),a(this).addClass("focus")}),p(".close_btn").on("click",function(){u.close()}),p(".webuploader-element-invisible").on("change",function(){f(this)}),p(".image-select").on("click",function(){p(".webuploader-element-invisible").trigger("click")}),p(".btn-continue-add").on("click",function(){p(".webuploader-element-invisible").trigger("click")}),p(".btn-start-upload").on("click",function(){if(!u.uploadLock){if(0==u.todoList.length)return c.errorHandler(c.lang.noFileAdded,"error"),!1;a(this).addClass("disabled").text(c.lang.uploading),g(u.todoList.shift())}}),p(".btn-confirm").on("click",function(){return u.todoList.length>0?(c.errorHandler(c.lang.fileNotUpload,"error"),!1):0==u.selectedList.length?(c.errorHandler(c.lang.noFileSelected,"error"),!1):(c.callback(u.selectedList),void u.close())}),p(".btn-cancel").on("click",function(){u.close()}),p(".tab-online").on("click",function(){0==p(".imagelist .list").children().length&&q()}),p(".imagelist").on("scroll",function(){this.scrollTop+this.clientHeight>=this.scrollHeight&&q()})}function f(d){for(var e=d.files,f=u.todoList.length+u.uploadSuccessNum+e.length,g=u.addedFileNumber;gc.max_filenum)return void c.errorHandler(KindEditor.tmpl(c.lang.uploadLimit,{uploadLimit:c.max_filenum}),"error");var h=new b,i=e[g-u.addedFileNumber];h.append('
          • ');var k=m(i.name);""==k&&(k="default"),k=k.toLowerCase(),-1=="jpg|jpeg|gif|png|bmp".indexOf(k)?h.append(''):h.append(''),h.append('
            '+c.lang.remove+''+c.lang.rotateRight+""),h.append(''+c.lang.rotateLeft+'
            '),h.append('
          • ');var l=a(h.toString());l.find(".remove").on("click",function(){a(this).parents("li").remove();for(var b=a(this).attr("index"),c=0;c1?(a/1048576).toFixed(2)+"MB":(a/1024).toFixed(2)+"KB"}function l(a){var b=1024*c.max_filesize;if(b>0&&a.file.size>b)return o(KindEditor.tmpl(c.lang.sizeLimit,{sizeLimit:c.max_filesize}),a),!1;var d=m(a.file.name);return d&&-1!=c.ext_allow.indexOf(d)&&-1==c.ext_refuse.indexOf(d)?!0:(o(KindEditor.tmpl(c.lang.invalidExt,{invalidExt:d}),a),!1)}function m(a){if(!a)return!1;var b=a.lastIndexOf(".");return-1!=b?a.substr(b+1).toLowerCase():!1}function n(){var b=c.ext_allow.split("|"),d=[];return a.each(b,function(a,b){d.push(t[b])}),d.length>1?d.uinque().join(","):"*"}function o(a,b){p("#img-comtainer-"+v+b.index).find(".error").show().text(a)}function p(a){return u.dialog.find(a)}function q(){return c.list_url?u.noRecord?!1:(p(".loading-icon").show(),void a.get(c.list_url,{page:u.page,marker:u.marker,fileType:c.fileType},function(a){if(p(".loading-icon").hide(),"000"==a.code){if(!a.data[0])return void p(".online .no-data").text(c.lang.noDataText).show();u.marker=a.extra,u.page++,r(a.data,"online")}else p(".online .no-data").text(c.lang.noDataText).show(),u.noRecord=!0},"json")):(p(".online .no-data").html(''+c.lang.noListUrl+"").show(),!1)}function r(c,d){a.each(c,function(c,e){var f=new b;f.append("
          • ");var g=m(e.thumbURL);""==g&&(g="default"),g=g.toLowerCase();var h=e.width+"x"+e.height;-1=="jpg|jpeg|gif|png|bmp".indexOf(g)?(h=k(e.filesize),f.append('')):f.append(''),f.append(''+h+"
          • ");var i=a(f.toString());i.find(".ic").on("click",function(){var b=a(this).prev().data("src");a(this).data("module");a(this).hasClass("selected")?a(this).removeClass("selected"):(a(this).addClass("selected"),u.selectedList.push(b))}),i.find("img").imageCrop(113,113),"online"==d?p(".imagelist .list").append(i):"search"==d&&p(".search-imagelist-box .search-list").append(i)})}c=a.extend({src:"src",upload_url:null,list_url:null,data_type:"json",top:20,fileType:"image",max_filesize:2048,max_filenum:20,no_data_text:"(⊙o⊙)亲,没有多数据了。",ext_allow:"jpg|png|gif|jpeg",ext_refuse:"exe|txt",errorHandler:function(a,b){alert(a)},callback:function(a){console.log(a)}},c);var s={"000":"文件上传成功","001":"文件上传失败","003":"文件大小超出限制","004":"非法文件名后缀"},t={"3gpp":"audio/3gpp, video/3gpp",ac3:"audio/ac3",asf:"allpication/vnd.ms-asf",au:"audio/basic",css:"text/css",csv:"text/csv",doc:"application/msword",dot:"application/msword",dtd:"application/xml-dtd",dwg:"image/vnd.dwg",dxf:"image/vnd.dxf",gif:"image/gif",htm:"text/html",html:"text/html",jp2:"image/jp2",jpe:"image/jpeg",jpeg:"image/jpeg",jpg:"image/jpeg",js:"text/javascript, application/javascript",json:"application/json",mp2:"audio/mpeg, video/mpeg",mp3:"audio/mpeg",mp4:"audio/mp4, video/mp4",mpeg:"video/mpeg",mpg:"video/mpeg",mpp:"application/vnd.ms-project",ogg:"application/ogg, audio/ogg",pdf:"application/pdf",png:"image/png",pot:"application/vnd.ms-powerpoint",pps:"application/vnd.ms-powerpoint",ppt:"application/vnd.ms-powerpoint",rtf:"application/rtf, text/rtf",svf:"image/vnd.svf",tif:"image/tiff",tiff:"image/tiff",txt:"text/plain",wdb:"application/vnd.ms-works",wps:"application/vnd.ms-works",xhtml:"application/xhtml+xml",xlc:"application/vnd.ms-excel",xlm:"application/vnd.ms-excel",xls:"application/vnd.ms-excel",xlt:"application/vnd.ms-excel",xlw:"application/vnd.ms-excel",xml:"text/xml, application/xml",zip:"aplication/zip",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},u={};u.dialog=null,u.todoList=new Array,u.uploadSuccessNum=0,u.selectedList=new Array,u.addedFileNumber=0,u.totalFilesize=0,u.uploadLock=!1,u.page=1,u.marker=null,u.noRecord=!1;var v=Math.ceil(1e12*Math.random());return u.close=function(){u.dialog.remove(),"function"==typeof c.close&&c.close()},d(),e(),u};var b=function(){var a=new Array;b.prototype.append=function(b){a.push(b)},b.prototype.toString=function(){return a.join("")}}}(jQuery); \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/aep.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/aep.png new file mode 100644 index 0000000000000000000000000000000000000000..1ae4e9563666a11c7bb5d2f5206c025915e8b7d8 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/aep.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/asp.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/asp.png new file mode 100644 index 0000000000000000000000000000000000000000..a4fb17491ef378989a229e282dbd57bfb25ab901 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/asp.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/avi.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/avi.png new file mode 100644 index 0000000000000000000000000000000000000000..f3589939bb2856466f86e20e06eafc964e4ec980 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/avi.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/c.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/c.png new file mode 100644 index 0000000000000000000000000000000000000000..bdc1f780a83fd08c952c0796dc9024e23b8fb781 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/c.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/conf.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/conf.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9cf49b5a636a9a8ae1134ef38efbe30b5c2b2a Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/conf.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/css.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/css.png new file mode 100644 index 0000000000000000000000000000000000000000..5475124b642c6483614106bceacb1fe69f71ea7d Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/css.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/default.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/default.png new file mode 100644 index 0000000000000000000000000000000000000000..946d09537012b46f2d476b7983708b8dff4a1e29 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/default.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/doc.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..6b827c660bd98596c212ea333015da8d925a229b Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/doc.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/eml.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/eml.png new file mode 100644 index 0000000000000000000000000000000000000000..8edc0653b23d63d39beca847f9735e4e70d29b50 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/eml.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/eps.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/eps.png new file mode 100644 index 0000000000000000000000000000000000000000..0e6fb79c4693e9c336c89e421cbde5bab485c059 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/eps.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/fla.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/fla.png new file mode 100644 index 0000000000000000000000000000000000000000..767c56c3e47f77b60e20cbb9605e1c91a7fa977f Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/fla.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/htm.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/htm.png new file mode 100644 index 0000000000000000000000000000000000000000..9cc51714040aa9892a63552364f4215cecc86d9c Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/htm.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/idn.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/idn.png new file mode 100644 index 0000000000000000000000000000000000000000..3c83e99dfdf8dfebbd056bea1882d2b63feaa1a9 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/idn.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/ini.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/ini.png new file mode 100644 index 0000000000000000000000000000000000000000..0449595e0051064ddcdc370a6d350cd1173e2a28 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/ini.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/java.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/java.png new file mode 100644 index 0000000000000000000000000000000000000000..cbd350acb1fe58bb37350ccbed3160b27d343c3a Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/java.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/js.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/js.png new file mode 100644 index 0000000000000000000000000000000000000000..f65b15d81c55f9f7b4bdfa01e97ff81c7598d488 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/js.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/jsf.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/jsf.png new file mode 100644 index 0000000000000000000000000000000000000000..e551416ad6fe85407c02eb2b62a52ac8398e2f97 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/jsf.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/markdown.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/markdown.png new file mode 100644 index 0000000000000000000000000000000000000000..57e0870e7c32d7518244e0cf5f54716a462cce5e Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/markdown.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/mdb.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/mdb.png new file mode 100644 index 0000000000000000000000000000000000000000..56f037c4033c31b931190543ccbb0b57a27f4517 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/mdb.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/midi.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/midi.png new file mode 100644 index 0000000000000000000000000000000000000000..7ff836a76e712f9d98099d7a032e59b148e1ecb6 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/midi.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/mov.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/mov.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5b776cdb7650c0f9b529b7cfd70cb616f21d5d Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/mov.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/mp3.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/mp3.png new file mode 100644 index 0000000000000000000000000000000000000000..11f13adf0d7cd760b49c824915583927766bdd18 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/mp3.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/mpeg.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/mpeg.png new file mode 100644 index 0000000000000000000000000000000000000000..eccb9fc41537adfcee056b0dbfdac2455202173e Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/mpeg.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/pdf.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/pdf.png new file mode 100644 index 0000000000000000000000000000000000000000..ca81a58d301d2bf2c3883649bc2bc66fe033f345 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/pdf.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/php.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/php.png new file mode 100644 index 0000000000000000000000000000000000000000..8c4a2c2bd690cd4d2517d0071f8f6286b012c328 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/php.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/ppt.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/ppt.png new file mode 100644 index 0000000000000000000000000000000000000000..4b15ad6f690c7afae530b936582b76ab653726ed Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/ppt.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/psd.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/psd.png new file mode 100644 index 0000000000000000000000000000000000000000..a5f49e2c606142b8a11d0574a4fb517f118f66d2 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/psd.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/pst.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/pst.png new file mode 100644 index 0000000000000000000000000000000000000000..fbe7fe5cca4192250e715dcebd18e3b9777cb57c Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/pst.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/pub.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/pub.png new file mode 100644 index 0000000000000000000000000000000000000000..71a92c1c92a494e9f400a6fe9c04407121518643 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/pub.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/py.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/py.png new file mode 100644 index 0000000000000000000000000000000000000000..8e2f6e2a7d8e7f4e014e00db2b717f16b8f600fc Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/py.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/rb.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/rb.png new file mode 100644 index 0000000000000000000000000000000000000000..5956ee77e17463be62aab6c0786dfe935b417ced Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/rb.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/rmvb.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/rmvb.png new file mode 100644 index 0000000000000000000000000000000000000000..eccb9fc41537adfcee056b0dbfdac2455202173e Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/rmvb.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/scss.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/scss.png new file mode 100644 index 0000000000000000000000000000000000000000..e043f36f24bba56fe9cd3fe7bbc2dac4531d0199 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/scss.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/sql.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/sql.png new file mode 100644 index 0000000000000000000000000000000000000000..0023d84234ce6adef4f3774cc7382a5e06c57c16 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/sql.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/tif.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/tif.png new file mode 100644 index 0000000000000000000000000000000000000000..04e77a49688cdf6bb03c7bc82757020f6bb6dc63 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/tif.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/txt.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/txt.png new file mode 100644 index 0000000000000000000000000000000000000000..876352b868e733a0546a95107562a46ac6714a4a Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/txt.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/vsd.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/vsd.png new file mode 100644 index 0000000000000000000000000000000000000000..c248eb334935f7b82fe1dae4b8da73c6f88037bc Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/vsd.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/wav.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/wav.png new file mode 100644 index 0000000000000000000000000000000000000000..c6ec2f6a4745e31943fdcb0385f2c066b1e2b16d Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/wav.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/wma.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/wma.png new file mode 100644 index 0000000000000000000000000000000000000000..68316b5763352b7b1daf1a0029c706614dc4bf8b Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/wma.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/wmv.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/wmv.png new file mode 100644 index 0000000000000000000000000000000000000000..194ac20d9740b46e0e5b3620ee43c4e3e08fbccf Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/wmv.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/xls.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/xls.png new file mode 100644 index 0000000000000000000000000000000000000000..b9eada4ea6dd441f67ae3b0e740fd27e7cc9f1ab Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/xls.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/xml.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/xml.png new file mode 100644 index 0000000000000000000000000000000000000000..805f307c28cf16346b2e5918ca403cc37fed62ec Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/xml.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/icons/zip.png b/addons/nkeditor/assets/plugins/multiimage/css/icons/zip.png new file mode 100644 index 0000000000000000000000000000000000000000..6f0a4340bcd401c8945bcb0901ff3a0106a107da Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/icons/zip.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/images/dialog-title-bg.png b/addons/nkeditor/assets/plugins/multiimage/css/images/dialog-title-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..f744f267f797ebf9993b746ecaff21b85d556e83 Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/images/dialog-title-bg.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/images/icons-all.gif b/addons/nkeditor/assets/plugins/multiimage/css/images/icons-all.gif new file mode 100644 index 0000000000000000000000000000000000000000..21915e59dede0aa22cda8c7097a14f0f1f68906c Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/images/icons-all.gif differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/images/icons.png b/addons/nkeditor/assets/plugins/multiimage/css/images/icons.png new file mode 100644 index 0000000000000000000000000000000000000000..12e4700163ac87fa38ae3d92a2c39d0fb4690fed Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/images/icons.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/images/image.png b/addons/nkeditor/assets/plugins/multiimage/css/images/image.png new file mode 100644 index 0000000000000000000000000000000000000000..19699f6a9c6b09cb18ec0f488242d9753d2e341b Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/images/image.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/images/loader.gif b/addons/nkeditor/assets/plugins/multiimage/css/images/loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..5bb90fd6a49107a321c35b9cee4a7b810314b51f Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/images/loader.gif differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/images/progress.png b/addons/nkeditor/assets/plugins/multiimage/css/images/progress.png new file mode 100644 index 0000000000000000000000000000000000000000..717c4865c90a959c6a0e9ad1af9c777d900a2e9c Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/images/progress.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/images/success.png b/addons/nkeditor/assets/plugins/multiimage/css/images/success.png new file mode 100644 index 0000000000000000000000000000000000000000..94f968dc8fd3c7ca8f6cb599d006ef3f23b62c7d Binary files /dev/null and b/addons/nkeditor/assets/plugins/multiimage/css/images/success.png differ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/upload.css b/addons/nkeditor/assets/plugins/multiimage/css/upload.css new file mode 100644 index 0000000000000000000000000000000000000000..cff67e2fb05bf0b9e4e8832030e1b8faa74e0224 --- /dev/null +++ b/addons/nkeditor/assets/plugins/multiimage/css/upload.css @@ -0,0 +1,552 @@ +@charset "UTF-8"; +.uedbody { + box-sizing: content-box !important; + -webkit-box-sizing: content-box !important; + -moz-box-sizing: content-box !important; + width: 652px; + position: fixed; + padding: 2px 0px 0px 2px; + background-color: #FFF; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.2); + z-index: 811213; + font-family: "微软雅黑"; + font-size: 12px; + margin: 0px auto; } + .uedbody div, .uedbody dl, .uedbody dt, .uedbody dd, .uedbody ul, .uedbody li, .uedbody ol, .uedbody h1, .uedbody h2, .uedbody h3, .uedbody h4, .uedbody h5, .uedbody h6, .uedbody pre, .uedbody code, .uedbody form, .uedbody fieldset, .uedbody legend, .uedbody button, .uedbody textarea, .uedbody blockquote, .uedbody p { + margin: 0; + padding: 0; } + .uedbody h1, .uedbody h2, .uedbody h3, .uedbody h4, .uedbody h5, .uedbody h6 { + font-weight: normal; } + .uedbody li { + list-style-type: none; } + .uedbody ol, .uedbody ul, .uedbody dl { + list-style: none; } + .uedbody em { + font-style: normal; } + .uedbody img { + border: none; + vertical-align: middle; } + .uedbody select, .uedbody label, .uedbody input { + vertical-align: middle; + padding: 0; + margin: 0; + outline: medium; + font-size: 12px; } + .uedbody textarea { + resize: none; + line-height: 18px; } + .uedbody table { + border-collapse: collapse; + border-spacing: 0; + empty-cell: show; } + .uedbody a { + text-decoration: none; + color: #333; + outline: none; + cursor: pointer; } + .uedbody a:hover { + cursor: pointer; + blr: expression(this.onFocus=this.blur()); } + .uedbody * { + padding: 0; + margin: 0; + box-sizing: content-box !important; + -webkit-box-sizing: content-box !important; + -moz-box-sizing: content-box !important; } + .uedbody .clearfix:before, .uedbody .clearfix:after { + content: ""; + display: table; } + .uedbody .clearfix:after { + clear: both; } + .uedbody .clearfix { + *zoom: 1; } + .uedbody .fr { + float: right; } + .uedbody .fl { + float: left; } + .uedbody .ued_title { + height: 26px; + border-bottom: 1px solid #C6C6C6; + background: transparent url("images/dialog-title-bg.png") repeat-x scroll 0% 0%; + position: relative; + cursor: move; } + .uedbody .ued_title .icon { + background: url("images/icons-all.gif") no-repeat center; } + .uedbody .ued_title .uedbar span { + font-weight: bold; + font-size: 14px; + color: #444; + line-height: 26px; + padding-left: 5px; } + .uedbody .ued_title .close_btn { + height: 20px; + width: 20px; + cursor: pointer; + background-position: 0px -59px; + position: absolute; + right: 5px; + top: 3px; } + .uedbody .ued_title .close_btn:hover { + background-position: 0px -89px; } + .uedbody .btn { + display: inline-block; + margin-bottom: 0px; + margin-right: 5px; + padding: 4px 10px; + font-weight: 400; + text-align: center; + cursor: pointer; + border: 1px solid transparent; + white-space: nowrap; + font-size: 14px; + border-radius: 3px; + -moz-user-select: none; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + padding: 5px 14px; } + .uedbody .btn-default { + border: 1px solid #CFCFCF; + color: #565656; + background: #ffffff; } + .uedbody .btn-default:hover { + background: #f0f0f0; } + .uedbody .btn-primary { + background: #00b7ee; + color: #ffffff; } + .uedbody .btn-primary:hover { + background: #00a2d4; } + .uedbody .btn.disabled { + cursor: not-allowed; + opacity: .65; } + .uedbody .btn.disabled:hover { + background: #00b7ee; } + .uedbody .wrapper { + width: 630px; + height: 380px; + margin: 0px auto; + padding: 10px; + position: relative; + font-family: sans-serif; } + .uedbody .wrapper .wra_head span { + float: left; + padding: 0px 5px; + margin-right: 3px; + height: 30px; + border: 1px solid #CCC; + background: transparent url("images/dialog-title-bg.png") repeat-x scroll 0% 0%; + text-align: center; + line-height: 30px; + cursor: pointer; + position: relative; } + .uedbody .wrapper .wra_head span.focus { + height: 31px; + border-bottom: medium none; + background: #FFF none repeat scroll 0% 0%; + position: relative; + z-index: 2; } + .uedbody .wrapper .wra_body { + width: 100%; + height: 346px; + clear: both; + margin: 0px auto; + border: 1px solid #CCC; + display: block; + clip: auto; + overflow: hidden; + top: -1px; + position: relative; } + .uedbody .wrapper .wra_body .upload-panel .wra_pla { + zoom: 1; + overflow: hidden; + text-align: center; } + .uedbody .wrapper .wra_body .upload-panel .wra_pla .upload-image-placeholder { + margin: 10px; + border: 2px dashed #e6e6e6; + height: 172px; + padding-top: 150px; + text-align: center; + background: url("images/image.png") center 70px no-repeat; + position: relative; + top: 0; } + .uedbody .wrapper .wra_body .upload-panel .wra_pla .upload-image-placeholder .webuploader-element-invisible { + opacity: 0; + width: 0; + height: 0; } + .uedbody .wrapper .wra_body .upload-panel .wra_pla .upload-image-placeholder .image-select { + padding: 10px 30px; + cursor: pointer; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .wra_bar { + border-bottom: 1px solid #DADADA; + padding: 8px; + vertical-align: middle; + position: relative; + zoom: 1; + overflow: hidden; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .wra_bar .info { + font-size: 14px; + color: #666; + margin-top: 6px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .wra_bar .fr .btn { + padding: 6px 15px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist { + list-style: outside none none; + margin: 0px; + padding: 0px; + overflow-x: hidden; + overflow-y: auto; + position: relative; + height: 300px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li { + width: 113px; + height: 113px; + margin: 9px 0px 0px 9px; + position: relative; + display: block; + float: left; + overflow: hidden; + font-size: 12px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .imgWrap { + position: relative; + vertical-align: middle; + text-align: center; + overflow: hidden; + width: 113px; + height: 113px; + transform-origin: 50% 50% 0px; + transition: all 200ms ease-out 0s; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box { + position: absolute; + display: none; + background: rgba(0, 0, 0, 0.5) none repeat scroll 0% 0%; + width: 100%; + top: 0px; + left: 0px; + overflow: hidden; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box span { + width: 24px; + height: 24px; + display: inline; + float: right; + text-indent: -9999px; + overflow: hidden; + background: url("images/icons.png") no-repeat; + margin: 5px 1px 1px; + cursor: pointer; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .remove { + background-position: -48px -24px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .remove:hover { + background-position: -48px -0px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .rotateRight { + display: none; + background-position: -24px -24px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .rotateRight:hover { + background-position: -24px -0px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .rotateLeft { + display: none; + background-position: 0px -24px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .rotateLeft:hover { + background-position: 0px 0px; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .success { + background: url("images/success.png") no-repeat right; + position: absolute; + display: none; + left: 0px; + bottom: 0px; + height: 40px; + width: 100%; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .error { + position: absolute; + width: 100%; + display: none; + background: rgba(255, 255, 255, 0.7) none repeat scroll 0% 0%; + left: 0; + padding: 5px 3px; + color: #cc0000; + border: 1px solid #cccccc; + bottom: 0; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .progress { + position: absolute; + width: 100%; + bottom: 0; + left: 0; + bottom: 0; + height: 8px; + overflow: hidden; + z-index: 50; + margin: 0; + border-radius: 0; + background: none; + -webkit-box-shadow: 0 0 0; } + .uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .progress span { + width: 0; + height: 100%; + background: #1483d8 url("images/progress.png") repeat-x; + -webit-transition: width 200ms linear; + -moz-transition: width 200ms linear; + -o-transition: width 200ms linear; + -ms-transition: width 200ms linear; + transition: width 200ms linear; + -webkit-animation: progressmove 2s linear infinite; + -moz-animation: progressmove 2s linear infinite; + -o-animation: progressmove 2s linear infinite; + -ms-animation: progressmove 2s linear infinite; + animation: progressmove 2s linear infinite; + -webkit-transform: translateZ(0); } + .uedbody .wrapper .wra_body .online { + width: 100%; + height: 336px; + padding: 10px 0px 0px; + display: none; } + .uedbody .wrapper .wra_body .online .imagelist { + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + position: relative; } + .uedbody .wrapper .wra_body .online .imagelist .list li { + float: left; + display: block; + list-style: outside none none; + padding: 0px; + width: 113px; + height: 113px; + margin: 0px 0px 9px 9px; + background-color: #EEE; + overflow: hidden; + cursor: pointer; + position: relative; } + .uedbody .wrapper .wra_body .online .imagelist .list li img { + cursor: pointer; } + .uedbody .wrapper .wra_body .online .imagelist .list li span.ic { + position: absolute; + top: 0px; + left: 0px; + cursor: pointer; + width: 113px; + height: 113px; } + .uedbody .wrapper .wra_body .online .imagelist .list li span.ic .img-size { + font-size: 12px; + padding: 5px; + background: rgba(0, 0, 0, 0.6); + display: none; + color: #ffffff; } + .uedbody .wrapper .wra_body .online .imagelist .list li span.ic:hover { + width: 107px; + height: 107px; + border: 3px solid #1094FA; + background-position: 72px 72px; } + .uedbody .wrapper .wra_body .online .imagelist .list li span.ic:hover .img-size { + display: inline-block; + width: 97px; } + .uedbody .wrapper .wra_body .online .imagelist .list li span.selected { + background: url("images/success.png") no-repeat 75px 75px; } + .uedbody .wrapper .wra_body .searchbox { + width: 100%; + padding: 10px 0px 0px; + zoom: 1; + overflow: hidden; + display: none; } + .uedbody .wrapper .wra_body .searchbox .search-bar .searTxt { + margin-left: 5px; + background: #FFF none repeat scroll 0% 0%; + width: 300px; + height: 21px; + line-height: 21px; + padding: 3px 6px; + font-size: 14px; + line-height: 1.42857; + border: 1px solid #CCC; + border-radius: 4px; + box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.075) inset; + transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; + margin-right: 10px; } + .uedbody .wrapper .wra_body .searchbox .search-bar .searchBtn { + color: #FFF; + border-color: #285E8E; + background-color: #3B97D7; } + .uedbody .wrapper .wra_body .searchbox .search-bar .searchRese { + color: #333; + border-color: #CCC; + background-color: #FFF; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box { + width: 100%; + height: 292px; + overflow-x: hidden; + overflow-y: auto; + position: relative; + margin-top: 10px; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list { + zoom: 1; + overflow: hidden; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li { + float: left; + display: block; + list-style: outside none none; + padding: 0px; + width: 113px; + height: 113px; + margin: 0px 0px 9px 9px; + background-color: #EEE; + overflow: hidden; + cursor: pointer; + position: relative; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li img { + cursor: pointer; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.ic { + position: absolute; + top: 0px; + left: 0px; + cursor: pointer; + width: 113px; + height: 113px; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.ic .img-size { + font-size: 12px; + padding: 5px; + background: rgba(0, 0, 0, 0.6); + display: none; + color: #ffffff; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.ic:hover { + width: 107px; + height: 107px; + border: 3px solid #1094FA; + background-position: 72px 72px; + overflow: hidden; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.ic:hover .img-size { + display: inline-block; + width: 97px; } + .uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.selected { + background: url("images/success.png") no-repeat 75px 75px; } + .uedbody .wrapper .wra_body .no-data { + line-height: 40px; + height: 40px; + font-size: 14px; + color: #999999; + text-align: center; + display: none; } + .uedbody .wrapper .wra_body .no-data .error { + color: #cc0000; } + .uedbody .wrapper .wra_body .loading-icon { + background: rgba(0, 0, 0, 0.4) url("images/loader.gif") no-repeat center center; + position: absolute; + width: 100%; + height: 346px; + top: 0; + left: 0; + display: none; + text-align: center; } + .uedbody .wrapper .wra_body .loading-icon .loading-message { + position: absolute; + font-size: 14px; + color: #f0f0f0; + top: 210px; + left: 253px; } + .uedbody .wrapper .wra_body .icon-placeholder { + background-size: 113px 113px; + display: block; + width: 113px; + height: 113px; } + .uedbody .wrapper .wra_body .icon-aep, .uedbody .wrapper .wra_body .icon-aepx { + background-image: url("icons/aep.png"); } + .uedbody .wrapper .wra_body .icon-asp { + background-image: url("icons/asp.png"); } + .uedbody .wrapper .wra_body .icon-avi { + background-image: url("icons/avi.png"); } + .uedbody .wrapper .wra_body .icon-c, .uedbody .wrapper .wra_body .icon-cpp { + background-image: url("icons/c.png"); } + .uedbody .wrapper .wra_body .icon-conf { + background-image: url("icons/conf.png"); } + .uedbody .wrapper .wra_body .icon-css { + background-image: url("icons/css.png"); } + .uedbody .wrapper .wra_body .icon-htm, .uedbody .wrapper .wra_body .icon-html { + background-image: url("icons/htm.png"); } + .uedbody .wrapper .wra_body .icon-default { + background-image: url("icons/txt.png"); } + .uedbody .wrapper .wra_body .icon-doc, .uedbody .wrapper .wra_body .icon-docx { + background-image: url("icons/doc.png"); } + .uedbody .wrapper .wra_body .icon-eps { + background-image: url("icons/eps.png"); } + .uedbody .wrapper .wra_body .icon-fla, .uedbody .wrapper .wra_body .icon-swf { + background-image: url("icons/fla.png"); } + .uedbody .wrapper .wra_body .icon-idn { + background-image: url("icons/idn.png"); } + .uedbody .wrapper .wra_body .icon-ini { + background-image: url("icons/ini.png"); } + .uedbody .wrapper .wra_body .icon-java, .uedbody .wrapper .wra_body .icon-jar, .uedbody .wrapper .wra_body .icon-war { + background-image: url("icons/java.png"); } + .uedbody .wrapper .wra_body .icon-js { + background-image: url("icons/js.png"); } + .uedbody .wrapper .wra_body .icon-jsf { + background-image: url("icons/jsf.png"); } + .uedbody .wrapper .wra_body .icon-md, .uedbody .wrapper .wra_body .icon-markdown { + background-image: url("icons/markdown.png"); } + .uedbody .wrapper .wra_body .icon-mdb { + background-image: url("icons/mdb.png"); } + .uedbody .wrapper .wra_body .icon-midi { + background-image: url("icons/midi.png"); } + .uedbody .wrapper .wra_body .icon-mov { + background-image: url("icons/mov.png"); } + .uedbody .wrapper .wra_body .icon-mp3 { + background-image: url("icons/mp3.png"); } + .uedbody .wrapper .wra_body .icon-mpeg { + background-image: url("icons/mpeg.png"); } + .uedbody .wrapper .wra_body .icon-pdf { + background-image: url("icons/pdf.png"); } + .uedbody .wrapper .wra_body .icon-php { + background-image: url("icons/php.png"); } + .uedbody .wrapper .wra_body .icon-ppt, .uedbody .wrapper .wra_body .icon-pptx { + background-image: url("icons/ppt.png"); } + .uedbody .wrapper .wra_body .icon-psd { + background-image: url("icons/psd.png"); } + .uedbody .wrapper .wra_body .icon-pst { + background-image: url("icons/pst.png"); } + .uedbody .wrapper .wra_body .icon-pub { + background-image: url("icons/pub.png"); } + .uedbody .wrapper .wra_body .icon-py { + background-image: url("icons/py.png"); } + .uedbody .wrapper .wra_body .icon-rb { + background-image: url("icons/rb.png"); } + .uedbody .wrapper .wra_body .icon-rm, .uedbody .wrapper .wra_body .icon-rmvb { + background-image: url("icons/rmvb.png"); } + .uedbody .wrapper .wra_body .icon-scss { + background-image: url("icons/scss.png"); } + .uedbody .wrapper .wra_body .icon-tif { + background-image: url("icons/tif.png"); } + .uedbody .wrapper .wra_body .icon-txt { + background-image: url("icons/txt.png"); } + .uedbody .wrapper .wra_body .icon-vsd { + background-image: url("icons/vsd.png"); } + .uedbody .wrapper .wra_body .icon-wav { + background-image: url("icons/wav.png"); } + .uedbody .wrapper .wra_body .icon-wma { + background-image: url("icons/wma.png"); } + .uedbody .wrapper .wra_body .icon-wmv { + background-image: url("icons/wmv.png"); } + .uedbody .wrapper .wra_body .icon-xls, .uedbody .wrapper .wra_body .icon-xlsx { + background-image: url("icons/xls.png"); } + .uedbody .wrapper .wra_body .icon-xml { + background-image: url("icons/xml.png"); } + .uedbody .wrapper .wra_body .icon-zip, .uedbody .wrapper .wra_body .icon-rar, .uedbody .wrapper .wra_body .icon-tgz, .uedbody .wrapper .wra_body .icon-gz, .uedbody .wrapper .wra_body .icon-tar, .uedbody .wrapper .wra_body .icon-7z { + background-image: url("icons/zip.png"); } + .uedbody .wrapper .wra_body_server { + height: 380px; } + .uedbody .wrapper .wra_body_server .online { + display: block !important; + height: 365px; } + .uedbody .wra-btn-group { + clear: both; + zoom: 1; + text-align: right; + padding: 10px 20px 20px 0px; } + .uedbody .wra-btn-group .tip-text { + float: left; + padding: 5px 10px; + color: #999; + font-size: 14px; } + +/*# sourceMappingURL=upload.css.map */ diff --git a/addons/nkeditor/assets/plugins/multiimage/css/upload.min.css b/addons/nkeditor/assets/plugins/multiimage/css/upload.min.css new file mode 100644 index 0000000000000000000000000000000000000000..3f463d74220f30637cece66f435b87f29921a8e6 --- /dev/null +++ b/addons/nkeditor/assets/plugins/multiimage/css/upload.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.uedbody{box-sizing:content-box!important;-webkit-box-sizing:content-box!important;-moz-box-sizing:content-box!important;width:652px;position:fixed;padding:2px 0 0 2px;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 5px 10px rgba(0,0,0,.2);z-index:811213;font-family:"微软雅黑";font-size:12px;margin:0 auto}.uedbody blockquote,.uedbody button,.uedbody code,.uedbody dd,.uedbody div,.uedbody dl,.uedbody dt,.uedbody fieldset,.uedbody form,.uedbody h1,.uedbody h2,.uedbody h3,.uedbody h4,.uedbody h5,.uedbody h6,.uedbody legend,.uedbody li,.uedbody ol,.uedbody p,.uedbody pre,.uedbody textarea,.uedbody ul{margin:0;padding:0}.uedbody h1,.uedbody h2,.uedbody h3,.uedbody h4,.uedbody h5,.uedbody h6{font-weight:400}.uedbody li{list-style-type:none}.uedbody dl,.uedbody ol,.uedbody ul{list-style:none}.uedbody em{font-style:normal}.uedbody img{border:none;vertical-align:middle}.uedbody input,.uedbody label,.uedbody select{vertical-align:middle;padding:0;margin:0;outline:medium;font-size:12px}.uedbody textarea{resize:none;line-height:18px}.uedbody table{border-collapse:collapse;border-spacing:0;empty-cell:show}.uedbody a{text-decoration:none;color:#333;outline:0;cursor:pointer}.uedbody a:hover{cursor:pointer;blr:expression(this.onFocus=this.blur())}.uedbody *{padding:0;margin:0;box-sizing:content-box!important;-webkit-box-sizing:content-box!important;-moz-box-sizing:content-box!important}.uedbody .clearfix:after,.uedbody .clearfix:before{content:"";display:table}.uedbody .clearfix:after{clear:both}.uedbody .fr{float:right}.uedbody .fl{float:left}.uedbody .ued_title{height:26px;border-bottom:1px solid #c6c6c6;background:transparent url(images/dialog-title-bg.png) repeat-x scroll 0 0;position:relative;cursor:move}.uedbody .ued_title .icon{background:url(images/icons-all.gif) no-repeat center}.uedbody .ued_title .uedbar span{font-weight:700;font-size:14px;color:#444;line-height:26px;padding-left:5px}.uedbody .ued_title .close_btn{height:20px;width:20px;cursor:pointer;background-position:0 -59px;position:absolute;right:5px;top:3px}.uedbody .ued_title .close_btn:hover{background-position:0 -89px}.uedbody .btn{display:inline-block;margin-bottom:0;margin-right:5px;padding:4px 10px;font-weight:400;text-align:center;cursor:pointer;border:1px solid transparent;white-space:nowrap;font-size:14px;border-radius:3px;-moz-user-select:none;box-shadow:0 1px 1px rgba(0,0,0,.1);padding:5px 14px}.uedbody .btn-default{border:1px solid #cfcfcf;color:#565656;background:#fff}.uedbody .btn-default:hover{background:#f0f0f0}.uedbody .btn-primary{background:#00b7ee;color:#fff}.uedbody .btn-primary:hover{background:#00a2d4}.uedbody .btn.disabled{cursor:not-allowed;opacity:.65}.uedbody .btn.disabled:hover{background:#00b7ee}.uedbody .wrapper{width:630px;height:380px;margin:0 auto;padding:10px;position:relative;font-family:sans-serif}.uedbody .wrapper .wra_head span{float:left;padding:0 5px;margin-right:3px;height:30px;border:1px solid #ccc;background:transparent url(images/dialog-title-bg.png) repeat-x scroll 0 0;text-align:center;line-height:30px;cursor:pointer;position:relative}.uedbody .wrapper .wra_head span.focus{height:31px;border-bottom:medium none;background:#fff none repeat scroll 0 0;position:relative;z-index:2}.uedbody .wrapper .wra_body{width:100%;height:346px;clear:both;margin:0 auto;border:1px solid #ccc;display:block;clip:auto;overflow:hidden;top:-1px;position:relative}.uedbody .wrapper .wra_body .upload-panel .wra_pla{zoom:1;overflow:hidden;text-align:center}.uedbody .wrapper .wra_body .upload-panel .wra_pla .upload-image-placeholder{margin:10px;border:2px dashed #e6e6e6;height:172px;padding-top:150px;text-align:center;background:url(images/image.png) center 70px no-repeat;position:relative;top:0}.uedbody .wrapper .wra_body .upload-panel .wra_pla .upload-image-placeholder .webuploader-element-invisible{opacity:0;width:0;height:0}.uedbody .wrapper .wra_body .upload-panel .wra_pla .upload-image-placeholder .image-select{padding:10px 30px;cursor:pointer}.uedbody .wrapper .wra_body .upload-panel .image-list-box .wra_bar{border-bottom:1px solid #dadada;padding:8px;vertical-align:middle;position:relative;zoom:1;overflow:hidden}.uedbody .wrapper .wra_body .upload-panel .image-list-box .wra_bar .info{font-size:14px;color:#666;margin-top:6px}.uedbody .wrapper .wra_body .upload-panel .image-list-box .wra_bar .fr .btn{padding:6px 15px}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist{list-style:outside none none;margin:0;padding:0;overflow-x:hidden;overflow-y:auto;position:relative;height:300px}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li{width:113px;height:113px;margin:9px 0 0 9px;position:relative;display:block;float:left;overflow:hidden;font-size:12px}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .imgWrap{position:relative;vertical-align:middle;text-align:center;overflow:hidden;width:113px;height:113px;transform-origin:50% 50% 0;transition:all .2s ease-out 0s}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box{position:absolute;display:none;background:rgba(0,0,0,.5) none repeat scroll 0 0;width:100%;top:0;left:0;overflow:hidden}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box span{width:24px;height:24px;display:inline;float:right;text-indent:-9999px;overflow:hidden;background:url(images/icons.png) no-repeat;margin:5px 1px 1px;cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .remove{background-position:-48px -24px}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .remove:hover{background-position:-48px 0}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .rotateRight{display:none;background-position:-24px -24px}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .rotateRight:hover{background-position:-24px 0}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .rotateLeft{display:none;background-position:0 -24px}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .file-opt-box .rotateLeft:hover{background-position:0 0}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .success{background:url(images/success.png) no-repeat right;position:absolute;display:none;left:0;bottom:0;height:40px;width:100%}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .error{position:absolute;width:100%;display:none;background:rgba(255,255,255,.7) none repeat scroll 0 0;left:0;padding:5px 3px;color:#c00;border:1px solid #ccc;bottom:0}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .progress{position:absolute;width:100%;bottom:0;left:0;bottom:0;height:8px;overflow:hidden;z-index:50;margin:0;border-radius:0;background:0 0;-webkit-box-shadow:0 0 0}.uedbody .wrapper .wra_body .upload-panel .image-list-box .filelist li .progress span{width:0;height:100%;background:#1483d8 url(images/progress.png) repeat-x;-webit-transition:width .2s linear;-moz-transition:width .2s linear;-o-transition:width .2s linear;-ms-transition:width .2s linear;transition:width .2s linear;-webkit-animation:progressmove 2s linear infinite;-moz-animation:progressmove 2s linear infinite;-o-animation:progressmove 2s linear infinite;-ms-animation:progressmove 2s linear infinite;animation:progressmove 2s linear infinite;-webkit-transform:translateZ(0)}.uedbody .wrapper .wra_body .online{width:100%;height:336px;padding:10px 0 0;display:none}.uedbody .wrapper .wra_body .online .imagelist{width:100%;height:100%;overflow-x:hidden;overflow-y:auto;position:relative}.uedbody .wrapper .wra_body .online .imagelist .list li{float:left;display:block;list-style:outside none none;padding:0;width:113px;height:113px;margin:0 0 9px 9px;background-color:#eee;overflow:hidden;cursor:pointer;position:relative}.uedbody .wrapper .wra_body .online .imagelist .list li img{cursor:pointer}.uedbody .wrapper .wra_body .online .imagelist .list li span.ic{position:absolute;top:0;left:0;cursor:pointer;width:113px;height:113px}.uedbody .wrapper .wra_body .online .imagelist .list li span.ic .img-size{font-size:12px;padding:5px;background:rgba(0,0,0,.6);display:none;color:#fff}.uedbody .wrapper .wra_body .online .imagelist .list li span.ic:hover{width:107px;height:107px;border:3px solid #1094fa;background-position:72px 72px}.uedbody .wrapper .wra_body .online .imagelist .list li span.ic:hover .img-size{display:inline-block;width:97px}.uedbody .wrapper .wra_body .online .imagelist .list li span.selected{background:url(images/success.png) no-repeat 75px 75px}.uedbody .wrapper .wra_body .searchbox{width:100%;padding:10px 0 0;zoom:1;overflow:hidden;display:none}.uedbody .wrapper .wra_body .searchbox .search-bar .searTxt{margin-left:5px;background:#fff none repeat scroll 0 0;width:300px;height:21px;line-height:21px;padding:3px 6px;font-size:14px;line-height:1.42857;border:1px solid #ccc;border-radius:4px;box-shadow:0 1px 1px rgba(0,0,0,.075) inset;transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;margin-right:10px}.uedbody .wrapper .wra_body .searchbox .search-bar .searchBtn{color:#fff;border-color:#285e8e;background-color:#3b97d7}.uedbody .wrapper .wra_body .searchbox .search-bar .searchRese{color:#333;border-color:#ccc;background-color:#fff}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box{width:100%;height:292px;overflow-x:hidden;overflow-y:auto;position:relative;margin-top:10px}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list{zoom:1;overflow:hidden}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li{float:left;display:block;list-style:outside none none;padding:0;width:113px;height:113px;margin:0 0 9px 9px;background-color:#eee;overflow:hidden;cursor:pointer;position:relative}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li img{cursor:pointer}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.ic{position:absolute;top:0;left:0;cursor:pointer;width:113px;height:113px}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.ic .img-size{font-size:12px;padding:5px;background:rgba(0,0,0,.6);display:none;color:#fff}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.ic:hover{width:107px;height:107px;border:3px solid #1094fa;background-position:72px 72px;overflow:hidden}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.ic:hover .img-size{display:inline-block;width:97px}.uedbody .wrapper .wra_body .searchbox .search-imagelist-box .search-list li span.selected{background:url(images/success.png) no-repeat 75px 75px}.uedbody .wrapper .wra_body .no-data{line-height:40px;height:40px;font-size:14px;color:#999;text-align:center;display:none}.uedbody .wrapper .wra_body .no-data .error{color:#c00}.uedbody .wrapper .wra_body .loading-icon{background:rgba(0,0,0,.4) url(images/loader.gif) no-repeat center center;position:absolute;width:100%;height:346px;top:0;left:0;display:none;text-align:center}.uedbody .wrapper .wra_body .loading-icon .loading-message{position:absolute;font-size:14px;color:#f0f0f0;top:210px;left:253px}.uedbody .wrapper .wra_body .icon-placeholder{background-size:113px 113px;display:block;width:113px;height:113px}.uedbody .wrapper .wra_body .icon-aep,.uedbody .wrapper .wra_body .icon-aepx{background-image:url(icons/aep.png)}.uedbody .wrapper .wra_body .icon-asp{background-image:url(icons/asp.png)}.uedbody .wrapper .wra_body .icon-avi{background-image:url(icons/avi.png)}.uedbody .wrapper .wra_body .icon-c,.uedbody .wrapper .wra_body .icon-cpp{background-image:url(icons/c.png)}.uedbody .wrapper .wra_body .icon-conf{background-image:url(icons/conf.png)}.uedbody .wrapper .wra_body .icon-css{background-image:url(icons/css.png)}.uedbody .wrapper .wra_body .icon-htm,.uedbody .wrapper .wra_body .icon-html{background-image:url(icons/htm.png)}.uedbody .wrapper .wra_body .icon-default{background-image:url(icons/txt.png)}.uedbody .wrapper .wra_body .icon-doc,.uedbody .wrapper .wra_body .icon-docx{background-image:url(icons/doc.png)}.uedbody .wrapper .wra_body .icon-eps{background-image:url(icons/eps.png)}.uedbody .wrapper .wra_body .icon-fla,.uedbody .wrapper .wra_body .icon-swf{background-image:url(icons/fla.png)}.uedbody .wrapper .wra_body .icon-idn{background-image:url(icons/idn.png)}.uedbody .wrapper .wra_body .icon-ini{background-image:url(icons/ini.png)}.uedbody .wrapper .wra_body .icon-jar,.uedbody .wrapper .wra_body .icon-java,.uedbody .wrapper .wra_body .icon-war{background-image:url(icons/java.png)}.uedbody .wrapper .wra_body .icon-js{background-image:url(icons/js.png)}.uedbody .wrapper .wra_body .icon-jsf{background-image:url(icons/jsf.png)}.uedbody .wrapper .wra_body .icon-markdown,.uedbody .wrapper .wra_body .icon-md{background-image:url(icons/markdown.png)}.uedbody .wrapper .wra_body .icon-mdb{background-image:url(icons/mdb.png)}.uedbody .wrapper .wra_body .icon-midi{background-image:url(icons/midi.png)}.uedbody .wrapper .wra_body .icon-mov{background-image:url(icons/mov.png)}.uedbody .wrapper .wra_body .icon-mp3{background-image:url(icons/mp3.png)}.uedbody .wrapper .wra_body .icon-mpeg{background-image:url(icons/mpeg.png)}.uedbody .wrapper .wra_body .icon-pdf{background-image:url(icons/pdf.png)}.uedbody .wrapper .wra_body .icon-php{background-image:url(icons/php.png)}.uedbody .wrapper .wra_body .icon-ppt,.uedbody .wrapper .wra_body .icon-pptx{background-image:url(icons/ppt.png)}.uedbody .wrapper .wra_body .icon-psd{background-image:url(icons/psd.png)}.uedbody .wrapper .wra_body .icon-pst{background-image:url(icons/pst.png)}.uedbody .wrapper .wra_body .icon-pub{background-image:url(icons/pub.png)}.uedbody .wrapper .wra_body .icon-py{background-image:url(icons/py.png)}.uedbody .wrapper .wra_body .icon-rb{background-image:url(icons/rb.png)}.uedbody .wrapper .wra_body .icon-rm,.uedbody .wrapper .wra_body .icon-rmvb{background-image:url(icons/rmvb.png)}.uedbody .wrapper .wra_body .icon-scss{background-image:url(icons/scss.png)}.uedbody .wrapper .wra_body .icon-tif{background-image:url(icons/tif.png)}.uedbody .wrapper .wra_body .icon-txt{background-image:url(icons/txt.png)}.uedbody .wrapper .wra_body .icon-vsd{background-image:url(icons/vsd.png)}.uedbody .wrapper .wra_body .icon-wav{background-image:url(icons/wav.png)}.uedbody .wrapper .wra_body .icon-wma{background-image:url(icons/wma.png)}.uedbody .wrapper .wra_body .icon-wmv{background-image:url(icons/wmv.png)}.uedbody .wrapper .wra_body .icon-xls,.uedbody .wrapper .wra_body .icon-xlsx{background-image:url(icons/xls.png)}.uedbody .wrapper .wra_body .icon-xml{background-image:url(icons/xml.png)}.uedbody .wrapper .wra_body .icon-7z,.uedbody .wrapper .wra_body .icon-gz,.uedbody .wrapper .wra_body .icon-rar,.uedbody .wrapper .wra_body .icon-tar,.uedbody .wrapper .wra_body .icon-tgz,.uedbody .wrapper .wra_body .icon-zip{background-image:url(icons/zip.png)}.uedbody .wrapper .wra_body_server{height:380px}.uedbody .wrapper .wra_body_server .online{display:block!important;height:365px}.uedbody .wra-btn-group{clear:both;zoom:1;text-align:right;padding:10px 20px 20px 0}.uedbody .wra-btn-group .tip-text{float:left;padding:5px 10px;color:#999;font-size:14px} \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/multiimage/css/upload.scss b/addons/nkeditor/assets/plugins/multiimage/css/upload.scss new file mode 100644 index 0000000000000000000000000000000000000000..10ff83207e95b46ce5a1e8ebcd5a52f282a97804 --- /dev/null +++ b/addons/nkeditor/assets/plugins/multiimage/css/upload.scss @@ -0,0 +1,642 @@ +$dialogWidth:652px; +$dialogZindex:811213; +$fontsize:14px; +.uedbody{ + div, dl, dt, dd, ul, li,ol, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, button, textarea, blockquote,p{margin:0; padding:0;} + h1,h2,h3,h4,h5,h6 {font-weight:normal;} + li{list-style-type:none;} + ol,ul,dl{list-style:none;} + em{font-style:normal;} + img{border:none;vertical-align:middle;} + select,label,input{vertical-align:middle; padding:0; margin:0;outline:medium;font-size:12px;} + textarea{resize: none; line-height:18px;} + table { border-collapse: collapse; border-spacing: 0; empty-cell:show;} + a{text-decoration:none;color:#333;outline:none; cursor:pointer;} + a:hover{cursor:pointer;blr:expression(this.onFocus=this.blur());} + + box-sizing : content-box !important; + -webkit-box-sizing: content-box !important; + -moz-box-sizing: content-box !important; + + * { + padding: 0; margin: 0; + box-sizing : content-box !important; + -webkit-box-sizing: content-box !important; + -moz-box-sizing: content-box !important; + } + + .clearfix:before, .clearfix:after { + content: ""; + display: table; + } + .clearfix:after{ + clear: both; + } + .clearfix{ + *zoom: 1; + } + .fr{float: right;} + .fl{float: left;} + + width: $dialogWidth; + position: fixed; + padding: 2px 0px 0px 2px; + background-color: #FFF; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.2); + z-index: $dialogZindex; + font-family:"微软雅黑"; + font-size: 12px; + margin: 0px auto; + + //start of ued_title + .ued_title{ + height: 26px; + border-bottom: 1px solid #C6C6C6; + background: transparent url("images/dialog-title-bg.png") repeat-x scroll 0% 0%; + position: relative; + cursor: move; + + .icon{background: url("images/icons-all.gif") no-repeat center;} + + .uedbar { + span{ + font-weight: bold; + font-size: 14px; + color: #444; + line-height: 26px; + padding-left: 5px; + } + } + + .close_btn{ + height: 20px; + width: 20px; + cursor: pointer; + background-position :0px -59px; + position: absolute; + right: 5px; + top: 3px; + + &:hover{background-position: 0px -89px;} + } + } + //end of ued_title + + //button styles + .btn { + display: inline-block; + margin-bottom: 0px; + margin-right: 5px; + padding: 4px 10px; + font-weight: 400; + text-align: center; + cursor: pointer; + border: 1px solid transparent; + white-space: nowrap; + font-size: $fontsize; + border-radius: 3px; + -moz-user-select: none; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); + padding: 5px 14px; + } + .btn-default { + border: 1px solid #CFCFCF; + color: #565656; + background: #ffffff; + &:hover { + background: #f0f0f0; + } + } + .btn-primary { + background:#00b7ee; + color: #ffffff; + &:hover { + background: #00a2d4; + } + }//button style end + .btn.disabled { + cursor: not-allowed; + opacity: .65; + &:hover { + background: #00b7ee; + } + } + + //start of wrapper + .wrapper { + width: 630px; + height: 380px; + margin: 0px auto; + padding: 10px; + position: relative; + font-family: sans-serif; + + //start of wra_head + .wra_head { + span { + float: left; + padding: 0px 5px; + margin-right:3px; + height: 30px; + border: 1px solid #CCC; + background: transparent url("images/dialog-title-bg.png") repeat-x scroll 0% 0%; + text-align: center; + line-height: 30px; + cursor: pointer; + position: relative; + } + span.focus { + height: 31px; + border-bottom: medium none; + background: #FFF none repeat scroll 0% 0%; + position: relative; + z-index: 2; + } + }//end of wra_head + + //start of wra_body + .wra_body{ + + width: 100%; + height: 346px; + clear: both; + margin: 0px auto; + border: 1px solid #CCC; + display: block; + clip: auto; + overflow: hidden; + top: -1px; + position: relative; + + //upload panel start + .upload-panel { + .wra_pla { + zoom: 1; overflow: hidden; + text-align: center; + + .upload-image-placeholder { + margin: 10px; + border: 2px dashed #e6e6e6; + height: 172px; + padding-top: 150px; + text-align: center; + background: url("images/image.png") center 70px no-repeat; + position: relative; + top: 0; + + .webuploader-element-invisible { + //width: 145px; + //height: 40px; + //position: absolute; + //left: 225px; + opacity: 0; + width: 0; height: 0; + } + + .image-select { + padding: 10px 30px; + cursor: pointer; + } + } + } + + //image list box start + .image-list-box { + .wra_bar { + border-bottom: 1px solid #DADADA; + padding: 8px; + vertical-align: middle; + position: relative; + zoom: 1; overflow: hidden; + + .info{ + font-size: $fontsize; + color: #666; + margin-top: 6px; + } + + .fr { + .btn {padding: 6px 15px;} + } + + } + + //filelist start + .filelist{ + list-style: outside none none; + margin: 0px; + padding: 0px; + overflow-x: hidden; + overflow-y: auto; + position: relative; + height: 300px; + + li { + width: 113px; + height: 113px; + margin: 9px 0px 0px 9px; + position: relative; + display: block; + float: left; + overflow: hidden; + font-size: 12px; + + .imgWrap{ + position: relative; + vertical-align: middle; + text-align: center; + overflow: hidden; + width: 113px; + height: 113px; + transform-origin: 50% 50% 0px; + transition: all 200ms ease-out 0s; + + } + + //file opt box start + .file-opt-box{ + position: absolute; + display: none; + background: rgba(0, 0, 0, 0.5) none repeat scroll 0% 0%; + width: 100%; + top: 0px; + left: 0px; + overflow: hidden; + + span { + width: 24px; + height: 24px; + display: inline; + float: right; + text-indent: -9999px; + overflow: hidden; + background: url("images/icons.png") no-repeat; + margin: 5px 1px 1px; + cursor: pointer; + -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + .remove{ + background-position: -48px -24px; + &:hover{ + background-position: -48px -0px; + } + } + .rotateRight{ + display: none; + background-position: -24px -24px; + &:hover{ + background-position: -24px -0px; + } + } + .rotateLeft{ + display: none; + background-position: 0px -24px; + &:hover{ + background-position: 0px 0px; + } + } + }//file opt box end + + .success{ + background: url("images/success.png") no-repeat right; + position: absolute; + display: none; + left: 0px; + bottom: 0px; + height: 40px; + width: 100%; + } + + .error { + position: absolute; + width: 100%; + display: none; + background: rgba(255, 255, 255, 0.7) none repeat scroll 0% 0%; + left: 0; + padding:5px 3px; + color: #cc0000; + border: 1px solid #cccccc; + bottom: 0; + } + + .progress { + position: absolute; + width: 100%; + bottom: 0; + left: 0; + bottom: 0; + height: 8px; + overflow: hidden; + z-index: 50; + margin: 0; + border-radius: 0; + background: none; + -webkit-box-shadow: 0 0 0; + + span { + width: 0; + height: 100%; + background: #1483d8 url("images/progress.png") repeat-x; + -webit-transition: width 200ms linear; + -moz-transition: width 200ms linear; + -o-transition: width 200ms linear; + -ms-transition: width 200ms linear; + transition: width 200ms linear; + -webkit-animation: progressmove 2s linear infinite; + -moz-animation: progressmove 2s linear infinite; + -o-animation: progressmove 2s linear infinite; + -ms-animation: progressmove 2s linear infinite; + animation: progressmove 2s linear infinite; + -webkit-transform: translateZ(0); + } + } + }//end li + + }//filelist end + + }//image list box end + }//upload panel end + + //image online start + .online{ + width: 100%; + height: 336px; + padding: 10px 0px 0px; + display: none; + + .imagelist { + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + position: relative; + + .list { + li { + float: left; + display: block; + list-style: outside none none; + padding: 0px; + width: 113px; + height: 113px; + margin: 0px 0px 9px 9px; + background-color: #EEE; + overflow: hidden; + cursor: pointer; + position: relative; + + img{cursor: pointer;} + + span.ic { + position: absolute; + top: 0px; + left: 0px; + cursor: pointer; + width: 113px; + height: 113px; + + .img-size { + font-size:12px; + padding: 5px; + background:rgba(0,0,0,0.6); + display: none; + color: #ffffff; + } + + &:hover{ + width: 107px; + height: 107px; + border: 3px solid #1094FA; + background-position: 72px 72px; + .img-size { + display: inline-block; + width: 97px; + } + + } + } + span.selected { + background: url("images/success.png") no-repeat 75px 75px; + } + } + } + + } + + } //image online end + + //image search start + .searchbox { + width: 100%; + padding: 10px 0px 0px; + zoom: 1; overflow: hidden; + display: none; + + //搜索条 + .search-bar { + + .searTxt{ + margin-left: 5px; + background: #FFF none repeat scroll 0% 0%; + width: 300px; + height: 21px; + line-height: 21px; + padding: 3px 6px; + font-size: $fontsize; + line-height: 1.42857; + border: 1px solid #CCC; + border-radius: 4px; + box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.075) inset; + transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; + margin-right:10px; + } + + .searchBtn { + color: #FFF; + border-color: #285E8E; + background-color: #3B97D7; + } + .searchRese{ + color: #333; + border-color: #CCC; + background-color: #FFF; + } + } + + .search-imagelist-box { + width: 100%; + height: 292px; + overflow-x: hidden; + overflow-y: auto; + position: relative; + margin-top:10px; + + .search-list { + zoom:1; overflow: hidden; + li { + float: left; + display: block; + list-style: outside none none; + padding: 0px; + width: 113px; + height: 113px; + margin: 0px 0px 9px 9px; + background-color: #EEE; + overflow: hidden; + cursor: pointer; + position: relative; + + img { + cursor: pointer; + } + + span.ic { + position: absolute; + top: 0px; + left: 0px; + cursor: pointer; + width: 113px; + height: 113px; + + .img-size { + font-size:12px; + padding: 5px; + background:rgba(0,0,0,0.6); + display: none; + color: #ffffff; + } + + &:hover { + width: 107px; + height: 107px; + border: 3px solid #1094FA; + background-position: 72px 72px; + overflow: hidden; + .img-size { + display: inline-block; + width: 97px; + } + } + } + span.selected { + background: url("images/success.png") no-repeat 75px 75px; + } + } + } + } + + }//image search start end + + .no-data { + line-height: 40px; + height: 40px; + font-size:$fontsize; + color: #999999; + text-align: center; + display: none; + .error { + color: #cc0000; + } + } + + .loading-icon { + background:rgba(0,0,0,0.4) url("images/loader.gif") no-repeat center center; + position: absolute; + width: 100%; + height: 346px; + top:0; left: 0; + display: none; + text-align: center; + + .loading-message { + position: absolute; + font-size: 14px; + color: #f0f0f0; + top: 210px; + left:253px; + } + } + + //图片占位符 + .icon-placeholder { + background-size: 113px 113px; + display: block; + width: 113px; + height: 113px; + } + .icon-aep, .icon-aepx {background-image: url("icons/aep.png");} + .icon-asp {background-image: url("icons/asp.png");} + .icon-avi {background-image: url("icons/avi.png");} + .icon-c, .icon-cpp {background-image: url("icons/c.png");} + .icon-conf {background-image: url("icons/conf.png");} + .icon-css {background-image: url("icons/css.png");} + .icon-htm,.icon-html {background-image: url("icons/htm.png");} + .icon-default {background-image: url("icons/txt.png");} + .icon-doc,.icon-docx {background-image: url("icons/doc.png");} + .icon-eps {background-image: url("icons/eps.png");} + .icon-fla,.icon-swf {background-image: url("icons/fla.png");} + .icon-idn {background-image: url("icons/idn.png");} + .icon-ini {background-image: url("icons/ini.png");} + .icon-java, .icon-jar, .icon-war {background-image: url("icons/java.png");} + .icon-js {background-image: url("icons/js.png");} + .icon-jsf {background-image: url("icons/jsf.png");} + .icon-md, .icon-markdown {background-image: url("icons/markdown.png");} + .icon-mdb {background-image: url("icons/mdb.png");} + .icon-midi {background-image: url("icons/midi.png");} + .icon-mov {background-image: url("icons/mov.png");} + .icon-mp3 {background-image: url("icons/mp3.png");} + .icon-mpeg {background-image: url("icons/mpeg.png");} + .icon-pdf {background-image: url("icons/pdf.png");} + .icon-php {background-image: url("icons/php.png");} + .icon-ppt, .icon-pptx {background-image: url("icons/ppt.png");} + .icon-psd {background-image: url("icons/psd.png");} + .icon-pst {background-image: url("icons/pst.png");} + .icon-pub {background-image: url("icons/pub.png");} + .icon-py {background-image: url("icons/py.png");} + .icon-rb {background-image: url("icons/rb.png");} + .icon-rm, .icon-rmvb {background-image: url("icons/rmvb.png");} + .icon-scss {background-image: url("icons/scss.png");} + .icon-tif {background-image: url("icons/tif.png");} + .icon-txt {background-image: url("icons/txt.png");} + .icon-vsd {background-image: url("icons/vsd.png");} + .icon-wav {background-image: url("icons/wav.png");} + .icon-wma {background-image: url("icons/wma.png");} + .icon-wmv {background-image: url("icons/wmv.png");} + .icon-xls, .icon-xlsx {background-image: url("icons/xls.png");} + .icon-xml {background-image: url("icons/xml.png");} + .icon-zip, .icon-rar, .icon-tgz, .icon-gz, .icon-tar, .icon-7z {background-image: url("icons/zip.png");} + + }//end of wra_body + + .wra_body_server { + height: 380px; + + .online { + display: block !important; + height: 365px; + } + } + + }//start of wrapper + + .wra-btn-group { + clear: both; + zoom: 1; + text-align: right; + padding: 10px 20px 20px 0px; + + .tip-text { + float: left; + padding: 5px 10px; + color: #999; + font-size: 14px; + } + } +} \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/multiimage/multiimage.js b/addons/nkeditor/assets/plugins/multiimage/multiimage.js new file mode 100644 index 0000000000000000000000000000000000000000..fbc89b3f5c1d838ad3bdd68630dff4b8f6e2fb51 --- /dev/null +++ b/addons/nkeditor/assets/plugins/multiimage/multiimage.js @@ -0,0 +1,90 @@ +/** + * HTML5 批量文件上传 + * @author yangjian + * @since v4.1.12(2017-09-12) + * @site http://git.oschina.net/blackfox/kindeditor + */ + +KindEditor.plugin('multiimage', function(K) { + var self = this, name = 'multiimage', + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'), + imageSizeLimit = K.undef(self.imageSizeLimit, 2048), //单位KB + imageFileTypes = K.undef(self.imageFileTypes, 'jpg|png|gif|jpeg'), + imageUploadLimit = K.undef(self.imageUploadLimit, 20), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + + if(typeof jQuery == 'undefined') { + K.options.errorMsgHandler(lang.depJQueryError, "error"); + return; + } else { + K.loadScript(K.options.pluginsPath+name+"/BUpload.js"); + K.loadStyle(K.options.pluginsPath+name+"/css/upload.css"); + } + + //锁屏插件 + K.locker = function () { + var docWidth = Math.max(document.documentElement.clientWidth, document.body.clientWidth); + var docHeight = Math.max(document.documentElement.clientHeight, document.body.clientHeight, $(document).height()) + document.documentElement.scrollTop; + return K.widget({ + x : 0, + y : 0, + cls : 'ke-dialog-lock', + width : docWidth, + height : docHeight + }); + } + self.plugin.multiImageDialog = function(options) { + + if ( !window.applicationCache ) { + K.options.errorMsgHandler("您当前的浏览器不支持HTML5,请先升级浏览器才能使用该上传插件!", "error"); + return; + } + var clickFn = options.clickFn; + var locker = K.locker(); + locker.show(); + + var dialog = new BUpload({ + src : filePostName, + upload_url : uploadJson, + list_url : fileManagerJson, //图片列表数据获取url + max_filesize : imageSizeLimit, + max_filenum : imageUploadLimit, + ext_allow : imageFileTypes, + lang : lang, + top : self.dialogOffset, + fileType : "image", + errorHandler : K.options.errorMsgHandler, + callback : function(data) { + //console.log(data); + clickFn.call(this, data); + }, + close : function () { + locker.remove(); + } + }); + + return dialog; + }; + self.clickToolbar(name, function() { + self.plugin.multiImageDialog({ + clickFn : function (urlList) { + + if (urlList.length === 0) { + return; + } + K.each(urlList, function(i, data) { + if (self.afterUpload) { + self.afterUpload.call(self, data, data, 'multiimage'); + } + self.exec('insertimage', data); + }); + // Bugfix: [Firefox] 上传图片后,总是出现正在加载的样式,需要延迟执行hideDialog + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }); +}); diff --git a/addons/nkeditor/assets/plugins/multiimage/template/template.html b/addons/nkeditor/assets/plugins/multiimage/template/template.html new file mode 100644 index 0000000000000000000000000000000000000000..6625f0a8584d1feff2d0a05bac9c0310b9049918 --- /dev/null +++ b/addons/nkeditor/assets/plugins/multiimage/template/template.html @@ -0,0 +1,95 @@ +
            +
            +
            + 多图上传 +
            +
            +
            + +
            +
            + 本地上传 + 文件服务器 + 图片搜索 +
            + +
            +
            +
            +
            +
            点击选择图片
            + +
            +
            + + +
            + +
            +
            +
              +
            • + + "> +
            • +
            +
            (⊙o⊙)亲,没有多数据了。
            +
            +
            + + + +
            +
            + +
            + +
            + 确认 + 取消 +
            +
            \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/pagebreak/pagebreak.js b/addons/nkeditor/assets/plugins/pagebreak/pagebreak.js new file mode 100644 index 0000000000000000000000000000000000000000..dfa883afc2bbf3d6d5dc7d3979e01a39d5d51227 --- /dev/null +++ b/addons/nkeditor/assets/plugins/pagebreak/pagebreak.js @@ -0,0 +1,27 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('pagebreak', function(K) { + var self = this; + var name = 'pagebreak'; + var pagebreakHtml = K.undef(self.pagebreakHtml, '
            '); + + self.clickToolbar(name, function() { + var cmd = self.cmd, range = cmd.range; + self.focus(); + var tail = self.newlineTag == 'br' || K.WEBKIT ? '' : ''; + self.insertHtml(pagebreakHtml + tail); + if (tail !== '') { + var p = K('#__kindeditor_tail_tag__', self.edit.doc); + range.selectNodeContents(p[0]); + p.removeAttr('id'); + cmd.select(); + } + }); +}); diff --git a/addons/nkeditor/assets/plugins/plainpaste/plainpaste.js b/addons/nkeditor/assets/plugins/plainpaste/plainpaste.js new file mode 100644 index 0000000000000000000000000000000000000000..8f7bed803c93e3cb286604a3646cd6291ce8cbd3 --- /dev/null +++ b/addons/nkeditor/assets/plugins/plainpaste/plainpaste.js @@ -0,0 +1,41 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('plainpaste', function(K) { + var self = this, name = 'plainpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '
            ' + + '
            ' + lang.comment + '
            ' + + '' + + '
            ', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var html = textarea.val(); + html = K.escape(html); + html = html.replace(/ {2}/g, '  '); + if (self.newlineTag == 'p') { + html = html.replace(/^/, '

            ').replace(/$/, '

            ').replace(/\n/g, '

            '); + } else { + html = html.replace(/\n/g, '
            $&'); + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); diff --git a/addons/nkeditor/assets/plugins/preview/preview.js b/addons/nkeditor/assets/plugins/preview/preview.js new file mode 100644 index 0000000000000000000000000000000000000000..029c227346918e3a071fb74411bba5ecef15de01 --- /dev/null +++ b/addons/nkeditor/assets/plugins/preview/preview.js @@ -0,0 +1,134 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('preview', function(K) { + var self = this, name = 'preview', undefined; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + width = document.documentElement.clientWidth * 0.9, + height = document.documentElement.clientHeight - 160, + html = '

            ' + + '' + + '
            ', + dialog = self.createDialog({ + name : name, + width : width, + title : self.lang(name), + body : html + }), + iframe = K('iframe', dialog.div), + doc = K.iframeDoc(iframe); + doc.open(); + + var cssPath = self.options.cssPath; + var jsPath = self.options.jsPath; + var arr = [ + '', + '', + //'', + ''); + // 加载 css + if (!K.isArray(cssPath)) { + cssPath = [cssPath]; + } + if (K.inArray(self.options.pluginsPath+'code/prism.css', cssPath) < 0) { + cssPath.push(self.options.pluginsPath+'code/prism.css'); + } + K.each(cssPath, function(i, path) { + if (path) { + arr.push(''); + } + }); + if (self.options.cssData) { + arr.push(''); + } + arr.push(''); + // 获取编辑器内容 + arr.push(self.fullHtml()); + // 加载脚本 + if (!K.isArray(jsPath)) { + jsPath = [jsPath]; + } + // 加载代码高亮的脚本 + if (K.inArray(self.options.pluginsPath+'code/prism.js', jsPath) < 0) { + jsPath.push(self.options.pluginsPath+'code/prism.js'); + } + K.each(jsPath, function(i, path) { + if (path) { + arr.push(''); + } + }); + arr.push(''); + doc.write(arr.join('\n')); + doc.close(); + K(doc.body).css('background-color', '#FFF'); + iframe[0].contentWindow.focus(); + }); +}); diff --git a/addons/nkeditor/assets/plugins/quickformat/quickformat.js b/addons/nkeditor/assets/plugins/quickformat/quickformat.js new file mode 100644 index 0000000000000000000000000000000000000000..5b98c7227d3093656a98c7501d2c97783d845d27 --- /dev/null +++ b/addons/nkeditor/assets/plugins/quickformat/quickformat.js @@ -0,0 +1,81 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('quickformat', function(K) { + var self = this, name = 'quickformat', + blockMap = K.toMap('blockquote,center,div,h1,h2,h3,h4,h5,h6,p'); + function getFirstChild(knode) { + var child = knode.first(); + while (child && child.first()) { + child = child.first(); + } + return child; + } + self.clickToolbar(name, function() { + self.focus(); + var doc = self.edit.doc, + range = self.cmd.range, + child = K(doc.body).first(), next, + nodeList = [], subList = [], + bookmark = range.createBookmark(true); + while(child) { + next = child.next(); + var firstChild = getFirstChild(child); + if (!firstChild || firstChild.name != 'img') { + if (blockMap[child.name]) { + child.html(child.html().replace(/^(\s| | )+/ig, '')); + child.css('text-indent', '2em'); + } else { + subList.push(child); + } + if (!next || (blockMap[next.name] || blockMap[child.name] && !blockMap[next.name])) { + if (subList.length > 0) { + nodeList.push(subList); + } + subList = []; + } + } + child = next; + } + K.each(nodeList, function(i, subList) { + var wrapper = K('

            ', doc); + subList[0].before(wrapper); + K.each(subList, function(i, knode) { + wrapper.append(knode); + }); + }); + range.moveToBookmark(bookmark); + self.addBookmark(); + }); +}); + +/** +-------------------------- +abcd
            +1234
            + +to + +

            + abcd
            + 1234
            +

            + +-------------------------- + +  abcd1233 +

            1234

            + +to + +

            abcd1233

            +

            1234

            + +-------------------------- +*/ \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/quote/quote.js b/addons/nkeditor/assets/plugins/quote/quote.js new file mode 100644 index 0000000000000000000000000000000000000000..b4daca4d8d144bfb71c78b58ee4f93f9d086dd86 --- /dev/null +++ b/addons/nkeditor/assets/plugins/quote/quote.js @@ -0,0 +1,12 @@ +/** + * 引用插件 + * @author yangjian + */ +KindEditor.plugin('quote', function(K) { + var self = this; + var name = 'quote'; + self.clickToolbar(name, function() { + self.insertHtml('

            这里输入引用内容...


            '); + self.focus(); + }); +}); diff --git a/addons/nkeditor/assets/plugins/table/table.js b/addons/nkeditor/assets/plugins/table/table.js new file mode 100644 index 0000000000000000000000000000000000000000..1068edcd0f624680bacb39f0c96dfbf4043df587 --- /dev/null +++ b/addons/nkeditor/assets/plugins/table/table.js @@ -0,0 +1,746 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('table', function(K) { + var self = this, name = 'table', lang = self.lang(name + '.'), zeroborder = 'ke-zeroborder'; + var borderColor = K.undef(self.options.tableBorderColor, '#cccccc'); + // 设置颜色 + function _setColor(box, color) { + color = color.toUpperCase(); + box.css('background-color', color); + box.css('color', color === '#000000' ? '#FFFFFF' : '#000000'); + box.html(color); + } + // 初始化取色器 + var pickerList = []; + function _initColorPicker(dialogDiv, colorBox) { + colorBox.bind('click,mousedown', function(e){ + e.stopPropagation(); + }); + function removePicker() { + K.each(pickerList, function() { + this.remove(); + }); + pickerList = []; + K(document).unbind('click,mousedown', removePicker); + dialogDiv.unbind('click,mousedown', removePicker); + } + colorBox.click(function(e) { + removePicker(); + var box = K(this), + pos = box.pos(); + var picker = K.colorpicker({ + x : pos.x, + y : pos.y + box.height(), + z : 811214, + selectedColor : K(this).html(), + colors : self.colorTable, + noColor : self.lang('noColor'), + shadowMode : self.shadowMode, + click : function(color) { + _setColor(box, color); + removePicker(); + } + }); + pickerList.push(picker); + K(document).bind('click,mousedown', removePicker); + dialogDiv.bind('click,mousedown', removePicker); + }); + } + // 取得下一行cell的index + function _getCellIndex(table, row, cell) { + var rowSpanCount = 0; + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i] == cell) { + break; + } + rowSpanCount += row.cells[i].rowSpan - 1; + } + return cell.cellIndex - rowSpanCount; + } + self.plugin.table = { + //insert or modify table + prop : function(isInsert) { + var html = [ + '
            ', + //rows, cols + '
            ', + '', + '
            ', + lang.rows + '   ', + lang.cols + ' ', + '
            ', + '
            ', + //width, height + '
            ', + '', + '
            ', + lang.width + '   ', + '   ', + lang.height + '   ', + '', + '
            ', + '
            ', + //space, padding + '
            ', + '', + '
            ', + lang.padding + '   ', + lang.spacing + ' ', + '
            ', + '
            ', + //align + '
            ', + '', + '
            ', + '', + '
            ', + '
            ', + //border + '
            ', + '', + '
            ', + lang.borderWidth + '   ', + lang.borderColor + ' ', + '
            ', + '
            ', + //background color + '
            ', + '', + '
            ', + '', + '
            ', + '
            ', + '
            ' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var rows = rowsBox.val(), + cols = colsBox.val(), + width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + align = alignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (rows == 0 || !/^\d+$/.test(rows)) { + K.options.errorMsgHandler(self.lang('invalidRows'), "error"); + rowsBox[0].focus(); + return; + } + if (cols == 0 || !/^\d+$/.test(cols)) { + K.options.errorMsgHandler(self.lang('invalidRows'), "error"); + colsBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + K.options.errorMsgHandler(self.lang('invalidWidth'), "error"); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + K.options.errorMsgHandler(self.lang('invalidHeight'), "error"); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(padding)) { + K.options.errorMsgHandler(self.lang('invalidPadding'), "error"); + paddingBox[0].focus(); + return; + } + if (!/^\d*$/.test(spacing)) { + K.options.errorMsgHandler(self.lang('invalidSpacing'), "error"); + spacingBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + K.options.errorMsgHandler(self.lang('invalidBorder'), "error"); + borderBox[0].focus(); + return; + } + //modify table + if (table) { + if (width !== '') { + table.width(width + widthType); + } else { + table.css('width', ''); + } + if (table[0].width !== undefined) { + table.removeAttr('width'); + } + if (height !== '') { + table.height(height + heightType); + } else { + table.css('height', ''); + } + if (table[0].height !== undefined) { + table.removeAttr('height'); + } + table.css('background-color', bgColor); + if (table[0].bgColor !== undefined) { + table.removeAttr('bgColor'); + } + if (padding !== '') { + table[0].cellPadding = padding; + } else { + table.removeAttr('cellPadding'); + } + if (spacing !== '') { + table[0].cellSpacing = spacing; + } else { + table.removeAttr('cellSpacing'); + } + if (align !== '') { + table[0].align = align; + } else { + table.removeAttr('align'); + } + if (border !== '') { + table.attr('border', border); + } else { + table.removeAttr('border'); + } + if (border === '' || border === '0') { + table.addClass(zeroborder); + } else { + table.removeClass(zeroborder); + } + if (borderColor !== '') { + table.attr('borderColor', borderColor); + } else { + table.removeAttr('borderColor'); + } + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + return; + } + //insert new table + var style = ''; + if (width !== '') { + style += 'width:' + width + widthType + ';'; + } + if (height !== '') { + style += 'height:' + height + heightType + ';'; + } + if (bgColor !== '') { + style += 'background-color:' + bgColor + ';'; + } + var html = '') + ''; + } + html += ''; + } + html += '
            '; + if (!K.IE) { + html += '
            '; + } + // 取得range的block标签 + function getAncestorTag(range) { + var ancestor = K(range.commonAncestor()); + while (ancestor) { + if (ancestor.type == 1 && !ancestor.isStyle()) { + break; + } + ancestor = ancestor.parent(); + } + return ancestor; + } + // 如果是在 p 标签中插入表格,则自动删除当前 p 标签 + var tag = getAncestorTag(self.cmd.range); + if (tag.name == 'p') { + tag.before(K(html)); + tag.remove(); + self.cmd.selection(); + self.insertHtml('
            '); + self.select().hideDialog().focus(); + } else { + self.insertHtml(html); + self.select().hideDialog().focus(); + self.addBookmark(); + } + } + } + }), + div = dialog.div, + rowsBox = K('[name="rows"]', div).val(3), + colsBox = K('[name="cols"]', div).val(2), + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(0), + spacingBox = K('[name="spacing"]', div).val(0), + alignBox = K('[name="align"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + //_setColor(colorBox.eq(0), borderColor); + _setColor(colorBox.eq(1), ''); + // foucs and select + rowsBox[0].focus(); + rowsBox[0].select(); + var table; + if (isInsert) { + return; + } + //get selected table node + table = self.plugin.getSelectedTable(); + if (table) { + rowsBox.val(table[0].rows.length); + colsBox.val(table[0].rows.length > 0 ? table[0].rows[0].cells.length : 0); + rowsBox.attr('disabled', true); + colsBox.attr('disabled', true); + var match, + tableWidth = table[0].style.width || table[0].width, + tableHeight = table[0].style.height || table[0].height; + if (tableWidth !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if (tableHeight !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + paddingBox.val(table[0].cellPadding || ''); + spacingBox.val(table[0].cellSpacing || ''); + alignBox.val(table[0].align || ''); + borderBox.val(table[0].border === undefined ? '' : table[0].border); + _setColor(colorBox.eq(0), K.toHex(table.attr('borderColor') || '')); + _setColor(colorBox.eq(1), K.toHex(table[0].style.backgroundColor || table[0].bgColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + } + }, + //modify cell + cellprop : function() { + var html = [ + '
            ', + //width, height + '
            ', + '', + lang.width + '   ', + '   ', + lang.height + '   ', + '', + '
            ', + //align + '
            ', + '', + lang.textAlign + ' ', + lang.verticalAlign + ' ', + '
            ', + //border + '
            ', + '', + lang.borderWidth + '   ', + lang.borderColor + ' ', + '
            ', + //background color + '
            ', + '', + '', + '
            ', + '
            ' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang('tablecell'), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + textAlign = textAlignBox.val(), + verticalAlign = verticalAlignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (!/^\d*$/.test(width)) { + K.options.errorMsgHandler(self.lang('invalidWidth'), "error"); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + K.options.errorMsgHandler(self.lang('invalidHeight'), "error"); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + K.options.errorMsgHandler(self.lang('invalidBorder'), "error"); + borderBox[0].focus(); + return; + } + cell.css({ + width : width !== '' ? (width + widthType) : '', + height : height !== '' ? (height + heightType) : '', + 'background-color' : bgColor, + 'text-align' : textAlign, + 'vertical-align' : verticalAlign, + 'border-width' : border, + 'border-style' : border !== '' ? 'solid' : '', + 'border-color' : borderColor + }); + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + } + } + }), + div = dialog.div, + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(0), + spacingBox = K('[name="spacing"]', div).val(0), + textAlignBox = K('[name="textAlign"]', div), + verticalAlignBox = K('[name="verticalAlign"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + //_setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + // foucs and select + widthBox[0].focus(); + widthBox[0].select(); + // get selected cell + var cell = self.plugin.getSelectedCell(); + var match, + cellWidth = cell[0].style.width || cell[0].width || '', + cellHeight = cell[0].style.height || cell[0].height || ''; + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + textAlignBox.val(cell[0].style.textAlign || ''); + verticalAlignBox.val(cell[0].style.verticalAlign || ''); + var border = cell[0].style.borderWidth || ''; + if (border) { + border = parseInt(border); + } + borderBox.val(border); + _setColor(colorBox.eq(0), K.toHex(cell[0].style.borderColor || '')); + _setColor(colorBox.eq(1), K.toHex(cell[0].style.backgroundColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + }, + insert : function() { + this.prop(true); + }, + 'delete' : function() { + var table = self.plugin.getSelectedTable(); + self.cmd.range.setStartBefore(table[0]).collapse(true); + self.cmd.select(); + table.remove(); + self.addBookmark(); + }, + colinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex + offset; + // 取得第一行的index + index += table.rows[0].cells.length - row.cells.length; + + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.insertCell(index); + newCell.innerHTML = K.IE ? '' : '
            '; + // 调整下一行的单元格index + index = _getCellIndex(table, newRow, newCell); + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colinsertleft : function() { + this.colinsert(0); + }, + colinsertright : function() { + this.colinsert(1); + }, + rowinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0]; + var rowIndex = row.rowIndex; + if (offset === 1) { + rowIndex = row.rowIndex + (cell.rowSpan - 1) + offset; + } + var newRow = table.insertRow(rowIndex); + + for (var i = 0, len = row.cells.length; i < len; i++) { + // 调整cell个数 + if (row.cells[i].rowSpan > 1) { + len -= row.cells[i].rowSpan - 1; + } + var newCell = newRow.insertCell(i); + // copy colspan + if (offset === 1 && row.cells[i].colSpan > 1) { + newCell.colSpan = row.cells[i].colSpan; + } + newCell.innerHTML = K.IE ? '' : '
            '; + } + // 调整rowspan + for (var j = rowIndex; j >= 0; j--) { + var cells = table.rows[j].cells; + if (cells.length > i) { + for (var k = cell.cellIndex; k >= 0; k--) { + if (cells[k].rowSpan > 1) { + cells[k].rowSpan += 1; + } + } + break; + } + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowinsertabove : function() { + this.rowinsert(0); + }, + rowinsertbelow : function() { + this.rowinsert(1); + }, + rowmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, // 当前行的index + nextRowIndex = rowIndex + cell.rowSpan, // 下一行的index + nextRow = table.rows[nextRowIndex]; // 下一行 + // 最后一行不能合并 + if (table.rows.length <= nextRowIndex) { + return; + } + var cellIndex = cell.cellIndex; // 下一行单元格的index + if (nextRow.cells.length <= cellIndex) { + return; + } + var nextCell = nextRow.cells[cellIndex]; // 下一行单元格 + // 上下行的colspan不一致时不能合并 + if (cell.colSpan !== nextCell.colSpan) { + return; + } + cell.rowSpan += nextCell.rowSpan; + nextRow.deleteCell(cellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, // 当前行的index + cellIndex = cell.cellIndex, + nextCellIndex = cellIndex + 1; + // 最后一列不能合并 + if (row.cells.length <= nextCellIndex) { + return; + } + var nextCell = row.cells[nextCellIndex]; + // 左右列的rowspan不一致时不能合并 + if (cell.rowSpan !== nextCell.rowSpan) { + return; + } + cell.colSpan += nextCell.colSpan; + row.deleteCell(nextCellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + // 不是可分割单元格 + if (cell.rowSpan === 1) { + return; + } + var cellIndex = _getCellIndex(table, row, cell); + for (var i = 1, len = cell.rowSpan; i < len; i++) { + var newRow = table.rows[rowIndex + i], + newCell = newRow.insertCell(cellIndex); + if (cell.colSpan > 1) { + newCell.colSpan = cell.colSpan; + } + newCell.innerHTML = K.IE ? '' : '
            '; + // 调整下一行的单元格index + cellIndex = _getCellIndex(table, newRow, newCell); + } + K(cell).removeAttr('rowSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + cellIndex = cell.cellIndex; + // 不是可分割单元格 + if (cell.colSpan === 1) { + return; + } + for (var i = 1, len = cell.colSpan; i < len; i++) { + var newCell = row.insertCell(cellIndex + i); + if (cell.rowSpan > 1) { + newCell.rowSpan = cell.rowSpan; + } + newCell.innerHTML = K.IE ? '' : '
            '; + } + K(cell).removeAttr('colSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + coldelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.cells[index]; + if (newCell.colSpan > 1) { + newCell.colSpan -= 1; + if (newCell.colSpan === 1) { + K(newCell).removeAttr('colSpan'); + } + } else { + newRow.deleteCell(index); + } + // 跳过不需要删除的行 + if (newCell.rowSpan > 1) { + i += newCell.rowSpan - 1; + } + } + if (row.cells.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + }, + rowdelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + // 从下到上删除 + for (var i = cell.rowSpan - 1; i >= 0; i--) { + table.deleteRow(rowIndex + i); + } + if (table.rows.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.table.prop); +}); diff --git a/addons/nkeditor/assets/plugins/template/html/1.html b/addons/nkeditor/assets/plugins/template/html/1.html new file mode 100644 index 0000000000000000000000000000000000000000..034126b72b4050d4159695c176e9dec8be8ff580 --- /dev/null +++ b/addons/nkeditor/assets/plugins/template/html/1.html @@ -0,0 +1,14 @@ + + + + + + +

            + 在此处输入标题 +

            +

            + 在此处输入内容 +

            + + \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/template/html/2.html b/addons/nkeditor/assets/plugins/template/html/2.html new file mode 100644 index 0000000000000000000000000000000000000000..dc2584a0d300a70b35c81e96dbcaf97936daa9a1 --- /dev/null +++ b/addons/nkeditor/assets/plugins/template/html/2.html @@ -0,0 +1,42 @@ + + + + + + +

            + 标题 +

            + + + + + + + + + + + + + + + +
            +

            标题1

            +
            +

            标题1

            +
            + 内容1 + + 内容2 +
            + 内容3 + + 内容4 +
            +

            + 表格说明 +

            + + \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/template/html/3.html b/addons/nkeditor/assets/plugins/template/html/3.html new file mode 100644 index 0000000000000000000000000000000000000000..873f0c65d948664fdc858c210578e1e7c9c6ba59 --- /dev/null +++ b/addons/nkeditor/assets/plugins/template/html/3.html @@ -0,0 +1,36 @@ + + + + + + +

            + 在此处输入内容 +

            +
              +
            1. + 描述1 +
            2. +
            3. + 描述2 +
            4. +
            5. + 描述3 +
            6. +
            +

            + 在此处输入内容 +

            +
              +
            • + 描述1 +
            • +
            • + 描述2 +
            • +
            • + 描述3 +
            • +
            + + \ No newline at end of file diff --git a/addons/nkeditor/assets/plugins/template/template.js b/addons/nkeditor/assets/plugins/template/template.js new file mode 100644 index 0000000000000000000000000000000000000000..30d0dc344c2ec9b742dc569878e8ab3c5fa536e8 --- /dev/null +++ b/addons/nkeditor/assets/plugins/template/template.js @@ -0,0 +1,58 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('template', function(K) { + var self = this, name = 'template', lang = self.lang(name + '.'), + htmlPath = self.pluginsPath + name + '/html/'; + function getFilePath(fileName) { + return htmlPath + fileName + '?ver=' + encodeURIComponent(K.DEBUG ? K.TIME : K.VERSION); + } + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + arr = ['
            ', + '
            ', + '
            ', + // left start + lang. selectTemplate + ' ', + // right start + ' ', + '
            ', + '
            ', + + //template iframe + '', + '
            '].join(''); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var doc = K.iframeDoc(iframe); + self[checkbox[0].checked ? 'html' : 'insertHtml'](doc.body.innerHTML).hideDialog().focus(); + } + } + }); + var selectBox = K('select', dialog.div), + checkbox = K('[name="replaceFlag"]', dialog.div), + iframe = K('iframe', dialog.div); + checkbox[0].checked = true; + iframe.attr('src', getFilePath(selectBox.val())); + selectBox.change(function() { + iframe.attr('src', getFilePath(this.value)); + }); + }); +}); diff --git a/addons/nkeditor/assets/plugins/wordpaste/wordpaste.js b/addons/nkeditor/assets/plugins/wordpaste/wordpaste.js new file mode 100644 index 0000000000000000000000000000000000000000..22061e15e829833818bd5b88399ef98c71f143d6 --- /dev/null +++ b/addons/nkeditor/assets/plugins/wordpaste/wordpaste.js @@ -0,0 +1,51 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('wordpaste', function(K) { + var self = this, name = 'wordpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '
            ' + + '
            ' + lang.comment + '
            ' + + '' + + '
            ', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var str = doc.body.innerHTML; + str = K.clearMsWord(str, self.filterMode ? self.htmlTags : K.options.htmlTags); + self.insertHtml(str).hideDialog().focus(); + } + } + }), + div = dialog.div, + iframe = K('iframe', div), + doc = K.iframeDoc(iframe); + if (!K.IE) { + doc.designMode = 'on'; + } + doc.open(); + doc.write('WordPaste'); + doc.write(''); + if (!K.IE) { + doc.write('
            '); + } + doc.write(''); + doc.close(); + if (K.IE) { + doc.body.contentEditable = 'true'; + } + iframe[0].contentWindow.focus(); + }); +}); diff --git a/addons/nkeditor/assets/themes/app.css b/addons/nkeditor/assets/themes/app.css new file mode 100644 index 0000000000000000000000000000000000000000..baba45f72cd7fe7010cbc7b554fb7b395c4613f2 --- /dev/null +++ b/addons/nkeditor/assets/themes/app.css @@ -0,0 +1,96 @@ +/* 引用样式 */ +blockquote { + padding: 20px; + margin: 20px 0; + border: 1px solid #eee; + border-left-width: 5px; + border-left-color: #ce4844; + border-radius: 3px; +} + +blockquote, q { + quotes: none; +} + +/* 表格样式 */ +table { + border-spacing: 0; + border-collapse: collapse; +} + +td, +th { + padding: 0; +} + +.table { + border-collapse: collapse !important; +} + +.table td, +.table th { + background-color: #fff !important; + border: 1px solid #ddd; +} + +.table-bordered th, +.table-bordered td { + border: 1px solid #ddd !important; +} + +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} + +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} + +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} + +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} + +.table > tbody + tbody { + border-top: 2px solid #ddd; +} + +.table .table { + background-color: #fff; +} + +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} + +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} + +.ke-content img { + max-width: 100%; +} diff --git a/addons/nkeditor/assets/themes/black/editor.css b/addons/nkeditor/assets/themes/black/editor.css new file mode 100644 index 0000000000000000000000000000000000000000..a84525cf184b1c0bf1c1f6890988786e6ee79e25 --- /dev/null +++ b/addons/nkeditor/assets/themes/black/editor.css @@ -0,0 +1,822 @@ +@charset "UTF-8"; +/** +公共样式 +*/ +.ke-clearfix { + zoom: 1; + clear: both; } + +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; } + +.ke-animated { + animation: zoomIn; + animation-duration: 0.3s; + animation-fill-mode: both; } + +@keyframes zoomIn { + from { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); } + 50% { + opacity: 1; } } +.ke-dialog-mask { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; } + +.ke-dialog-lock { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; + z-index: 811213; + left: 0; + top: 0; + position: absolute; } + +/** +编辑器样式开始 + */ +.ke-container { + display: block; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + /** + 通用样式 + */ + /** + toolbar 样式 + */ + /** + ke-edit + */ + /** + statusbar start + */ } + .ke-container .ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + background-color: #F0F0EE; } + .ke-container .ke-menu a, + .ke-container .ke-menu a:hover, + .ke-container .ke-dialog a, + .ke-container .ke-dialog a:hover { + color: #337FE5; + text-decoration: none; } + .ke-container .ke-toolbar { + text-align: left; + overflow: hidden; + zoom: 1; + padding: 0px 5px; } + .ke-container .ke-toolbar .ke-outline { + padding: 10px 5px; + font-size: 0; + line-height: 0; + cursor: pointer; + display: block; + float: left; + /** + * 按钮通用样式 + */ } + .ke-container .ke-toolbar .ke-outline .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; } + .ke-container .ke-toolbar .ke-on { + background: #ebebeb; } + .ke-container .ke-toolbar .ke-selected { + background-color: #ebebeb; } + .ke-container .ke-toolbar .ke-disabled { + cursor: default; } + .ke-container .ke-toolbar .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; } + .ke-container .ke-toolbar .ke-hr { + clear: both; + height: 1px; + width: calc(100% - (2 * 2px)); + background: #ebebeb; } + .ke-container .ke-edit { + padding: 0; } + .ke-container .ke-edit .ke-edit-iframe, + .ke-container .ke-edit .ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; } + .ke-container .ke-edit .ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; } + .ke-container .ke-edit .ke-edit-textarea:focus { + outline: none; } + .ke-container .ke-statusbar { + position: relative; + background-color: #f5f5f5; + border-top: 1px solid #e1e1e1; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; + display: none; } + .ke-container .ke-statusbar .ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; } + .ke-container .ke-statusbar .ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + width: 11px; + height: 11px; } + +/** + menu 右键菜单 + */ +.ke-menu { + border: 1px solid #cccccc; + background-color: #f5f5f5; + color: #222222; + padding: 2px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; + /** + 表情插件 + */ } + .ke-menu .ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; } + .ke-menu .ke-menu-item .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-inline-block .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; } + .ke-menu .ke-menu-item .ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; } + .ke-menu .ke-menu-item .ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: 1px solid #e1e1e1; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; } + .ke-menu .ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons { + position: relative; } + .ke-menu .ke-plugin-emoticons .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; } + .ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img { + border: 0; + margin: 0; + padding: 0; } + .ke-menu .ke-plugin-emoticons .ke-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell { + margin: 0; + padding: 1px; + border: 1px solid #f5f5f5; + cursor: pointer; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img { + display: block; + background-repeat: no-repeat; + overflow: hidden; + margin: 2px; + width: 24px; + height: 24px; + margin: 0; + padding: 0; + border: 0; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + color: #333; + text-decoration: none; } + +/** + colorpicker + */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; } + .ke-colorpicker .ke-colorpicker-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin: 3px; + padding: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top { + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F1F1F1; + cursor: pointer; + margin: 0; + padding: 0; + text-align: center; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on { + border: 1px solid #5690D2; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected { + border: 1px solid #2446AB; } + +/** + dialog + */ +.ke-dialog { + margin: 0; + padding: 0; + border: 1px solid #cccccc; + zoom: 1; + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + overflow: hidden; } + .ke-dialog .ke-dialog-header { + border: 0; + margin: 0; + font-weight: bold; + font-size: 14px; + height: 30px; + line-height: 30px; + padding: 0px 10px; + text-align: left; + color: #222; + cursor: move; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-bottom: 1px solid #c6c6c6; + background: transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0; + position: relative; + cursor: move; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close { + height: 20px; + width: 20px; + cursor: pointer; + background: url("../common/icons-all.gif") 0 -59px; + position: absolute; + right: 5px; + top: 4px; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover { + background-position: 0px -89px; } + .ke-dialog .ke-dialog-content { + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + outline: 0; + zoom: 1; } + .ke-dialog .ke-dialog-content .ke-dialog-body { + font: 12px/1.5 "sans serif", tahoma, verdana, helvetica; + text-align: left; + overflow: hidden; + width: 100%; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + border: 1px solid #cccccc; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus { + border-color: #66afe9; + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; + border: 1px solid #cccccc; + height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-form { + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number { + width: 50px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox { + position: relative; + top: 6px; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus { + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text { + display: inline-block !important; + max-width: 400px; + height: 30px; + line-height: 30px; + border: 1px solid #cccccc; + font-size: 14px; + margin: 0; + outline: 0; + padding: 0px 10px; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus { + border-color: #66afe9; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color { + border: 1px solid #e1e1e1; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 30px; + line-height: 30px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + top: -1px; + position: relative; + *height: 25px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + cursor: pointer; + width: 62px; + height: 30px; + filter: alpha(opacity=0); } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common { + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button { + padding: 8px 15px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner { + padding: 10px 20px 0px 20px; + /** + tabs + */ } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row { + border: 1px solid #FFFFFF; + margin-bottom: 10px; + overflow: hidden; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left { + float: left; + height: 30px; + line-height: 30px; + width: 60px; + text-align: right; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right { + float: left; + text-align: left; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button { + position: relative; + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label { + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + text-align: right; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header { + height: 30px; + line-height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text { + height: 22px; + line-height: 22px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button { + padding: 3px 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox { + margin-left: 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + border-bottom: 1px solid #e1e1e1; + margin-bottom: 20px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul { + list-style: none outside none; + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li { + position: relative; + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #337ab7; + cursor: pointer; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected { + background-color: #FFF; + border: 1px solid #e1e1e1; + border-bottom: 1px solid #FFF; + color: #555555; + cursor: default; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on { + background-color: #FFF; + color: #000; } + .ke-dialog .ke-dialog-content .ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; } + .ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat center; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; } + .ke-dialog .ke-dialog-footer { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + text-align: right; + padding: 0 15px 5px 0; + background-color: #FFF; + height: 40px; } + .ke-dialog .ke-dialog-footer .ke-dialog-yes { + margin: 5px; } + .ke-dialog .ke-dialog-footer .ke-dialog-no { + margin: 5px 10px 5px 5px; } + .ke-dialog .ke-button-common { + display: inline-block; + text-align: center; + background: none; + border: none; + padding: 0; + cursor: pointer; } + .ke-dialog .ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-button { + color: #333; + font-size: 12px; + border: 1px solid #e6e6e6; + background-color: #e6e6e6; + padding: 7px 10px; + margin-top: -4px; + color: #444; + text-decoration: none; + transition: background-color .3s ease-out, border-color .3s ease-out; } + .ke-dialog .ke-button:hover { + border: 1px solid #e1e1e1; + background-color: #e1e1e1; } + .ke-dialog .ke-dialog-btn { + font-size: 12px; + margin: 5px; + background: #2e8ded; + color: #fff !important; + padding: 8px 12px; + display: inline-block; + border-radius: 2px; + cursor: pointer; + text-decoration: none; + transition: .3s ease-out; } + .ke-dialog .ke-dialog-btn:hover { + filter: alpha(opacity=80); + box-shadow: none; + box-shadow: none; + opacity: .8; } + +.ke-container-black .ke-toolbar { + border-top: 5px solid #222222; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + background-clip: padding-box; + text-rendering: optimizelegibility; } + .ke-container-black .ke-toolbar .ke-toolbar-icon { + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; } + .ke-container-black .ke-toolbar .ke-icon-source { + background-position: 0 0px; } + .ke-container-black .ke-toolbar .ke-icon-preview { + background-position: 0 -63px; } + .ke-container-black .ke-toolbar .ke-icon-print { + background-position: 0 -84px; } + .ke-container-black .ke-toolbar .ke-icon-undo { + background-position: 0 -21px; } + .ke-container-black .ke-toolbar .ke-icon-redo { + background-position: 0 -42px; } + .ke-container-black .ke-toolbar .ke-icon-template { + background-position: 0 -105px; } + .ke-container-black .ke-toolbar .ke-icon-cut { + background-position: 0 -147px; } + .ke-container-black .ke-toolbar .ke-icon-copy { + background-position: 0 -168px; } + .ke-container-black .ke-toolbar .ke-icon-paste { + background-position: 0 -189px; } + .ke-container-black .ke-toolbar .ke-icon-selectall { + background-position: 0 -483px; } + .ke-container-black .ke-toolbar .ke-icon-justifyleft { + background-position: 0 -252px; } + .ke-container-black .ke-toolbar .ke-icon-justifycenter { + background-position: 0 -273px; } + .ke-container-black .ke-toolbar .ke-icon-justifyright { + background-position: 0 -294px; } + .ke-container-black .ke-toolbar .ke-icon-justifyfull { + background-position: 0 -315px; } + .ke-container-black .ke-toolbar .ke-icon-insertorderedlist { + background-position: 0 -336px; } + .ke-container-black .ke-toolbar .ke-icon-insertunorderedlist { + background-position: 0 -357px; } + .ke-container-black .ke-toolbar .ke-icon-indent { + background-position: 0 -378px; } + .ke-container-black .ke-toolbar .ke-icon-outdent { + background-position: 0 -399px; } + .ke-container-black .ke-toolbar .ke-icon-subscript { + background-position: 0 -420px; } + .ke-container-black .ke-toolbar .ke-icon-superscript { + background-position: 0 -441px; } + .ke-container-black .ke-toolbar .ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-formatblock { + background-position: 0 -546px; } + .ke-container-black .ke-toolbar .ke-icon-fontname { + background-position: 0 -567px; } + .ke-container-black .ke-toolbar .ke-icon-fontsize { + background-position: 0 -588px; } + .ke-container-black .ke-toolbar .ke-icon-forecolor { + background-position: 0 -609px; } + .ke-container-black .ke-toolbar .ke-icon-hilitecolor { + background-position: 0 -630px; } + .ke-container-black .ke-toolbar .ke-icon-bold { + background-position: 0 -651px; } + .ke-container-black .ke-toolbar .ke-icon-italic { + background-position: 0 -672px; } + .ke-container-black .ke-toolbar .ke-icon-underline { + background-position: 0 -693px; } + .ke-container-black .ke-toolbar .ke-icon-strikethrough { + background-position: 0 -714px; } + .ke-container-black .ke-toolbar .ke-icon-removeformat { + background-position: 0 -756px; } + .ke-container-black .ke-toolbar .ke-icon-image { + background-position: 0 -777px; } + .ke-container-black .ke-toolbar .ke-icon-flash { + background-position: 0 -840px; } + .ke-container-black .ke-toolbar .ke-icon-media { + background-position: 0 -861px; } + .ke-container-black .ke-toolbar .ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-hr { + background-position: 0 -924px; } + .ke-container-black .ke-toolbar .ke-icon-emoticons { + background-position: 0 -945px; } + .ke-container-black .ke-toolbar .ke-icon-link { + background-position: 0 -1008px; } + .ke-container-black .ke-toolbar .ke-icon-unlink { + background-position: 0 -1029px; } + .ke-container-black .ke-toolbar .ke-icon-fullscreen { + background-position: 0 -525px; } + .ke-container-black .ke-toolbar .ke-icon-about { + background-position: 0 -1092px; } + .ke-container-black .ke-toolbar .ke-icon-quote { + background-position: 0 -1114px; } + .ke-container-black .ke-toolbar .ke-icon-plainpaste { + background-position: 0 -210px; } + .ke-container-black .ke-toolbar .ke-icon-wordpaste { + background-position: 0 -231px; } + .ke-container-black .ke-toolbar .ke-icon-table { + background-position: 0px -903px; + width: 18px !important; } + .ke-container-black .ke-toolbar .ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-code { + background-position: 0 -126px; } + .ke-container-black .ke-toolbar .ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-baidumap { + background-position: 0 -1050px; } + .ke-container-black .ke-toolbar .ke-icon-lineheight { + background-position: 0 -735px; } + .ke-container-black .ke-toolbar .ke-icon-clearhtml { + background-position: 0 -462px; } + .ke-container-black .ke-toolbar .ke-icon-pagebreak { + background-position: 0 -966px; } + .ke-container-black .ke-toolbar .ke-icon-insertfile { + background-position: 0 -882px; } + .ke-container-black .ke-toolbar .ke-icon-quickformat { + background-position: 0 -504px; } + .ke-container-black .ke-toolbar .ke-icon-anchor { + background-position: 0 -987px; } + .ke-container-black .ke-toolbar .ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; } + .ke-container-black .ke-toolbar .ke-icon-multiimage { + background-position: 0 -798px; } + .ke-container-black .ke-toolbar .ke-icon-graft { + background-position: 0 -819px; } + +/** + menu 右键菜单 + */ +.ke-menu-black .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tableinsert { + background-position: 0 -903px; + width: 18px !important; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tabledelete { + background-position: 0 -1428px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertleft { + background-position: 0 -1176px; + width: 18px !important; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertright { + background-position: 0 -1323px; + width: 18px !important; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertabove { + background-position: 0 -1302px; + width: 22px !important; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertbelow { + background-position: 0 -1155px; + width: 22px !important; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecoldelete { + background-position: 0 -1239px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowdelete { + background-position: 0 -1260px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecellprop { + background-position: 0 -1218px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tableprop { + background-position: 0 -1134px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowmerge { + background-position: -1px -1197px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowsplit { + background-position: 0 -1344px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecolmerge { + background-position: -4px -1365px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecolsplit { + background-position: 0 -1344px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-image { + background-position: 0 -777px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-flash { + background-position: 0 -840px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-media { + background-position: 0 -861px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-link { + background-position: 0 -1008px; } + .ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-checked { + background-position: 0 -1407px; } + +/*# sourceMappingURL=editor.css.map */ diff --git a/addons/nkeditor/assets/themes/black/editor.min.css b/addons/nkeditor/assets/themes/black/editor.min.css new file mode 100644 index 0000000000000000000000000000000000000000..f5d26e024146cebaeaee3cae9e80876f9fd8b2cc --- /dev/null +++ b/addons/nkeditor/assets/themes/black/editor.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.ke-clearfix{zoom:1;clear:both}.ke-clearfix:after{content:".";display:block;clear:both;font-size:0;height:0;line-height:0;visibility:hidden}.ke-animated{animation:zoomIn;animation-duration:.3s;animation-fill-mode:both}@keyframes zoomIn{from{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.ke-dialog-mask{background-color:#fff;opacity:.5}.ke-dialog-lock{background-color:#fff;opacity:.5;z-index:811213;left:0;top:0;position:absolute}.ke-container{display:block;background-color:#fff;overflow:hidden;margin:0;padding:0;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 1px 1px rgba(0,0,0,.16)}.ke-container .ke-shadow{box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;background-color:#f0f0ee}.ke-container .ke-dialog a,.ke-container .ke-dialog a:hover,.ke-container .ke-menu a,.ke-container .ke-menu a:hover{color:#337fe5;text-decoration:none}.ke-container .ke-toolbar{text-align:left;overflow:hidden;zoom:1;padding:0 5px}.ke-container .ke-toolbar .ke-outline{padding:10px 5px;font-size:0;line-height:0;cursor:pointer;display:block;float:left}.ke-container .ke-toolbar .ke-outline .ke-toolbar-icon{font-size:0;line-height:0;overflow:hidden;display:block;width:16px;height:16px;margin:0 2px}.ke-container .ke-toolbar .ke-on{background:#ebebeb}.ke-container .ke-toolbar .ke-selected{background-color:#ebebeb}.ke-container .ke-toolbar .ke-disabled{cursor:default}.ke-container .ke-toolbar .ke-separator{height:16px;margin:2px 3px;border-left:1px solid #a0a0a0;border-right:1px solid #fff;border-top:0;border-bottom:0;width:0;font-size:0;line-height:0;overflow:hidden;display:block;float:left}.ke-container .ke-toolbar .ke-hr{clear:both;height:1px;width:calc(100% - (2 * 2px));background:#ebebeb}.ke-container .ke-edit{padding:0}.ke-container .ke-edit .ke-edit-iframe,.ke-container .ke-edit .ke-edit-textarea{border:0;margin:0;padding:0;overflow:auto}.ke-container .ke-edit .ke-edit-textarea{font:12px/1.5 Consolas,Monaco,"Bitstream Vera Sans Mono","Courier New",Courier,monospace;color:#000;overflow:auto;resize:none}.ke-container .ke-edit .ke-edit-textarea:focus{outline:0}.ke-container .ke-statusbar{position:relative;background-color:#f5f5f5;border-top:1px solid #e1e1e1;font-size:0;line-height:0;overflow:hidden;text-align:center;cursor:s-resize;display:none}.ke-container .ke-statusbar .ke-statusbar-center-icon{background-position:0 -754px;width:15px;height:11px}.ke-container .ke-statusbar .ke-statusbar-right-icon{position:absolute;right:0;bottom:0;cursor:se-resize;width:11px;height:11px}.ke-menu{border:1px solid #ccc;background-color:#f5f5f5;color:#222;padding:2px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;text-align:left;overflow:hidden}.ke-menu .ke-menu-item{border:1px solid #f1f1f1;background-color:#f1f1f1;color:#222;height:24px;overflow:hidden;cursor:pointer}.ke-menu .ke-menu-item .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-menu .ke-menu-item .ke-inline-block .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-menu .ke-menu-item .ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu .ke-menu-item .ke-menu-item-center{width:0;height:24px;border-left:1px solid #e3e3e3;border-right:1px solid #fff;border-top:0;border-bottom:0}.ke-menu .ke-menu-item .ke-menu-item-center-on{border-left:1px solid #e9eff6;border-right:1px solid #e9eff6}.ke-menu .ke-menu-item .ke-menu-item-right{border:0;padding:0 0 0 5px;line-height:24px;text-align:left;overflow:hidden}.ke-menu .ke-menu-item .ke-menu-separator{margin:2px 0;height:0;overflow:hidden;border-top:1px solid #e1e1e1;border-bottom:1px solid #fff;border-left:0;border-right:0}.ke-menu .ke-menu-item-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu .ke-plugin-emoticons{position:relative}.ke-menu .ke-plugin-emoticons .ke-preview{position:absolute;text-align:center;margin:2px;padding:10px;top:0;border:1px solid #a0a0a0;background-color:#fff;display:none}.ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img{border:0;margin:0;padding:0}.ke-menu .ke-plugin-emoticons .ke-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-menu .ke-plugin-emoticons .ke-table .ke-cell{margin:0;padding:1px;border:1px solid #f5f5f5;cursor:pointer}.ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img{display:block;background-repeat:no-repeat;overflow:hidden;margin:2px;width:24px;height:24px;margin:0;padding:0;border:0}.ke-menu .ke-plugin-emoticons .ke-table .ke-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu .ke-plugin-emoticons .ke-page{text-align:right;margin:5px;padding:0;border:0;font:12px/1 "sans serif",tahoma,verdana,helvetica;color:#333;text-decoration:none}.ke-colorpicker{border:1px solid #a0a0a0;background-color:#f1f1f1;color:#222;padding:2px}.ke-colorpicker .ke-colorpicker-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell{font-size:0;line-height:0;border:1px solid #f0f0ee;cursor:pointer;margin:3px;padding:0}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color{width:14px;height:14px;margin:3px;padding:0;border:0}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top{font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;line-height:24px;border:1px solid #f1f1f1;cursor:pointer;margin:0;padding:0;text-align:center}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on{border:1px solid #5690d2}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected{border:1px solid #2446ab}.ke-dialog{margin:0;padding:0;border:1px solid #ccc;zoom:1;box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;overflow:hidden}.ke-dialog .ke-dialog-header{border:0;margin:0;font-weight:700;font-size:14px;height:30px;line-height:30px;padding:0 10px;text-align:left;color:#222;cursor:move;border-top-left-radius:6px;border-top-right-radius:6px;border-bottom:1px solid #c6c6c6;background:transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0;position:relative;cursor:move}.ke-dialog .ke-dialog-header .ke-dialog-icon-close{height:20px;width:20px;cursor:pointer;background:url(../common/icons-all.gif) 0 -59px;position:absolute;right:5px;top:4px}.ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover{background-position:0 -89px}.ke-dialog .ke-dialog-content{background-color:#fff;width:100%;height:100%;color:#333;outline:0;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body{font:12px/1.5 "sans serif",tahoma,verdana,helvetica;text-align:left;overflow:hidden;width:100%}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea{display:block;width:408px;height:260px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;border:1px solid #ccc}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus{border-color:#66afe9;outline:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-select{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1;width:auto;border:1px solid #ccc;height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-form{margin:0;padding:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number{width:50px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox{position:relative;top:6px}.ke-dialog .ke-dialog-content .ke-dialog-body textarea{display:block;overflow:auto;padding:0;resize:none}.ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus{outline:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text{display:inline-block!important;max-width:400px;height:30px;line-height:30px;border:1px solid #ccc;font-size:14px;margin:0;outline:0;padding:0 10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus{border-color:#66afe9}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color{border:1px solid #e1e1e1;background-color:#fff;font-size:12px;width:60px;height:30px;line-height:30px;padding-left:5px;overflow:hidden;cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area{position:relative;overflow:hidden;margin:0;padding:0;top:-1px;position:relative}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file{position:absolute;font-size:60px;top:0;right:0;padding:0;margin:0;z-index:811212;border:0 none;opacity:0;cursor:pointer;width:62px;height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common{top:-1px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button{padding:8px 15px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner{padding:10px 20px 0 20px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row{border:1px solid #fff;margin-bottom:10px;overflow:hidden}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left{float:left;height:30px;line-height:30px;width:60px;text-align:right}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right{float:left;text-align:left}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button{position:relative;top:-1px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label{cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;text-align:right;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header{height:30px;line-height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text{height:22px;line-height:22px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button{padding:3px 10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox{margin-left:10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs{font:12px/1 "sans serif",tahoma,verdana,helvetica;border-bottom:1px solid #e1e1e1;margin-bottom:20px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul{list-style:none outside none;margin:0;padding:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li{position:relative;margin:0 2px -1px 0;padding:0 20px;float:left;line-height:25px;text-align:center;color:#337ab7;cursor:pointer}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected{background-color:#fff;border:1px solid #e1e1e1;border-bottom:1px solid #fff;color:#555;cursor:default;border-top-left-radius:3px;border-top-right-radius:3px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on{background-color:#fff;color:#000}.ke-dialog .ke-dialog-content .ke-dialog-loading{position:absolute;top:0;left:1px;z-index:1;text-align:center}.ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content{background:url(../common/loading.gif) no-repeat center;color:#666;font-size:14px;font-weight:700;height:31px;line-height:31px;padding-left:36px}.ke-dialog .ke-dialog-footer{font:12px/1 "sans serif",tahoma,verdana,helvetica;text-align:right;padding:0 15px 5px 0;background-color:#fff;height:40px}.ke-dialog .ke-dialog-footer .ke-dialog-yes{margin:5px}.ke-dialog .ke-dialog-footer .ke-dialog-no{margin:5px 10px 5px 5px}.ke-dialog .ke-button-common{display:inline-block;text-align:center;background:0 0;border:none;padding:0;cursor:pointer}.ke-dialog .ke-button-outer{background-position:0 -25px;padding:0;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-button{color:#333;font-size:12px;border:1px solid #e6e6e6;background-color:#e6e6e6;padding:7px 10px;margin-top:-4px;color:#444;text-decoration:none;transition:background-color .3s ease-out,border-color .3s ease-out}.ke-dialog .ke-button:hover{border:1px solid #e1e1e1;background-color:#e1e1e1}.ke-dialog .ke-dialog-btn{font-size:12px;margin:5px;background:#2e8ded;color:#fff!important;padding:8px 12px;display:inline-block;border-radius:2px;cursor:pointer;text-decoration:none;transition:.3s ease-out}.ke-dialog .ke-dialog-btn:hover{box-shadow:none;box-shadow:none;opacity:.8}.ke-container-black .ke-toolbar{border-top:5px solid #222;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 1px 1px rgba(0,0,0,.16);background-clip:padding-box;text-rendering:optimizelegibility}.ke-container-black .ke-toolbar .ke-toolbar-icon{background:url(images/nkeditor.svg) no-repeat}.ke-container-black .ke-toolbar .ke-icon-source{background-position:0 0}.ke-container-black .ke-toolbar .ke-icon-preview{background-position:0 -63px}.ke-container-black .ke-toolbar .ke-icon-print{background-position:0 -84px}.ke-container-black .ke-toolbar .ke-icon-undo{background-position:0 -21px}.ke-container-black .ke-toolbar .ke-icon-redo{background-position:0 -42px}.ke-container-black .ke-toolbar .ke-icon-template{background-position:0 -105px}.ke-container-black .ke-toolbar .ke-icon-cut{background-position:0 -147px}.ke-container-black .ke-toolbar .ke-icon-copy{background-position:0 -168px}.ke-container-black .ke-toolbar .ke-icon-paste{background-position:0 -189px}.ke-container-black .ke-toolbar .ke-icon-selectall{background-position:0 -483px}.ke-container-black .ke-toolbar .ke-icon-justifyleft{background-position:0 -252px}.ke-container-black .ke-toolbar .ke-icon-justifycenter{background-position:0 -273px}.ke-container-black .ke-toolbar .ke-icon-justifyright{background-position:0 -294px}.ke-container-black .ke-toolbar .ke-icon-justifyfull{background-position:0 -315px}.ke-container-black .ke-toolbar .ke-icon-insertorderedlist{background-position:0 -336px}.ke-container-black .ke-toolbar .ke-icon-insertunorderedlist{background-position:0 -357px}.ke-container-black .ke-toolbar .ke-icon-indent{background-position:0 -378px}.ke-container-black .ke-toolbar .ke-icon-outdent{background-position:0 -399px}.ke-container-black .ke-toolbar .ke-icon-subscript{background-position:0 -420px}.ke-container-black .ke-toolbar .ke-icon-superscript{background-position:0 -441px}.ke-container-black .ke-toolbar .ke-icon-date{background-position:0 -304px;width:25px;height:16px}.ke-container-black .ke-toolbar .ke-icon-time{background-position:0 -320px;width:25px;height:16px}.ke-container-black .ke-toolbar .ke-icon-formatblock{background-position:0 -546px}.ke-container-black .ke-toolbar .ke-icon-fontname{background-position:0 -567px}.ke-container-black .ke-toolbar .ke-icon-fontsize{background-position:0 -588px}.ke-container-black .ke-toolbar .ke-icon-forecolor{background-position:0 -609px}.ke-container-black .ke-toolbar .ke-icon-hilitecolor{background-position:0 -630px}.ke-container-black .ke-toolbar .ke-icon-bold{background-position:0 -651px}.ke-container-black .ke-toolbar .ke-icon-italic{background-position:0 -672px}.ke-container-black .ke-toolbar .ke-icon-underline{background-position:0 -693px}.ke-container-black .ke-toolbar .ke-icon-strikethrough{background-position:0 -714px}.ke-container-black .ke-toolbar .ke-icon-removeformat{background-position:0 -756px}.ke-container-black .ke-toolbar .ke-icon-image{background-position:0 -777px}.ke-container-black .ke-toolbar .ke-icon-flash{background-position:0 -840px}.ke-container-black .ke-toolbar .ke-icon-media{background-position:0 -861px}.ke-container-black .ke-toolbar .ke-icon-div{background-position:0 -544px;width:16px;height:16px}.ke-container-black .ke-toolbar .ke-icon-formula{background-position:0 -576px;width:16px;height:16px}.ke-container-black .ke-toolbar .ke-icon-hr{background-position:0 -924px}.ke-container-black .ke-toolbar .ke-icon-emoticons{background-position:0 -945px}.ke-container-black .ke-toolbar .ke-icon-link{background-position:0 -1008px}.ke-container-black .ke-toolbar .ke-icon-unlink{background-position:0 -1029px}.ke-container-black .ke-toolbar .ke-icon-fullscreen{background-position:0 -525px}.ke-container-black .ke-toolbar .ke-icon-about{background-position:0 -1092px}.ke-container-black .ke-toolbar .ke-icon-quote{background-position:0 -1114px}.ke-container-black .ke-toolbar .ke-icon-plainpaste{background-position:0 -210px}.ke-container-black .ke-toolbar .ke-icon-wordpaste{background-position:0 -231px}.ke-container-black .ke-toolbar .ke-icon-table{background-position:0 -903px;width:18px!important}.ke-container-black .ke-toolbar .ke-icon-tablemenu{background-position:0 -768px;width:16px;height:16px}.ke-container-black .ke-toolbar .ke-icon-code{background-position:0 -126px}.ke-container-black .ke-toolbar .ke-icon-map{background-position:0 -976px;width:16px;height:16px}.ke-container-black .ke-toolbar .ke-icon-baidumap{background-position:0 -1050px}.ke-container-black .ke-toolbar .ke-icon-lineheight{background-position:0 -735px}.ke-container-black .ke-toolbar .ke-icon-clearhtml{background-position:0 -462px}.ke-container-black .ke-toolbar .ke-icon-pagebreak{background-position:0 -966px}.ke-container-black .ke-toolbar .ke-icon-insertfile{background-position:0 -882px}.ke-container-black .ke-toolbar .ke-icon-quickformat{background-position:0 -504px}.ke-container-black .ke-toolbar .ke-icon-anchor{background-position:0 -987px}.ke-container-black .ke-toolbar .ke-icon-search{background-position:0 -1184px;width:16px;height:16px}.ke-container-black .ke-toolbar .ke-icon-new{background-position:0 -1200px;width:16px;height:16px}.ke-container-black .ke-toolbar .ke-icon-specialchar{background-position:0 -1216px;width:16px;height:16px}.ke-container-black .ke-toolbar .ke-icon-multiimage{background-position:0 -798px}.ke-container-black .ke-toolbar .ke-icon-graft{background-position:0 -819px}.ke-menu-black .ke-menu-item .ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-toolbar-icon{font-size:0;line-height:0;overflow:hidden;display:block;width:16px;height:16px;margin:0 2px;background:url(images/nkeditor.svg) no-repeat}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tableinsert{background-position:0 -903px;width:18px!important}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tabledelete{background-position:0 -1428px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertleft{background-position:0 -1176px;width:18px!important}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertright{background-position:0 -1323px;width:18px!important}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertabove{background-position:0 -1302px;width:22px!important}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertbelow{background-position:0 -1155px;width:22px!important}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecoldelete{background-position:0 -1239px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowdelete{background-position:0 -1260px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecellprop{background-position:0 -1218px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tableprop{background-position:0 -1134px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecellsplit{background-position:0 -1088px;width:16px;height:16px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowmerge{background-position:-1px -1197px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablerowsplit{background-position:0 -1344px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecolmerge{background-position:-4px -1365px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-tablecolsplit{background-position:0 -1344px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-image{background-position:0 -777px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-flash{background-position:0 -840px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-media{background-position:0 -861px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-link{background-position:0 -1008px}.ke-menu-black .ke-menu-item .ke-menu-item-left .ke-icon-checked{background-position:0 -1407px} \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/black/editor.scss b/addons/nkeditor/assets/themes/black/editor.scss new file mode 100644 index 0000000000000000000000000000000000000000..3148e8c53c10839a598c5d7a35a77dbfbdfbd950 --- /dev/null +++ b/addons/nkeditor/assets/themes/black/editor.scss @@ -0,0 +1,387 @@ +@import "../common/common"; + +.ke-container-black { + .ke-toolbar { + + border-top: 5px solid #222222; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + background-clip: padding-box; + text-rendering: optimizelegibility; + + .ke-toolbar-icon { + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; + } + + .ke-icon-source { + background-position: 0 0px; + } + .ke-icon-preview { + background-position: 0 -63px; + } + .ke-icon-print { + background-position: 0 -84px; + } + .ke-icon-undo { + background-position: 0 -21px; + } + + .ke-icon-redo { + background-position: 0 -42px; + } + + .ke-icon-template { + background-position: 0 -105px; + } + + .ke-icon-cut { + background-position: 0 -147px; + } + + .ke-icon-copy { + background-position: 0 -168px; + } + + .ke-icon-paste { + background-position: 0 -189px; + } + + .ke-icon-selectall { + background-position: 0 -483px; + } + + .ke-icon-justifyleft { + background-position: 0 -252px; + } + + .ke-icon-justifycenter { + background-position: 0 -273px; + } + + .ke-icon-justifyright { + background-position: 0 -294px; + } + + .ke-icon-justifyfull { + background-position: 0 -315px; + } + + .ke-icon-insertorderedlist { + background-position: 0 -336px; + } + + .ke-icon-insertunorderedlist { + background-position: 0 -357px; + } + + .ke-icon-indent { + background-position: 0 -378px; + } + + .ke-icon-outdent { + background-position: 0 -399px; + } + + .ke-icon-subscript { + background-position: 0 -420px; + } + + .ke-icon-superscript { + background-position: 0 -441px; + } + + .ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; + } + + .ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; + } + + .ke-icon-formatblock { + background-position: 0 -546px; + } + + .ke-icon-fontname { + background-position: 0 -567px; + } + + .ke-icon-fontsize { + background-position: 0 -588px; + } + + .ke-icon-forecolor { + background-position: 0 -609px; + } + + .ke-icon-hilitecolor { + background-position: 0 -630px; + } + + .ke-icon-bold { + background-position: 0 -651px; + } + + .ke-icon-italic { + background-position: 0 -672px; + } + + .ke-icon-underline { + background-position: 0 -693px; + } + + .ke-icon-strikethrough { + background-position: 0 -714px; + } + + .ke-icon-removeformat { + background-position: 0 -756px; + } + + .ke-icon-image { + background-position: 0 -777px; + } + + .ke-icon-flash { + background-position: 0 -840px; + } + + .ke-icon-media { + background-position: 0 -861px; + } + + .ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; + } + + .ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; + } + + .ke-icon-hr { + background-position: 0 -924px; + } + + .ke-icon-emoticons { + background-position: 0 -945px; + } + + .ke-icon-link { + background-position: 0 -1008px; + } + + .ke-icon-unlink { + background-position: 0 -1029px; + } + + .ke-icon-fullscreen { + background-position: 0 -525px; + } + + .ke-icon-about { + background-position: 0 -1092px; + } + + .ke-icon-quote { + background-position: 0 -1114px; + } + + .ke-icon-plainpaste { + background-position: 0 -210px; + } + + .ke-icon-wordpaste { + background-position: 0 -231px; + } + + .ke-icon-table { + background-position: 0px -903px; + width: 18px !important; + } + + .ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; + } + + .ke-icon-code { + background-position: 0 -126px; + } + + .ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; + } + + .ke-icon-baidumap { + background-position: 0 -1050px; + } + + .ke-icon-lineheight { + background-position: 0 -735px; + } + + .ke-icon-clearhtml { + background-position: 0 -462px; + } + + .ke-icon-pagebreak { + background-position: 0 -966px; + } + + .ke-icon-insertfile { + background-position: 0 -882px; + } + + .ke-icon-quickformat { + background-position: 0 -504px; + } + + .ke-icon-anchor { + background-position: 0 -987px; + } + + .ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; + } + + .ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; + } + + .ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; + } + + .ke-icon-multiimage { + background-position: 0 -798px; + } + + .ke-icon-graft { + background-position: 0 -819px; + } + } +} + +/** + menu 右键菜单 + */ +.ke-menu-black { + + .ke-menu-item { + + .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; + + .ke-toolbar-icon { + @include ke-toolbar-icon; + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; + } + + .ke-icon-tableinsert { + background-position: 0 -903px; + width: 18px !important; + } + + .ke-icon-tabledelete { + background-position: 0 -1428px; + } + + .ke-icon-tablecolinsertleft { + background-position: 0 -1176px; + width: 18px !important; + } + + .ke-icon-tablecolinsertright { + background-position: 0 -1323px; + width: 18px !important; + } + + .ke-icon-tablerowinsertabove { + background-position: 0 -1302px; + width: 22px !important; + } + + .ke-icon-tablerowinsertbelow { + background-position: 0 -1155px; + width: 22px !important; + } + + .ke-icon-tablecoldelete { + background-position: 0 -1239px; + } + + .ke-icon-tablerowdelete { + background-position: 0 -1260px; + } + + .ke-icon-tablecellprop { + background-position: 0 -1218px; + } + + .ke-icon-tableprop { + background-position: 0 -1134px; + } + .ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; + } + + .ke-icon-tablerowmerge { + background-position: -1px -1197px; + } + + .ke-icon-tablerowsplit { + background-position: 0 -1344px; + } + + .ke-icon-tablecolmerge { + background-position: -4px -1365px; + } + + .ke-icon-tablecolsplit { + background-position: 0 -1344px; + } + + //图片,视频右键菜单 + .ke-icon-image { + background-position: 0 -777px; + } + .ke-icon-flash { + background-position: 0 -840px; + } + .ke-icon-media { + background-position: 0 -861px; + } + .ke-icon-link { + background-position: 0 -1008px; + } + + .ke-icon-checked { + background-position: 0 -1407px; + } + + } + } +} +//menu end \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/black/images/nkeditor.png b/addons/nkeditor/assets/themes/black/images/nkeditor.png new file mode 100644 index 0000000000000000000000000000000000000000..f3fbea2d809b336eeb9f155d942a7aa844d5dbf6 Binary files /dev/null and b/addons/nkeditor/assets/themes/black/images/nkeditor.png differ diff --git a/addons/nkeditor/assets/themes/black/images/nkeditor.svg b/addons/nkeditor/assets/themes/black/images/nkeditor.svg new file mode 100644 index 0000000000000000000000000000000000000000..56416dd00c7f432b83293244c30962899a8dff01 --- /dev/null +++ b/addons/nkeditor/assets/themes/black/images/nkeditor.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/nkeditor/assets/themes/blue/editor.css b/addons/nkeditor/assets/themes/blue/editor.css new file mode 100644 index 0000000000000000000000000000000000000000..7a14292c60745dcfcb0d28914cf0a3e441f7b0fa --- /dev/null +++ b/addons/nkeditor/assets/themes/blue/editor.css @@ -0,0 +1,822 @@ +@charset "UTF-8"; +/** +公共样式 +*/ +.ke-clearfix { + zoom: 1; + clear: both; } + +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; } + +.ke-animated { + animation: zoomIn; + animation-duration: 0.3s; + animation-fill-mode: both; } + +@keyframes zoomIn { + from { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); } + 50% { + opacity: 1; } } +.ke-dialog-mask { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; } + +.ke-dialog-lock { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; + z-index: 811213; + left: 0; + top: 0; + position: absolute; } + +/** +编辑器样式开始 + */ +.ke-container { + display: block; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + /** + 通用样式 + */ + /** + toolbar 样式 + */ + /** + ke-edit + */ + /** + statusbar start + */ } + .ke-container .ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + background-color: #F0F0EE; } + .ke-container .ke-menu a, + .ke-container .ke-menu a:hover, + .ke-container .ke-dialog a, + .ke-container .ke-dialog a:hover { + color: #337FE5; + text-decoration: none; } + .ke-container .ke-toolbar { + text-align: left; + overflow: hidden; + zoom: 1; + padding: 0px 5px; } + .ke-container .ke-toolbar .ke-outline { + padding: 10px 5px; + font-size: 0; + line-height: 0; + cursor: pointer; + display: block; + float: left; + /** + * 按钮通用样式 + */ } + .ke-container .ke-toolbar .ke-outline .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; } + .ke-container .ke-toolbar .ke-on { + background: #ebebeb; } + .ke-container .ke-toolbar .ke-selected { + background-color: #ebebeb; } + .ke-container .ke-toolbar .ke-disabled { + cursor: default; } + .ke-container .ke-toolbar .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; } + .ke-container .ke-toolbar .ke-hr { + clear: both; + height: 1px; + width: calc(100% - (2 * 2px)); + background: #ebebeb; } + .ke-container .ke-edit { + padding: 0; } + .ke-container .ke-edit .ke-edit-iframe, + .ke-container .ke-edit .ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; } + .ke-container .ke-edit .ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; } + .ke-container .ke-edit .ke-edit-textarea:focus { + outline: none; } + .ke-container .ke-statusbar { + position: relative; + background-color: #f5f5f5; + border-top: 1px solid #e1e1e1; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; + display: none; } + .ke-container .ke-statusbar .ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; } + .ke-container .ke-statusbar .ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + width: 11px; + height: 11px; } + +/** + menu 右键菜单 + */ +.ke-menu { + border: 1px solid #cccccc; + background-color: #f5f5f5; + color: #222222; + padding: 2px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; + /** + 表情插件 + */ } + .ke-menu .ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; } + .ke-menu .ke-menu-item .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-inline-block .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; } + .ke-menu .ke-menu-item .ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; } + .ke-menu .ke-menu-item .ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: 1px solid #e1e1e1; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; } + .ke-menu .ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons { + position: relative; } + .ke-menu .ke-plugin-emoticons .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; } + .ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img { + border: 0; + margin: 0; + padding: 0; } + .ke-menu .ke-plugin-emoticons .ke-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell { + margin: 0; + padding: 1px; + border: 1px solid #f5f5f5; + cursor: pointer; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img { + display: block; + background-repeat: no-repeat; + overflow: hidden; + margin: 2px; + width: 24px; + height: 24px; + margin: 0; + padding: 0; + border: 0; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + color: #333; + text-decoration: none; } + +/** + colorpicker + */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; } + .ke-colorpicker .ke-colorpicker-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin: 3px; + padding: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top { + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F1F1F1; + cursor: pointer; + margin: 0; + padding: 0; + text-align: center; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on { + border: 1px solid #5690D2; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected { + border: 1px solid #2446AB; } + +/** + dialog + */ +.ke-dialog { + margin: 0; + padding: 0; + border: 1px solid #cccccc; + zoom: 1; + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + overflow: hidden; } + .ke-dialog .ke-dialog-header { + border: 0; + margin: 0; + font-weight: bold; + font-size: 14px; + height: 30px; + line-height: 30px; + padding: 0px 10px; + text-align: left; + color: #222; + cursor: move; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-bottom: 1px solid #c6c6c6; + background: transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0; + position: relative; + cursor: move; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close { + height: 20px; + width: 20px; + cursor: pointer; + background: url("../common/icons-all.gif") 0 -59px; + position: absolute; + right: 5px; + top: 4px; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover { + background-position: 0px -89px; } + .ke-dialog .ke-dialog-content { + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + outline: 0; + zoom: 1; } + .ke-dialog .ke-dialog-content .ke-dialog-body { + font: 12px/1.5 "sans serif", tahoma, verdana, helvetica; + text-align: left; + overflow: hidden; + width: 100%; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + border: 1px solid #cccccc; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus { + border-color: #66afe9; + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; + border: 1px solid #cccccc; + height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-form { + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number { + width: 50px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox { + position: relative; + top: 6px; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus { + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text { + display: inline-block !important; + max-width: 400px; + height: 30px; + line-height: 30px; + border: 1px solid #cccccc; + font-size: 14px; + margin: 0; + outline: 0; + padding: 0px 10px; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus { + border-color: #66afe9; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color { + border: 1px solid #e1e1e1; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 30px; + line-height: 30px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + top: -1px; + position: relative; + *height: 25px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + cursor: pointer; + width: 62px; + height: 30px; + filter: alpha(opacity=0); } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common { + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button { + padding: 8px 15px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner { + padding: 10px 20px 0px 20px; + /** + tabs + */ } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row { + border: 1px solid #FFFFFF; + margin-bottom: 10px; + overflow: hidden; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left { + float: left; + height: 30px; + line-height: 30px; + width: 60px; + text-align: right; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right { + float: left; + text-align: left; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button { + position: relative; + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label { + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + text-align: right; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header { + height: 30px; + line-height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text { + height: 22px; + line-height: 22px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button { + padding: 3px 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox { + margin-left: 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + border-bottom: 1px solid #e1e1e1; + margin-bottom: 20px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul { + list-style: none outside none; + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li { + position: relative; + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #337ab7; + cursor: pointer; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected { + background-color: #FFF; + border: 1px solid #e1e1e1; + border-bottom: 1px solid #FFF; + color: #555555; + cursor: default; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on { + background-color: #FFF; + color: #000; } + .ke-dialog .ke-dialog-content .ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; } + .ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat center; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; } + .ke-dialog .ke-dialog-footer { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + text-align: right; + padding: 0 15px 5px 0; + background-color: #FFF; + height: 40px; } + .ke-dialog .ke-dialog-footer .ke-dialog-yes { + margin: 5px; } + .ke-dialog .ke-dialog-footer .ke-dialog-no { + margin: 5px 10px 5px 5px; } + .ke-dialog .ke-button-common { + display: inline-block; + text-align: center; + background: none; + border: none; + padding: 0; + cursor: pointer; } + .ke-dialog .ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-button { + color: #333; + font-size: 12px; + border: 1px solid #e6e6e6; + background-color: #e6e6e6; + padding: 7px 10px; + margin-top: -4px; + color: #444; + text-decoration: none; + transition: background-color .3s ease-out, border-color .3s ease-out; } + .ke-dialog .ke-button:hover { + border: 1px solid #e1e1e1; + background-color: #e1e1e1; } + .ke-dialog .ke-dialog-btn { + font-size: 12px; + margin: 5px; + background: #2e8ded; + color: #fff !important; + padding: 8px 12px; + display: inline-block; + border-radius: 2px; + cursor: pointer; + text-decoration: none; + transition: .3s ease-out; } + .ke-dialog .ke-dialog-btn:hover { + filter: alpha(opacity=80); + box-shadow: none; + box-shadow: none; + opacity: .8; } + +.ke-container-blue .ke-toolbar { + border-top: 5px solid #1296db; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + background-clip: padding-box; + text-rendering: optimizelegibility; } + .ke-container-blue .ke-toolbar .ke-toolbar-icon { + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; } + .ke-container-blue .ke-toolbar .ke-icon-source { + background-position: 0 0px; } + .ke-container-blue .ke-toolbar .ke-icon-preview { + background-position: 0 -63px; } + .ke-container-blue .ke-toolbar .ke-icon-print { + background-position: 0 -84px; } + .ke-container-blue .ke-toolbar .ke-icon-undo { + background-position: 0 -21px; } + .ke-container-blue .ke-toolbar .ke-icon-redo { + background-position: 0 -42px; } + .ke-container-blue .ke-toolbar .ke-icon-template { + background-position: 0 -105px; } + .ke-container-blue .ke-toolbar .ke-icon-cut { + background-position: 0 -147px; } + .ke-container-blue .ke-toolbar .ke-icon-copy { + background-position: 0 -168px; } + .ke-container-blue .ke-toolbar .ke-icon-paste { + background-position: 0 -189px; } + .ke-container-blue .ke-toolbar .ke-icon-selectall { + background-position: 0 -483px; } + .ke-container-blue .ke-toolbar .ke-icon-justifyleft { + background-position: 0 -252px; } + .ke-container-blue .ke-toolbar .ke-icon-justifycenter { + background-position: 0 -273px; } + .ke-container-blue .ke-toolbar .ke-icon-justifyright { + background-position: 0 -294px; } + .ke-container-blue .ke-toolbar .ke-icon-justifyfull { + background-position: 0 -315px; } + .ke-container-blue .ke-toolbar .ke-icon-insertorderedlist { + background-position: 0 -336px; } + .ke-container-blue .ke-toolbar .ke-icon-insertunorderedlist { + background-position: 0 -357px; } + .ke-container-blue .ke-toolbar .ke-icon-indent { + background-position: 0 -378px; } + .ke-container-blue .ke-toolbar .ke-icon-outdent { + background-position: 0 -399px; } + .ke-container-blue .ke-toolbar .ke-icon-subscript { + background-position: 0 -420px; } + .ke-container-blue .ke-toolbar .ke-icon-superscript { + background-position: 0 -441px; } + .ke-container-blue .ke-toolbar .ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-formatblock { + background-position: 0 -546px; } + .ke-container-blue .ke-toolbar .ke-icon-fontname { + background-position: 0 -567px; } + .ke-container-blue .ke-toolbar .ke-icon-fontsize { + background-position: 0 -588px; } + .ke-container-blue .ke-toolbar .ke-icon-forecolor { + background-position: 0 -609px; } + .ke-container-blue .ke-toolbar .ke-icon-hilitecolor { + background-position: 0 -630px; } + .ke-container-blue .ke-toolbar .ke-icon-bold { + background-position: 0 -651px; } + .ke-container-blue .ke-toolbar .ke-icon-italic { + background-position: 0 -672px; } + .ke-container-blue .ke-toolbar .ke-icon-underline { + background-position: 0 -693px; } + .ke-container-blue .ke-toolbar .ke-icon-strikethrough { + background-position: 0 -714px; } + .ke-container-blue .ke-toolbar .ke-icon-removeformat { + background-position: 0 -756px; } + .ke-container-blue .ke-toolbar .ke-icon-image { + background-position: 0 -777px; } + .ke-container-blue .ke-toolbar .ke-icon-flash { + background-position: 0 -840px; } + .ke-container-blue .ke-toolbar .ke-icon-media { + background-position: 0 -861px; } + .ke-container-blue .ke-toolbar .ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-hr { + background-position: 0 -924px; } + .ke-container-blue .ke-toolbar .ke-icon-emoticons { + background-position: 0 -945px; } + .ke-container-blue .ke-toolbar .ke-icon-link { + background-position: 0 -1008px; } + .ke-container-blue .ke-toolbar .ke-icon-unlink { + background-position: 0 -1029px; } + .ke-container-blue .ke-toolbar .ke-icon-fullscreen { + background-position: 0 -525px; } + .ke-container-blue .ke-toolbar .ke-icon-about { + background-position: 0 -1092px; } + .ke-container-blue .ke-toolbar .ke-icon-quote { + background-position: 0 -1114px; } + .ke-container-blue .ke-toolbar .ke-icon-plainpaste { + background-position: 0 -210px; } + .ke-container-blue .ke-toolbar .ke-icon-wordpaste { + background-position: 0 -231px; } + .ke-container-blue .ke-toolbar .ke-icon-table { + background-position: 0px -903px; + width: 18px !important; } + .ke-container-blue .ke-toolbar .ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-code { + background-position: 0 -126px; } + .ke-container-blue .ke-toolbar .ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-baidumap { + background-position: 0 -1050px; } + .ke-container-blue .ke-toolbar .ke-icon-lineheight { + background-position: 0 -735px; } + .ke-container-blue .ke-toolbar .ke-icon-clearhtml { + background-position: 0 -462px; } + .ke-container-blue .ke-toolbar .ke-icon-pagebreak { + background-position: 0 -966px; } + .ke-container-blue .ke-toolbar .ke-icon-insertfile { + background-position: 0 -882px; } + .ke-container-blue .ke-toolbar .ke-icon-quickformat { + background-position: 0 -504px; } + .ke-container-blue .ke-toolbar .ke-icon-anchor { + background-position: 0 -987px; } + .ke-container-blue .ke-toolbar .ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; } + .ke-container-blue .ke-toolbar .ke-icon-multiimage { + background-position: 0 -798px; } + .ke-container-blue .ke-toolbar .ke-icon-graft { + background-position: 0 -819px; } + +/** + menu 右键菜单 + */ +.ke-menu-blue .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tableinsert { + background-position: 0 -903px; + width: 18px !important; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tabledelete { + background-position: 0 -1428px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertleft { + background-position: 0 -1176px; + width: 18px !important; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertright { + background-position: 0 -1323px; + width: 18px !important; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertabove { + background-position: 0 -1302px; + width: 22px !important; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertbelow { + background-position: 0 -1155px; + width: 22px !important; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecoldelete { + background-position: 0 -1239px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowdelete { + background-position: 0 -1260px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecellprop { + background-position: 0 -1218px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tableprop { + background-position: 0 -1134px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowmerge { + background-position: -1px -1197px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowsplit { + background-position: 0 -1344px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecolmerge { + background-position: -4px -1365px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecolsplit { + background-position: 0 -1344px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-image { + background-position: 0 -777px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-flash { + background-position: 0 -840px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-media { + background-position: 0 -861px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-link { + background-position: 0 -1008px; } + .ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-checked { + background-position: 0 -1407px; } + +/*# sourceMappingURL=editor.css.map */ diff --git a/addons/nkeditor/assets/themes/blue/editor.min.css b/addons/nkeditor/assets/themes/blue/editor.min.css new file mode 100644 index 0000000000000000000000000000000000000000..5297fab8fcd5f0c4a2d2817600f870c70e93ac7c --- /dev/null +++ b/addons/nkeditor/assets/themes/blue/editor.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.ke-clearfix{zoom:1;clear:both}.ke-clearfix:after{content:".";display:block;clear:both;font-size:0;height:0;line-height:0;visibility:hidden}.ke-animated{animation:zoomIn;animation-duration:.3s;animation-fill-mode:both}@keyframes zoomIn{from{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.ke-dialog-mask{background-color:#fff;opacity:.5}.ke-dialog-lock{background-color:#fff;opacity:.5;z-index:811213;left:0;top:0;position:absolute}.ke-container{display:block;background-color:#fff;overflow:hidden;margin:0;padding:0;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 1px 1px rgba(0,0,0,.16)}.ke-container .ke-shadow{box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;background-color:#f0f0ee}.ke-container .ke-dialog a,.ke-container .ke-dialog a:hover,.ke-container .ke-menu a,.ke-container .ke-menu a:hover{color:#337fe5;text-decoration:none}.ke-container .ke-toolbar{text-align:left;overflow:hidden;zoom:1;padding:0 5px}.ke-container .ke-toolbar .ke-outline{padding:10px 5px;font-size:0;line-height:0;cursor:pointer;display:block;float:left}.ke-container .ke-toolbar .ke-outline .ke-toolbar-icon{font-size:0;line-height:0;overflow:hidden;display:block;width:16px;height:16px;margin:0 2px}.ke-container .ke-toolbar .ke-on{background:#ebebeb}.ke-container .ke-toolbar .ke-selected{background-color:#ebebeb}.ke-container .ke-toolbar .ke-disabled{cursor:default}.ke-container .ke-toolbar .ke-separator{height:16px;margin:2px 3px;border-left:1px solid #a0a0a0;border-right:1px solid #fff;border-top:0;border-bottom:0;width:0;font-size:0;line-height:0;overflow:hidden;display:block;float:left}.ke-container .ke-toolbar .ke-hr{clear:both;height:1px;width:calc(100% - (2 * 2px));background:#ebebeb}.ke-container .ke-edit{padding:0}.ke-container .ke-edit .ke-edit-iframe,.ke-container .ke-edit .ke-edit-textarea{border:0;margin:0;padding:0;overflow:auto}.ke-container .ke-edit .ke-edit-textarea{font:12px/1.5 Consolas,Monaco,"Bitstream Vera Sans Mono","Courier New",Courier,monospace;color:#000;overflow:auto;resize:none}.ke-container .ke-edit .ke-edit-textarea:focus{outline:0}.ke-container .ke-statusbar{position:relative;background-color:#f5f5f5;border-top:1px solid #e1e1e1;font-size:0;line-height:0;overflow:hidden;text-align:center;cursor:s-resize;display:none}.ke-container .ke-statusbar .ke-statusbar-center-icon{background-position:0 -754px;width:15px;height:11px}.ke-container .ke-statusbar .ke-statusbar-right-icon{position:absolute;right:0;bottom:0;cursor:se-resize;width:11px;height:11px}.ke-menu{border:1px solid #ccc;background-color:#f5f5f5;color:#222;padding:2px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;text-align:left;overflow:hidden}.ke-menu .ke-menu-item{border:1px solid #f1f1f1;background-color:#f1f1f1;color:#222;height:24px;overflow:hidden;cursor:pointer}.ke-menu .ke-menu-item .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-menu .ke-menu-item .ke-inline-block .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-menu .ke-menu-item .ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu .ke-menu-item .ke-menu-item-center{width:0;height:24px;border-left:1px solid #e3e3e3;border-right:1px solid #fff;border-top:0;border-bottom:0}.ke-menu .ke-menu-item .ke-menu-item-center-on{border-left:1px solid #e9eff6;border-right:1px solid #e9eff6}.ke-menu .ke-menu-item .ke-menu-item-right{border:0;padding:0 0 0 5px;line-height:24px;text-align:left;overflow:hidden}.ke-menu .ke-menu-item .ke-menu-separator{margin:2px 0;height:0;overflow:hidden;border-top:1px solid #e1e1e1;border-bottom:1px solid #fff;border-left:0;border-right:0}.ke-menu .ke-menu-item-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu .ke-plugin-emoticons{position:relative}.ke-menu .ke-plugin-emoticons .ke-preview{position:absolute;text-align:center;margin:2px;padding:10px;top:0;border:1px solid #a0a0a0;background-color:#fff;display:none}.ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img{border:0;margin:0;padding:0}.ke-menu .ke-plugin-emoticons .ke-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-menu .ke-plugin-emoticons .ke-table .ke-cell{margin:0;padding:1px;border:1px solid #f5f5f5;cursor:pointer}.ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img{display:block;background-repeat:no-repeat;overflow:hidden;margin:2px;width:24px;height:24px;margin:0;padding:0;border:0}.ke-menu .ke-plugin-emoticons .ke-table .ke-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu .ke-plugin-emoticons .ke-page{text-align:right;margin:5px;padding:0;border:0;font:12px/1 "sans serif",tahoma,verdana,helvetica;color:#333;text-decoration:none}.ke-colorpicker{border:1px solid #a0a0a0;background-color:#f1f1f1;color:#222;padding:2px}.ke-colorpicker .ke-colorpicker-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell{font-size:0;line-height:0;border:1px solid #f0f0ee;cursor:pointer;margin:3px;padding:0}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color{width:14px;height:14px;margin:3px;padding:0;border:0}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top{font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;line-height:24px;border:1px solid #f1f1f1;cursor:pointer;margin:0;padding:0;text-align:center}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on{border:1px solid #5690d2}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected{border:1px solid #2446ab}.ke-dialog{margin:0;padding:0;border:1px solid #ccc;zoom:1;box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;overflow:hidden}.ke-dialog .ke-dialog-header{border:0;margin:0;font-weight:700;font-size:14px;height:30px;line-height:30px;padding:0 10px;text-align:left;color:#222;cursor:move;border-top-left-radius:6px;border-top-right-radius:6px;border-bottom:1px solid #c6c6c6;background:transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0;position:relative;cursor:move}.ke-dialog .ke-dialog-header .ke-dialog-icon-close{height:20px;width:20px;cursor:pointer;background:url(../common/icons-all.gif) 0 -59px;position:absolute;right:5px;top:4px}.ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover{background-position:0 -89px}.ke-dialog .ke-dialog-content{background-color:#fff;width:100%;height:100%;color:#333;outline:0;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body{font:12px/1.5 "sans serif",tahoma,verdana,helvetica;text-align:left;overflow:hidden;width:100%}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea{display:block;width:408px;height:260px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;border:1px solid #ccc}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus{border-color:#66afe9;outline:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-select{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1;width:auto;border:1px solid #ccc;height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-form{margin:0;padding:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number{width:50px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox{position:relative;top:6px}.ke-dialog .ke-dialog-content .ke-dialog-body textarea{display:block;overflow:auto;padding:0;resize:none}.ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus{outline:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text{display:inline-block!important;max-width:400px;height:30px;line-height:30px;border:1px solid #ccc;font-size:14px;margin:0;outline:0;padding:0 10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus{border-color:#66afe9}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color{border:1px solid #e1e1e1;background-color:#fff;font-size:12px;width:60px;height:30px;line-height:30px;padding-left:5px;overflow:hidden;cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area{position:relative;overflow:hidden;margin:0;padding:0;top:-1px;position:relative}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file{position:absolute;font-size:60px;top:0;right:0;padding:0;margin:0;z-index:811212;border:0 none;opacity:0;cursor:pointer;width:62px;height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common{top:-1px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button{padding:8px 15px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner{padding:10px 20px 0 20px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row{border:1px solid #fff;margin-bottom:10px;overflow:hidden}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left{float:left;height:30px;line-height:30px;width:60px;text-align:right}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right{float:left;text-align:left}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button{position:relative;top:-1px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label{cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;text-align:right;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header{height:30px;line-height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text{height:22px;line-height:22px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button{padding:3px 10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox{margin-left:10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs{font:12px/1 "sans serif",tahoma,verdana,helvetica;border-bottom:1px solid #e1e1e1;margin-bottom:20px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul{list-style:none outside none;margin:0;padding:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li{position:relative;margin:0 2px -1px 0;padding:0 20px;float:left;line-height:25px;text-align:center;color:#337ab7;cursor:pointer}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected{background-color:#fff;border:1px solid #e1e1e1;border-bottom:1px solid #fff;color:#555;cursor:default;border-top-left-radius:3px;border-top-right-radius:3px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on{background-color:#fff;color:#000}.ke-dialog .ke-dialog-content .ke-dialog-loading{position:absolute;top:0;left:1px;z-index:1;text-align:center}.ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content{background:url(../common/loading.gif) no-repeat center;color:#666;font-size:14px;font-weight:700;height:31px;line-height:31px;padding-left:36px}.ke-dialog .ke-dialog-footer{font:12px/1 "sans serif",tahoma,verdana,helvetica;text-align:right;padding:0 15px 5px 0;background-color:#fff;height:40px}.ke-dialog .ke-dialog-footer .ke-dialog-yes{margin:5px}.ke-dialog .ke-dialog-footer .ke-dialog-no{margin:5px 10px 5px 5px}.ke-dialog .ke-button-common{display:inline-block;text-align:center;background:0 0;border:none;padding:0;cursor:pointer}.ke-dialog .ke-button-outer{background-position:0 -25px;padding:0;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-button{color:#333;font-size:12px;border:1px solid #e6e6e6;background-color:#e6e6e6;padding:7px 10px;margin-top:-4px;color:#444;text-decoration:none;transition:background-color .3s ease-out,border-color .3s ease-out}.ke-dialog .ke-button:hover{border:1px solid #e1e1e1;background-color:#e1e1e1}.ke-dialog .ke-dialog-btn{font-size:12px;margin:5px;background:#2e8ded;color:#fff!important;padding:8px 12px;display:inline-block;border-radius:2px;cursor:pointer;text-decoration:none;transition:.3s ease-out}.ke-dialog .ke-dialog-btn:hover{box-shadow:none;box-shadow:none;opacity:.8}.ke-container-blue .ke-toolbar{border-top:5px solid #1296db;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 1px 1px rgba(0,0,0,.16);background-clip:padding-box;text-rendering:optimizelegibility}.ke-container-blue .ke-toolbar .ke-toolbar-icon{background:url(images/nkeditor.svg) no-repeat}.ke-container-blue .ke-toolbar .ke-icon-source{background-position:0 0}.ke-container-blue .ke-toolbar .ke-icon-preview{background-position:0 -63px}.ke-container-blue .ke-toolbar .ke-icon-print{background-position:0 -84px}.ke-container-blue .ke-toolbar .ke-icon-undo{background-position:0 -21px}.ke-container-blue .ke-toolbar .ke-icon-redo{background-position:0 -42px}.ke-container-blue .ke-toolbar .ke-icon-template{background-position:0 -105px}.ke-container-blue .ke-toolbar .ke-icon-cut{background-position:0 -147px}.ke-container-blue .ke-toolbar .ke-icon-copy{background-position:0 -168px}.ke-container-blue .ke-toolbar .ke-icon-paste{background-position:0 -189px}.ke-container-blue .ke-toolbar .ke-icon-selectall{background-position:0 -483px}.ke-container-blue .ke-toolbar .ke-icon-justifyleft{background-position:0 -252px}.ke-container-blue .ke-toolbar .ke-icon-justifycenter{background-position:0 -273px}.ke-container-blue .ke-toolbar .ke-icon-justifyright{background-position:0 -294px}.ke-container-blue .ke-toolbar .ke-icon-justifyfull{background-position:0 -315px}.ke-container-blue .ke-toolbar .ke-icon-insertorderedlist{background-position:0 -336px}.ke-container-blue .ke-toolbar .ke-icon-insertunorderedlist{background-position:0 -357px}.ke-container-blue .ke-toolbar .ke-icon-indent{background-position:0 -378px}.ke-container-blue .ke-toolbar .ke-icon-outdent{background-position:0 -399px}.ke-container-blue .ke-toolbar .ke-icon-subscript{background-position:0 -420px}.ke-container-blue .ke-toolbar .ke-icon-superscript{background-position:0 -441px}.ke-container-blue .ke-toolbar .ke-icon-date{background-position:0 -304px;width:25px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-time{background-position:0 -320px;width:25px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-formatblock{background-position:0 -546px}.ke-container-blue .ke-toolbar .ke-icon-fontname{background-position:0 -567px}.ke-container-blue .ke-toolbar .ke-icon-fontsize{background-position:0 -588px}.ke-container-blue .ke-toolbar .ke-icon-forecolor{background-position:0 -609px}.ke-container-blue .ke-toolbar .ke-icon-hilitecolor{background-position:0 -630px}.ke-container-blue .ke-toolbar .ke-icon-bold{background-position:0 -651px}.ke-container-blue .ke-toolbar .ke-icon-italic{background-position:0 -672px}.ke-container-blue .ke-toolbar .ke-icon-underline{background-position:0 -693px}.ke-container-blue .ke-toolbar .ke-icon-strikethrough{background-position:0 -714px}.ke-container-blue .ke-toolbar .ke-icon-removeformat{background-position:0 -756px}.ke-container-blue .ke-toolbar .ke-icon-image{background-position:0 -777px}.ke-container-blue .ke-toolbar .ke-icon-flash{background-position:0 -840px}.ke-container-blue .ke-toolbar .ke-icon-media{background-position:0 -861px}.ke-container-blue .ke-toolbar .ke-icon-div{background-position:0 -544px;width:16px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-formula{background-position:0 -576px;width:16px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-hr{background-position:0 -924px}.ke-container-blue .ke-toolbar .ke-icon-emoticons{background-position:0 -945px}.ke-container-blue .ke-toolbar .ke-icon-link{background-position:0 -1008px}.ke-container-blue .ke-toolbar .ke-icon-unlink{background-position:0 -1029px}.ke-container-blue .ke-toolbar .ke-icon-fullscreen{background-position:0 -525px}.ke-container-blue .ke-toolbar .ke-icon-about{background-position:0 -1092px}.ke-container-blue .ke-toolbar .ke-icon-quote{background-position:0 -1114px}.ke-container-blue .ke-toolbar .ke-icon-plainpaste{background-position:0 -210px}.ke-container-blue .ke-toolbar .ke-icon-wordpaste{background-position:0 -231px}.ke-container-blue .ke-toolbar .ke-icon-table{background-position:0 -903px;width:18px!important}.ke-container-blue .ke-toolbar .ke-icon-tablemenu{background-position:0 -768px;width:16px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-code{background-position:0 -126px}.ke-container-blue .ke-toolbar .ke-icon-map{background-position:0 -976px;width:16px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-baidumap{background-position:0 -1050px}.ke-container-blue .ke-toolbar .ke-icon-lineheight{background-position:0 -735px}.ke-container-blue .ke-toolbar .ke-icon-clearhtml{background-position:0 -462px}.ke-container-blue .ke-toolbar .ke-icon-pagebreak{background-position:0 -966px}.ke-container-blue .ke-toolbar .ke-icon-insertfile{background-position:0 -882px}.ke-container-blue .ke-toolbar .ke-icon-quickformat{background-position:0 -504px}.ke-container-blue .ke-toolbar .ke-icon-anchor{background-position:0 -987px}.ke-container-blue .ke-toolbar .ke-icon-search{background-position:0 -1184px;width:16px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-new{background-position:0 -1200px;width:16px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-specialchar{background-position:0 -1216px;width:16px;height:16px}.ke-container-blue .ke-toolbar .ke-icon-multiimage{background-position:0 -798px}.ke-container-blue .ke-toolbar .ke-icon-graft{background-position:0 -819px}.ke-menu-blue .ke-menu-item .ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-toolbar-icon{font-size:0;line-height:0;overflow:hidden;display:block;width:16px;height:16px;margin:0 2px;background:url(images/nkeditor.svg) no-repeat}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tableinsert{background-position:0 -903px;width:18px!important}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tabledelete{background-position:0 -1428px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertleft{background-position:0 -1176px;width:18px!important}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertright{background-position:0 -1323px;width:18px!important}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertabove{background-position:0 -1302px;width:22px!important}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertbelow{background-position:0 -1155px;width:22px!important}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecoldelete{background-position:0 -1239px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowdelete{background-position:0 -1260px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecellprop{background-position:0 -1218px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tableprop{background-position:0 -1134px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecellsplit{background-position:0 -1088px;width:16px;height:16px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowmerge{background-position:-1px -1197px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablerowsplit{background-position:0 -1344px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecolmerge{background-position:-4px -1365px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-tablecolsplit{background-position:0 -1344px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-image{background-position:0 -777px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-flash{background-position:0 -840px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-media{background-position:0 -861px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-link{background-position:0 -1008px}.ke-menu-blue .ke-menu-item .ke-menu-item-left .ke-icon-checked{background-position:0 -1407px} \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/blue/editor.scss b/addons/nkeditor/assets/themes/blue/editor.scss new file mode 100644 index 0000000000000000000000000000000000000000..56739c1eeffac9299b0039535392445785731308 --- /dev/null +++ b/addons/nkeditor/assets/themes/blue/editor.scss @@ -0,0 +1,387 @@ +@import "../common/common"; + +.ke-container-blue { + .ke-toolbar { + + border-top: 5px solid #1296db; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + background-clip: padding-box; + text-rendering: optimizelegibility; + + .ke-toolbar-icon { + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; + } + + .ke-icon-source { + background-position: 0 0px; + } + .ke-icon-preview { + background-position: 0 -63px; + } + .ke-icon-print { + background-position: 0 -84px; + } + .ke-icon-undo { + background-position: 0 -21px; + } + + .ke-icon-redo { + background-position: 0 -42px; + } + + .ke-icon-template { + background-position: 0 -105px; + } + + .ke-icon-cut { + background-position: 0 -147px; + } + + .ke-icon-copy { + background-position: 0 -168px; + } + + .ke-icon-paste { + background-position: 0 -189px; + } + + .ke-icon-selectall { + background-position: 0 -483px; + } + + .ke-icon-justifyleft { + background-position: 0 -252px; + } + + .ke-icon-justifycenter { + background-position: 0 -273px; + } + + .ke-icon-justifyright { + background-position: 0 -294px; + } + + .ke-icon-justifyfull { + background-position: 0 -315px; + } + + .ke-icon-insertorderedlist { + background-position: 0 -336px; + } + + .ke-icon-insertunorderedlist { + background-position: 0 -357px; + } + + .ke-icon-indent { + background-position: 0 -378px; + } + + .ke-icon-outdent { + background-position: 0 -399px; + } + + .ke-icon-subscript { + background-position: 0 -420px; + } + + .ke-icon-superscript { + background-position: 0 -441px; + } + + .ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; + } + + .ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; + } + + .ke-icon-formatblock { + background-position: 0 -546px; + } + + .ke-icon-fontname { + background-position: 0 -567px; + } + + .ke-icon-fontsize { + background-position: 0 -588px; + } + + .ke-icon-forecolor { + background-position: 0 -609px; + } + + .ke-icon-hilitecolor { + background-position: 0 -630px; + } + + .ke-icon-bold { + background-position: 0 -651px; + } + + .ke-icon-italic { + background-position: 0 -672px; + } + + .ke-icon-underline { + background-position: 0 -693px; + } + + .ke-icon-strikethrough { + background-position: 0 -714px; + } + + .ke-icon-removeformat { + background-position: 0 -756px; + } + + .ke-icon-image { + background-position: 0 -777px; + } + + .ke-icon-flash { + background-position: 0 -840px; + } + + .ke-icon-media { + background-position: 0 -861px; + } + + .ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; + } + + .ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; + } + + .ke-icon-hr { + background-position: 0 -924px; + } + + .ke-icon-emoticons { + background-position: 0 -945px; + } + + .ke-icon-link { + background-position: 0 -1008px; + } + + .ke-icon-unlink { + background-position: 0 -1029px; + } + + .ke-icon-fullscreen { + background-position: 0 -525px; + } + + .ke-icon-about { + background-position: 0 -1092px; + } + + .ke-icon-quote { + background-position: 0 -1114px; + } + + .ke-icon-plainpaste { + background-position: 0 -210px; + } + + .ke-icon-wordpaste { + background-position: 0 -231px; + } + + .ke-icon-table { + background-position: 0px -903px; + width: 18px !important; + } + + .ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; + } + + .ke-icon-code { + background-position: 0 -126px; + } + + .ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; + } + + .ke-icon-baidumap { + background-position: 0 -1050px; + } + + .ke-icon-lineheight { + background-position: 0 -735px; + } + + .ke-icon-clearhtml { + background-position: 0 -462px; + } + + .ke-icon-pagebreak { + background-position: 0 -966px; + } + + .ke-icon-insertfile { + background-position: 0 -882px; + } + + .ke-icon-quickformat { + background-position: 0 -504px; + } + + .ke-icon-anchor { + background-position: 0 -987px; + } + + .ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; + } + + .ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; + } + + .ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; + } + + .ke-icon-multiimage { + background-position: 0 -798px; + } + + .ke-icon-graft { + background-position: 0 -819px; + } + } +} + +/** + menu 右键菜单 + */ +.ke-menu-blue { + + .ke-menu-item { + + .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; + + .ke-toolbar-icon { + @include ke-toolbar-icon; + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; + } + + .ke-icon-tableinsert { + background-position: 0 -903px; + width: 18px !important; + } + + .ke-icon-tabledelete { + background-position: 0 -1428px; + } + + .ke-icon-tablecolinsertleft { + background-position: 0 -1176px; + width: 18px !important; + } + + .ke-icon-tablecolinsertright { + background-position: 0 -1323px; + width: 18px !important; + } + + .ke-icon-tablerowinsertabove { + background-position: 0 -1302px; + width: 22px !important; + } + + .ke-icon-tablerowinsertbelow { + background-position: 0 -1155px; + width: 22px !important; + } + + .ke-icon-tablecoldelete { + background-position: 0 -1239px; + } + + .ke-icon-tablerowdelete { + background-position: 0 -1260px; + } + + .ke-icon-tablecellprop { + background-position: 0 -1218px; + } + + .ke-icon-tableprop { + background-position: 0 -1134px; + } + .ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; + } + + .ke-icon-tablerowmerge { + background-position: -1px -1197px; + } + + .ke-icon-tablerowsplit { + background-position: 0 -1344px; + } + + .ke-icon-tablecolmerge { + background-position: -4px -1365px; + } + + .ke-icon-tablecolsplit { + background-position: 0 -1344px; + } + + //图片,视频右键菜单 + .ke-icon-image { + background-position: 0 -777px; + } + .ke-icon-flash { + background-position: 0 -840px; + } + .ke-icon-media { + background-position: 0 -861px; + } + .ke-icon-link { + background-position: 0 -1008px; + } + + .ke-icon-checked { + background-position: 0 -1407px; + } + + } + } +} +//menu end \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/blue/images/nkeditor.png b/addons/nkeditor/assets/themes/blue/images/nkeditor.png new file mode 100644 index 0000000000000000000000000000000000000000..6cf968ade12c3fbac92a5c61aea3f847c2c1e827 Binary files /dev/null and b/addons/nkeditor/assets/themes/blue/images/nkeditor.png differ diff --git a/addons/nkeditor/assets/themes/blue/images/nkeditor.svg b/addons/nkeditor/assets/themes/blue/images/nkeditor.svg new file mode 100644 index 0000000000000000000000000000000000000000..5f1245339a454f13dbf51a0da342a13fef27a980 --- /dev/null +++ b/addons/nkeditor/assets/themes/blue/images/nkeditor.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/nkeditor/assets/themes/common/anchor.gif b/addons/nkeditor/assets/themes/common/anchor.gif new file mode 100644 index 0000000000000000000000000000000000000000..61145ea78138f12df43b666409bcc4b8e3231a60 Binary files /dev/null and b/addons/nkeditor/assets/themes/common/anchor.gif differ diff --git a/addons/nkeditor/assets/themes/common/blank.gif b/addons/nkeditor/assets/themes/common/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..5bfd67a2d6f72ac3a55cbfcea5866e841d22f5d9 Binary files /dev/null and b/addons/nkeditor/assets/themes/common/blank.gif differ diff --git a/addons/nkeditor/assets/themes/common/common.css b/addons/nkeditor/assets/themes/common/common.css new file mode 100644 index 0000000000000000000000000000000000000000..a92c5dede846337a676e7f6377f6b836cb6fb768 --- /dev/null +++ b/addons/nkeditor/assets/themes/common/common.css @@ -0,0 +1,605 @@ +@charset "UTF-8"; +/** +公共样式 +*/ +.ke-clearfix { + zoom: 1; + clear: both; } + +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; } + +.ke-animated { + animation: zoomIn; + animation-duration: 0.3s; + animation-fill-mode: both; } + +@keyframes zoomIn { + from { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); } + 50% { + opacity: 1; } } +.ke-dialog-mask { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; } + +.ke-dialog-lock { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; + z-index: 811213; + left: 0; + top: 0; + position: absolute; } + +/** +编辑器样式开始 + */ +.ke-container { + display: block; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + /** + 通用样式 + */ + /** + toolbar 样式 + */ + /** + ke-edit + */ + /** + statusbar start + */ } + .ke-container .ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + background-color: #F0F0EE; } + .ke-container .ke-menu a, + .ke-container .ke-menu a:hover, + .ke-container .ke-dialog a, + .ke-container .ke-dialog a:hover { + color: #337FE5; + text-decoration: none; } + .ke-container .ke-toolbar { + text-align: left; + overflow: hidden; + zoom: 1; + padding: 0px 5px; } + .ke-container .ke-toolbar .ke-outline { + padding: 10px 5px; + font-size: 0; + line-height: 0; + cursor: pointer; + display: block; + float: left; + /** + * 按钮通用样式 + */ } + .ke-container .ke-toolbar .ke-outline .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; } + .ke-container .ke-toolbar .ke-on { + background: #ebebeb; } + .ke-container .ke-toolbar .ke-selected { + background-color: #ebebeb; } + .ke-container .ke-toolbar .ke-disabled { + cursor: default; } + .ke-container .ke-toolbar .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; } + .ke-container .ke-toolbar .ke-hr { + clear: both; + height: 1px; + width: calc(100% - (2 * 2px)); + background: #ebebeb; } + .ke-container .ke-edit { + padding: 0; } + .ke-container .ke-edit .ke-edit-iframe, + .ke-container .ke-edit .ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; } + .ke-container .ke-edit .ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; } + .ke-container .ke-edit .ke-edit-textarea:focus { + outline: none; } + .ke-container .ke-statusbar { + position: relative; + background-color: #f5f5f5; + border-top: 1px solid #e1e1e1; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; + display: none; } + .ke-container .ke-statusbar .ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; } + .ke-container .ke-statusbar .ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + width: 11px; + height: 11px; } + +/** + menu 右键菜单 + */ +.ke-menu { + border: 1px solid #cccccc; + background-color: #f5f5f5; + color: #222222; + padding: 2px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; + /** + 表情插件 + */ } + .ke-menu .ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; } + .ke-menu .ke-menu-item .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-inline-block .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; } + .ke-menu .ke-menu-item .ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; } + .ke-menu .ke-menu-item .ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: 1px solid #e1e1e1; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; } + .ke-menu .ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons { + position: relative; } + .ke-menu .ke-plugin-emoticons .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; } + .ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img { + border: 0; + margin: 0; + padding: 0; } + .ke-menu .ke-plugin-emoticons .ke-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell { + margin: 0; + padding: 1px; + border: 1px solid #f5f5f5; + cursor: pointer; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img { + display: block; + background-repeat: no-repeat; + overflow: hidden; + margin: 2px; + width: 24px; + height: 24px; + margin: 0; + padding: 0; + border: 0; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + color: #333; + text-decoration: none; } + +/** + colorpicker + */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; } + .ke-colorpicker .ke-colorpicker-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin: 3px; + padding: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top { + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F1F1F1; + cursor: pointer; + margin: 0; + padding: 0; + text-align: center; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on { + border: 1px solid #5690D2; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected { + border: 1px solid #2446AB; } + +/** + dialog + */ +.ke-dialog { + margin: 0; + padding: 0; + border: 1px solid #cccccc; + zoom: 1; + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + overflow: hidden; } + .ke-dialog .ke-dialog-header { + border: 0; + margin: 0; + font-weight: bold; + font-size: 14px; + height: 30px; + line-height: 30px; + padding: 0px 10px; + text-align: left; + color: #222; + cursor: move; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-bottom: 1px solid #c6c6c6; + background: transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0; + position: relative; + cursor: move; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close { + height: 20px; + width: 20px; + cursor: pointer; + background: url("../common/icons-all.gif") 0 -59px; + position: absolute; + right: 5px; + top: 4px; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover { + background-position: 0px -89px; } + .ke-dialog .ke-dialog-content { + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + outline: 0; + zoom: 1; } + .ke-dialog .ke-dialog-content .ke-dialog-body { + font: 12px/1.5 "sans serif", tahoma, verdana, helvetica; + text-align: left; + overflow: hidden; + width: 100%; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + border: 1px solid #cccccc; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus { + border-color: #66afe9; + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; + border: 1px solid #cccccc; + height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-form { + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number { + width: 50px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox { + position: relative; + top: 6px; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus { + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text { + display: inline-block !important; + max-width: 400px; + height: 30px; + line-height: 30px; + border: 1px solid #cccccc; + font-size: 14px; + margin: 0; + outline: 0; + padding: 0px 10px; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus { + border-color: #66afe9; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color { + border: 1px solid #e1e1e1; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 30px; + line-height: 30px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + top: -1px; + position: relative; + *height: 25px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + cursor: pointer; + width: 62px; + height: 30px; + filter: alpha(opacity=0); } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common { + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button { + padding: 8px 15px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner { + padding: 10px 20px 0px 20px; + /** + tabs + */ } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row { + border: 1px solid #FFFFFF; + margin-bottom: 10px; + overflow: hidden; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left { + float: left; + height: 30px; + line-height: 30px; + width: 60px; + text-align: right; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right { + float: left; + text-align: left; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button { + position: relative; + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label { + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + text-align: right; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header { + height: 30px; + line-height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text { + height: 22px; + line-height: 22px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button { + padding: 3px 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox { + margin-left: 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + border-bottom: 1px solid #e1e1e1; + margin-bottom: 20px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul { + list-style: none outside none; + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li { + position: relative; + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #337ab7; + cursor: pointer; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected { + background-color: #FFF; + border: 1px solid #e1e1e1; + border-bottom: 1px solid #FFF; + color: #555555; + cursor: default; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on { + background-color: #FFF; + color: #000; } + .ke-dialog .ke-dialog-content .ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; } + .ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat center; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; } + .ke-dialog .ke-dialog-footer { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + text-align: right; + padding: 0 15px 5px 0; + background-color: #FFF; + height: 40px; } + .ke-dialog .ke-dialog-footer .ke-dialog-yes { + margin: 5px; } + .ke-dialog .ke-dialog-footer .ke-dialog-no { + margin: 5px 10px 5px 5px; } + .ke-dialog .ke-button-common { + display: inline-block; + text-align: center; + background: none; + border: none; + padding: 0; + cursor: pointer; } + .ke-dialog .ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-button { + color: #333; + font-size: 12px; + border: 1px solid #e6e6e6; + background-color: #e6e6e6; + padding: 7px 10px; + margin-top: -4px; + color: #444; + text-decoration: none; + transition: background-color .3s ease-out, border-color .3s ease-out; } + .ke-dialog .ke-button:hover { + border: 1px solid #e1e1e1; + background-color: #e1e1e1; } + .ke-dialog .ke-dialog-btn { + font-size: 12px; + margin: 5px; + background: #2e8ded; + color: #fff !important; + padding: 8px 12px; + display: inline-block; + border-radius: 2px; + cursor: pointer; + text-decoration: none; + transition: .3s ease-out; } + .ke-dialog .ke-dialog-btn:hover { + filter: alpha(opacity=80); + box-shadow: none; + box-shadow: none; + opacity: .8; } + +/*# sourceMappingURL=common.css.map */ diff --git a/addons/nkeditor/assets/themes/common/common.scss b/addons/nkeditor/assets/themes/common/common.scss new file mode 100644 index 0000000000000000000000000000000000000000..5e8549b12b39d2475eb998da951768063f7e4080 --- /dev/null +++ b/addons/nkeditor/assets/themes/common/common.scss @@ -0,0 +1,830 @@ +$inputBorderColor : #cccccc; +$inputFocusBorderColor : #66afe9; +$inputHeight : 30px; +$editorBorderStyle : 1px solid #e1e1e1; +$dialogBorderStyle : 1px solid #cccccc; +$menuBgColor : #f5f5f5; + +@mixin ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +//工具栏图标样式 +@mixin ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; +} +//阴影 +@mixin ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); +} + +/** +公共样式 +*/ +//清除浮动 +.ke-clearfix { + zoom: 1; + clear: both; +} +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; +} +// 过渡动画 +.ke-animated { + animation: zoomIn; + animation-duration: 0.3s; + animation-fill-mode: both; +} +@keyframes zoomIn { + from { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); + } + 50% { + opacity: 1; + } +} + +//遮罩层 +.ke-dialog-mask { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; +} +.ke-dialog-lock { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; + z-index: 811213; + left: 0; + top: 0; + position: absolute; +} + +/** +编辑器样式开始 + */ +.ke-container { + + display: block; + //border: $editorBorderStyle; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; + box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 1px 1px rgba(0,0,0,0.16); + + /** + 通用样式 + */ + .ke-shadow { + @include ke-shadow; + background-color: #F0F0EE; + } + + .ke-menu a, + .ke-menu a:hover, + .ke-dialog a, + .ke-dialog a:hover { + color: #337FE5; + text-decoration: none; + } + + /** + toolbar 样式 + */ + .ke-toolbar { + //border-bottom: $editorBorderStyle; + text-align: left; + overflow: hidden; + zoom: 1; + padding: 0px 5px; + + .ke-outline { + //border: 1px solid #f5f5f5; + padding: 10px 5px; + font-size: 0; + line-height: 0; + cursor: pointer; + display: block; + float: left; + + /** + * 按钮通用样式 + */ + .ke-toolbar-icon { + @include ke-toolbar-icon; + } + + } + + .ke-on { + background: #ebebeb; + } + .ke-selected { + background-color: #ebebeb; + } + .ke-disabled { + cursor: default; + } + .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; + } + .ke-hr { + clear: both; + height: 1px; + width: calc(100% - (2 * 2px)); + background: #ebebeb; + } + } + //end ke-toolbar + + /** + ke-edit + */ + .ke-edit { + padding: 0; + + .ke-edit-iframe, + .ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; + } + .ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; + + &:focus { + outline: none; + } + } + } + //end ke-edit + + /** + statusbar start + */ + .ke-statusbar { + position: relative; + background-color: #f5f5f5; + border-top: $editorBorderStyle; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; + display: none; + + .ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; + } + + .ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + width: 11px; + height: 11px; + } + } + //end ke-statusbar +} + +/** + menu 右键菜单 + */ +.ke-menu { + border: $dialogBorderStyle; + background-color: $menuBgColor; + color: #222222; + padding: 2px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; + + .ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; + + .ke-inline-block { + @include ke-inline-block; + + .ke-inline-block { + @include ke-inline-block; + } + } + + .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; + + + } + + .ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; + } + + .ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; + } + + .ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; + } + + .ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: $editorBorderStyle; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; + } + } + + .ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; + } + + /** + 表情插件 + */ + .ke-plugin-emoticons { + position: relative; + + .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; + + .ke-preview-img { + border: 0; + margin: 0; + padding: 0; + } + } //end ke-preview + + .ke-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; + + .ke-cell { + margin: 0; + padding: 1px; + border: 1px solid #f5f5f5; + cursor: pointer; + + .ke-img { + display: block; + background-repeat: no-repeat; + overflow: hidden; + margin: 2px; + width: 24px; + height: 24px; + margin: 0; + padding: 0; + border: 0; + } + } + .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; + } + } //end ke-table + + .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + color: #333; + text-decoration: none; + } + } + +} +//menu end + +/** + colorpicker + */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; + + .ke-colorpicker-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; + + .ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin: 3px; + padding: 0; + + .ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; + } + } + .ke-colorpicker-cell-top { + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F1F1F1; + cursor: pointer; + margin: 0; + padding: 0; + text-align: center; + } + .ke-colorpicker-cell-on { + border: 1px solid #5690D2; + } + .ke-colorpicker-cell-selected { + border: 1px solid #2446AB; + } + + } +} //colorpicker end + +/** + dialog + */ +.ke-dialog { + margin: 0; + padding: 0; + border: $dialogBorderStyle; + zoom: 1; + @include ke-shadow; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + overflow: hidden; + + // start ke-dialog-header + .ke-dialog-header { + border: 0; + margin: 0; + font-weight: bold; + font-size: 14px; + height: 30px; + line-height: 30px; + padding: 0px 10px; + text-align: left; + color: #222; + cursor: move; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-bottom: 1px solid #c6c6c6; + background: transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0; + position: relative; + cursor: move; + + .ke-dialog-icon-close { + height: 20px; + width: 20px; + cursor: pointer; + background: url("../common/icons-all.gif") 0 -59px; + position: absolute; + right: 5px; + top: 4px; + + &:hover { + background-position: 0px -89px; + } + } + + } //end ke-dialog-header + + //start ke-content + .ke-dialog-content { + + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + outline: 0; + zoom: 1; + + // ke-dialog-body start + .ke-dialog-body { + font: 12px/1.5 "sans serif", tahoma, verdana, helvetica; + text-align: left; + overflow: hidden; + width: 100%; + + .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + border: 1px solid $inputBorderColor; + + &:focus { + border-color: $inputFocusBorderColor; + outline: none; + } + } + + .ke-select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; + border: 1px solid $inputBorderColor; + height: $inputHeight; + } + .ke-form { + margin: 0; + padding: 0; + } + + .ke-input-number { + width: 50px; + } + + .ke-input-checkbox { + position: relative; + top:6px; + } + + textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; + + &:focus { + outline: none; + } + } + + .ke-input-text { + display: inline-block !important; + max-width: 400px; + height: $inputHeight; + line-height: $inputHeight; + border:1px solid $inputBorderColor; + font-size: 14px; + margin: 0; + outline: 0; + padding: 0px 10px; + *display: inline; + + &:focus { + border-color: $inputFocusBorderColor; + } + } + + .ke-input-color { + border: $editorBorderStyle; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 30px; + line-height: 30px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + } + + .ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + top:-1px; + position: relative; + *height: 25px; + + .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + cursor: pointer; + width: 62px; + height: 30px; + filter: alpha(opacity=0); + + } + + .ke-button-common { + top: -1px; + } + .ke-button { + padding: 8px 15px; + } + } + + .ke-dialog-content-inner { + padding: 10px 20px 0px 20px; + + .ke-dialog-row { + border:1px solid #FFFFFF; + margin-bottom: 10px; + overflow: hidden; + + .row-left { + float: left; + height: 30px; + line-height: 30px; + width: 60px; + text-align: right; + } + .row-right { + float: left; + text-align: left; + + .ke-inline-block { + @include ke-inline-block; + + .ke-upload-button { + position: relative; + top: -1px; + } + } + + label { + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + text-align: right; + zoom: 1; + *display: inline; + + img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + } + } + } + + + } //end ke-dialog-row + + //百度地图样式 + .ke-header { + height: 30px; + line-height: 30px; + + .ke-input-text { + height: 22px; + line-height: 22px; + } + .ke-button { + padding: 3px 10px; + } + .checkbox { + margin-left:10px; + } + } + + /** + tabs + */ + .ke-tabs { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + border-bottom: $editorBorderStyle; + margin-bottom: 20px; + + .ke-tabs-ul { + list-style: none outside none; + margin: 0; + padding: 0; + + .ke-tabs-li { + position: relative; + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #337ab7; + cursor: pointer; + } + .ke-tabs-li-selected { + background-color: #FFF; + border: $editorBorderStyle; + border-bottom: 1px solid #FFF; + color: #555555; + cursor: default; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + } + + .ke-tabs-li-on { + background-color: #FFF; + color: #000; + } + } //end ul + } //end tabs + + } //end ke-dialog-content-inner + + + } // end ke-dialog-body + + .ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; + + .ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat center; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; + } + } //end ke-dialog-loading + + } //end ke-content + + .ke-dialog-footer { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + text-align: right; + padding: 0 15px 5px 0; + background-color: #FFF; + height: 40px; + + .ke-dialog-yes { + margin: 5px; + } + + .ke-dialog-no { + margin: 5px 10px 5px 5px; + } + } // ke-dialog-footer + + .ke-button-common { + display: inline-block; + text-align: center; + background: none; + border: none; + padding: 0; + cursor: pointer; + } + + .ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + } + + .ke-button { + color: #333; + font-size: 12px; + border: 1px solid #e6e6e6; + background-color: #e6e6e6; + padding: 7px 10px; + margin-top: -4px; + color: #444; + text-decoration: none; + transition: background-color .3s ease-out, border-color .3s ease-out; + + &:hover { + border: $editorBorderStyle; + background-color: #e1e1e1; + } + } + + .ke-dialog-btn { + font-size: 12px; + margin: 5px; + background: #2e8ded; + color: #fff !important; + padding: 8px 12px; + display: inline-block; + border-radius: 2px; + cursor: pointer; + text-decoration: none; + transition: .3s ease-out; + + &:hover { + filter: alpha(opacity=80); + box-shadow: none; + box-shadow: none; + opacity: .8; + } + } + + +} //dialog end + +//.ke-dialog-preview { +// margin: 5px; +//} + + +//.ke-plugin-plainpaste-textarea, +//.ke-plugin-wordpaste-iframe { +// display: block; +// width: 408px; +// height: 260px; +// font-family: "sans serif", tahoma, verdana, helvetica; +// font-size: 12px; +// border-color: #848484 #E0E0E0 #E0E0E0 #848484; +// border-style: solid; +// border-width: 1px; +//} + + diff --git a/addons/nkeditor/assets/themes/common/dialog-title-bg.png b/addons/nkeditor/assets/themes/common/dialog-title-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..f744f267f797ebf9993b746ecaff21b85d556e83 Binary files /dev/null and b/addons/nkeditor/assets/themes/common/dialog-title-bg.png differ diff --git a/addons/nkeditor/assets/themes/common/flash.gif b/addons/nkeditor/assets/themes/common/flash.gif new file mode 100644 index 0000000000000000000000000000000000000000..2cb12b28429f8c2e5294a177e14dfda6f533e6fc Binary files /dev/null and b/addons/nkeditor/assets/themes/common/flash.gif differ diff --git a/addons/nkeditor/assets/themes/common/flash.png b/addons/nkeditor/assets/themes/common/flash.png new file mode 100644 index 0000000000000000000000000000000000000000..cc3be67ca5d55dce91a4966b629ee10e07387799 Binary files /dev/null and b/addons/nkeditor/assets/themes/common/flash.png differ diff --git a/addons/nkeditor/assets/themes/common/flash.svg b/addons/nkeditor/assets/themes/common/flash.svg new file mode 100644 index 0000000000000000000000000000000000000000..31750f27ab3dd7a73f16189940464468cf698e35 --- /dev/null +++ b/addons/nkeditor/assets/themes/common/flash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/common/icons-all.gif b/addons/nkeditor/assets/themes/common/icons-all.gif new file mode 100644 index 0000000000000000000000000000000000000000..21915e59dede0aa22cda8c7097a14f0f1f68906c Binary files /dev/null and b/addons/nkeditor/assets/themes/common/icons-all.gif differ diff --git a/addons/nkeditor/assets/themes/common/loading.gif b/addons/nkeditor/assets/themes/common/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..c69e937232b24ea30f01c68bbd2ebc798dcecfcb Binary files /dev/null and b/addons/nkeditor/assets/themes/common/loading.gif differ diff --git a/addons/nkeditor/assets/themes/common/media.gif b/addons/nkeditor/assets/themes/common/media.gif new file mode 100644 index 0000000000000000000000000000000000000000..e1c0e30afb2587f6d4ed4f8bd90bd4f865a98aa6 Binary files /dev/null and b/addons/nkeditor/assets/themes/common/media.gif differ diff --git a/addons/nkeditor/assets/themes/common/play.png b/addons/nkeditor/assets/themes/common/play.png new file mode 100644 index 0000000000000000000000000000000000000000..7899c5a4190d9041719cabbe10cf7f7a53053cdc Binary files /dev/null and b/addons/nkeditor/assets/themes/common/play.png differ diff --git a/addons/nkeditor/assets/themes/common/play.svg b/addons/nkeditor/assets/themes/common/play.svg new file mode 100644 index 0000000000000000000000000000000000000000..8d5cd9a98aab0cb9204811930693cd3fa4273aee --- /dev/null +++ b/addons/nkeditor/assets/themes/common/play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/common/rm.gif b/addons/nkeditor/assets/themes/common/rm.gif new file mode 100644 index 0000000000000000000000000000000000000000..d013d551de909a5588a7d81be96aba60089a846b Binary files /dev/null and b/addons/nkeditor/assets/themes/common/rm.gif differ diff --git a/addons/nkeditor/assets/themes/default/editor.css b/addons/nkeditor/assets/themes/default/editor.css new file mode 100644 index 0000000000000000000000000000000000000000..8518512e922ea5d86f062d6e29737a3159c9d60d --- /dev/null +++ b/addons/nkeditor/assets/themes/default/editor.css @@ -0,0 +1,1398 @@ +/* common */ +.ke-animated { + animation: zoomIn; + animation-duration: 0.3s; + animation-fill-mode: both; } + +@keyframes zoomIn { + from { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); } + 50% { + opacity: 1; } } + +.ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} + +.ke-clearfix { + zoom: 1; +} + +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; +} + +.ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + background-color: #F0F0EE; +} + +.ke-menu a, +.ke-menu a:hover, +.ke-dialog a, +.ke-dialog a:hover { + color: #337FE5; + text-decoration: none; +} + +/* icons */ +.ke-icon-source { + background-position: 0px 0px; + width: 16px; + height: 16px; +} + +.ke-icon-preview { + background-position: 0px -16px; + width: 16px; + height: 16px; +} + +.ke-icon-print { + background-position: 0px -32px; + width: 16px; + height: 16px; +} + +.ke-icon-undo { + background-position: 0px -48px; + width: 16px; + height: 16px; +} + +.ke-icon-redo { + background-position: 0px -64px; + width: 16px; + height: 16px; +} + +.ke-icon-cut { + background-position: 0px -80px; + width: 16px; + height: 16px; +} + +.ke-icon-copy { + background-position: 0px -96px; + width: 16px; + height: 16px; +} + +.ke-icon-paste { + background-position: 0px -112px; + width: 16px; + height: 16px; +} + +.ke-icon-selectall { + background-position: 0px -128px; + width: 16px; + height: 16px; +} + +.ke-icon-justifyleft { + background-position: 0px -144px; + width: 16px; + height: 16px; +} + +.ke-icon-justifycenter { + background-position: 0px -160px; + width: 16px; + height: 16px; +} + +.ke-icon-justifyright { + background-position: 0px -176px; + width: 16px; + height: 16px; +} + +.ke-icon-justifyfull { + background-position: 0px -192px; + width: 16px; + height: 16px; +} + +.ke-icon-insertorderedlist { + background-position: 0px -208px; + width: 16px; + height: 16px; +} + +.ke-icon-insertunorderedlist { + background-position: 0px -224px; + width: 16px; + height: 16px; +} + +.ke-icon-indent { + background-position: 0px -240px; + width: 16px; + height: 16px; +} + +.ke-icon-outdent { + background-position: 0px -256px; + width: 16px; + height: 16px; +} + +.ke-icon-subscript { + background-position: 0px -272px; + width: 16px; + height: 16px; +} + +.ke-icon-superscript { + background-position: 0px -288px; + width: 16px; + height: 16px; +} + +.ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; +} + +.ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; +} + +.ke-icon-formatblock { + background-position: 0px -336px; + width: 25px; + height: 16px; +} + +.ke-icon-fontname { + background-position: 0px -352px; + width: 21px; + height: 16px; +} + +.ke-icon-fontsize { + background-position: 0px -368px; + width: 23px; + height: 16px; +} + +.ke-icon-forecolor { + background-position: 0px -384px; + width: 20px; + height: 16px; +} + +.ke-icon-hilitecolor { + background-position: 0px -400px; + width: 23px; + height: 16px; +} + +.ke-icon-bold { + background-position: 0px -416px; + width: 16px; + height: 16px; +} + +.ke-icon-italic { + background-position: 0px -432px; + width: 16px; + height: 16px; +} + +.ke-icon-underline { + background-position: 0px -448px; + width: 16px; + height: 16px; +} + +.ke-icon-strikethrough { + background-position: 0px -464px; + width: 16px; + height: 16px; +} + +.ke-icon-removeformat { + background-position: 0px -480px; + width: 16px; + height: 16px; +} + +.ke-icon-image { + background-position: 0px -496px; + width: 16px; + height: 16px; +} + +.ke-icon-flash { + background-position: 0px -512px; + width: 16px; + height: 16px; +} + +.ke-icon-media { + background-position: 0px -528px; + width: 16px; + height: 16px; +} + +.ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; +} + +.ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; +} + +.ke-icon-hr { + background-position: 0px -592px; + width: 16px; + height: 16px; +} + +.ke-icon-emoticons { + background-position: 0px -608px; + width: 16px; + height: 16px; +} + +.ke-icon-link { + background-position: 0px -624px; + width: 16px; + height: 16px; +} + +.ke-icon-unlink { + background-position: 0px -640px; + width: 16px; + height: 16px; +} + +.ke-icon-fullscreen { + background-position: 0px -656px; + width: 16px; + height: 16px; +} + +.ke-icon-about { + background-position: 0px -672px; + width: 16px; + height: 16px; +} + +.ke-icon-plainpaste { + background-position: 0px -704px; + width: 16px; + height: 16px; +} + +.ke-icon-wordpaste { + background-position: 0px -720px; + width: 16px; + height: 16px; +} + +.ke-icon-table { + background-position: 0px -784px; + width: 16px; + height: 16px; +} + +.ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; +} + +.ke-icon-tableinsert { + background-position: 0px -784px; + width: 16px; + height: 16px; +} + +.ke-icon-tabledelete { + background-position: 0px -800px; + width: 16px; + height: 16px; +} + +.ke-icon-tablecolinsertleft { + background-position: 0px -816px; + width: 16px; + height: 16px; +} + +.ke-icon-tablecolinsertright { + background-position: 0px -832px; + width: 16px; + height: 16px; +} + +.ke-icon-tablerowinsertabove { + background-position: 0px -848px; + width: 16px; + height: 16px; +} + +.ke-icon-tablerowinsertbelow { + background-position: 0px -864px; + width: 16px; + height: 16px; +} + +.ke-icon-tablecoldelete { + background-position: 0px -880px; + width: 16px; + height: 16px; +} + +.ke-icon-tablerowdelete { + background-position: 0px -896px; + width: 16px; + height: 16px; +} + +.ke-icon-tablecellprop { + background-position: 0px -912px; + width: 16px; + height: 16px; +} + +.ke-icon-tableprop { + background-position: 0px -928px; + width: 16px; + height: 16px; +} + +.ke-icon-checked { + background-position: 0px -944px; + width: 16px; + height: 16px; +} + +.ke-icon-code { + background-position: 0px -960px; + width: 16px; + height: 16px; +} + +.ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; +} + +.ke-icon-baidumap { + background-position: 0px -976px; + width: 16px; + height: 16px; +} + +.ke-icon-lineheight { + background-position: 0px -992px; + width: 16px; + height: 16px; +} + +.ke-icon-clearhtml { + background-position: 0px -1008px; + width: 16px; + height: 16px; +} + +.ke-icon-pagebreak { + background-position: 0px -1024px; + width: 16px; + height: 16px; +} + +.ke-icon-insertfile { + background-position: 0px -1040px; + width: 16px; + height: 16px; +} + +.ke-icon-quickformat { + background-position: 0px -1056px; + width: 16px; + height: 16px; +} + +.ke-icon-template { + background-position: 0px -1072px; + width: 16px; + height: 16px; +} + +.ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; +} + +.ke-icon-tablerowmerge { + background-position: 0px -1104px; + width: 16px; + height: 16px; +} + +.ke-icon-tablerowsplit { + background-position: 0px -1120px; + width: 16px; + height: 16px; +} + +.ke-icon-tablecolmerge { + background-position: 0px -1136px; + width: 16px; + height: 16px; +} + +.ke-icon-tablecolsplit { + background-position: 0px -1152px; + width: 16px; + height: 16px; +} + +.ke-icon-anchor { + background-position: 0px -1168px; + width: 16px; + height: 16px; +} + +.ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; +} + +.ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; +} + +.ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; +} + +.ke-icon-multiimage { + background-position: 0px -1232px; + width: 16px; + height: 16px; +} + +.ke-icon-graft { + background: url("images/scrawl.png") !important; + width: 16px; + height: 16px; +} + +/* container */ +.ke-container { + display: block; + border: 1px solid #CCCCCC; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; +} + +/* toolbar */ +.ke-toolbar { + border-bottom: 1px solid #CCC; + background-color: #FFFFFF; + padding: 2px 5px; + text-align: left; + overflow: hidden; + zoom: 1; +} + +.ke-toolbar-icon { + background-repeat: no-repeat; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; +} + +.ke-toolbar-icon-url { + background-image: url(images/default.png); +} + +.ke-toolbar .ke-outline { + border: 1px solid #F0F0EE; + margin: 1px; + padding: 1px 2px; + font-size: 0; + line-height: 0; + cursor: pointer; + display: block; + float: left; +} + +.ke-toolbar .ke-on { + border: 1px solid #5690D2; +} + +.ke-toolbar .ke-selected { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} + +.ke-toolbar .ke-disabled { + cursor: default; +} + +.ke-toolbar .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; +} + +.ke-toolbar .ke-hr { + overflow: hidden; + height: 1px; + clear: both; +} + +/* edit */ +.ke-edit { + padding: 0; +} + +.ke-edit-iframe, +.ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; +} + +.ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; +} + +.ke-edit-textarea:focus { + outline: none; +} + +/* statusbar */ +.ke-statusbar { + position: relative; + background-color: #F0F0EE; + border-top: 1px solid #CCCCCC; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; +} + +.ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; + background-image: url(images/default.png); +} + +.ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + background-position: -5px -741px; + width: 11px; + height: 11px; + background-image: url(images/default.png); +} + +/* menu */ +.ke-menu { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; +} + +.ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; +} + +.ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} + +.ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; +} + +.ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; +} + +.ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; +} + +.ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; +} + +.ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: 1px solid #CCCCCC; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; +} + +/* colorpicker */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; +} + +.ke-colorpicker-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; +} + +.ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin: 3px; + padding: 0; +} + +.ke-colorpicker-cell-top { + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F0F0EE; + cursor: pointer; + margin: 0; + padding: 0; + text-align: center; +} + +.ke-colorpicker-cell-on { + border: 1px solid #5690D2; +} + +.ke-colorpicker-cell-selected { + border: 1px solid #2446AB; +} + +.ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; +} + +/* dialog */ +.ke-dialog { + position: absolute; + margin: 0; + padding: 0; +} + +.ke-dialog .ke-header { + width: 100%; + margin-bottom: 10px; +} + +.ke-dialog .ke-header .ke-left { + float: left; +} + +.ke-dialog .ke-header .ke-right { + float: right; +} + +.ke-dialog .ke-header label { + margin-right: 0; + cursor: pointer; + font-weight: normal; + display: inline; + vertical-align: top; +} + +.ke-dialog-content { + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + outline: 0; +} + +.ke-dialog-header { + border: 0; + margin: 0; + font-weight: bold; + font-size: 14px; + background: #F8F8F8; + border-bottom: 1px solid #eeeeee; + height: 30px; + line-height: 30px; + padding: 0px 10px; + text-align: left; + color: #222; + cursor: move; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + +} + +.ke-dialog-icon-close { + display: block; + background: url(images/default.png) no-repeat scroll 0px -688px; + width: 16px; + height: 16px; + position: absolute; + right: 6px; + top: 8px; + cursor: pointer; +} + +.ke-dialog-body { + font: 12px/1.5 "sans serif", tahoma, verdana, helvetica; + text-align: left; + overflow: hidden; + width: 100%; +} + +.ke-dialog-body textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; +} + +.ke-dialog-body textarea:focus, +.ke-dialog-body input:focus, +.ke-dialog-body select:focus { + outline: none; +} + +.ke-dialog-body label { + margin-right: 10px; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + text-align: right; + zoom: 1; + *display: inline; +} + +.ke-dialog-body img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} + +.ke-dialog-body select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; +} + +.ke-dialog-body .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; +} + +.ke-dialog-body .ke-form { + margin: 0; + padding: 0; +} + +.ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; +} + +.ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; +} + +.ke-dialog-row { + margin-bottom: 10px; +} + +.ke-dialog-footer { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + text-align: right; + padding: 0 15px 5px 0; + background-color: #FFF; + border-radius: 6px; + height: 45px; +} + +.ke-dialog-preview, +.ke-dialog-yes { + margin: 5px; +} + +.ke-dialog-no { + margin: 5px 10px 5px 5px; +} + +.ke-dialog-mask { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; +} + +.ke-button-common { + display: inline-block; + text-align: center; + background: none; + border: none; + padding: 0; + cursor: pointer; +} + +.ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} + +.ke-button { + color: #333; + font-size: 12px; + border: 1px solid #e6e6e6; + background-color: #e6e6e6; + padding: 5px 10px; + margin-top: -2px; + color: #444; + text-decoration: none; + transition: background-color .3s ease-out, border-color .3s ease-out; +} + +.ke-button:hover { + border: 1px solid #d1d1d1; + background-color: #d1d1d1; +} + +.ke-dialog-btn { + font-size: 12px; + margin: 5px; + background: #2e8ded; + color: #fff !important; + padding: 8px 12px; + display: inline-block; + border-radius: 2px; + cursor: pointer; + text-decoration: none; + transition: .3s ease-out; +} + +.ke-dialog-btn:hover { + filter: alpha(opacity=80); + box-shadow: none; + box-shadow: none; + opacity: .8; +} + +/* inputbox */ +.ke-input-text { + display: inline-block !important; + width: 400px; + border: 1px solid #cccccc; + height: 20px; + line-height: 18px; + font-size: 14px; + padding: 3px; + margin: 0; + outline: 0; + *display: inline; +} + +.ke-input-text:focus { + border-color: #66afe9; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); +} + +.ke-input-number { + width: 50px; +} + +.ke-input-color { + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 20px; + line-height: 20px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} + +.ke-upload-button { + position: relative; + top: -1px; +} + +.ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + *height: 25px; +} + +.ke-upload-area .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + cursor: pointer; + width: 50px; + height: 30px; + filter: alpha(opacity=0); +} + +.ke-upload-area .ke-button { + padding: 6px 15px; +} + +/* tabs */ +.ke-tabs { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + border-bottom: 1px solid #cccccc; + padding-left: 5px; + margin-bottom: 20px; +} + +.ke-tabs-ul { + list-style-image: none; + list-style-position: outside; + list-style-type: none; + margin: 0; + padding: 0; +} + +.ke-tabs-li { + position: relative; + + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #337ab7; + cursor: pointer; +} + +.ke-tabs-li-selected { + background-color: #FFF; + border: 1px solid #cccccc; + border-bottom: 1px solid #FFF; + color: #555555; + cursor: default; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +.ke-tabs-li-on { + background-color: #FFF; + color: #000; +} + +/* progressbar */ +.ke-progressbar { + position: relative; + margin: 0; + padding: 0; +} + +.ke-progressbar-bar { + border: 1px solid #6FA5DB; + width: 80px; + height: 5px; + margin: 10px 10px 0 10px; + padding: 0; +} + +.ke-progressbar-bar-inner { + width: 0; + height: 5px; + background-color: #6FA5DB; + overflow: hidden; + margin: 0; + padding: 0; +} + +.ke-progressbar-percent { + position: absolute; + top: 0; + left: 40%; + display: none; +} + +/* swfupload */ +.ke-swfupload-top { + position: relative; + margin-bottom: 10px; + _width: 608px; +} + +.ke-swfupload-button { + height: 23px; + line-height: 23px; +} + +.ke-swfupload-desc { + padding: 0 10px; + height: 23px; + line-height: 23px; +} + +.ke-swfupload-startupload { + position: absolute; + top: 0; + right: 0; +} + +.ke-swfupload-body { + overflow: scroll; + background-color: #FFFFFF; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; + width: auto; + height: 370px; + padding: 5px; +} + +.ke-swfupload-body .ke-item { + width: 100px; + margin: 5px; +} + +.ke-swfupload-body .ke-photo { + position: relative; + border: 1px solid #DDDDDD; + background-color: #FFFFFF; + padding: 10px; +} + +.ke-swfupload-body .ke-delete { + display: block; + background: url(images/default.png) no-repeat scroll 0px -688px; + width: 16px; + height: 16px; + position: absolute; + right: 0; + top: 0; + cursor: pointer; +} + +.ke-swfupload-body .ke-status { + position: absolute; + left: 0; + bottom: 5px; + width: 100px; + height: 17px; +} + +.ke-swfupload-body .ke-message { + width: 100px; + text-align: center; + overflow: hidden; + height: 17px; +} + +.ke-swfupload-body .ke-error { + color: red; +} + +.ke-swfupload-body .ke-name { + width: 100px; + text-align: center; + overflow: hidden; + height: 16px; +} + +.ke-swfupload-body .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} + +/* emoticons */ +.ke-plugin-emoticons { + position: relative; +} + +.ke-plugin-emoticons .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; +} + +.ke-plugin-emoticons .ke-preview-img { + border: 0; + margin: 0; + padding: 0; +} + +.ke-plugin-emoticons .ke-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; +} + +.ke-plugin-emoticons .ke-cell { + margin: 0; + padding: 1px; + border: 1px solid #F0F0EE; + cursor: pointer; +} + +.ke-plugin-emoticons .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} + +.ke-plugin-emoticons .ke-img { + display: block; + background-repeat: no-repeat; + overflow: hidden; + margin: 2px; + width: 24px; + height: 24px; + margin: 0; + padding: 0; + border: 0; +} + +.ke-plugin-emoticons .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + color: #333; + text-decoration: none; +} + +.ke-plugin-plainpaste-textarea, +.ke-plugin-wordpaste-iframe { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; +} + +/* filemanager */ +.ke-plugin-filemanager-header { + width: 100%; + margin-bottom: 10px; +} + +.ke-plugin-filemanager-header .ke-left { + float: left; +} + +.ke-plugin-filemanager-header .ke-right { + float: right; +} + +.ke-plugin-filemanager-body { + overflow: scroll; + background-color: #FFFFFF; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; + width: auto; + height: 370px; + padding: 5px; +} + +.ke-plugin-filemanager-body .ke-item { + width: 100px; + margin: 5px; +} + +.ke-plugin-filemanager-body .ke-photo { + border: 1px solid #DDDDDD; + background-color: #FFFFFF; + padding: 10px; +} + +.ke-plugin-filemanager-body .ke-name { + width: 100px; + text-align: center; + overflow: hidden; + height: 16px; +} + +.ke-plugin-filemanager-body .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} + +.ke-plugin-filemanager-body .ke-table { + width: 95%; + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; +} + +.ke-plugin-filemanager-body .ke-table .ke-cell { + margin: 0; + padding: 0; + border: 0; +} + +.ke-plugin-filemanager-body .ke-table .ke-name { + width: 55%; + text-align: left; +} + +.ke-plugin-filemanager-body .ke-table .ke-size { + width: 15%; + text-align: left; +} + +.ke-plugin-filemanager-body .ke-table .ke-datetime { + width: 30%; + text-align: center; +} + +.ke-dialog-content-inner { + padding: 10px 20px; +} +.ke-dialog-content-inner .row-left { + float: left; +} +.ke-dialog-content-inner .row-right { + float: left; +} +.ke-dialog-default { + box-shadow: 0 5px 15px rgba(0, 0, 0, .2) !important; + border: 1px solid #999 !important; + border: 1px solid rgba(0, 0, 0, .2) !important; + border-radius: 6px; + outline: 0; + zoom: 1; + overflow: hidden; +} diff --git a/addons/nkeditor/assets/themes/default/editor.min.css b/addons/nkeditor/assets/themes/default/editor.min.css new file mode 100644 index 0000000000000000000000000000000000000000..cb8de2dbef99aeaca753106075d9b5d038642f2a --- /dev/null +++ b/addons/nkeditor/assets/themes/default/editor.min.css @@ -0,0 +1 @@ +.ke-animated{animation:zoomIn;animation-duration:.3s;animation-fill-mode:both}@keyframes zoomIn{from{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-clearfix{zoom:1}.ke-clearfix:after{content:".";display:block;clear:both;font-size:0;height:0;line-height:0;visibility:hidden}.ke-shadow{box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;background-color:#f0f0ee}.ke-dialog a,.ke-dialog a:hover,.ke-menu a,.ke-menu a:hover{color:#337fe5;text-decoration:none}.ke-icon-source{background-position:0 0;width:16px;height:16px}.ke-icon-preview{background-position:0 -16px;width:16px;height:16px}.ke-icon-print{background-position:0 -32px;width:16px;height:16px}.ke-icon-undo{background-position:0 -48px;width:16px;height:16px}.ke-icon-redo{background-position:0 -64px;width:16px;height:16px}.ke-icon-cut{background-position:0 -80px;width:16px;height:16px}.ke-icon-copy{background-position:0 -96px;width:16px;height:16px}.ke-icon-paste{background-position:0 -112px;width:16px;height:16px}.ke-icon-selectall{background-position:0 -128px;width:16px;height:16px}.ke-icon-justifyleft{background-position:0 -144px;width:16px;height:16px}.ke-icon-justifycenter{background-position:0 -160px;width:16px;height:16px}.ke-icon-justifyright{background-position:0 -176px;width:16px;height:16px}.ke-icon-justifyfull{background-position:0 -192px;width:16px;height:16px}.ke-icon-insertorderedlist{background-position:0 -208px;width:16px;height:16px}.ke-icon-insertunorderedlist{background-position:0 -224px;width:16px;height:16px}.ke-icon-indent{background-position:0 -240px;width:16px;height:16px}.ke-icon-outdent{background-position:0 -256px;width:16px;height:16px}.ke-icon-subscript{background-position:0 -272px;width:16px;height:16px}.ke-icon-superscript{background-position:0 -288px;width:16px;height:16px}.ke-icon-date{background-position:0 -304px;width:25px;height:16px}.ke-icon-time{background-position:0 -320px;width:25px;height:16px}.ke-icon-formatblock{background-position:0 -336px;width:25px;height:16px}.ke-icon-fontname{background-position:0 -352px;width:21px;height:16px}.ke-icon-fontsize{background-position:0 -368px;width:23px;height:16px}.ke-icon-forecolor{background-position:0 -384px;width:20px;height:16px}.ke-icon-hilitecolor{background-position:0 -400px;width:23px;height:16px}.ke-icon-bold{background-position:0 -416px;width:16px;height:16px}.ke-icon-italic{background-position:0 -432px;width:16px;height:16px}.ke-icon-underline{background-position:0 -448px;width:16px;height:16px}.ke-icon-strikethrough{background-position:0 -464px;width:16px;height:16px}.ke-icon-removeformat{background-position:0 -480px;width:16px;height:16px}.ke-icon-image{background-position:0 -496px;width:16px;height:16px}.ke-icon-flash{background-position:0 -512px;width:16px;height:16px}.ke-icon-media{background-position:0 -528px;width:16px;height:16px}.ke-icon-div{background-position:0 -544px;width:16px;height:16px}.ke-icon-formula{background-position:0 -576px;width:16px;height:16px}.ke-icon-hr{background-position:0 -592px;width:16px;height:16px}.ke-icon-emoticons{background-position:0 -608px;width:16px;height:16px}.ke-icon-link{background-position:0 -624px;width:16px;height:16px}.ke-icon-unlink{background-position:0 -640px;width:16px;height:16px}.ke-icon-fullscreen{background-position:0 -656px;width:16px;height:16px}.ke-icon-about{background-position:0 -672px;width:16px;height:16px}.ke-icon-plainpaste{background-position:0 -704px;width:16px;height:16px}.ke-icon-wordpaste{background-position:0 -720px;width:16px;height:16px}.ke-icon-table{background-position:0 -784px;width:16px;height:16px}.ke-icon-tablemenu{background-position:0 -768px;width:16px;height:16px}.ke-icon-tableinsert{background-position:0 -784px;width:16px;height:16px}.ke-icon-tabledelete{background-position:0 -800px;width:16px;height:16px}.ke-icon-tablecolinsertleft{background-position:0 -816px;width:16px;height:16px}.ke-icon-tablecolinsertright{background-position:0 -832px;width:16px;height:16px}.ke-icon-tablerowinsertabove{background-position:0 -848px;width:16px;height:16px}.ke-icon-tablerowinsertbelow{background-position:0 -864px;width:16px;height:16px}.ke-icon-tablecoldelete{background-position:0 -880px;width:16px;height:16px}.ke-icon-tablerowdelete{background-position:0 -896px;width:16px;height:16px}.ke-icon-tablecellprop{background-position:0 -912px;width:16px;height:16px}.ke-icon-tableprop{background-position:0 -928px;width:16px;height:16px}.ke-icon-checked{background-position:0 -944px;width:16px;height:16px}.ke-icon-code{background-position:0 -960px;width:16px;height:16px}.ke-icon-map{background-position:0 -976px;width:16px;height:16px}.ke-icon-baidumap{background-position:0 -976px;width:16px;height:16px}.ke-icon-lineheight{background-position:0 -992px;width:16px;height:16px}.ke-icon-clearhtml{background-position:0 -1008px;width:16px;height:16px}.ke-icon-pagebreak{background-position:0 -1024px;width:16px;height:16px}.ke-icon-insertfile{background-position:0 -1040px;width:16px;height:16px}.ke-icon-quickformat{background-position:0 -1056px;width:16px;height:16px}.ke-icon-template{background-position:0 -1072px;width:16px;height:16px}.ke-icon-tablecellsplit{background-position:0 -1088px;width:16px;height:16px}.ke-icon-tablerowmerge{background-position:0 -1104px;width:16px;height:16px}.ke-icon-tablerowsplit{background-position:0 -1120px;width:16px;height:16px}.ke-icon-tablecolmerge{background-position:0 -1136px;width:16px;height:16px}.ke-icon-tablecolsplit{background-position:0 -1152px;width:16px;height:16px}.ke-icon-anchor{background-position:0 -1168px;width:16px;height:16px}.ke-icon-search{background-position:0 -1184px;width:16px;height:16px}.ke-icon-new{background-position:0 -1200px;width:16px;height:16px}.ke-icon-specialchar{background-position:0 -1216px;width:16px;height:16px}.ke-icon-multiimage{background-position:0 -1232px;width:16px;height:16px}.ke-icon-graft{background:url(images/scrawl.png)!important;width:16px;height:16px}.ke-container{display:block;border:1px solid #ccc;background-color:#fff;overflow:hidden;margin:0;padding:0}.ke-toolbar{border-bottom:1px solid #ccc;background-color:#fff;padding:2px 5px;text-align:left;overflow:hidden;zoom:1}.ke-toolbar-icon{background-repeat:no-repeat;font-size:0;line-height:0;overflow:hidden;display:block}.ke-toolbar-icon-url{background-image:url(images/default.png)}.ke-toolbar .ke-outline{border:1px solid #f0f0ee;margin:1px;padding:1px 2px;font-size:0;line-height:0;cursor:pointer;display:block;float:left}.ke-toolbar .ke-on{border:1px solid #5690d2}.ke-toolbar .ke-selected{border:1px solid #5690d2;background-color:#e9eff6}.ke-toolbar .ke-disabled{cursor:default}.ke-toolbar .ke-separator{height:16px;margin:2px 3px;border-left:1px solid #a0a0a0;border-right:1px solid #fff;border-top:0;border-bottom:0;width:0;font-size:0;line-height:0;overflow:hidden;display:block;float:left}.ke-toolbar .ke-hr{overflow:hidden;height:1px;clear:both}.ke-edit{padding:0}.ke-edit-iframe,.ke-edit-textarea{border:0;margin:0;padding:0;overflow:auto}.ke-edit-textarea{font:12px/1.5 Consolas,Monaco,"Bitstream Vera Sans Mono","Courier New",Courier,monospace;color:#000;overflow:auto;resize:none}.ke-edit-textarea:focus{outline:0}.ke-statusbar{position:relative;background-color:#f0f0ee;border-top:1px solid #ccc;font-size:0;line-height:0;overflow:hidden;text-align:center;cursor:s-resize}.ke-statusbar-center-icon{background-position:0 -754px;width:15px;height:11px;background-image:url(images/default.png)}.ke-statusbar-right-icon{position:absolute;right:0;bottom:0;cursor:se-resize;background-position:-5px -741px;width:11px;height:11px;background-image:url(images/default.png)}.ke-menu{border:1px solid #a0a0a0;background-color:#f1f1f1;color:#222;padding:2px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;text-align:left;overflow:hidden}.ke-menu-item{border:1px solid #f1f1f1;background-color:#f1f1f1;color:#222;height:24px;overflow:hidden;cursor:pointer}.ke-menu-item-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu-item-center{width:0;height:24px;border-left:1px solid #e3e3e3;border-right:1px solid #fff;border-top:0;border-bottom:0}.ke-menu-item-center-on{border-left:1px solid #e9eff6;border-right:1px solid #e9eff6}.ke-menu-item-right{border:0;padding:0 0 0 5px;line-height:24px;text-align:left;overflow:hidden}.ke-menu-separator{margin:2px 0;height:0;overflow:hidden;border-top:1px solid #ccc;border-bottom:1px solid #fff;border-left:0;border-right:0}.ke-colorpicker{border:1px solid #a0a0a0;background-color:#f1f1f1;color:#222;padding:2px}.ke-colorpicker-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-colorpicker-cell{font-size:0;line-height:0;border:1px solid #f0f0ee;cursor:pointer;margin:3px;padding:0}.ke-colorpicker-cell-top{font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;line-height:24px;border:1px solid #f0f0ee;cursor:pointer;margin:0;padding:0;text-align:center}.ke-colorpicker-cell-on{border:1px solid #5690d2}.ke-colorpicker-cell-selected{border:1px solid #2446ab}.ke-colorpicker-cell-color{width:14px;height:14px;margin:3px;padding:0;border:0}.ke-dialog{position:absolute;margin:0;padding:0}.ke-dialog .ke-header{width:100%;margin-bottom:10px}.ke-dialog .ke-header .ke-left{float:left}.ke-dialog .ke-header .ke-right{float:right}.ke-dialog .ke-header label{margin-right:0;cursor:pointer;font-weight:400;display:inline;vertical-align:top}.ke-dialog-content{background-color:#fff;width:100%;height:100%;color:#333;outline:0}.ke-dialog-header{border:0;margin:0;font-weight:700;font-size:14px;background:#f8f8f8;border-bottom:1px solid #eee;height:30px;line-height:30px;padding:0 10px;text-align:left;color:#222;cursor:move;border-top-left-radius:6px;border-top-right-radius:6px}.ke-dialog-icon-close{display:block;background:url(images/default.png) no-repeat scroll 0 -688px;width:16px;height:16px;position:absolute;right:6px;top:8px;cursor:pointer}.ke-dialog-body{font:12px/1.5 "sans serif",tahoma,verdana,helvetica;text-align:left;overflow:hidden;width:100%}.ke-dialog-body textarea{display:block;overflow:auto;padding:0;resize:none}.ke-dialog-body input:focus,.ke-dialog-body select:focus,.ke-dialog-body textarea:focus{outline:0}.ke-dialog-body label{margin-right:10px;cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;text-align:right;zoom:1}.ke-dialog-body img{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog-body select{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1;width:auto}.ke-dialog-body .ke-textarea{display:block;width:408px;height:260px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;border-color:#848484 #e0e0e0 #e0e0e0 #848484;border-style:solid;border-width:1px}.ke-dialog-body .ke-form{margin:0;padding:0}.ke-dialog-loading{position:absolute;top:0;left:1px;z-index:1;text-align:center}.ke-dialog-loading-content{background:url(../common/loading.gif) no-repeat;color:#666;font-size:14px;font-weight:700;height:31px;line-height:31px;padding-left:36px}.ke-dialog-row{margin-bottom:10px}.ke-dialog-footer{font:12px/1 "sans serif",tahoma,verdana,helvetica;text-align:right;padding:0 15px 5px 0;background-color:#fff;border-radius:6px;height:45px}.ke-dialog-preview,.ke-dialog-yes{margin:5px}.ke-dialog-no{margin:5px 10px 5px 5px}.ke-dialog-mask{background-color:#fff;opacity:.5}.ke-button-common{display:inline-block;text-align:center;background:0 0;border:none;padding:0;cursor:pointer}.ke-button-outer{background-position:0 -25px;padding:0;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-button{color:#333;font-size:12px;border:1px solid #e6e6e6;background-color:#e6e6e6;padding:5px 10px;margin-top:-2px;color:#444;text-decoration:none;transition:background-color .3s ease-out,border-color .3s ease-out}.ke-button:hover{border:1px solid #d1d1d1;background-color:#d1d1d1}.ke-dialog-btn{font-size:12px;margin:5px;background:#2e8ded;color:#fff!important;padding:8px 12px;display:inline-block;border-radius:2px;cursor:pointer;text-decoration:none;transition:.3s ease-out}.ke-dialog-btn:hover{box-shadow:none;box-shadow:none;opacity:.8}.ke-input-text{display:inline-block!important;width:400px;border:1px solid #ccc;height:20px;line-height:18px;font-size:14px;padding:3px;margin:0;outline:0}.ke-input-text:focus{border-color:#66afe9;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.ke-input-number{width:50px}.ke-input-color{border:1px solid #a0a0a0;background-color:#fff;font-size:12px;width:60px;height:20px;line-height:20px;padding-left:5px;overflow:hidden;cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-upload-button{position:relative;top:-1px}.ke-upload-area{position:relative;overflow:hidden;margin:0;padding:0}.ke-upload-area .ke-upload-file{position:absolute;font-size:60px;top:0;right:0;padding:0;margin:0;z-index:811212;border:0 none;opacity:0;cursor:pointer;width:50px;height:30px}.ke-upload-area .ke-button{padding:6px 15px}.ke-tabs{font:12px/1 "sans serif",tahoma,verdana,helvetica;border-bottom:1px solid #ccc;padding-left:5px;margin-bottom:20px}.ke-tabs-ul{list-style-image:none;list-style-position:outside;list-style-type:none;margin:0;padding:0}.ke-tabs-li{position:relative;margin:0 2px -1px 0;padding:0 20px;float:left;line-height:25px;text-align:center;color:#337ab7;cursor:pointer}.ke-tabs-li-selected{background-color:#fff;border:1px solid #ccc;border-bottom:1px solid #fff;color:#555;cursor:default;border-top-left-radius:3px;border-top-right-radius:3px}.ke-tabs-li-on{background-color:#fff;color:#000}.ke-progressbar{position:relative;margin:0;padding:0}.ke-progressbar-bar{border:1px solid #6fa5db;width:80px;height:5px;margin:10px 10px 0 10px;padding:0}.ke-progressbar-bar-inner{width:0;height:5px;background-color:#6fa5db;overflow:hidden;margin:0;padding:0}.ke-progressbar-percent{position:absolute;top:0;left:40%;display:none}.ke-swfupload-top{position:relative;margin-bottom:10px}.ke-swfupload-button{height:23px;line-height:23px}.ke-swfupload-desc{padding:0 10px;height:23px;line-height:23px}.ke-swfupload-startupload{position:absolute;top:0;right:0}.ke-swfupload-body{overflow:scroll;background-color:#fff;border-color:#848484 #e0e0e0 #e0e0e0 #848484;border-style:solid;border-width:1px;width:auto;height:370px;padding:5px}.ke-swfupload-body .ke-item{width:100px;margin:5px}.ke-swfupload-body .ke-photo{position:relative;border:1px solid #ddd;background-color:#fff;padding:10px}.ke-swfupload-body .ke-delete{display:block;background:url(images/default.png) no-repeat scroll 0 -688px;width:16px;height:16px;position:absolute;right:0;top:0;cursor:pointer}.ke-swfupload-body .ke-status{position:absolute;left:0;bottom:5px;width:100px;height:17px}.ke-swfupload-body .ke-message{width:100px;text-align:center;overflow:hidden;height:17px}.ke-swfupload-body .ke-error{color:red}.ke-swfupload-body .ke-name{width:100px;text-align:center;overflow:hidden;height:16px}.ke-swfupload-body .ke-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-plugin-emoticons{position:relative}.ke-plugin-emoticons .ke-preview{position:absolute;text-align:center;margin:2px;padding:10px;top:0;border:1px solid #a0a0a0;background-color:#fff;display:none}.ke-plugin-emoticons .ke-preview-img{border:0;margin:0;padding:0}.ke-plugin-emoticons .ke-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-plugin-emoticons .ke-cell{margin:0;padding:1px;border:1px solid #f0f0ee;cursor:pointer}.ke-plugin-emoticons .ke-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-plugin-emoticons .ke-img{display:block;background-repeat:no-repeat;overflow:hidden;margin:2px;width:24px;height:24px;margin:0;padding:0;border:0}.ke-plugin-emoticons .ke-page{text-align:right;margin:5px;padding:0;border:0;font:12px/1 "sans serif",tahoma,verdana,helvetica;color:#333;text-decoration:none}.ke-plugin-plainpaste-textarea,.ke-plugin-wordpaste-iframe{display:block;width:408px;height:260px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;border-color:#848484 #e0e0e0 #e0e0e0 #848484;border-style:solid;border-width:1px}.ke-plugin-filemanager-header{width:100%;margin-bottom:10px}.ke-plugin-filemanager-header .ke-left{float:left}.ke-plugin-filemanager-header .ke-right{float:right}.ke-plugin-filemanager-body{overflow:scroll;background-color:#fff;border-color:#848484 #e0e0e0 #e0e0e0 #848484;border-style:solid;border-width:1px;width:auto;height:370px;padding:5px}.ke-plugin-filemanager-body .ke-item{width:100px;margin:5px}.ke-plugin-filemanager-body .ke-photo{border:1px solid #ddd;background-color:#fff;padding:10px}.ke-plugin-filemanager-body .ke-name{width:100px;text-align:center;overflow:hidden;height:16px}.ke-plugin-filemanager-body .ke-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-plugin-filemanager-body .ke-table{width:95%;border:0;margin:0;padding:0;border-collapse:separate}.ke-plugin-filemanager-body .ke-table .ke-cell{margin:0;padding:0;border:0}.ke-plugin-filemanager-body .ke-table .ke-name{width:55%;text-align:left}.ke-plugin-filemanager-body .ke-table .ke-size{width:15%;text-align:left}.ke-plugin-filemanager-body .ke-table .ke-datetime{width:30%;text-align:center}.ke-dialog-content-inner{padding:10px 20px}.ke-dialog-content-inner .row-left{float:left}.ke-dialog-content-inner .row-right{float:left}.ke-dialog-default{box-shadow:0 5px 15px rgba(0,0,0,.2)!important;border:1px solid #999!important;border:1px solid rgba(0,0,0,.2)!important;border-radius:6px;outline:0;zoom:1;overflow:hidden} \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/default/images/background.png b/addons/nkeditor/assets/themes/default/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..e59bd6890d1633243d5de27c09f06ede17392a56 Binary files /dev/null and b/addons/nkeditor/assets/themes/default/images/background.png differ diff --git a/addons/nkeditor/assets/themes/default/images/default.png b/addons/nkeditor/assets/themes/default/images/default.png new file mode 100644 index 0000000000000000000000000000000000000000..cc9e72d2bdf9a67ae587dba81b94bfc2d1edc827 Binary files /dev/null and b/addons/nkeditor/assets/themes/default/images/default.png differ diff --git a/addons/nkeditor/assets/themes/default/images/scrawl.png b/addons/nkeditor/assets/themes/default/images/scrawl.png new file mode 100644 index 0000000000000000000000000000000000000000..58e04ec42651cd800e4940dd74a39a5a2f8a4aed Binary files /dev/null and b/addons/nkeditor/assets/themes/default/images/scrawl.png differ diff --git a/addons/nkeditor/assets/themes/grey/editor.css b/addons/nkeditor/assets/themes/grey/editor.css new file mode 100644 index 0000000000000000000000000000000000000000..beb0eaea8ed9800cc50e5380ddc6a409e29e99d2 --- /dev/null +++ b/addons/nkeditor/assets/themes/grey/editor.css @@ -0,0 +1,822 @@ +@charset "UTF-8"; +/** +公共样式 +*/ +.ke-clearfix { + zoom: 1; + clear: both; } + +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; } + +.ke-animated { + animation: zoomIn; + animation-duration: 0.3s; + animation-fill-mode: both; } + +@keyframes zoomIn { + from { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); } + 50% { + opacity: 1; } } +.ke-dialog-mask { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; } + +.ke-dialog-lock { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; + z-index: 811213; + left: 0; + top: 0; + position: absolute; } + +/** +编辑器样式开始 + */ +.ke-container { + display: block; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + /** + 通用样式 + */ + /** + toolbar 样式 + */ + /** + ke-edit + */ + /** + statusbar start + */ } + .ke-container .ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + background-color: #F0F0EE; } + .ke-container .ke-menu a, + .ke-container .ke-menu a:hover, + .ke-container .ke-dialog a, + .ke-container .ke-dialog a:hover { + color: #337FE5; + text-decoration: none; } + .ke-container .ke-toolbar { + text-align: left; + overflow: hidden; + zoom: 1; + padding: 0px 5px; } + .ke-container .ke-toolbar .ke-outline { + padding: 10px 5px; + font-size: 0; + line-height: 0; + cursor: pointer; + display: block; + float: left; + /** + * 按钮通用样式 + */ } + .ke-container .ke-toolbar .ke-outline .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; } + .ke-container .ke-toolbar .ke-on { + background: #ebebeb; } + .ke-container .ke-toolbar .ke-selected { + background-color: #ebebeb; } + .ke-container .ke-toolbar .ke-disabled { + cursor: default; } + .ke-container .ke-toolbar .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; } + .ke-container .ke-toolbar .ke-hr { + clear: both; + height: 1px; + width: calc(100% - (2 * 2px)); + background: #ebebeb; } + .ke-container .ke-edit { + padding: 0; } + .ke-container .ke-edit .ke-edit-iframe, + .ke-container .ke-edit .ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; } + .ke-container .ke-edit .ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; } + .ke-container .ke-edit .ke-edit-textarea:focus { + outline: none; } + .ke-container .ke-statusbar { + position: relative; + background-color: #f5f5f5; + border-top: 1px solid #e1e1e1; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; + display: none; } + .ke-container .ke-statusbar .ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; } + .ke-container .ke-statusbar .ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + width: 11px; + height: 11px; } + +/** + menu 右键菜单 + */ +.ke-menu { + border: 1px solid #cccccc; + background-color: #f5f5f5; + color: #222222; + padding: 2px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; + /** + 表情插件 + */ } + .ke-menu .ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; } + .ke-menu .ke-menu-item .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-inline-block .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; } + .ke-menu .ke-menu-item .ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; } + .ke-menu .ke-menu-item .ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: 1px solid #e1e1e1; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; } + .ke-menu .ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons { + position: relative; } + .ke-menu .ke-plugin-emoticons .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; } + .ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img { + border: 0; + margin: 0; + padding: 0; } + .ke-menu .ke-plugin-emoticons .ke-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell { + margin: 0; + padding: 1px; + border: 1px solid #f5f5f5; + cursor: pointer; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img { + display: block; + background-repeat: no-repeat; + overflow: hidden; + margin: 2px; + width: 24px; + height: 24px; + margin: 0; + padding: 0; + border: 0; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + color: #333; + text-decoration: none; } + +/** + colorpicker + */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; } + .ke-colorpicker .ke-colorpicker-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin: 3px; + padding: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top { + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F1F1F1; + cursor: pointer; + margin: 0; + padding: 0; + text-align: center; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on { + border: 1px solid #5690D2; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected { + border: 1px solid #2446AB; } + +/** + dialog + */ +.ke-dialog { + margin: 0; + padding: 0; + border: 1px solid #cccccc; + zoom: 1; + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + overflow: hidden; } + .ke-dialog .ke-dialog-header { + border: 0; + margin: 0; + font-weight: bold; + font-size: 14px; + height: 30px; + line-height: 30px; + padding: 0px 10px; + text-align: left; + color: #222; + cursor: move; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-bottom: 1px solid #c6c6c6; + background: transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0; + position: relative; + cursor: move; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close { + height: 20px; + width: 20px; + cursor: pointer; + background: url("../common/icons-all.gif") 0 -59px; + position: absolute; + right: 5px; + top: 4px; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover { + background-position: 0px -89px; } + .ke-dialog .ke-dialog-content { + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + outline: 0; + zoom: 1; } + .ke-dialog .ke-dialog-content .ke-dialog-body { + font: 12px/1.5 "sans serif", tahoma, verdana, helvetica; + text-align: left; + overflow: hidden; + width: 100%; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + border: 1px solid #cccccc; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus { + border-color: #66afe9; + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; + border: 1px solid #cccccc; + height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-form { + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number { + width: 50px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox { + position: relative; + top: 6px; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus { + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text { + display: inline-block !important; + max-width: 400px; + height: 30px; + line-height: 30px; + border: 1px solid #cccccc; + font-size: 14px; + margin: 0; + outline: 0; + padding: 0px 10px; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus { + border-color: #66afe9; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color { + border: 1px solid #e1e1e1; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 30px; + line-height: 30px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + top: -1px; + position: relative; + *height: 25px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + cursor: pointer; + width: 62px; + height: 30px; + filter: alpha(opacity=0); } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common { + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button { + padding: 8px 15px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner { + padding: 10px 20px 0px 20px; + /** + tabs + */ } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row { + border: 1px solid #FFFFFF; + margin-bottom: 10px; + overflow: hidden; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left { + float: left; + height: 30px; + line-height: 30px; + width: 60px; + text-align: right; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right { + float: left; + text-align: left; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button { + position: relative; + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label { + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + text-align: right; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header { + height: 30px; + line-height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text { + height: 22px; + line-height: 22px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button { + padding: 3px 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox { + margin-left: 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + border-bottom: 1px solid #e1e1e1; + margin-bottom: 20px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul { + list-style: none outside none; + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li { + position: relative; + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #337ab7; + cursor: pointer; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected { + background-color: #FFF; + border: 1px solid #e1e1e1; + border-bottom: 1px solid #FFF; + color: #555555; + cursor: default; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on { + background-color: #FFF; + color: #000; } + .ke-dialog .ke-dialog-content .ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; } + .ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat center; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; } + .ke-dialog .ke-dialog-footer { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + text-align: right; + padding: 0 15px 5px 0; + background-color: #FFF; + height: 40px; } + .ke-dialog .ke-dialog-footer .ke-dialog-yes { + margin: 5px; } + .ke-dialog .ke-dialog-footer .ke-dialog-no { + margin: 5px 10px 5px 5px; } + .ke-dialog .ke-button-common { + display: inline-block; + text-align: center; + background: none; + border: none; + padding: 0; + cursor: pointer; } + .ke-dialog .ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-button { + color: #333; + font-size: 12px; + border: 1px solid #e6e6e6; + background-color: #e6e6e6; + padding: 7px 10px; + margin-top: -4px; + color: #444; + text-decoration: none; + transition: background-color .3s ease-out, border-color .3s ease-out; } + .ke-dialog .ke-button:hover { + border: 1px solid #e1e1e1; + background-color: #e1e1e1; } + .ke-dialog .ke-dialog-btn { + font-size: 12px; + margin: 5px; + background: #2e8ded; + color: #fff !important; + padding: 8px 12px; + display: inline-block; + border-radius: 2px; + cursor: pointer; + text-decoration: none; + transition: .3s ease-out; } + .ke-dialog .ke-dialog-btn:hover { + filter: alpha(opacity=80); + box-shadow: none; + box-shadow: none; + opacity: .8; } + +.ke-container-grey .ke-toolbar { + border-top: 5px solid #8a8a8a; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + background-clip: padding-box; + text-rendering: optimizelegibility; } + .ke-container-grey .ke-toolbar .ke-toolbar-icon { + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; } + .ke-container-grey .ke-toolbar .ke-icon-source { + background-position: 0 0px; } + .ke-container-grey .ke-toolbar .ke-icon-preview { + background-position: 0 -63px; } + .ke-container-grey .ke-toolbar .ke-icon-print { + background-position: 0 -84px; } + .ke-container-grey .ke-toolbar .ke-icon-undo { + background-position: 0 -21px; } + .ke-container-grey .ke-toolbar .ke-icon-redo { + background-position: 0 -42px; } + .ke-container-grey .ke-toolbar .ke-icon-template { + background-position: 0 -105px; } + .ke-container-grey .ke-toolbar .ke-icon-cut { + background-position: 0 -147px; } + .ke-container-grey .ke-toolbar .ke-icon-copy { + background-position: 0 -168px; } + .ke-container-grey .ke-toolbar .ke-icon-paste { + background-position: 0 -189px; } + .ke-container-grey .ke-toolbar .ke-icon-selectall { + background-position: 0 -483px; } + .ke-container-grey .ke-toolbar .ke-icon-justifyleft { + background-position: 0 -252px; } + .ke-container-grey .ke-toolbar .ke-icon-justifycenter { + background-position: 0 -273px; } + .ke-container-grey .ke-toolbar .ke-icon-justifyright { + background-position: 0 -294px; } + .ke-container-grey .ke-toolbar .ke-icon-justifyfull { + background-position: 0 -315px; } + .ke-container-grey .ke-toolbar .ke-icon-insertorderedlist { + background-position: 0 -336px; } + .ke-container-grey .ke-toolbar .ke-icon-insertunorderedlist { + background-position: 0 -357px; } + .ke-container-grey .ke-toolbar .ke-icon-indent { + background-position: 0 -378px; } + .ke-container-grey .ke-toolbar .ke-icon-outdent { + background-position: 0 -399px; } + .ke-container-grey .ke-toolbar .ke-icon-subscript { + background-position: 0 -420px; } + .ke-container-grey .ke-toolbar .ke-icon-superscript { + background-position: 0 -441px; } + .ke-container-grey .ke-toolbar .ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-formatblock { + background-position: 0 -546px; } + .ke-container-grey .ke-toolbar .ke-icon-fontname { + background-position: 0 -567px; } + .ke-container-grey .ke-toolbar .ke-icon-fontsize { + background-position: 0 -588px; } + .ke-container-grey .ke-toolbar .ke-icon-forecolor { + background-position: 0 -609px; } + .ke-container-grey .ke-toolbar .ke-icon-hilitecolor { + background-position: 0 -630px; } + .ke-container-grey .ke-toolbar .ke-icon-bold { + background-position: 0 -651px; } + .ke-container-grey .ke-toolbar .ke-icon-italic { + background-position: 0 -672px; } + .ke-container-grey .ke-toolbar .ke-icon-underline { + background-position: 0 -693px; } + .ke-container-grey .ke-toolbar .ke-icon-strikethrough { + background-position: 0 -714px; } + .ke-container-grey .ke-toolbar .ke-icon-removeformat { + background-position: 0 -756px; } + .ke-container-grey .ke-toolbar .ke-icon-image { + background-position: 0 -777px; } + .ke-container-grey .ke-toolbar .ke-icon-flash { + background-position: 0 -840px; } + .ke-container-grey .ke-toolbar .ke-icon-media { + background-position: 0 -861px; } + .ke-container-grey .ke-toolbar .ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-hr { + background-position: 0 -924px; } + .ke-container-grey .ke-toolbar .ke-icon-emoticons { + background-position: 0 -945px; } + .ke-container-grey .ke-toolbar .ke-icon-link { + background-position: 0 -1008px; } + .ke-container-grey .ke-toolbar .ke-icon-unlink { + background-position: 0 -1029px; } + .ke-container-grey .ke-toolbar .ke-icon-fullscreen { + background-position: 0 -525px; } + .ke-container-grey .ke-toolbar .ke-icon-about { + background-position: 0 -1092px; } + .ke-container-grey .ke-toolbar .ke-icon-quote { + background-position: 0 -1114px; } + .ke-container-grey .ke-toolbar .ke-icon-plainpaste { + background-position: 0 -210px; } + .ke-container-grey .ke-toolbar .ke-icon-wordpaste { + background-position: 0 -231px; } + .ke-container-grey .ke-toolbar .ke-icon-table { + background-position: 0px -903px; + width: 18px !important; } + .ke-container-grey .ke-toolbar .ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-code { + background-position: 0 -126px; } + .ke-container-grey .ke-toolbar .ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-baidumap { + background-position: 0 -1050px; } + .ke-container-grey .ke-toolbar .ke-icon-lineheight { + background-position: 0 -735px; } + .ke-container-grey .ke-toolbar .ke-icon-clearhtml { + background-position: 0 -462px; } + .ke-container-grey .ke-toolbar .ke-icon-pagebreak { + background-position: 0 -966px; } + .ke-container-grey .ke-toolbar .ke-icon-insertfile { + background-position: 0 -882px; } + .ke-container-grey .ke-toolbar .ke-icon-quickformat { + background-position: 0 -504px; } + .ke-container-grey .ke-toolbar .ke-icon-anchor { + background-position: 0 -987px; } + .ke-container-grey .ke-toolbar .ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; } + .ke-container-grey .ke-toolbar .ke-icon-multiimage { + background-position: 0 -798px; } + .ke-container-grey .ke-toolbar .ke-icon-graft { + background-position: 0 -819px; } + +/** + menu 右键菜单 + */ +.ke-menu-grey .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tableinsert { + background-position: 0 -903px; + width: 18px !important; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tabledelete { + background-position: 0 -1428px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertleft { + background-position: 0 -1176px; + width: 18px !important; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertright { + background-position: 0 -1323px; + width: 18px !important; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertabove { + background-position: 0 -1302px; + width: 22px !important; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertbelow { + background-position: 0 -1155px; + width: 22px !important; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecoldelete { + background-position: 0 -1239px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowdelete { + background-position: 0 -1260px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecellprop { + background-position: 0 -1218px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tableprop { + background-position: 0 -1134px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowmerge { + background-position: -1px -1197px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowsplit { + background-position: 0 -1344px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecolmerge { + background-position: -4px -1365px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecolsplit { + background-position: 0 -1344px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-image { + background-position: 0 -777px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-flash { + background-position: 0 -840px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-media { + background-position: 0 -861px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-link { + background-position: 0 -1008px; } + .ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-checked { + background-position: 0 -1407px; } + +/*# sourceMappingURL=editor.css.map */ diff --git a/addons/nkeditor/assets/themes/grey/editor.min.css b/addons/nkeditor/assets/themes/grey/editor.min.css new file mode 100644 index 0000000000000000000000000000000000000000..34fe061c4ad4cd7bad358940e1a96b1140abc014 --- /dev/null +++ b/addons/nkeditor/assets/themes/grey/editor.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.ke-clearfix{zoom:1;clear:both}.ke-clearfix:after{content:".";display:block;clear:both;font-size:0;height:0;line-height:0;visibility:hidden}.ke-animated{animation:zoomIn;animation-duration:.3s;animation-fill-mode:both}@keyframes zoomIn{from{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.ke-dialog-mask{background-color:#fff;opacity:.5}.ke-dialog-lock{background-color:#fff;opacity:.5;z-index:811213;left:0;top:0;position:absolute}.ke-container{display:block;background-color:#fff;overflow:hidden;margin:0;padding:0;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 1px 1px rgba(0,0,0,.16)}.ke-container .ke-shadow{box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;background-color:#f0f0ee}.ke-container .ke-dialog a,.ke-container .ke-dialog a:hover,.ke-container .ke-menu a,.ke-container .ke-menu a:hover{color:#337fe5;text-decoration:none}.ke-container .ke-toolbar{text-align:left;overflow:hidden;zoom:1;padding:0 5px}.ke-container .ke-toolbar .ke-outline{padding:10px 5px;font-size:0;line-height:0;cursor:pointer;display:block;float:left}.ke-container .ke-toolbar .ke-outline .ke-toolbar-icon{font-size:0;line-height:0;overflow:hidden;display:block;width:16px;height:16px;margin:0 2px}.ke-container .ke-toolbar .ke-on{background:#ebebeb}.ke-container .ke-toolbar .ke-selected{background-color:#ebebeb}.ke-container .ke-toolbar .ke-disabled{cursor:default}.ke-container .ke-toolbar .ke-separator{height:16px;margin:2px 3px;border-left:1px solid #a0a0a0;border-right:1px solid #fff;border-top:0;border-bottom:0;width:0;font-size:0;line-height:0;overflow:hidden;display:block;float:left}.ke-container .ke-toolbar .ke-hr{clear:both;height:1px;width:calc(100% - (2 * 2px));background:#ebebeb}.ke-container .ke-edit{padding:0}.ke-container .ke-edit .ke-edit-iframe,.ke-container .ke-edit .ke-edit-textarea{border:0;margin:0;padding:0;overflow:auto}.ke-container .ke-edit .ke-edit-textarea{font:12px/1.5 Consolas,Monaco,"Bitstream Vera Sans Mono","Courier New",Courier,monospace;color:#000;overflow:auto;resize:none}.ke-container .ke-edit .ke-edit-textarea:focus{outline:0}.ke-container .ke-statusbar{position:relative;background-color:#f5f5f5;border-top:1px solid #e1e1e1;font-size:0;line-height:0;overflow:hidden;text-align:center;cursor:s-resize;display:none}.ke-container .ke-statusbar .ke-statusbar-center-icon{background-position:0 -754px;width:15px;height:11px}.ke-container .ke-statusbar .ke-statusbar-right-icon{position:absolute;right:0;bottom:0;cursor:se-resize;width:11px;height:11px}.ke-menu{border:1px solid #ccc;background-color:#f5f5f5;color:#222;padding:2px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;text-align:left;overflow:hidden}.ke-menu .ke-menu-item{border:1px solid #f1f1f1;background-color:#f1f1f1;color:#222;height:24px;overflow:hidden;cursor:pointer}.ke-menu .ke-menu-item .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-menu .ke-menu-item .ke-inline-block .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-menu .ke-menu-item .ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu .ke-menu-item .ke-menu-item-center{width:0;height:24px;border-left:1px solid #e3e3e3;border-right:1px solid #fff;border-top:0;border-bottom:0}.ke-menu .ke-menu-item .ke-menu-item-center-on{border-left:1px solid #e9eff6;border-right:1px solid #e9eff6}.ke-menu .ke-menu-item .ke-menu-item-right{border:0;padding:0 0 0 5px;line-height:24px;text-align:left;overflow:hidden}.ke-menu .ke-menu-item .ke-menu-separator{margin:2px 0;height:0;overflow:hidden;border-top:1px solid #e1e1e1;border-bottom:1px solid #fff;border-left:0;border-right:0}.ke-menu .ke-menu-item-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu .ke-plugin-emoticons{position:relative}.ke-menu .ke-plugin-emoticons .ke-preview{position:absolute;text-align:center;margin:2px;padding:10px;top:0;border:1px solid #a0a0a0;background-color:#fff;display:none}.ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img{border:0;margin:0;padding:0}.ke-menu .ke-plugin-emoticons .ke-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-menu .ke-plugin-emoticons .ke-table .ke-cell{margin:0;padding:1px;border:1px solid #f5f5f5;cursor:pointer}.ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img{display:block;background-repeat:no-repeat;overflow:hidden;margin:2px;width:24px;height:24px;margin:0;padding:0;border:0}.ke-menu .ke-plugin-emoticons .ke-table .ke-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu .ke-plugin-emoticons .ke-page{text-align:right;margin:5px;padding:0;border:0;font:12px/1 "sans serif",tahoma,verdana,helvetica;color:#333;text-decoration:none}.ke-colorpicker{border:1px solid #a0a0a0;background-color:#f1f1f1;color:#222;padding:2px}.ke-colorpicker .ke-colorpicker-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell{font-size:0;line-height:0;border:1px solid #f0f0ee;cursor:pointer;margin:3px;padding:0}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color{width:14px;height:14px;margin:3px;padding:0;border:0}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top{font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;line-height:24px;border:1px solid #f1f1f1;cursor:pointer;margin:0;padding:0;text-align:center}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on{border:1px solid #5690d2}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected{border:1px solid #2446ab}.ke-dialog{margin:0;padding:0;border:1px solid #ccc;zoom:1;box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;overflow:hidden}.ke-dialog .ke-dialog-header{border:0;margin:0;font-weight:700;font-size:14px;height:30px;line-height:30px;padding:0 10px;text-align:left;color:#222;cursor:move;border-top-left-radius:6px;border-top-right-radius:6px;border-bottom:1px solid #c6c6c6;background:transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0;position:relative;cursor:move}.ke-dialog .ke-dialog-header .ke-dialog-icon-close{height:20px;width:20px;cursor:pointer;background:url(../common/icons-all.gif) 0 -59px;position:absolute;right:5px;top:4px}.ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover{background-position:0 -89px}.ke-dialog .ke-dialog-content{background-color:#fff;width:100%;height:100%;color:#333;outline:0;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body{font:12px/1.5 "sans serif",tahoma,verdana,helvetica;text-align:left;overflow:hidden;width:100%}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea{display:block;width:408px;height:260px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;border:1px solid #ccc}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus{border-color:#66afe9;outline:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-select{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1;width:auto;border:1px solid #ccc;height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-form{margin:0;padding:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number{width:50px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox{position:relative;top:6px}.ke-dialog .ke-dialog-content .ke-dialog-body textarea{display:block;overflow:auto;padding:0;resize:none}.ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus{outline:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text{display:inline-block!important;max-width:400px;height:30px;line-height:30px;border:1px solid #ccc;font-size:14px;margin:0;outline:0;padding:0 10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus{border-color:#66afe9}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color{border:1px solid #e1e1e1;background-color:#fff;font-size:12px;width:60px;height:30px;line-height:30px;padding-left:5px;overflow:hidden;cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area{position:relative;overflow:hidden;margin:0;padding:0;top:-1px;position:relative}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file{position:absolute;font-size:60px;top:0;right:0;padding:0;margin:0;z-index:811212;border:0 none;opacity:0;cursor:pointer;width:62px;height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common{top:-1px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button{padding:8px 15px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner{padding:10px 20px 0 20px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row{border:1px solid #fff;margin-bottom:10px;overflow:hidden}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left{float:left;height:30px;line-height:30px;width:60px;text-align:right}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right{float:left;text-align:left}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button{position:relative;top:-1px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label{cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;text-align:right;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header{height:30px;line-height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text{height:22px;line-height:22px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button{padding:3px 10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox{margin-left:10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs{font:12px/1 "sans serif",tahoma,verdana,helvetica;border-bottom:1px solid #e1e1e1;margin-bottom:20px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul{list-style:none outside none;margin:0;padding:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li{position:relative;margin:0 2px -1px 0;padding:0 20px;float:left;line-height:25px;text-align:center;color:#337ab7;cursor:pointer}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected{background-color:#fff;border:1px solid #e1e1e1;border-bottom:1px solid #fff;color:#555;cursor:default;border-top-left-radius:3px;border-top-right-radius:3px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on{background-color:#fff;color:#000}.ke-dialog .ke-dialog-content .ke-dialog-loading{position:absolute;top:0;left:1px;z-index:1;text-align:center}.ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content{background:url(../common/loading.gif) no-repeat center;color:#666;font-size:14px;font-weight:700;height:31px;line-height:31px;padding-left:36px}.ke-dialog .ke-dialog-footer{font:12px/1 "sans serif",tahoma,verdana,helvetica;text-align:right;padding:0 15px 5px 0;background-color:#fff;height:40px}.ke-dialog .ke-dialog-footer .ke-dialog-yes{margin:5px}.ke-dialog .ke-dialog-footer .ke-dialog-no{margin:5px 10px 5px 5px}.ke-dialog .ke-button-common{display:inline-block;text-align:center;background:0 0;border:none;padding:0;cursor:pointer}.ke-dialog .ke-button-outer{background-position:0 -25px;padding:0;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-button{color:#333;font-size:12px;border:1px solid #e6e6e6;background-color:#e6e6e6;padding:7px 10px;margin-top:-4px;color:#444;text-decoration:none;transition:background-color .3s ease-out,border-color .3s ease-out}.ke-dialog .ke-button:hover{border:1px solid #e1e1e1;background-color:#e1e1e1}.ke-dialog .ke-dialog-btn{font-size:12px;margin:5px;background:#2e8ded;color:#fff!important;padding:8px 12px;display:inline-block;border-radius:2px;cursor:pointer;text-decoration:none;transition:.3s ease-out}.ke-dialog .ke-dialog-btn:hover{box-shadow:none;box-shadow:none;opacity:.8}.ke-container-grey .ke-toolbar{border-top:5px solid #8a8a8a;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 1px 1px rgba(0,0,0,.16);background-clip:padding-box;text-rendering:optimizelegibility}.ke-container-grey .ke-toolbar .ke-toolbar-icon{background:url(images/nkeditor.svg) no-repeat}.ke-container-grey .ke-toolbar .ke-icon-source{background-position:0 0}.ke-container-grey .ke-toolbar .ke-icon-preview{background-position:0 -63px}.ke-container-grey .ke-toolbar .ke-icon-print{background-position:0 -84px}.ke-container-grey .ke-toolbar .ke-icon-undo{background-position:0 -21px}.ke-container-grey .ke-toolbar .ke-icon-redo{background-position:0 -42px}.ke-container-grey .ke-toolbar .ke-icon-template{background-position:0 -105px}.ke-container-grey .ke-toolbar .ke-icon-cut{background-position:0 -147px}.ke-container-grey .ke-toolbar .ke-icon-copy{background-position:0 -168px}.ke-container-grey .ke-toolbar .ke-icon-paste{background-position:0 -189px}.ke-container-grey .ke-toolbar .ke-icon-selectall{background-position:0 -483px}.ke-container-grey .ke-toolbar .ke-icon-justifyleft{background-position:0 -252px}.ke-container-grey .ke-toolbar .ke-icon-justifycenter{background-position:0 -273px}.ke-container-grey .ke-toolbar .ke-icon-justifyright{background-position:0 -294px}.ke-container-grey .ke-toolbar .ke-icon-justifyfull{background-position:0 -315px}.ke-container-grey .ke-toolbar .ke-icon-insertorderedlist{background-position:0 -336px}.ke-container-grey .ke-toolbar .ke-icon-insertunorderedlist{background-position:0 -357px}.ke-container-grey .ke-toolbar .ke-icon-indent{background-position:0 -378px}.ke-container-grey .ke-toolbar .ke-icon-outdent{background-position:0 -399px}.ke-container-grey .ke-toolbar .ke-icon-subscript{background-position:0 -420px}.ke-container-grey .ke-toolbar .ke-icon-superscript{background-position:0 -441px}.ke-container-grey .ke-toolbar .ke-icon-date{background-position:0 -304px;width:25px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-time{background-position:0 -320px;width:25px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-formatblock{background-position:0 -546px}.ke-container-grey .ke-toolbar .ke-icon-fontname{background-position:0 -567px}.ke-container-grey .ke-toolbar .ke-icon-fontsize{background-position:0 -588px}.ke-container-grey .ke-toolbar .ke-icon-forecolor{background-position:0 -609px}.ke-container-grey .ke-toolbar .ke-icon-hilitecolor{background-position:0 -630px}.ke-container-grey .ke-toolbar .ke-icon-bold{background-position:0 -651px}.ke-container-grey .ke-toolbar .ke-icon-italic{background-position:0 -672px}.ke-container-grey .ke-toolbar .ke-icon-underline{background-position:0 -693px}.ke-container-grey .ke-toolbar .ke-icon-strikethrough{background-position:0 -714px}.ke-container-grey .ke-toolbar .ke-icon-removeformat{background-position:0 -756px}.ke-container-grey .ke-toolbar .ke-icon-image{background-position:0 -777px}.ke-container-grey .ke-toolbar .ke-icon-flash{background-position:0 -840px}.ke-container-grey .ke-toolbar .ke-icon-media{background-position:0 -861px}.ke-container-grey .ke-toolbar .ke-icon-div{background-position:0 -544px;width:16px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-formula{background-position:0 -576px;width:16px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-hr{background-position:0 -924px}.ke-container-grey .ke-toolbar .ke-icon-emoticons{background-position:0 -945px}.ke-container-grey .ke-toolbar .ke-icon-link{background-position:0 -1008px}.ke-container-grey .ke-toolbar .ke-icon-unlink{background-position:0 -1029px}.ke-container-grey .ke-toolbar .ke-icon-fullscreen{background-position:0 -525px}.ke-container-grey .ke-toolbar .ke-icon-about{background-position:0 -1092px}.ke-container-grey .ke-toolbar .ke-icon-quote{background-position:0 -1114px}.ke-container-grey .ke-toolbar .ke-icon-plainpaste{background-position:0 -210px}.ke-container-grey .ke-toolbar .ke-icon-wordpaste{background-position:0 -231px}.ke-container-grey .ke-toolbar .ke-icon-table{background-position:0 -903px;width:18px!important}.ke-container-grey .ke-toolbar .ke-icon-tablemenu{background-position:0 -768px;width:16px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-code{background-position:0 -126px}.ke-container-grey .ke-toolbar .ke-icon-map{background-position:0 -976px;width:16px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-baidumap{background-position:0 -1050px}.ke-container-grey .ke-toolbar .ke-icon-lineheight{background-position:0 -735px}.ke-container-grey .ke-toolbar .ke-icon-clearhtml{background-position:0 -462px}.ke-container-grey .ke-toolbar .ke-icon-pagebreak{background-position:0 -966px}.ke-container-grey .ke-toolbar .ke-icon-insertfile{background-position:0 -882px}.ke-container-grey .ke-toolbar .ke-icon-quickformat{background-position:0 -504px}.ke-container-grey .ke-toolbar .ke-icon-anchor{background-position:0 -987px}.ke-container-grey .ke-toolbar .ke-icon-search{background-position:0 -1184px;width:16px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-new{background-position:0 -1200px;width:16px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-specialchar{background-position:0 -1216px;width:16px;height:16px}.ke-container-grey .ke-toolbar .ke-icon-multiimage{background-position:0 -798px}.ke-container-grey .ke-toolbar .ke-icon-graft{background-position:0 -819px}.ke-menu-grey .ke-menu-item .ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-toolbar-icon{font-size:0;line-height:0;overflow:hidden;display:block;width:16px;height:16px;margin:0 2px;background:url(images/nkeditor.svg) no-repeat}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tableinsert{background-position:0 -903px;width:18px!important}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tabledelete{background-position:0 -1428px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertleft{background-position:0 -1176px;width:18px!important}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertright{background-position:0 -1323px;width:18px!important}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertabove{background-position:0 -1302px;width:22px!important}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertbelow{background-position:0 -1155px;width:22px!important}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecoldelete{background-position:0 -1239px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowdelete{background-position:0 -1260px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecellprop{background-position:0 -1218px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tableprop{background-position:0 -1134px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecellsplit{background-position:0 -1088px;width:16px;height:16px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowmerge{background-position:-1px -1197px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablerowsplit{background-position:0 -1344px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecolmerge{background-position:-4px -1365px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-tablecolsplit{background-position:0 -1344px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-image{background-position:0 -777px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-flash{background-position:0 -840px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-media{background-position:0 -861px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-link{background-position:0 -1008px}.ke-menu-grey .ke-menu-item .ke-menu-item-left .ke-icon-checked{background-position:0 -1407px} \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/grey/editor.scss b/addons/nkeditor/assets/themes/grey/editor.scss new file mode 100644 index 0000000000000000000000000000000000000000..9549839778536235f47009d3548419c222ab57ac --- /dev/null +++ b/addons/nkeditor/assets/themes/grey/editor.scss @@ -0,0 +1,387 @@ +@import "../common/common"; + +.ke-container-grey { + .ke-toolbar { + + border-top: 5px solid #8a8a8a; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + background-clip: padding-box; + text-rendering: optimizelegibility; + + .ke-toolbar-icon { + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; + } + + .ke-icon-source { + background-position: 0 0px; + } + .ke-icon-preview { + background-position: 0 -63px; + } + .ke-icon-print { + background-position: 0 -84px; + } + .ke-icon-undo { + background-position: 0 -21px; + } + + .ke-icon-redo { + background-position: 0 -42px; + } + + .ke-icon-template { + background-position: 0 -105px; + } + + .ke-icon-cut { + background-position: 0 -147px; + } + + .ke-icon-copy { + background-position: 0 -168px; + } + + .ke-icon-paste { + background-position: 0 -189px; + } + + .ke-icon-selectall { + background-position: 0 -483px; + } + + .ke-icon-justifyleft { + background-position: 0 -252px; + } + + .ke-icon-justifycenter { + background-position: 0 -273px; + } + + .ke-icon-justifyright { + background-position: 0 -294px; + } + + .ke-icon-justifyfull { + background-position: 0 -315px; + } + + .ke-icon-insertorderedlist { + background-position: 0 -336px; + } + + .ke-icon-insertunorderedlist { + background-position: 0 -357px; + } + + .ke-icon-indent { + background-position: 0 -378px; + } + + .ke-icon-outdent { + background-position: 0 -399px; + } + + .ke-icon-subscript { + background-position: 0 -420px; + } + + .ke-icon-superscript { + background-position: 0 -441px; + } + + .ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; + } + + .ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; + } + + .ke-icon-formatblock { + background-position: 0 -546px; + } + + .ke-icon-fontname { + background-position: 0 -567px; + } + + .ke-icon-fontsize { + background-position: 0 -588px; + } + + .ke-icon-forecolor { + background-position: 0 -609px; + } + + .ke-icon-hilitecolor { + background-position: 0 -630px; + } + + .ke-icon-bold { + background-position: 0 -651px; + } + + .ke-icon-italic { + background-position: 0 -672px; + } + + .ke-icon-underline { + background-position: 0 -693px; + } + + .ke-icon-strikethrough { + background-position: 0 -714px; + } + + .ke-icon-removeformat { + background-position: 0 -756px; + } + + .ke-icon-image { + background-position: 0 -777px; + } + + .ke-icon-flash { + background-position: 0 -840px; + } + + .ke-icon-media { + background-position: 0 -861px; + } + + .ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; + } + + .ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; + } + + .ke-icon-hr { + background-position: 0 -924px; + } + + .ke-icon-emoticons { + background-position: 0 -945px; + } + + .ke-icon-link { + background-position: 0 -1008px; + } + + .ke-icon-unlink { + background-position: 0 -1029px; + } + + .ke-icon-fullscreen { + background-position: 0 -525px; + } + + .ke-icon-about { + background-position: 0 -1092px; + } + + .ke-icon-quote { + background-position: 0 -1114px; + } + + .ke-icon-plainpaste { + background-position: 0 -210px; + } + + .ke-icon-wordpaste { + background-position: 0 -231px; + } + + .ke-icon-table { + background-position: 0px -903px; + width: 18px !important; + } + + .ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; + } + + .ke-icon-code { + background-position: 0 -126px; + } + + .ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; + } + + .ke-icon-baidumap { + background-position: 0 -1050px; + } + + .ke-icon-lineheight { + background-position: 0 -735px; + } + + .ke-icon-clearhtml { + background-position: 0 -462px; + } + + .ke-icon-pagebreak { + background-position: 0 -966px; + } + + .ke-icon-insertfile { + background-position: 0 -882px; + } + + .ke-icon-quickformat { + background-position: 0 -504px; + } + + .ke-icon-anchor { + background-position: 0 -987px; + } + + .ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; + } + + .ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; + } + + .ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; + } + + .ke-icon-multiimage { + background-position: 0 -798px; + } + + .ke-icon-graft { + background-position: 0 -819px; + } + } +} + +/** + menu 右键菜单 + */ +.ke-menu-grey { + + .ke-menu-item { + + .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; + + .ke-toolbar-icon { + @include ke-toolbar-icon; + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; + } + + .ke-icon-tableinsert { + background-position: 0 -903px; + width: 18px !important; + } + + .ke-icon-tabledelete { + background-position: 0 -1428px; + } + + .ke-icon-tablecolinsertleft { + background-position: 0 -1176px; + width: 18px !important; + } + + .ke-icon-tablecolinsertright { + background-position: 0 -1323px; + width: 18px !important; + } + + .ke-icon-tablerowinsertabove { + background-position: 0 -1302px; + width: 22px !important; + } + + .ke-icon-tablerowinsertbelow { + background-position: 0 -1155px; + width: 22px !important; + } + + .ke-icon-tablecoldelete { + background-position: 0 -1239px; + } + + .ke-icon-tablerowdelete { + background-position: 0 -1260px; + } + + .ke-icon-tablecellprop { + background-position: 0 -1218px; + } + + .ke-icon-tableprop { + background-position: 0 -1134px; + } + .ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; + } + + .ke-icon-tablerowmerge { + background-position: -1px -1197px; + } + + .ke-icon-tablerowsplit { + background-position: 0 -1344px; + } + + .ke-icon-tablecolmerge { + background-position: -4px -1365px; + } + + .ke-icon-tablecolsplit { + background-position: 0 -1344px; + } + + //图片,视频右键菜单 + .ke-icon-image { + background-position: 0 -777px; + } + .ke-icon-flash { + background-position: 0 -840px; + } + .ke-icon-media { + background-position: 0 -861px; + } + .ke-icon-link { + background-position: 0 -1008px; + } + + .ke-icon-checked { + background-position: 0 -1407px; + } + + } + } +} +//menu end \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/grey/images/nkeditor.png b/addons/nkeditor/assets/themes/grey/images/nkeditor.png new file mode 100644 index 0000000000000000000000000000000000000000..3e12962d33dd914fabc2f2c8f10670b3cba42cbd Binary files /dev/null and b/addons/nkeditor/assets/themes/grey/images/nkeditor.png differ diff --git a/addons/nkeditor/assets/themes/grey/images/nkeditor.svg b/addons/nkeditor/assets/themes/grey/images/nkeditor.svg new file mode 100644 index 0000000000000000000000000000000000000000..7a5b61d3cd73c62a60c8bdcca173104f53eafe16 --- /dev/null +++ b/addons/nkeditor/assets/themes/grey/images/nkeditor.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/nkeditor/assets/themes/primary/editor.css b/addons/nkeditor/assets/themes/primary/editor.css new file mode 100644 index 0000000000000000000000000000000000000000..33f3788f8bd232ee195c502ceeb03e555c38a6fd --- /dev/null +++ b/addons/nkeditor/assets/themes/primary/editor.css @@ -0,0 +1,822 @@ +@charset "UTF-8"; +/** +公共样式 +*/ +.ke-clearfix { + zoom: 1; + clear: both; } + +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; } + +.ke-animated { + animation: zoomIn; + animation-duration: 0.3s; + animation-fill-mode: both; } + +@keyframes zoomIn { + from { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); } + 50% { + opacity: 1; } } +.ke-dialog-mask { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; } + +.ke-dialog-lock { + background-color: #FFF; + filter: alpha(opacity=50); + opacity: 0.5; + z-index: 811213; + left: 0; + top: 0; + position: absolute; } + +/** +编辑器样式开始 + */ +.ke-container { + display: block; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + /** + 通用样式 + */ + /** + toolbar 样式 + */ + /** + ke-edit + */ + /** + statusbar start + */ } + .ke-container .ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + background-color: #F0F0EE; } + .ke-container .ke-menu a, + .ke-container .ke-menu a:hover, + .ke-container .ke-dialog a, + .ke-container .ke-dialog a:hover { + color: #337FE5; + text-decoration: none; } + .ke-container .ke-toolbar { + text-align: left; + overflow: hidden; + zoom: 1; + padding: 0px 5px; } + .ke-container .ke-toolbar .ke-outline { + padding: 10px 5px; + font-size: 0; + line-height: 0; + cursor: pointer; + display: block; + float: left; + /** + * 按钮通用样式 + */ } + .ke-container .ke-toolbar .ke-outline .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; } + .ke-container .ke-toolbar .ke-on { + background: #ebebeb; } + .ke-container .ke-toolbar .ke-selected { + background-color: #ebebeb; } + .ke-container .ke-toolbar .ke-disabled { + cursor: default; } + .ke-container .ke-toolbar .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; } + .ke-container .ke-toolbar .ke-hr { + clear: both; + height: 1px; + width: calc(100% - (2 * 2px)); + background: #ebebeb; } + .ke-container .ke-edit { + padding: 0; } + .ke-container .ke-edit .ke-edit-iframe, + .ke-container .ke-edit .ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; } + .ke-container .ke-edit .ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; } + .ke-container .ke-edit .ke-edit-textarea:focus { + outline: none; } + .ke-container .ke-statusbar { + position: relative; + background-color: #f5f5f5; + border-top: 1px solid #e1e1e1; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; + display: none; } + .ke-container .ke-statusbar .ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; } + .ke-container .ke-statusbar .ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + width: 11px; + height: 11px; } + +/** + menu 右键菜单 + */ +.ke-menu { + border: 1px solid #cccccc; + background-color: #f5f5f5; + color: #222222; + padding: 2px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; + /** + 表情插件 + */ } + .ke-menu .ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; } + .ke-menu .ke-menu-item .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-inline-block .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-menu .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; } + .ke-menu .ke-menu-item .ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; } + .ke-menu .ke-menu-item .ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; } + .ke-menu .ke-menu-item .ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: 1px solid #e1e1e1; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; } + .ke-menu .ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons { + position: relative; } + .ke-menu .ke-plugin-emoticons .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; } + .ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img { + border: 0; + margin: 0; + padding: 0; } + .ke-menu .ke-plugin-emoticons .ke-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell { + margin: 0; + padding: 1px; + border: 1px solid #f5f5f5; + cursor: pointer; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img { + display: block; + background-repeat: no-repeat; + overflow: hidden; + margin: 2px; + width: 24px; + height: 24px; + margin: 0; + padding: 0; + border: 0; } + .ke-menu .ke-plugin-emoticons .ke-table .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; } + .ke-menu .ke-plugin-emoticons .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + color: #333; + text-decoration: none; } + +/** + colorpicker + */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; } + .ke-colorpicker .ke-colorpicker-table { + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin: 3px; + padding: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top { + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F1F1F1; + cursor: pointer; + margin: 0; + padding: 0; + text-align: center; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on { + border: 1px solid #5690D2; } + .ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected { + border: 1px solid #2446AB; } + +/** + dialog + */ +.ke-dialog { + margin: 0; + padding: 0; + border: 1px solid #cccccc; + zoom: 1; + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + overflow: hidden; } + .ke-dialog .ke-dialog-header { + border: 0; + margin: 0; + font-weight: bold; + font-size: 14px; + height: 30px; + line-height: 30px; + padding: 0px 10px; + text-align: left; + color: #222; + cursor: move; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + border-bottom: 1px solid #c6c6c6; + background: transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0; + position: relative; + cursor: move; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close { + height: 20px; + width: 20px; + cursor: pointer; + background: url("../common/icons-all.gif") 0 -59px; + position: absolute; + right: 5px; + top: 4px; } + .ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover { + background-position: 0px -89px; } + .ke-dialog .ke-dialog-content { + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + outline: 0; + zoom: 1; } + .ke-dialog .ke-dialog-content .ke-dialog-body { + font: 12px/1.5 "sans serif", tahoma, verdana, helvetica; + text-align: left; + overflow: hidden; + width: 100%; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 12px; + border: 1px solid #cccccc; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus { + border-color: #66afe9; + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; + border: 1px solid #cccccc; + height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-form { + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number { + width: 50px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox { + position: relative; + top: 6px; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus { + outline: none; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text { + display: inline-block !important; + max-width: 400px; + height: 30px; + line-height: 30px; + border: 1px solid #cccccc; + font-size: 14px; + margin: 0; + outline: 0; + padding: 0px 10px; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus { + border-color: #66afe9; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color { + border: 1px solid #e1e1e1; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 30px; + line-height: 30px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + top: -1px; + position: relative; + *height: 25px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + cursor: pointer; + width: 62px; + height: 30px; + filter: alpha(opacity=0); } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common { + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button { + padding: 8px 15px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner { + padding: 10px 20px 0px 20px; + /** + tabs + */ } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row { + border: 1px solid #FFFFFF; + margin-bottom: 10px; + overflow: hidden; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left { + float: left; + height: 30px; + line-height: 30px; + width: 60px; + text-align: right; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right { + float: left; + text-align: left; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button { + position: relative; + top: -1px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label { + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + text-align: right; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header { + height: 30px; + line-height: 30px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text { + height: 22px; + line-height: 22px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button { + padding: 3px 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox { + margin-left: 10px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + border-bottom: 1px solid #e1e1e1; + margin-bottom: 20px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul { + list-style: none outside none; + margin: 0; + padding: 0; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li { + position: relative; + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #337ab7; + cursor: pointer; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected { + background-color: #FFF; + border: 1px solid #e1e1e1; + border-bottom: 1px solid #FFF; + color: #555555; + cursor: default; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + .ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on { + background-color: #FFF; + color: #000; } + .ke-dialog .ke-dialog-content .ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; } + .ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat center; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; } + .ke-dialog .ke-dialog-footer { + font: 12px/1 "sans serif", tahoma, verdana, helvetica; + text-align: right; + padding: 0 15px 5px 0; + background-color: #FFF; + height: 40px; } + .ke-dialog .ke-dialog-footer .ke-dialog-yes { + margin: 5px; } + .ke-dialog .ke-dialog-footer .ke-dialog-no { + margin: 5px 10px 5px 5px; } + .ke-dialog .ke-button-common { + display: inline-block; + text-align: center; + background: none; + border: none; + padding: 0; + cursor: pointer; } + .ke-dialog .ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; } + .ke-dialog .ke-button { + color: #333; + font-size: 12px; + border: 1px solid #e6e6e6; + background-color: #e6e6e6; + padding: 7px 10px; + margin-top: -4px; + color: #444; + text-decoration: none; + transition: background-color .3s ease-out, border-color .3s ease-out; } + .ke-dialog .ke-button:hover { + border: 1px solid #e1e1e1; + background-color: #e1e1e1; } + .ke-dialog .ke-dialog-btn { + font-size: 12px; + margin: 5px; + background: #2e8ded; + color: #fff !important; + padding: 8px 12px; + display: inline-block; + border-radius: 2px; + cursor: pointer; + text-decoration: none; + transition: .3s ease-out; } + .ke-dialog .ke-dialog-btn:hover { + filter: alpha(opacity=80); + box-shadow: none; + box-shadow: none; + opacity: .8; } + +.ke-container-primary .ke-toolbar { + border-top: 5px solid #009688; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + background-clip: padding-box; + text-rendering: optimizelegibility; } + .ke-container-primary .ke-toolbar .ke-toolbar-icon { + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; } + .ke-container-primary .ke-toolbar .ke-icon-source { + background-position: 0 0px; } + .ke-container-primary .ke-toolbar .ke-icon-preview { + background-position: 0 -63px; } + .ke-container-primary .ke-toolbar .ke-icon-print { + background-position: 0 -84px; } + .ke-container-primary .ke-toolbar .ke-icon-undo { + background-position: 0 -21px; } + .ke-container-primary .ke-toolbar .ke-icon-redo { + background-position: 0 -42px; } + .ke-container-primary .ke-toolbar .ke-icon-template { + background-position: 0 -105px; } + .ke-container-primary .ke-toolbar .ke-icon-cut { + background-position: 0 -147px; } + .ke-container-primary .ke-toolbar .ke-icon-copy { + background-position: 0 -168px; } + .ke-container-primary .ke-toolbar .ke-icon-paste { + background-position: 0 -189px; } + .ke-container-primary .ke-toolbar .ke-icon-selectall { + background-position: 0 -483px; } + .ke-container-primary .ke-toolbar .ke-icon-justifyleft { + background-position: 0 -252px; } + .ke-container-primary .ke-toolbar .ke-icon-justifycenter { + background-position: 0 -273px; } + .ke-container-primary .ke-toolbar .ke-icon-justifyright { + background-position: 0 -294px; } + .ke-container-primary .ke-toolbar .ke-icon-justifyfull { + background-position: 0 -315px; } + .ke-container-primary .ke-toolbar .ke-icon-insertorderedlist { + background-position: 0 -336px; } + .ke-container-primary .ke-toolbar .ke-icon-insertunorderedlist { + background-position: 0 -357px; } + .ke-container-primary .ke-toolbar .ke-icon-indent { + background-position: 0 -378px; } + .ke-container-primary .ke-toolbar .ke-icon-outdent { + background-position: 0 -399px; } + .ke-container-primary .ke-toolbar .ke-icon-subscript { + background-position: 0 -420px; } + .ke-container-primary .ke-toolbar .ke-icon-superscript { + background-position: 0 -441px; } + .ke-container-primary .ke-toolbar .ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-formatblock { + background-position: 0 -546px; } + .ke-container-primary .ke-toolbar .ke-icon-fontname { + background-position: 0 -567px; } + .ke-container-primary .ke-toolbar .ke-icon-fontsize { + background-position: 0 -588px; } + .ke-container-primary .ke-toolbar .ke-icon-forecolor { + background-position: 0 -609px; } + .ke-container-primary .ke-toolbar .ke-icon-hilitecolor { + background-position: 0 -630px; } + .ke-container-primary .ke-toolbar .ke-icon-bold { + background-position: 0 -651px; } + .ke-container-primary .ke-toolbar .ke-icon-italic { + background-position: 0 -672px; } + .ke-container-primary .ke-toolbar .ke-icon-underline { + background-position: 0 -693px; } + .ke-container-primary .ke-toolbar .ke-icon-strikethrough { + background-position: 0 -714px; } + .ke-container-primary .ke-toolbar .ke-icon-removeformat { + background-position: 0 -756px; } + .ke-container-primary .ke-toolbar .ke-icon-image { + background-position: 0 -777px; } + .ke-container-primary .ke-toolbar .ke-icon-flash { + background-position: 0 -840px; } + .ke-container-primary .ke-toolbar .ke-icon-media { + background-position: 0 -861px; } + .ke-container-primary .ke-toolbar .ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-hr { + background-position: 0 -924px; } + .ke-container-primary .ke-toolbar .ke-icon-emoticons { + background-position: 0 -945px; } + .ke-container-primary .ke-toolbar .ke-icon-link { + background-position: 0 -1008px; } + .ke-container-primary .ke-toolbar .ke-icon-unlink { + background-position: 0 -1029px; } + .ke-container-primary .ke-toolbar .ke-icon-fullscreen { + background-position: 0 -525px; } + .ke-container-primary .ke-toolbar .ke-icon-about { + background-position: 0 -1092px; } + .ke-container-primary .ke-toolbar .ke-icon-quote { + background-position: 0 -1114px; } + .ke-container-primary .ke-toolbar .ke-icon-plainpaste { + background-position: 0 -210px; } + .ke-container-primary .ke-toolbar .ke-icon-wordpaste { + background-position: 0 -231px; } + .ke-container-primary .ke-toolbar .ke-icon-table { + background-position: 0px -903px; + width: 18px !important; } + .ke-container-primary .ke-toolbar .ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-code { + background-position: 0 -126px; } + .ke-container-primary .ke-toolbar .ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-baidumap { + background-position: 0 -1050px; } + .ke-container-primary .ke-toolbar .ke-icon-lineheight { + background-position: 0 -735px; } + .ke-container-primary .ke-toolbar .ke-icon-clearhtml { + background-position: 0 -462px; } + .ke-container-primary .ke-toolbar .ke-icon-pagebreak { + background-position: 0 -966px; } + .ke-container-primary .ke-toolbar .ke-icon-insertfile { + background-position: 0 -882px; } + .ke-container-primary .ke-toolbar .ke-icon-quickformat { + background-position: 0 -504px; } + .ke-container-primary .ke-toolbar .ke-icon-anchor { + background-position: 0 -987px; } + .ke-container-primary .ke-toolbar .ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; } + .ke-container-primary .ke-toolbar .ke-icon-multiimage { + background-position: 0 -798px; } + .ke-container-primary .ke-toolbar .ke-icon-graft { + background-position: 0 -819px; } + +/** + menu 右键菜单 + */ +.ke-menu-primary .ke-menu-item .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-toolbar-icon { + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + width: 16px; + height: 16px; + margin: 0px 2px; + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tableinsert { + background-position: 0 -903px; + width: 18px !important; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tabledelete { + background-position: 0 -1428px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertleft { + background-position: 0 -1176px; + width: 18px !important; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertright { + background-position: 0 -1323px; + width: 18px !important; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertabove { + background-position: 0 -1302px; + width: 22px !important; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertbelow { + background-position: 0 -1155px; + width: 22px !important; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecoldelete { + background-position: 0 -1239px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowdelete { + background-position: 0 -1260px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecellprop { + background-position: 0 -1218px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tableprop { + background-position: 0 -1134px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowmerge { + background-position: -1px -1197px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowsplit { + background-position: 0 -1344px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecolmerge { + background-position: -4px -1365px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecolsplit { + background-position: 0 -1344px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-image { + background-position: 0 -777px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-flash { + background-position: 0 -840px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-media { + background-position: 0 -861px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-link { + background-position: 0 -1008px; } + .ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-checked { + background-position: 0 -1407px; } + +/*# sourceMappingURL=editor.css.map */ diff --git a/addons/nkeditor/assets/themes/primary/editor.min.css b/addons/nkeditor/assets/themes/primary/editor.min.css new file mode 100644 index 0000000000000000000000000000000000000000..62d52031e932363bc616940c7debb62e697d1583 --- /dev/null +++ b/addons/nkeditor/assets/themes/primary/editor.min.css @@ -0,0 +1 @@ +@charset "UTF-8";.ke-clearfix{zoom:1;clear:both}.ke-clearfix:after{content:".";display:block;clear:both;font-size:0;height:0;line-height:0;visibility:hidden}.ke-animated{animation:zoomIn;animation-duration:.3s;animation-fill-mode:both}@keyframes zoomIn{from{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.ke-dialog-mask{background-color:#fff;opacity:.5}.ke-dialog-lock{background-color:#fff;opacity:.5;z-index:811213;left:0;top:0;position:absolute}.ke-container{display:block;background-color:#fff;overflow:hidden;margin:0;padding:0;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 1px 1px rgba(0,0,0,.16)}.ke-container .ke-shadow{box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;background-color:#f0f0ee}.ke-container .ke-dialog a,.ke-container .ke-dialog a:hover,.ke-container .ke-menu a,.ke-container .ke-menu a:hover{color:#337fe5;text-decoration:none}.ke-container .ke-toolbar{text-align:left;overflow:hidden;zoom:1;padding:0 5px}.ke-container .ke-toolbar .ke-outline{padding:10px 5px;font-size:0;line-height:0;cursor:pointer;display:block;float:left}.ke-container .ke-toolbar .ke-outline .ke-toolbar-icon{font-size:0;line-height:0;overflow:hidden;display:block;width:16px;height:16px;margin:0 2px}.ke-container .ke-toolbar .ke-on{background:#ebebeb}.ke-container .ke-toolbar .ke-selected{background-color:#ebebeb}.ke-container .ke-toolbar .ke-disabled{cursor:default}.ke-container .ke-toolbar .ke-separator{height:16px;margin:2px 3px;border-left:1px solid #a0a0a0;border-right:1px solid #fff;border-top:0;border-bottom:0;width:0;font-size:0;line-height:0;overflow:hidden;display:block;float:left}.ke-container .ke-toolbar .ke-hr{clear:both;height:1px;width:calc(100% - (2 * 2px));background:#ebebeb}.ke-container .ke-edit{padding:0}.ke-container .ke-edit .ke-edit-iframe,.ke-container .ke-edit .ke-edit-textarea{border:0;margin:0;padding:0;overflow:auto}.ke-container .ke-edit .ke-edit-textarea{font:12px/1.5 Consolas,Monaco,"Bitstream Vera Sans Mono","Courier New",Courier,monospace;color:#000;overflow:auto;resize:none}.ke-container .ke-edit .ke-edit-textarea:focus{outline:0}.ke-container .ke-statusbar{position:relative;background-color:#f5f5f5;border-top:1px solid #e1e1e1;font-size:0;line-height:0;overflow:hidden;text-align:center;cursor:s-resize;display:none}.ke-container .ke-statusbar .ke-statusbar-center-icon{background-position:0 -754px;width:15px;height:11px}.ke-container .ke-statusbar .ke-statusbar-right-icon{position:absolute;right:0;bottom:0;cursor:se-resize;width:11px;height:11px}.ke-menu{border:1px solid #ccc;background-color:#f5f5f5;color:#222;padding:2px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;text-align:left;overflow:hidden}.ke-menu .ke-menu-item{border:1px solid #f1f1f1;background-color:#f1f1f1;color:#222;height:24px;overflow:hidden;cursor:pointer}.ke-menu .ke-menu-item .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-menu .ke-menu-item .ke-inline-block .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-menu .ke-menu-item .ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu .ke-menu-item .ke-menu-item-center{width:0;height:24px;border-left:1px solid #e3e3e3;border-right:1px solid #fff;border-top:0;border-bottom:0}.ke-menu .ke-menu-item .ke-menu-item-center-on{border-left:1px solid #e9eff6;border-right:1px solid #e9eff6}.ke-menu .ke-menu-item .ke-menu-item-right{border:0;padding:0 0 0 5px;line-height:24px;text-align:left;overflow:hidden}.ke-menu .ke-menu-item .ke-menu-separator{margin:2px 0;height:0;overflow:hidden;border-top:1px solid #e1e1e1;border-bottom:1px solid #fff;border-left:0;border-right:0}.ke-menu .ke-menu-item-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu .ke-plugin-emoticons{position:relative}.ke-menu .ke-plugin-emoticons .ke-preview{position:absolute;text-align:center;margin:2px;padding:10px;top:0;border:1px solid #a0a0a0;background-color:#fff;display:none}.ke-menu .ke-plugin-emoticons .ke-preview .ke-preview-img{border:0;margin:0;padding:0}.ke-menu .ke-plugin-emoticons .ke-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-menu .ke-plugin-emoticons .ke-table .ke-cell{margin:0;padding:1px;border:1px solid #f5f5f5;cursor:pointer}.ke-menu .ke-plugin-emoticons .ke-table .ke-cell .ke-img{display:block;background-repeat:no-repeat;overflow:hidden;margin:2px;width:24px;height:24px;margin:0;padding:0;border:0}.ke-menu .ke-plugin-emoticons .ke-table .ke-on{border:1px solid #5690d2;background-color:#e9eff6}.ke-menu .ke-plugin-emoticons .ke-page{text-align:right;margin:5px;padding:0;border:0;font:12px/1 "sans serif",tahoma,verdana,helvetica;color:#333;text-decoration:none}.ke-colorpicker{border:1px solid #a0a0a0;background-color:#f1f1f1;color:#222;padding:2px}.ke-colorpicker .ke-colorpicker-table{border:0;margin:0;padding:0;border-collapse:separate}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell{font-size:0;line-height:0;border:1px solid #f0f0ee;cursor:pointer;margin:3px;padding:0}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell .ke-colorpicker-cell-color{width:14px;height:14px;margin:3px;padding:0;border:0}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-top{font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;line-height:24px;border:1px solid #f1f1f1;cursor:pointer;margin:0;padding:0;text-align:center}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-on{border:1px solid #5690d2}.ke-colorpicker .ke-colorpicker-table .ke-colorpicker-cell-selected{border:1px solid #2446ab}.ke-dialog{margin:0;padding:0;border:1px solid #ccc;zoom:1;box-shadow:1px 1px 3px #a0a0a0;-moz-box-shadow:1px 1px 3px #a0a0a0;-webkit-box-shadow:1px 1px 3px #a0a0a0;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;overflow:hidden}.ke-dialog .ke-dialog-header{border:0;margin:0;font-weight:700;font-size:14px;height:30px;line-height:30px;padding:0 10px;text-align:left;color:#222;cursor:move;border-top-left-radius:6px;border-top-right-radius:6px;border-bottom:1px solid #c6c6c6;background:transparent url(../common/dialog-title-bg.png) repeat-x scroll 0 0;position:relative;cursor:move}.ke-dialog .ke-dialog-header .ke-dialog-icon-close{height:20px;width:20px;cursor:pointer;background:url(../common/icons-all.gif) 0 -59px;position:absolute;right:5px;top:4px}.ke-dialog .ke-dialog-header .ke-dialog-icon-close:hover{background-position:0 -89px}.ke-dialog .ke-dialog-content{background-color:#fff;width:100%;height:100%;color:#333;outline:0;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body{font:12px/1.5 "sans serif",tahoma,verdana,helvetica;text-align:left;overflow:hidden;width:100%}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea{display:block;width:408px;height:260px;font-family:"sans serif",tahoma,verdana,helvetica;font-size:12px;border:1px solid #ccc}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-textarea:focus{border-color:#66afe9;outline:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-select{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1;width:auto;border:1px solid #ccc;height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-form{margin:0;padding:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-number{width:50px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-checkbox{position:relative;top:6px}.ke-dialog .ke-dialog-content .ke-dialog-body textarea{display:block;overflow:auto;padding:0;resize:none}.ke-dialog .ke-dialog-content .ke-dialog-body textarea:focus{outline:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text{display:inline-block!important;max-width:400px;height:30px;line-height:30px;border:1px solid #ccc;font-size:14px;margin:0;outline:0;padding:0 10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-text:focus{border-color:#66afe9}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-input-color{border:1px solid #e1e1e1;background-color:#fff;font-size:12px;width:60px;height:30px;line-height:30px;padding-left:5px;overflow:hidden;cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area{position:relative;overflow:hidden;margin:0;padding:0;top:-1px;position:relative}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-upload-file{position:absolute;font-size:60px;top:0;right:0;padding:0;margin:0;z-index:811212;border:0 none;opacity:0;cursor:pointer;width:62px;height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button-common{top:-1px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-upload-area .ke-button{padding:8px 15px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner{padding:10px 20px 0 20px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row{border:1px solid #fff;margin-bottom:10px;overflow:hidden}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-left{float:left;height:30px;line-height:30px;width:60px;text-align:right}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right{float:left;text-align:left}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right .ke-inline-block .ke-upload-button{position:relative;top:-1px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label{cursor:pointer;display:-moz-inline-stack;display:inline-block;vertical-align:middle;text-align:right;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-dialog-row .row-right label img{display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header{height:30px;line-height:30px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-input-text{height:22px;line-height:22px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .ke-button{padding:3px 10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-header .checkbox{margin-left:10px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs{font:12px/1 "sans serif",tahoma,verdana,helvetica;border-bottom:1px solid #e1e1e1;margin-bottom:20px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul{list-style:none outside none;margin:0;padding:0}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li{position:relative;margin:0 2px -1px 0;padding:0 20px;float:left;line-height:25px;text-align:center;color:#337ab7;cursor:pointer}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-selected{background-color:#fff;border:1px solid #e1e1e1;border-bottom:1px solid #fff;color:#555;cursor:default;border-top-left-radius:3px;border-top-right-radius:3px}.ke-dialog .ke-dialog-content .ke-dialog-body .ke-dialog-content-inner .ke-tabs .ke-tabs-ul .ke-tabs-li-on{background-color:#fff;color:#000}.ke-dialog .ke-dialog-content .ke-dialog-loading{position:absolute;top:0;left:1px;z-index:1;text-align:center}.ke-dialog .ke-dialog-content .ke-dialog-loading .ke-dialog-loading-content{background:url(../common/loading.gif) no-repeat center;color:#666;font-size:14px;font-weight:700;height:31px;line-height:31px;padding-left:36px}.ke-dialog .ke-dialog-footer{font:12px/1 "sans serif",tahoma,verdana,helvetica;text-align:right;padding:0 15px 5px 0;background-color:#fff;height:40px}.ke-dialog .ke-dialog-footer .ke-dialog-yes{margin:5px}.ke-dialog .ke-dialog-footer .ke-dialog-no{margin:5px 10px 5px 5px}.ke-dialog .ke-button-common{display:inline-block;text-align:center;background:0 0;border:none;padding:0;cursor:pointer}.ke-dialog .ke-button-outer{background-position:0 -25px;padding:0;display:-moz-inline-stack;display:inline-block;vertical-align:middle;zoom:1}.ke-dialog .ke-button{color:#333;font-size:12px;border:1px solid #e6e6e6;background-color:#e6e6e6;padding:7px 10px;margin-top:-4px;color:#444;text-decoration:none;transition:background-color .3s ease-out,border-color .3s ease-out}.ke-dialog .ke-button:hover{border:1px solid #e1e1e1;background-color:#e1e1e1}.ke-dialog .ke-dialog-btn{font-size:12px;margin:5px;background:#2e8ded;color:#fff!important;padding:8px 12px;display:inline-block;border-radius:2px;cursor:pointer;text-decoration:none;transition:.3s ease-out}.ke-dialog .ke-dialog-btn:hover{box-shadow:none;box-shadow:none;opacity:.8}.ke-container-primary .ke-toolbar{border-top:5px solid #009688;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 1px 1px rgba(0,0,0,.16);background-clip:padding-box;text-rendering:optimizelegibility}.ke-container-primary .ke-toolbar .ke-toolbar-icon{background:url(images/nkeditor.svg) no-repeat}.ke-container-primary .ke-toolbar .ke-icon-source{background-position:0 0}.ke-container-primary .ke-toolbar .ke-icon-preview{background-position:0 -63px}.ke-container-primary .ke-toolbar .ke-icon-print{background-position:0 -84px}.ke-container-primary .ke-toolbar .ke-icon-undo{background-position:0 -21px}.ke-container-primary .ke-toolbar .ke-icon-redo{background-position:0 -42px}.ke-container-primary .ke-toolbar .ke-icon-template{background-position:0 -105px}.ke-container-primary .ke-toolbar .ke-icon-cut{background-position:0 -147px}.ke-container-primary .ke-toolbar .ke-icon-copy{background-position:0 -168px}.ke-container-primary .ke-toolbar .ke-icon-paste{background-position:0 -189px}.ke-container-primary .ke-toolbar .ke-icon-selectall{background-position:0 -483px}.ke-container-primary .ke-toolbar .ke-icon-justifyleft{background-position:0 -252px}.ke-container-primary .ke-toolbar .ke-icon-justifycenter{background-position:0 -273px}.ke-container-primary .ke-toolbar .ke-icon-justifyright{background-position:0 -294px}.ke-container-primary .ke-toolbar .ke-icon-justifyfull{background-position:0 -315px}.ke-container-primary .ke-toolbar .ke-icon-insertorderedlist{background-position:0 -336px}.ke-container-primary .ke-toolbar .ke-icon-insertunorderedlist{background-position:0 -357px}.ke-container-primary .ke-toolbar .ke-icon-indent{background-position:0 -378px}.ke-container-primary .ke-toolbar .ke-icon-outdent{background-position:0 -399px}.ke-container-primary .ke-toolbar .ke-icon-subscript{background-position:0 -420px}.ke-container-primary .ke-toolbar .ke-icon-superscript{background-position:0 -441px}.ke-container-primary .ke-toolbar .ke-icon-date{background-position:0 -304px;width:25px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-time{background-position:0 -320px;width:25px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-formatblock{background-position:0 -546px}.ke-container-primary .ke-toolbar .ke-icon-fontname{background-position:0 -567px}.ke-container-primary .ke-toolbar .ke-icon-fontsize{background-position:0 -588px}.ke-container-primary .ke-toolbar .ke-icon-forecolor{background-position:0 -609px}.ke-container-primary .ke-toolbar .ke-icon-hilitecolor{background-position:0 -630px}.ke-container-primary .ke-toolbar .ke-icon-bold{background-position:0 -651px}.ke-container-primary .ke-toolbar .ke-icon-italic{background-position:0 -672px}.ke-container-primary .ke-toolbar .ke-icon-underline{background-position:0 -693px}.ke-container-primary .ke-toolbar .ke-icon-strikethrough{background-position:0 -714px}.ke-container-primary .ke-toolbar .ke-icon-removeformat{background-position:0 -756px}.ke-container-primary .ke-toolbar .ke-icon-image{background-position:0 -777px}.ke-container-primary .ke-toolbar .ke-icon-flash{background-position:0 -840px}.ke-container-primary .ke-toolbar .ke-icon-media{background-position:0 -861px}.ke-container-primary .ke-toolbar .ke-icon-div{background-position:0 -544px;width:16px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-formula{background-position:0 -576px;width:16px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-hr{background-position:0 -924px}.ke-container-primary .ke-toolbar .ke-icon-emoticons{background-position:0 -945px}.ke-container-primary .ke-toolbar .ke-icon-link{background-position:0 -1008px}.ke-container-primary .ke-toolbar .ke-icon-unlink{background-position:0 -1029px}.ke-container-primary .ke-toolbar .ke-icon-fullscreen{background-position:0 -525px}.ke-container-primary .ke-toolbar .ke-icon-about{background-position:0 -1092px}.ke-container-primary .ke-toolbar .ke-icon-quote{background-position:0 -1114px}.ke-container-primary .ke-toolbar .ke-icon-plainpaste{background-position:0 -210px}.ke-container-primary .ke-toolbar .ke-icon-wordpaste{background-position:0 -231px}.ke-container-primary .ke-toolbar .ke-icon-table{background-position:0 -903px;width:18px!important}.ke-container-primary .ke-toolbar .ke-icon-tablemenu{background-position:0 -768px;width:16px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-code{background-position:0 -126px}.ke-container-primary .ke-toolbar .ke-icon-map{background-position:0 -976px;width:16px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-baidumap{background-position:0 -1050px}.ke-container-primary .ke-toolbar .ke-icon-lineheight{background-position:0 -735px}.ke-container-primary .ke-toolbar .ke-icon-clearhtml{background-position:0 -462px}.ke-container-primary .ke-toolbar .ke-icon-pagebreak{background-position:0 -966px}.ke-container-primary .ke-toolbar .ke-icon-insertfile{background-position:0 -882px}.ke-container-primary .ke-toolbar .ke-icon-quickformat{background-position:0 -504px}.ke-container-primary .ke-toolbar .ke-icon-anchor{background-position:0 -987px}.ke-container-primary .ke-toolbar .ke-icon-search{background-position:0 -1184px;width:16px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-new{background-position:0 -1200px;width:16px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-specialchar{background-position:0 -1216px;width:16px;height:16px}.ke-container-primary .ke-toolbar .ke-icon-multiimage{background-position:0 -798px}.ke-container-primary .ke-toolbar .ke-icon-graft{background-position:0 -819px}.ke-menu-primary .ke-menu-item .ke-menu-item-left{width:27px;text-align:center;overflow:hidden}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-toolbar-icon{font-size:0;line-height:0;overflow:hidden;display:block;width:16px;height:16px;margin:0 2px;background:url(images/nkeditor.svg) no-repeat}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tableinsert{background-position:0 -903px;width:18px!important}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tabledelete{background-position:0 -1428px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertleft{background-position:0 -1176px;width:18px!important}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecolinsertright{background-position:0 -1323px;width:18px!important}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertabove{background-position:0 -1302px;width:22px!important}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowinsertbelow{background-position:0 -1155px;width:22px!important}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecoldelete{background-position:0 -1239px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowdelete{background-position:0 -1260px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecellprop{background-position:0 -1218px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tableprop{background-position:0 -1134px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecellsplit{background-position:0 -1088px;width:16px;height:16px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowmerge{background-position:-1px -1197px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablerowsplit{background-position:0 -1344px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecolmerge{background-position:-4px -1365px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-tablecolsplit{background-position:0 -1344px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-image{background-position:0 -777px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-flash{background-position:0 -840px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-media{background-position:0 -861px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-link{background-position:0 -1008px}.ke-menu-primary .ke-menu-item .ke-menu-item-left .ke-icon-checked{background-position:0 -1407px} \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/primary/editor.scss b/addons/nkeditor/assets/themes/primary/editor.scss new file mode 100644 index 0000000000000000000000000000000000000000..c20d945c70546c3e854d684b22f285985445cad7 --- /dev/null +++ b/addons/nkeditor/assets/themes/primary/editor.scss @@ -0,0 +1,387 @@ +@import "../common/common"; + +.ke-container-primary { + .ke-toolbar { + + border-top: 5px solid #009688; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 1px 1px rgba(0, 0, 0, 0.16); + background-clip: padding-box; + text-rendering: optimizelegibility; + + .ke-toolbar-icon { + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; + } + + .ke-icon-source { + background-position: 0 0px; + } + .ke-icon-preview { + background-position: 0 -63px; + } + .ke-icon-print { + background-position: 0 -84px; + } + .ke-icon-undo { + background-position: 0 -21px; + } + + .ke-icon-redo { + background-position: 0 -42px; + } + + .ke-icon-template { + background-position: 0 -105px; + } + + .ke-icon-cut { + background-position: 0 -147px; + } + + .ke-icon-copy { + background-position: 0 -168px; + } + + .ke-icon-paste { + background-position: 0 -189px; + } + + .ke-icon-selectall { + background-position: 0 -483px; + } + + .ke-icon-justifyleft { + background-position: 0 -252px; + } + + .ke-icon-justifycenter { + background-position: 0 -273px; + } + + .ke-icon-justifyright { + background-position: 0 -294px; + } + + .ke-icon-justifyfull { + background-position: 0 -315px; + } + + .ke-icon-insertorderedlist { + background-position: 0 -336px; + } + + .ke-icon-insertunorderedlist { + background-position: 0 -357px; + } + + .ke-icon-indent { + background-position: 0 -378px; + } + + .ke-icon-outdent { + background-position: 0 -399px; + } + + .ke-icon-subscript { + background-position: 0 -420px; + } + + .ke-icon-superscript { + background-position: 0 -441px; + } + + .ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; + } + + .ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; + } + + .ke-icon-formatblock { + background-position: 0 -546px; + } + + .ke-icon-fontname { + background-position: 0 -567px; + } + + .ke-icon-fontsize { + background-position: 0 -588px; + } + + .ke-icon-forecolor { + background-position: 0 -609px; + } + + .ke-icon-hilitecolor { + background-position: 0 -630px; + } + + .ke-icon-bold { + background-position: 0 -651px; + } + + .ke-icon-italic { + background-position: 0 -672px; + } + + .ke-icon-underline { + background-position: 0 -693px; + } + + .ke-icon-strikethrough { + background-position: 0 -714px; + } + + .ke-icon-removeformat { + background-position: 0 -756px; + } + + .ke-icon-image { + background-position: 0 -777px; + } + + .ke-icon-flash { + background-position: 0 -840px; + } + + .ke-icon-media { + background-position: 0 -861px; + } + + .ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; + } + + .ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; + } + + .ke-icon-hr { + background-position: 0 -924px; + } + + .ke-icon-emoticons { + background-position: 0 -945px; + } + + .ke-icon-link { + background-position: 0 -1008px; + } + + .ke-icon-unlink { + background-position: 0 -1029px; + } + + .ke-icon-fullscreen { + background-position: 0 -525px; + } + + .ke-icon-about { + background-position: 0 -1092px; + } + + .ke-icon-quote { + background-position: 0 -1114px; + } + + .ke-icon-plainpaste { + background-position: 0 -210px; + } + + .ke-icon-wordpaste { + background-position: 0 -231px; + } + + .ke-icon-table { + background-position: 0px -903px; + width: 18px !important; + } + + .ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; + } + + .ke-icon-code { + background-position: 0 -126px; + } + + .ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; + } + + .ke-icon-baidumap { + background-position: 0 -1050px; + } + + .ke-icon-lineheight { + background-position: 0 -735px; + } + + .ke-icon-clearhtml { + background-position: 0 -462px; + } + + .ke-icon-pagebreak { + background-position: 0 -966px; + } + + .ke-icon-insertfile { + background-position: 0 -882px; + } + + .ke-icon-quickformat { + background-position: 0 -504px; + } + + .ke-icon-anchor { + background-position: 0 -987px; + } + + .ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; + } + + .ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; + } + + .ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; + } + + .ke-icon-multiimage { + background-position: 0 -798px; + } + + .ke-icon-graft { + background-position: 0 -819px; + } + } +} + +/** + menu 右键菜单 + */ +.ke-menu-primary { + + .ke-menu-item { + + .ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; + + .ke-toolbar-icon { + @include ke-toolbar-icon; + *background-image: url(images/nkeditor.png); + background: url(images/nkeditor.svg) no-repeat; + } + + .ke-icon-tableinsert { + background-position: 0 -903px; + width: 18px !important; + } + + .ke-icon-tabledelete { + background-position: 0 -1428px; + } + + .ke-icon-tablecolinsertleft { + background-position: 0 -1176px; + width: 18px !important; + } + + .ke-icon-tablecolinsertright { + background-position: 0 -1323px; + width: 18px !important; + } + + .ke-icon-tablerowinsertabove { + background-position: 0 -1302px; + width: 22px !important; + } + + .ke-icon-tablerowinsertbelow { + background-position: 0 -1155px; + width: 22px !important; + } + + .ke-icon-tablecoldelete { + background-position: 0 -1239px; + } + + .ke-icon-tablerowdelete { + background-position: 0 -1260px; + } + + .ke-icon-tablecellprop { + background-position: 0 -1218px; + } + + .ke-icon-tableprop { + background-position: 0 -1134px; + } + .ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; + } + + .ke-icon-tablerowmerge { + background-position: -1px -1197px; + } + + .ke-icon-tablerowsplit { + background-position: 0 -1344px; + } + + .ke-icon-tablecolmerge { + background-position: -4px -1365px; + } + + .ke-icon-tablecolsplit { + background-position: 0 -1344px; + } + + //图片,视频右键菜单 + .ke-icon-image { + background-position: 0 -777px; + } + .ke-icon-flash { + background-position: 0 -840px; + } + .ke-icon-media { + background-position: 0 -861px; + } + .ke-icon-link { + background-position: 0 -1008px; + } + + .ke-icon-checked { + background-position: 0 -1407px; + } + + } + } +} +//menu end \ No newline at end of file diff --git a/addons/nkeditor/assets/themes/primary/images/nkeditor.png b/addons/nkeditor/assets/themes/primary/images/nkeditor.png new file mode 100644 index 0000000000000000000000000000000000000000..2bd53f2099d3d5a054c49af33923af8e3adcf47c Binary files /dev/null and b/addons/nkeditor/assets/themes/primary/images/nkeditor.png differ diff --git a/addons/nkeditor/assets/themes/primary/images/nkeditor.svg b/addons/nkeditor/assets/themes/primary/images/nkeditor.svg new file mode 100644 index 0000000000000000000000000000000000000000..3c83f022d13ed4ab9c05e2dabb4c6c0feee30c81 --- /dev/null +++ b/addons/nkeditor/assets/themes/primary/images/nkeditor.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/nkeditor/bootstrap.js b/addons/nkeditor/bootstrap.js new file mode 100644 index 0000000000000000000000000000000000000000..3ffd68adb4ce84968c2ae003e51f2c6b8b16093e --- /dev/null +++ b/addons/nkeditor/bootstrap.js @@ -0,0 +1,249 @@ +require.config({ + paths: { + 'nkeditor': '../addons/nkeditor/js/customplugin', + 'nkeditor-core': '../addons/nkeditor/nkeditor.min', + 'nkeditor-lang': '../addons/nkeditor/lang/zh-CN', + }, + shim: { + 'nkeditor': { + deps: [ + 'nkeditor-core', + 'nkeditor-lang' + ] + }, + 'nkeditor-core': { + deps: [ + 'css!../addons/nkeditor/themes/black/editor.min.css', + 'css!../addons/nkeditor/css/common.css' + ], + exports: 'window.KindEditor' + }, + 'nkeditor-lang': { + deps: [ + 'nkeditor-core' + ] + } + } +}); +if ($(".editor").size() > 0) { + require(['nkeditor', 'upload'], function (Nkeditor, Upload) { + var getImageFromClipboard, getImageFromDrop; + getImageFromClipboard = function (data) { + var i, item; + i = 0; + while (i < data.clipboardData.items.length) { + item = data.clipboardData.items[i]; + if (item.type.indexOf("image") !== -1) { + return item.getAsFile() || false; + } + i++; + } + return false; + }; + getImageFromDrop = function (data) { + var i, item, images; + i = 0; + images = []; + while (i < data.dataTransfer.files.length) { + item = data.dataTransfer.files[i]; + if (item.type.indexOf("image") !== -1) { + images.push(item); + } + i++; + } + return images; + }; + + var getImageFromUrl = function (url, callback, outputFormat) { + var canvas = document.createElement('CANVAS'), + ctx = canvas.getContext('2d'), + img = new Image; + img.crossOrigin = 'Anonymous'; + img.onload = function () { + var urlArr = url.split('.'); + var suffix = urlArr.pop(); + suffix = suffix.match(/^(jpg|png|gif|bmp|jpeg)$/i) ? suffix : 'png'; + + try { + canvas.height = img.height; + canvas.width = img.width; + ctx.drawImage(img, 0, 0); + var dataURL = canvas.toDataURL(outputFormat || 'image/' + suffix); + + var arr = dataURL.split(','), mime = arr[0].match(/:(.*?);/)[1], + bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + var filename = url.substr(url.lastIndexOf('/') + 1); + var exp = new RegExp("\\." + suffix + "$", "i"); + filename = exp.test(filename) ? filename : filename + "." + suffix; + var file = new File([u8arr], filename, {type: mime}); + } catch (e) { + callback.call(this, null); + } + + callback.call(this, file); + canvas = null; + }; + img.onerror = function (e) { + callback.call(this, null); + }; + img.src = url; + }; + + Nkeditor.lang({ + remoteimage: '下载远程图片' + }); + //远程下载图片 + Nkeditor.plugin('remoteimage', function (K) { + var editor = this, name = 'remoteimage'; + editor.plugin.remoteimage = { + download: function (e) { + var that = this; + var html = that.html(); + var staging = {}, orgined = {}, index = 0, images = 0, completed = 0, failured = 0; + var checkrestore = function () { + if (completed + failured >= images) { + $.each(staging, function (i, j) { + that.html(that.html().replace("" + i + "", j)); + }); + } + }; + html.replace(/([\s\S]*?)<\/code>/g, function (code) { + staging[index] = code; + return "" + index + ""; + } + ); + html = html.replace(//g, function () { + images++; + var url = arguments[3]; + var placeholder = ''; + //如果是云存储的链接,则忽略 + if (Config.upload.cdnurl && url.indexOf(Config.upload.cdnurl) > -1) { + completed++; + return arguments[0]; + } else { + orgined[index] = arguments[0]; + } + //下载远程图片 + (function (index, url, placeholder) { + getImageFromUrl(url, function (file) { + if (!file) { + failured++; + that.html(that.html().replace(placeholder, orgined[index])); + checkrestore(); + } else { + Upload.api.send(file, function (data) { + completed++; + that.html(that.html().replace(placeholder, '')); + checkrestore(); + }, function (data) { + failured++; + that.html(that.html().replace(placeholder, orgined[index])); + checkrestore(); + }); + } + }); + })(index, url, placeholder); + index++; + return placeholder; + }); + if (index > 0) { + that.html(html); + } else { + Toastr.info("没有需要下载的远程图片"); + } + } + }; + // 点击图标时执行 + editor.clickToolbar(name, editor.plugin.remoteimage.download); + }); + + $(".editor").each(function () { + var that = this; + Nkeditor.create(that, { + width: '100%', + filterMode: false, + wellFormatMode: false, + allowMediaUpload: true, //是否允许媒体上传 + allowFileManager: true, + allowImageUpload: true, + cssPath: Fast.api.cdnurl('/assets/addons/nkeditor/plugins/code/prism.css'), + cssData: "body {font-size: 13px}", + fillDescAfterUploadImage: false, //是否在上传后继续添加描述信息 + themeType: typeof Config.nkeditor != 'undefined' ? Config.nkeditor.theme : 'black', //编辑器皮肤,这个值从后台获取 + fileManagerJson: Fast.api.fixurl("/addons/nkeditor/index/attachment/module/" + Config.modulename), + items: [ + 'source', 'undo', 'redo', 'preview', 'print', 'template', 'code', 'quote', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', + 'formatblock', 'fontname', 'fontsize', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', 'image', 'multiimage', 'graft', + 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', 'remoteimage', 'about', 'fullscreen' + ], + afterCreate: function () { + var self = this; + //Ctrl+回车提交 + Nkeditor.ctrl(document, 13, function () { + self.sync(); + $(that).closest("form").submit(); + }); + Nkeditor.ctrl(self.edit.doc, 13, function () { + self.sync(); + $(that).closest("form").submit(); + }); + //粘贴上传 + $("body", self.edit.doc).bind('paste', function (event) { + var image, pasteEvent; + pasteEvent = event.originalEvent; + if (pasteEvent.clipboardData && pasteEvent.clipboardData.items) { + image = getImageFromClipboard(pasteEvent); + if (image) { + event.preventDefault(); + Upload.api.send(image, function (data) { + self.exec("insertimage", Fast.api.cdnurl(data.url)); + }); + } + } + }); + //挺拽上传 + $("body", self.edit.doc).bind('drop', function (event) { + var image, pasteEvent; + pasteEvent = event.originalEvent; + if (pasteEvent.dataTransfer && pasteEvent.dataTransfer.files) { + images = getImageFromDrop(pasteEvent); + if (images.length > 0) { + event.preventDefault(); + $.each(images, function (i, image) { + Upload.api.send(image, function (data) { + self.exec("insertimage", Fast.api.cdnurl(data.url)); + }); + }); + } + } + }); + }, + //FastAdmin自定义处理 + beforeUpload: function (callback, file) { + var file = file ? file : $("input.ke-upload-file", this.form).prop('files')[0]; + Upload.api.send(file, function (data) { + var data = {code: '000', data: {url: Fast.api.cdnurl(data.url)}, title: '', width: '', height: '', border: '', align: ''}; + callback(data); + }); + + }, + //错误处理 handler + errorMsgHandler: function (message, type) { + try { + console.log(message, type); + } catch (Error) { + alert(message); + } + } + }); + }); + }); +} \ No newline at end of file diff --git a/addons/nkeditor/config.php b/addons/nkeditor/config.php new file mode 100644 index 0000000000000000000000000000000000000000..c4d03096eed9033bb1e715be0e2a452db924cd39 --- /dev/null +++ b/addons/nkeditor/config.php @@ -0,0 +1,63 @@ + 'theme', + //显示的标题 + 'title' => '编辑器主题', + //类型 + 'type' => 'select', + //数据字典 + 'content' => [ + 'default' => '经典主题', + 'black' => '雅黑主题', + 'blue' => '淡蓝主题', + 'grey' => '深灰主题', + 'primary' => '深绿主题', + ], + //值 + 'value' => 'black', + //验证规则 + 'rule' => 'required', + //错误消息 + 'msg' => '', + //提示消息 + 'tip' => '', + //成功消息 + 'ok' => '', + //扩展信息 + 'extend' => '' + ], + [ + 'name' => 'attachmentmode_admin', + 'title' => '管理员附件选择模式', + 'type' => 'select', + 'content' => [ + 'all' => '任何管理员均可以查看全部上传的文件', + 'auth' => '仅可以查看自己及所有子管理员上传的文件', + 'personal' => '仅可以查看选择自己上传的文件', + ], + 'value' => 'all', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '' + ], + [ + 'name' => 'attachmentmode_index', + 'title' => '后台附件选择模式', + 'type' => 'select', + 'content' => [ + 'all' => '任何会员均可以查看全部上传的文件', + 'personal' => '仅可以查看选择自己上传的文件', + ], + 'value' => 'all', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '' + ], +]; diff --git a/addons/nkeditor/controller/Index.php b/addons/nkeditor/controller/Index.php new file mode 100644 index 0000000000000000000000000000000000000000..82c7edc2cf878815aaeaebe3a33225c39e701a08 --- /dev/null +++ b/addons/nkeditor/controller/Index.php @@ -0,0 +1,99 @@ +error('该插件暂无前台页面'); + } + + /** + * 文件列表 + */ + public function attachment() + { + $model = new Attachment; + $page = $this->request->request('page'); + $fileType = $this->request->request('fileType'); + $module = $this->request->param('module'); + $pagesize = 15; + $config = get_addon_config('nkeditor'); + $type = []; + $imageSuffix = ['png', 'jpg', 'jpeg', 'gif', 'bmp']; + if ($fileType == 'image') { + $type = $imageSuffix; + } else if ($fileType == 'flash') { + $type = ['swf', 'flv']; + } else if ($fileType == 'media') { + $type = ['swf', 'flv']; + } else if ($fileType == 'file') { + + } + if ($module == 'admin') { + $auth = \app\admin\library\Auth::instance(); + if (!$auth->id) { + $this->error('请登录后再操作!'); + } else { + $mode = $config['attachmentmode_admin']; + } + if ($mode == 'all') { + + } else { + if (!$auth->isSuperAdmin()) { + $adminIds = $mode == 'auth' ? $auth->getChildrenAdminIds(true) : [$auth->id]; + $model->where('admin_id', 'in', $adminIds); + } + } + } else { + if (!$this->auth->id) { + $this->error('请登录后再操作!'); + } else { + $mode = $config['attachmentmode_index']; + } + if ($mode == 'all') { + + } else { + $model->where('user_id', 'in', [$this->auth->id]); + } + } + + if ($type) { + $model->where('imagetype', 'in', $type); + } + + $list = $model + ->order('id', 'desc') + ->paginate($pagesize); + + $items = $list->items(); + $data = []; + $cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root()); + foreach ($items as $k => &$v) { + $v['fullurl'] = $v['storage'] == 'local' ? $cdnurl . $v['url'] : cdnurl($v['url']); + $v['imagetype'] = strtolower($v['imagetype']); + $data[] = [ + 'width' => $v['imagewidth'], + 'height' => $v['imageheight'], + 'filesize' => $v['filesize'], + 'oriURL' => $v['fullurl'], + 'thumbURL' => !in_array($v['imagetype'], $imageSuffix) ? "https://tool.fastadmin.net/icon/{$v['imagetype']}.png" : $v['fullurl'], + ]; + } + $result = [ + 'code' => '000', + 'count' => $list->total(), + 'page' => $page, + 'pagesize' => $pagesize, + 'extra' => '', + 'data' => $data + ]; + return json($result); + } + +} diff --git a/addons/nkeditor/info.ini b/addons/nkeditor/info.ini new file mode 100644 index 0000000000000000000000000000000000000000..13dc43b5569380b6af93bd2f6e3543c91d8d29af --- /dev/null +++ b/addons/nkeditor/info.ini @@ -0,0 +1,8 @@ +name = nkeditor +title = 简洁强大的富文本编辑器 +intro = 一款基于Kindeditor二次开发的编辑器 +author = Karson +website = https://www.fastadmin.net +version = 1.0.5 +state = 1 +url = /fastadmin/my/public/addons/nkeditor diff --git a/addons/nkeditor/license.txt b/addons/nkeditor/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..f166cc57b2783565bc48e8999103c572fca4c0e4 --- /dev/null +++ b/addons/nkeditor/license.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! \ No newline at end of file diff --git a/addons/qiniu/Qiniu.php b/addons/qiniu/Qiniu.php new file mode 100644 index 0000000000000000000000000000000000000000..6d9a279f15838c9c013c3eb334230237da9e9d5f --- /dev/null +++ b/addons/qiniu/Qiniu.php @@ -0,0 +1,65 @@ +getConfig(); + + $policy = array( + 'saveKey' => ltrim($qiniucfg['savekey'], '/'), + ); + //如果启用服务端回调 + if ($qiniucfg['notifyenabled']) { + $policy = array_merge($policy, [ + 'callbackUrl' => $qiniucfg['notifyurl'], + 'callbackBody' => 'filename=$(fname)&key=$(key)&imageInfo=$(imageInfo)&filesize=$(fsize)&admin=$(x:admin)&user=$(x:user)' + ]); + } + + $auth = new Auth($qiniucfg['app_key'], $qiniucfg['secret_key']); + $multipart['token'] = $auth->uploadToken($qiniucfg['bucket'], null, $qiniucfg['expire'], $policy); + $multipart['admin'] = (int)session('admin.id'); + $multipart['user'] = (int)cookie('uid'); + $upload = [ + 'cdnurl' => $qiniucfg['cdnurl'], + 'uploadurl' => $qiniucfg['uploadurl'], + 'bucket' => $qiniucfg['bucket'], + 'maxsize' => $qiniucfg['maxsize'], + 'mimetype' => $qiniucfg['mimetype'], + 'multipart' => $multipart, + 'multiple' => $qiniucfg['multiple'] ? true : false, + ]; + } + +} diff --git a/addons/qiniu/bootstrap.js b/addons/qiniu/bootstrap.js new file mode 100644 index 0000000000000000000000000000000000000000..8f88115e84b63d34c4d03c12fb1d3b6eeec55037 --- /dev/null +++ b/addons/qiniu/bootstrap.js @@ -0,0 +1,21 @@ +//修改上传的接口调用 +require(['upload'], function (Upload) { + var _onUploadResponse = Upload.events.onUploadResponse; + Upload.events.onUploadResponse = function (response) { + try { + var ret = typeof response === 'object' ? response : JSON.parse(response); + if (ret.hasOwnProperty("code") && ret.hasOwnProperty("data")) { + return _onUploadResponse.call(this, response); + } else if (ret.hasOwnProperty("key") && !ret.hasOwnProperty("err_code")) { + ret.code = 1; + ret.data = { + url: '/' + ret.key + }; + return _onUploadResponse.call(this, JSON.stringify(ret)); + } + } catch (e) { + } + return _onUploadResponse.call(this, response); + + }; +}); \ No newline at end of file diff --git a/addons/qiniu/config.php b/addons/qiniu/config.php new file mode 100644 index 0000000000000000000000000000000000000000..040e54dd79036d9f46e3658e336fd56f6acacda6 --- /dev/null +++ b/addons/qiniu/config.php @@ -0,0 +1,178 @@ + + array( + 'name' => 'app_key', + 'title' => 'app_key', + 'type' => 'string', + 'content' => + array(), + 'value' => 'your app_key', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请在个人中心 > 密钥管理中获取 > AK', + 'ok' => '', + 'extend' => '', + ), + 'secret_key' => + array( + 'name' => 'secret_key', + 'title' => 'secret_key', + 'type' => 'string', + 'content' => + array(), + 'value' => 'your secret_key', + 'rule' => 'required', + 'msg' => '', + 'tip' => '请在个人中心 > 密钥管理中获取 > SK', + 'ok' => '', + 'extend' => '', + ), + 'bucket' => + array( + 'name' => 'bucket', + 'title' => 'bucket', + 'type' => 'string', + 'content' => + array(), + 'value' => 'yourbucket', + 'rule' => 'required', + 'msg' => '', + 'tip' => '存储空间名称', + 'ok' => '', + 'extend' => '', + ), + 'uploadurl' => + array( + 'name' => 'uploadurl', + 'title' => '上传接口地址', + 'type' => 'select', + 'content' => + array( + 'https://upload-z0.qiniup.com' => '华东 https://upload-z0.qiniup.com', + 'https://upload-z1.qiniup.com' => '华北 https://upload-z1.qiniup.com', + 'https://upload-z2.qiniup.com' => '华南 https://upload-z2.qiniup.com', + 'https://upload-na0.qiniup.com' => '北美 https://upload-na0.qiniup.com', + 'https://upload-as0.qiniup.com' => '东南亚 https://upload-as0.qiniup.com', + ), + 'value' => 'https://upload-z2.qiniup.com', + 'rule' => 'required', + 'msg' => '', + 'tip' => '推荐选择最近的地址', + 'ok' => '', + 'extend' => '', + ), + 'cdnurl' => + array( + 'name' => 'cdnurl', + 'title' => 'CDN地址', + 'type' => 'string', + 'content' => + array(), + 'value' => 'http://yourbucket.bkt.clouddn.com', + 'rule' => 'required', + 'msg' => '', + 'tip' => '未绑定CDN的话可使用七牛分配的测试域名', + 'ok' => '', + 'extend' => '', + ), + 'notifyenabled' => + array( + 'name' => 'notifyenabled', + 'title' => '启用服务端回调', + 'type' => 'bool', + 'content' => + array(), + 'value' => '0', + 'rule' => '', + 'msg' => '', + 'tip' => '本地开发请禁用服务端回调', + 'ok' => '', + 'extend' => '', + ), + 'notifyurl' => + array( + 'name' => 'notifyurl', + 'title' => '回调通知地址', + 'type' => 'string', + 'content' => + array(), + 'value' => 'http://www.yoursite.com/addons/qiniu/index/notify', + 'rule' => '', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + 'savekey' => + array( + 'name' => 'savekey', + 'title' => '保存文件名', + 'type' => 'string', + 'content' => + array(), + 'value' => '/uploads/$(year)$(mon)$(day)/$(etag)$(ext)', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + 'expire' => + array( + 'name' => 'expire', + 'title' => '上传有效时长', + 'type' => 'string', + 'content' => + array(), + 'value' => '600', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + 'maxsize' => + array( + 'name' => 'maxsize', + 'title' => '最大可上传', + 'type' => 'string', + 'content' => + array(), + 'value' => '10M', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + 'mimetype' => + array( + 'name' => 'mimetype', + 'title' => '可上传后缀格式', + 'type' => 'string', + 'content' => + array(), + 'value' => 'jpg,png,bmp,jpeg,gif,zip,rar,xls,xlsx', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), + 'multiple' => + array( + 'name' => 'multiple', + 'title' => '多文件上传', + 'type' => 'bool', + 'content' => + array(), + 'value' => '0', + 'rule' => 'required', + 'msg' => '', + 'tip' => '', + 'ok' => '', + 'extend' => '', + ), +); diff --git a/addons/qiniu/controller/Index.php b/addons/qiniu/controller/Index.php new file mode 100644 index 0000000000000000000000000000000000000000..8968e5a39cbfe3bdcb79494727db39d6d77d97ce --- /dev/null +++ b/addons/qiniu/controller/Index.php @@ -0,0 +1,60 @@ +error("当前插件暂无前台页面"); + } + + public function notify() + { + $config = get_addon_config('qiniu'); + $auth = new Auth($config['app_key'], $config['secret_key']); + $contentType = 'application/x-www-form-urlencoded'; + $authorization = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : ''; + if (!$authorization && function_exists('apache_request_headers')) { + $headers = apache_request_headers(); + $authorization = isset($headers['Authorization']) ? $headers['Authorization'] : ''; + } + + $url = $config['notifyurl']; + $body = file_get_contents('php://input'); + $ret = $auth->verifyCallback($contentType, $authorization, $url, $body); + if ($ret) { + parse_str($body, $arr); + $admin_id = isset($arr['admin']) ? $arr['admin'] : 0; + $user_id = isset($arr['user']) ? $arr['user'] : 0; + $imageInfo = json_decode($arr['imageInfo'], TRUE); + $params = array( + 'admin_id' => (int)$admin_id, + 'user_id' => (int)$user_id, + 'filesize' => $arr['filesize'], + 'imagewidth' => isset($imageInfo['width']) ? $imageInfo['width'] : 0, + 'imageheight' => isset($imageInfo['height']) ? $imageInfo['height'] : 0, + 'imagetype' => isset($imageInfo['format']) ? $imageInfo['format'] : '', + 'imageframes' => 1, + 'mimetype' => "image/" . (isset($imageInfo['format']) ? $imageInfo['format'] : ''), + 'extparam' => '', + 'url' => '/' . $arr['key'], + 'uploadtime' => time(), + 'storage' => 'qiniu' + ); + Attachment::create($params); + return json(['ret' => 'success', 'code' => 1, 'data' => ['url' => $params['url']]]); + } + return json(['ret' => 'failed']); + } + +} diff --git a/addons/qiniu/info.ini b/addons/qiniu/info.ini new file mode 100644 index 0000000000000000000000000000000000000000..2a5877062a28ca57e8cd436a5a08c6785299457e --- /dev/null +++ b/addons/qiniu/info.ini @@ -0,0 +1,8 @@ +name = qiniu +title = 七牛上传 +intro = 使用七牛云存储,上传时直传七牛 +author = Karson +website = https://www.fastadmin.net +version = 1.0.2 +state = 0 +url = /fastadmin/my/public/addons/qiniu diff --git a/addons/qiniu/library/Auth.php b/addons/qiniu/library/Auth.php new file mode 100644 index 0000000000000000000000000000000000000000..3f4e0596caa5b6bb9acbbdc2b8339640f54b98cb --- /dev/null +++ b/addons/qiniu/library/Auth.php @@ -0,0 +1,170 @@ +accessKey = $accessKey; + $this->secretKey = $secretKey; + } + + public function getAccessKey() + { + return $this->accessKey; + } + + public function sign($data) + { + $hmac = hash_hmac('sha1', $data, $this->secretKey, true); + return $this->accessKey . ':' . $this->base64_urlSafeEncode($hmac); + } + + public function signWithData($data) + { + $encodedData = $this->base64_urlSafeEncode($data); + return $this->sign($encodedData) . ':' . $encodedData; + } + + public function signRequest($urlString, $body, $contentType = null) + { + $url = parse_url($urlString); + $data = ''; + if (array_key_exists('path', $url)) + { + $data = $url['path']; + } + if (array_key_exists('query', $url)) + { + $data .= '?' . $url['query']; + } + $data .= "\n"; + if ($body !== null && $contentType === 'application/x-www-form-urlencoded') + { + $data .= $body; + } + return $this->sign($data); + } + + public function verifyCallback($contentType, $originAuthorization, $url, $body) + { + $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType); + return $originAuthorization === $authorization; + } + + public function privateDownloadUrl($baseUrl, $expires = 3600) + { + $deadline = time() + $expires; + $pos = strpos($baseUrl, '?'); + if ($pos !== false) + { + $baseUrl .= '&e='; + } + else + { + $baseUrl .= '?e='; + } + $baseUrl .= $deadline; + $token = $this->sign($baseUrl); + return "$baseUrl&token=$token"; + } + + public function uploadToken($bucket, $key = null, $expires = 3600, $policy = null, $strictPolicy = true) + { + $deadline = time() + $expires; + $scope = $bucket; + if ($key !== null) + { + $scope .= ':' . $key; + } + $args = self::copyPolicy($args, $policy, $strictPolicy); + $args['scope'] = $scope; + $args['deadline'] = $deadline; + $b = json_encode($args); + return $this->signWithData($b); + } + + /** + * 上传策略,参数规格详见 + * http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html + */ + private static $policyFields = array( + 'callbackUrl', + 'callbackBody', + 'callbackHost', + 'callbackBodyType', + 'callbackFetchKey', + 'returnUrl', + 'returnBody', + 'endUser', + 'saveKey', + 'insertOnly', + 'detectMime', + 'mimeLimit', + 'fsizeMin', + 'fsizeLimit', + 'persistentOps', + 'persistentNotifyUrl', + 'persistentPipeline', + 'deleteAfterDays', + 'fileType', + 'upHosts', + ); + + private static function copyPolicy(&$policy, $originPolicy, $strictPolicy) + { + if ($originPolicy === null) + { + return array(); + } + foreach ($originPolicy as $key => $value) + { + if (!$strictPolicy || in_array((string) $key, self::$policyFields, true)) + { + $policy[$key] = $value; + } + } + return $policy; + } + + public function authorization($url, $body = null, $contentType = null) + { + $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType); + return array('Authorization' => $authorization); + } + + /** + * 对提供的数据进行urlsafe的base64编码。 + * + * @param string $data 待编码的数据,一般为字符串 + * + * @return string 编码后的字符串 + * @link http://developer.qiniu.com/docs/v6/api/overview/appendix.html#urlsafe-base64 + */ + function base64_urlSafeEncode($data) + { + $find = array('+', '/'); + $replace = array('-', '_'); + return str_replace($find, $replace, base64_encode($data)); + } + + /** + * 对提供的urlsafe的base64编码的数据进行解码 + * + * @param string $str 待解码的数据,一般为字符串 + * + * @return string 解码后的字符串 + */ + function base64_urlSafeDecode($str) + { + $find = array('-', '_'); + $replace = array('+', '/'); + return base64_decode(str_replace($find, $replace, $str)); + } + +} diff --git a/application/admin/command/Install/install.lock b/application/admin/command/Install/install.lock new file mode 100644 index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de --- /dev/null +++ b/application/admin/command/Install/install.lock @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/application/admin/controller/general/Config.php b/application/admin/controller/general/Config.php index 24b405a46fccffe7afed8f7193e4c0b5ef42e8ed..aadf212f15d8391fcf153c78f20f2eb640548685 100644 --- a/application/admin/controller/general/Config.php +++ b/application/admin/controller/general/Config.php @@ -46,7 +46,6 @@ class Config extends Backend $siteList[$k]['title'] = $v; $siteList[$k]['list'] = []; } - foreach ($this->model->all() as $k => $v) { if (!isset($siteList[$v['group']])) { continue; diff --git a/application/common/library/Auth.php b/application/common/library/Auth.php index 5822241eaed4f17c9eb87885ceb1b1fb89e0a927..dfc06a5bb67b9a42ccd0490e67ac4922fd2d7300 100644 --- a/application/common/library/Auth.php +++ b/application/common/library/Auth.php @@ -36,6 +36,28 @@ class Auth $this->options = array_merge($this->config, $options); } + + /** + * 获取用户id + * + * @return int + */ + public static function id() + { + $user = self::user(); + return $user?$user['id']:null; + } + + /** + * 获取User模型 + * + * @return User + */ + public static function user() + { + return (self::instance())->getUser(); + } + /** * * @param array $options 参数 diff --git a/application/database.php b/application/database.php index e55d0247ac4d3cc1049177be98d575d5ce29eea3..719360cca52b1497b7c645505c502e921b88d6f9 100755 --- a/application/database.php +++ b/application/database.php @@ -18,11 +18,11 @@ return [ // 服务器地址 'hostname' => Env::get('database.hostname', '127.0.0.1'), // 数据库名 - 'database' => Env::get('database.database', 'fastadmin'), + 'database' => Env::get('database.database', 'fastadmin_my'), // 用户名 'username' => Env::get('database.username', 'root'), // 密码 - 'password' => Env::get('database.password', ''), + 'password' => Env::get('database.password', 'root'), // 端口 'hostport' => Env::get('database.hostport', ''), // 连接dsn @@ -32,7 +32,7 @@ return [ // 数据库编码默认采用utf8 'charset' => Env::get('database.charset', 'utf8'), // 数据库表前缀 - 'prefix' => Env::get('database.prefix', 'fa_'), + 'prefix' => Env::get('database.prefix', 'h_'), // 数据库调试模式 'debug' => Env::get('database.debug', false), // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) diff --git a/application/extra/addons.php b/application/extra/addons.php index e74b2f9ccd6ca2aa4bc6f14d2127386ed8b24782..2b4e8329cac0b379dffd6ce97d7f3789e55b060e 100644 --- a/application/extra/addons.php +++ b/application/extra/addons.php @@ -4,6 +4,25 @@ return array ( 'autoload' => false, 'hooks' => array ( + 'app_init' => + array ( + 0 => 'alioss', + 1 => 'cos', + ), + 'upload_config_init' => + array ( + 0 => 'alioss', + 1 => 'cos', + ), + 'upload_delete' => + array ( + 0 => 'alioss', + 1 => 'cos', + ), + 'config_init' => + array ( + 0 => 'nkeditor', + ), ), 'route' => array ( diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000000000000000000000000000000000..e8d413c7f7d7c1aacda0c46a4d071bcd8db6cc91 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1929 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "2f52d61f8902111ffe48ca7afa10285a", + "packages": [ + { + "name": "doctrine/cache", + "version": "v1.4.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "6433826dd02c9e5be8a127320dc13e7e6625d020" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/6433826dd02c9e5be8a127320dc13e7e6625d020", + "reference": "6433826dd02c9e5be8a127320dc13e7e6625d020", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.2" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": ">=3.7", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Cache\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2015-11-02T18:33:51+00:00" + }, + { + "name": "endroid/qr-code", + "version": "1.9.3", + "source": { + "type": "git", + "url": "https://github.com/endroid/qr-code.git", + "reference": "c9644bec2a9cc9318e98d1437de3c628dcd1ef93" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/c9644bec2a9cc9318e98d1437de3c628dcd1ef93", + "reference": "c9644bec2a9cc9318e98d1437de3c628dcd1ef93", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-gd": "*", + "php": ">=5.4", + "symfony/options-resolver": "^2.3|^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0|^5.0", + "sensio/framework-extra-bundle": "^3.0", + "symfony/browser-kit": "^2.3|^3.0", + "symfony/framework-bundle": "^2.3|^3.0", + "symfony/http-kernel": "^2.3|^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Endroid\\QrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeroen van den Enden", + "email": "info@endroid.nl", + "homepage": "http://endroid.nl/" + } + ], + "description": "Endroid QR Code", + "homepage": "https://github.com/endroid/QrCode", + "keywords": [ + "bundle", + "code", + "endroid", + "qr", + "qrcode", + "symfony" + ], + "time": "2017-04-08T09:13:59+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "0274c05370a7bc9bb3a33838858253418bd7d14b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0274c05370a7bc9bb3a33838858253418bd7d14b", + "reference": "0274c05370a7bc9bb3a33838858253418bd7d14b", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2019-12-21T08:51:15+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "karsonzhang/fastadmin-addons", + "version": "1.1.10", + "source": { + "type": "git", + "url": "https://github.com/karsonzhang/fastadmin-addons.git", + "reference": "69dedfc101bdf219c66dac05cbe1f393fa99be84" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/karsonzhang/fastadmin-addons/zipball/69dedfc101bdf219c66dac05cbe1f393fa99be84", + "reference": "69dedfc101bdf219c66dac05cbe1f393fa99be84", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "think-config": { + "addons": "src/config.php" + } + }, + "autoload": { + "psr-4": { + "think\\": "src/" + }, + "files": [ + "src/common.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "karsonzhang", + "email": "karsonzhang@163.com" + }, + { + "name": "xiaobo.sun", + "email": "xiaobo.sun@qq.com" + } + ], + "description": "addons package for fastadmin", + "homepage": "https://github.com/karsonzhang/fastadmin-addons", + "time": "2019-08-27T12:10:18+00:00" + }, + { + "name": "markbaker/complex", + "version": "1.4.7", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/1ea674a8308baf547cbcbd30c5fcd6d301b7c000", + "reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", + "phpcompatibility/php-compatibility": "^8.0", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "2.*", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^4.8.35|^5.4.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "^3.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + }, + "files": [ + "classes/src/functions/abs.php", + "classes/src/functions/acos.php", + "classes/src/functions/acosh.php", + "classes/src/functions/acot.php", + "classes/src/functions/acoth.php", + "classes/src/functions/acsc.php", + "classes/src/functions/acsch.php", + "classes/src/functions/argument.php", + "classes/src/functions/asec.php", + "classes/src/functions/asech.php", + "classes/src/functions/asin.php", + "classes/src/functions/asinh.php", + "classes/src/functions/atan.php", + "classes/src/functions/atanh.php", + "classes/src/functions/conjugate.php", + "classes/src/functions/cos.php", + "classes/src/functions/cosh.php", + "classes/src/functions/cot.php", + "classes/src/functions/coth.php", + "classes/src/functions/csc.php", + "classes/src/functions/csch.php", + "classes/src/functions/exp.php", + "classes/src/functions/inverse.php", + "classes/src/functions/ln.php", + "classes/src/functions/log2.php", + "classes/src/functions/log10.php", + "classes/src/functions/negative.php", + "classes/src/functions/pow.php", + "classes/src/functions/rho.php", + "classes/src/functions/sec.php", + "classes/src/functions/sech.php", + "classes/src/functions/sin.php", + "classes/src/functions/sinh.php", + "classes/src/functions/sqrt.php", + "classes/src/functions/tan.php", + "classes/src/functions/tanh.php", + "classes/src/functions/theta.php", + "classes/src/operations/add.php", + "classes/src/operations/subtract.php", + "classes/src/operations/multiply.php", + "classes/src/operations/divideby.php", + "classes/src/operations/divideinto.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "time": "2018-10-13T23:28:42+00:00" + }, + { + "name": "markbaker/matrix", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "5348c5a67e3b75cd209d70103f916a93b1f1ed21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/5348c5a67e3b75cd209d70103f916a93b1f1ed21", + "reference": "5348c5a67e3b75cd209d70103f916a93b1f1ed21", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "dev-master", + "phploc/phploc": "^4", + "phpmd/phpmd": "dev-master", + "phpunit/phpunit": "^5.7", + "sebastian/phpcpd": "^3.0", + "squizlabs/php_codesniffer": "^3.0@dev" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + }, + "files": [ + "classes/src/functions/adjoint.php", + "classes/src/functions/antidiagonal.php", + "classes/src/functions/cofactors.php", + "classes/src/functions/determinant.php", + "classes/src/functions/diagonal.php", + "classes/src/functions/identity.php", + "classes/src/functions/inverse.php", + "classes/src/functions/minors.php", + "classes/src/functions/trace.php", + "classes/src/functions/transpose.php", + "classes/src/operations/add.php", + "classes/src/operations/directsum.php", + "classes/src/operations/subtract.php", + "classes/src/operations/multiply.php", + "classes/src/operations/divideby.php", + "classes/src/operations/divideinto.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "time": "2019-10-06T11:29:25+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.25.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "fa82921994db851a8becaf3787a9e73c5976b6f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fa82921994db851a8becaf3787a9e73c5976b6f1", + "reference": "fa82921994db851a8becaf3787a9e73c5976b6f1", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2019-12-20T14:15:16+00:00" + }, + { + "name": "mtdowling/cron-expression", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/mtdowling/cron-expression.git", + "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/9504fa9ea681b586028adaaa0877db4aecf32bad", + "reference": "9504fa9ea681b586028adaaa0877db4aecf32bad", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "time": "2017-01-23T04:29:33+00:00" + }, + { + "name": "overtrue/pinyin", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/overtrue/pinyin.git", + "reference": "3b781d267197b74752daa32814d3a2cf5d140779" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/overtrue/pinyin/zipball/3b781d267197b74752daa32814d3a2cf5d140779", + "reference": "3b781d267197b74752daa32814d3a2cf5d140779", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Overtrue\\Pinyin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carlos", + "homepage": "http://github.com/overtrue" + } + ], + "description": "Chinese to pinyin translator.", + "homepage": "https://github.com/overtrue/pinyin", + "keywords": [ + "Chinese", + "Pinyin", + "cn2pinyin" + ], + "time": "2017-07-10T07:20:01+00:00" + }, + { + "name": "overtrue/socialite", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/overtrue/socialite.git", + "reference": "fda55f0acef43a144799b1957a8f93d9f5deffce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/overtrue/socialite/zipball/fda55f0acef43a144799b1957a8f93d9f5deffce", + "reference": "fda55f0acef43a144799b1957a8f93d9f5deffce", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "guzzlehttp/guzzle": "~5.0|~6.0", + "php": ">=5.4.0", + "symfony/http-foundation": "~2.6|~2.7|~2.8|~3.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Overtrue\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "A collection of OAuth 2 packages that extracts from laravel/socialite.", + "keywords": [ + "login", + "oauth", + "qq", + "social", + "wechat", + "weibo" + ], + "time": "2017-08-04T06:28:22+00:00" + }, + { + "name": "overtrue/wechat", + "version": "3.3.33", + "source": { + "type": "git", + "url": "https://github.com/overtrue/wechat.git", + "reference": "78e5476df330754040d1c400d0bca640d5b77cb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/overtrue/wechat/zipball/78e5476df330754040d1c400d0bca640d5b77cb7", + "reference": "78e5476df330754040d1c400d0bca640d5b77cb7", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "doctrine/cache": "1.4.*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "~6.2", + "monolog/monolog": "^1.17", + "overtrue/socialite": "^1.0.25", + "php": ">=5.5.0", + "pimple/pimple": "~3.0", + "symfony/http-foundation": "~2.6|~2.7|~2.8|~3.0", + "symfony/psr-http-message-bridge": "~0.3|^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.9", + "overtrue/phplint": "dev-master", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "EasyWeChat\\": "src/" + }, + "files": [ + "src/Payment/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "微信SDK", + "keywords": [ + "sdk", + "wechat", + "weixin", + "weixin-sdk" + ], + "time": "2018-10-17T12:27:27+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v5.2.27", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "dde1db116511aa4956389d75546c5be4c2beb2a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/dde1db116511aa4956389d75546c5be4c2beb2a6", + "reference": "dde1db116511aa4956389d75546c5be4c2beb2a6", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-ctype": "*", + "php": ">=5.0.0" + }, + "require-dev": { + "doctrine/annotations": "1.2.*", + "jms/serializer": "0.16.*", + "phpdocumentor/phpdocumentor": "2.*", + "phpunit/phpunit": "4.8.*", + "symfony/debug": "2.8.*", + "symfony/filesystem": "2.8.*", + "symfony/translation": "2.8.*", + "symfony/yaml": "2.8.*", + "zendframework/zend-cache": "2.5.1", + "zendframework/zend-config": "2.5.1", + "zendframework/zend-eventmanager": "2.5.1", + "zendframework/zend-filter": "2.5.1", + "zendframework/zend-i18n": "2.5.1", + "zendframework/zend-json": "2.5.1", + "zendframework/zend-math": "2.5.1", + "zendframework/zend-serializer": "2.5.*", + "zendframework/zend-servicemanager": "2.5.*", + "zendframework/zend-stdlib": "2.5.1" + }, + "suggest": { + "league/oauth2-google": "Needed for Google XOAUTH2 authentication" + }, + "type": "library", + "autoload": { + "classmap": [ + "class.phpmailer.php", + "class.phpmaileroauth.php", + "class.phpmaileroauthgoogle.php", + "class.smtp.php", + "class.pop3.php", + "extras/EasyPeasyICS.php", + "extras/ntlm_sasl_client.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "time": "2018-11-15T22:32:31+00:00" + }, + { + "name": "phpoffice/phpspreadsheet", + "version": "1.10.1", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "1648dc9ebef6ebe0c5a172e16cf66732918416e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/1648dc9ebef6ebe0c5a172e16cf66732918416e0", + "reference": "1648dc9ebef6ebe0c5a172e16cf66732918416e0", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "markbaker/complex": "^1.4", + "markbaker/matrix": "^1.2", + "php": "^7.1", + "psr/simple-cache": "^1.0" + }, + "require-dev": { + "dompdf/dompdf": "^0.8.3", + "friendsofphp/php-cs-fixer": "^2.16", + "jpgraph/jpgraph": "^4.0", + "mpdf/mpdf": "^8.0", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.5", + "squizlabs/php_codesniffer": "^3.5", + "tecnickcom/tcpdf": "^6.3" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "https://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "time": "2019-12-01T23:13:51+00:00" + }, + { + "name": "pimple/pimple", + "version": "v3.2.3", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32", + "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0", + "psr/container": "^1.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ], + "time": "2018-01-21T07:42:36+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2019-11-01T11:05:21+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v3.4.36", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "d2d0cfe8e319d9df44c4cca570710fcf221d4593" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d2d0cfe8e319d9df44c4cca570710fcf221d4593", + "reference": "d2d0cfe8e319d9df44c4cca570710fcf221d4593", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php70": "~1.6" + }, + "require-dev": { + "symfony/expression-language": "~2.8|~3.0|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "time": "2019-11-28T12:52:59+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v3.4.36", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "b224d20be60e6f7b55cd66914379a13a0b28651a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b224d20be60e6f7b55cd66914379a13a0b28651a", + "reference": "b224d20be60e6f7b55cd66914379a13a0b28651a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2019-10-26T11:02:01+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.13.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", + "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.13-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2019-11-27T14:18:11+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.13.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "af23c7bb26a73b850840823662dda371484926c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/af23c7bb26a73b850840823662dda371484926c4", + "reference": "af23c7bb26a73b850840823662dda371484926c4", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.13-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2019-11-27T13:56:44+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "9ab9d71f97d5c7d35a121a7fb69f74fee95cd0ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/9ab9d71f97d5c7d35a121a7fb69f74fee95cd0ad", + "reference": "9ab9d71f97d5c7d35a121a7fb69f74fee95cd0ad", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^3.4 || ^4.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "symfony/phpunit-bridge": "^3.4.20 || ^4.0", + "zendframework/zend-diactoros": "^1.4.1 || ^2.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "time": "2019-03-11T18:22:33+00:00" + }, + { + "name": "topthink/framework", + "version": "v5.0.24", + "source": { + "type": "git", + "url": "https://github.com/top-think/framework.git", + "reference": "c255c22b2f5fa30f320ecf6c1d29f7740eb3e8be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/framework/zipball/c255c22b2f5fa30f320ecf6c1d29f7740eb3e8be", + "reference": "c255c22b2f5fa30f320ecf6c1d29f7740eb3e8be", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.4.0", + "topthink/think-installer": "~1.0" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.0", + "mikey179/vfsstream": "~1.6", + "phpdocumentor/reflection-docblock": "^2.0", + "phploc/phploc": "2.*", + "phpunit/phpunit": "4.8.*", + "sebastian/phpcpd": "2.*" + }, + "type": "think-framework", + "autoload": { + "psr-4": { + "think\\": "library/think" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "the new thinkphp framework", + "homepage": "http://thinkphp.cn/", + "keywords": [ + "framework", + "orm", + "thinkphp" + ], + "time": "2019-01-11T08:04:58+00:00" + }, + { + "name": "topthink/think-captcha", + "version": "v1.0.8", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-captcha.git", + "reference": "1d64363c814c92f6086c4fa5e3223fe7e23db09d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-captcha/zipball/1d64363c814c92f6086c4fa5e3223fe7e23db09d", + "reference": "1d64363c814c92f6086c4fa5e3223fe7e23db09d", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "topthink/framework": "~5.0.0", + "topthink/think-installer": ">=1.0.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "think\\captcha\\": "src/" + }, + "files": [ + "src/helper.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "captcha package for thinkphp5", + "time": "2019-01-28T04:48:36+00:00" + }, + { + "name": "topthink/think-installer", + "version": "v1.0.12", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-installer.git", + "reference": "1be326e68f63de4e95977ed50f46ae75f017556d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-installer/zipball/1be326e68f63de4e95977ed50f46ae75f017556d", + "reference": "1be326e68f63de4e95977ed50f46ae75f017556d", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "composer-plugin-api": "^1.0" + }, + "require-dev": { + "composer/composer": "1.0.*@dev" + }, + "type": "composer-plugin", + "extra": { + "class": "think\\composer\\Plugin" + }, + "autoload": { + "psr-4": { + "think\\composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "time": "2017-05-27T06:58:09+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.6.0" + }, + "platform-dev": [] +} diff --git a/public/assets/js/addons.js b/public/assets/js/addons.js index d2c1d20a916e5c3e1b297ec9df356442c5e33b53..499b29e3121ff94169f64c4cabc50d45e102355f 100644 --- a/public/assets/js/addons.js +++ b/public/assets/js/addons.js @@ -1,3 +1,447 @@ define([], function () { - + //如果开启了alioss客户端上传模式 +if (typeof Config.upload.storage !== 'undefined' && Config.upload.storage === 'alioss') { + require(['upload', '../addons/alioss/js/spark'], function (Upload, SparkMD5) { + var _onFileAdded = Upload.events.onFileAdded; + var _onUploadResponse = Upload.events.onUploadResponse; + var getFileMd5 = function (file, cb) { + var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice, + file = file.getNative(), + chunkSize = 2097152, // Read in chunks of 2MB + chunks = Math.ceil(file.size / chunkSize), + currentChunk = 0, + spark = new SparkMD5.ArrayBuffer(), + fileReader = new FileReader(); + + fileReader.onload = function (e) { + spark.append(e.target.result); // Append array buffer + currentChunk++; + if (currentChunk < chunks) { + loadNext(); + } else { + cb && cb(spark.end()); // Compute hash + } + }; + + fileReader.onerror = function () { + console.warn('oops, something went wrong.'); + }; + + function loadNext() { + var start = currentChunk * chunkSize, + end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize; + + fileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); + } + + loadNext(); + }; + var _process = function (up, file) { + (function (up, file) { + getFileMd5(file, function (md5) { + Fast.api.ajax({ + url: "/addons/alioss/index/params", + data: {method: 'POST', md5: md5, name: file.name, type: file.type, size: file.size}, + }, function (data) { + file.md5 = md5; + file.status = 1; + file.key = data.key; + file.OSSAccessKeyId = data.id; + file.policy = data.policy; + file.signature = data.signature; + up.start(); + return false; + }); + }); + })(up, file); + }; + Upload.events.onFileAdded = function (up, files) { + return _onFileAdded.call(this, up, files); + }; + Upload.events.onBeforeUpload = function (up, file) { + if (typeof file.md5 === 'undefined') { + up.stop(); + _process(up, file); + } else { + up.settings.headers = up.settings.headers || {}; + up.settings.multipart_params.key = file.key; + up.settings.multipart_params.OSSAccessKeyId = file.OSSAccessKeyId; + up.settings.multipart_params.success_action_status = 200; + if (typeof file.callback !== 'undefined') { + up.settings.multipart_params.callback = file.callback; + } + up.settings.multipart_params.policy = file.policy; + up.settings.multipart_params.signature = file.signature; + //up.settings.send_file_name = false; + } + }; + Upload.events.onUploadResponse = function (response, info, up, file) { + try { + var ret = {}; + if (info.status === 200) { + var url = '/' + file.key; + Fast.api.ajax({ + url: "/addons/alioss/index/notify", + data: {method: 'POST', name: file.name, url: url, md5: file.md5, size: file.size, type: file.type, policy: file.policy, signature: file.signature} + }, function () { + return false; + }); + ret.code = 1; + ret.data = { + url: url + }; + } else { + ret.code = 0; + ret.msg = info.response; + } + return _onUploadResponse.call(this, JSON.stringify(ret)); + + } catch (e) { + } + return _onUploadResponse.call(this, response); + + }; + }); +} +//修改上传的接口调用 +require(['upload', '../addons/cos/js/spark'], function (Upload, SparkMD5) { + var _onFileAdded = Upload.events.onFileAdded; + var _onUploadResponse = Upload.events.onUploadResponse; + var _process = function (up, file) { + (function (up, file) { + var blob = file.getNative(); + var loadedBytes = file.loaded; + var chunkSize = 2097152; + var chunkBlob = blob.slice(loadedBytes, loadedBytes + chunkSize); + var reader = new FileReader(); + reader.addEventListener('loadend', function (e) { + var spark = new SparkMD5.ArrayBuffer(); + spark.append(e.target.result); + var md5 = spark.end(); + Fast.api.ajax({ + url: "/addons/cos/index/params", + data: {method: 'POST', md5: md5, name: file.name, type: file.type, size: file.size}, + }, function (data) { + file.md5 = md5; + file.status = 1; + file.key = data.key; + file.filename = data.filename; + file.token = data.token; + file.signature = data.signature; + file.notifysignature = data.notifysignature; + up.start(); + return false; + }); + return; + }); + reader.readAsArrayBuffer(chunkBlob); + })(up, file); + }; + Upload.events.onFileAdded = function (up, files) { + return _onFileAdded.call(this, up, files); + }; + Upload.events.onBeforeUpload = function (up, file) { + if (up.settings.url == Config.upload.uploadurl) { + if (typeof file.md5 === 'undefined') { + up.stop(); + _process(up, file); + } else { + up.settings.headers = up.settings.headers || {}; + up.settings.multipart_params.key = file.key; + up.settings.multipart_params.Signature = file.signature; + up.settings.multipart_params.success_action_status = 200; + up.settings.multipart_params['Content-Disposition'] = 'inline; filename=' + file.filename; + up.settings.multipart_params['Content-Type'] = file.type; + up.settings.multipart_params['x-cos-security-token'] = file.token; + up.settings.send_file_name = false; + } + } + }; + Upload.events.onUploadResponse = function (response, info, up, file) { + if (up.settings.url == Config.upload.uploadurl) { + try { + var ret = {}; + if (info.status === 200) { + var url = '/' + file.key; + Fast.api.ajax({ + url: "/addons/cos/index/notify", + data: { + method: 'POST', + name: file.name, + url: url, + md5: file.md5, + size: file.size, + type: file.type, + signature: file.signature, + token: file.token, + notifysignature: file.notifysignature + } + }, function () { + return false; + }); + ret.code = 1; + ret.data = { + url: url + }; + } else { + ret.code = 0; + ret.msg = info.response; + } + return _onUploadResponse.call(this, JSON.stringify(ret)); + + } catch (e) { + } + } + return _onUploadResponse.call(this, response); + }; +}); +require.config({ + paths: { + 'nkeditor': '../addons/nkeditor/js/customplugin', + 'nkeditor-core': '../addons/nkeditor/nkeditor.min', + 'nkeditor-lang': '../addons/nkeditor/lang/zh-CN', + }, + shim: { + 'nkeditor': { + deps: [ + 'nkeditor-core', + 'nkeditor-lang' + ] + }, + 'nkeditor-core': { + deps: [ + 'css!../addons/nkeditor/themes/black/editor.min.css', + 'css!../addons/nkeditor/css/common.css' + ], + exports: 'window.KindEditor' + }, + 'nkeditor-lang': { + deps: [ + 'nkeditor-core' + ] + } + } +}); +if ($(".editor").size() > 0) { + require(['nkeditor', 'upload'], function (Nkeditor, Upload) { + var getImageFromClipboard, getImageFromDrop; + getImageFromClipboard = function (data) { + var i, item; + i = 0; + while (i < data.clipboardData.items.length) { + item = data.clipboardData.items[i]; + if (item.type.indexOf("image") !== -1) { + return item.getAsFile() || false; + } + i++; + } + return false; + }; + getImageFromDrop = function (data) { + var i, item, images; + i = 0; + images = []; + while (i < data.dataTransfer.files.length) { + item = data.dataTransfer.files[i]; + if (item.type.indexOf("image") !== -1) { + images.push(item); + } + i++; + } + return images; + }; + + var getImageFromUrl = function (url, callback, outputFormat) { + var canvas = document.createElement('CANVAS'), + ctx = canvas.getContext('2d'), + img = new Image; + img.crossOrigin = 'Anonymous'; + img.onload = function () { + var urlArr = url.split('.'); + var suffix = urlArr.pop(); + suffix = suffix.match(/^(jpg|png|gif|bmp|jpeg)$/i) ? suffix : 'png'; + + try { + canvas.height = img.height; + canvas.width = img.width; + ctx.drawImage(img, 0, 0); + var dataURL = canvas.toDataURL(outputFormat || 'image/' + suffix); + + var arr = dataURL.split(','), mime = arr[0].match(/:(.*?);/)[1], + bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + var filename = url.substr(url.lastIndexOf('/') + 1); + var exp = new RegExp("\\." + suffix + "$", "i"); + filename = exp.test(filename) ? filename : filename + "." + suffix; + var file = new File([u8arr], filename, {type: mime}); + } catch (e) { + callback.call(this, null); + } + + callback.call(this, file); + canvas = null; + }; + img.onerror = function (e) { + callback.call(this, null); + }; + img.src = url; + }; + + Nkeditor.lang({ + remoteimage: '下载远程图片' + }); + //远程下载图片 + Nkeditor.plugin('remoteimage', function (K) { + var editor = this, name = 'remoteimage'; + editor.plugin.remoteimage = { + download: function (e) { + var that = this; + var html = that.html(); + var staging = {}, orgined = {}, index = 0, images = 0, completed = 0, failured = 0; + var checkrestore = function () { + if (completed + failured >= images) { + $.each(staging, function (i, j) { + that.html(that.html().replace("" + i + "", j)); + }); + } + }; + html.replace(/([\s\S]*?)<\/code>/g, function (code) { + staging[index] = code; + return "" + index + ""; + } + ); + html = html.replace(//g, function () { + images++; + var url = arguments[3]; + var placeholder = ''; + //如果是云存储的链接,则忽略 + if (Config.upload.cdnurl && url.indexOf(Config.upload.cdnurl) > -1) { + completed++; + return arguments[0]; + } else { + orgined[index] = arguments[0]; + } + //下载远程图片 + (function (index, url, placeholder) { + getImageFromUrl(url, function (file) { + if (!file) { + failured++; + that.html(that.html().replace(placeholder, orgined[index])); + checkrestore(); + } else { + Upload.api.send(file, function (data) { + completed++; + that.html(that.html().replace(placeholder, '')); + checkrestore(); + }, function (data) { + failured++; + that.html(that.html().replace(placeholder, orgined[index])); + checkrestore(); + }); + } + }); + })(index, url, placeholder); + index++; + return placeholder; + }); + if (index > 0) { + that.html(html); + } else { + Toastr.info("没有需要下载的远程图片"); + } + } + }; + // 点击图标时执行 + editor.clickToolbar(name, editor.plugin.remoteimage.download); + }); + + $(".editor").each(function () { + var that = this; + Nkeditor.create(that, { + width: '100%', + filterMode: false, + wellFormatMode: false, + allowMediaUpload: true, //是否允许媒体上传 + allowFileManager: true, + allowImageUpload: true, + cssPath: Fast.api.cdnurl('/assets/addons/nkeditor/plugins/code/prism.css'), + cssData: "body {font-size: 13px}", + fillDescAfterUploadImage: false, //是否在上传后继续添加描述信息 + themeType: typeof Config.nkeditor != 'undefined' ? Config.nkeditor.theme : 'black', //编辑器皮肤,这个值从后台获取 + fileManagerJson: Fast.api.fixurl("/addons/nkeditor/index/attachment/module/" + Config.modulename), + items: [ + 'source', 'undo', 'redo', 'preview', 'print', 'template', 'code', 'quote', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', + 'formatblock', 'fontname', 'fontsize', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', 'image', 'multiimage', 'graft', + 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', 'remoteimage', 'about', 'fullscreen' + ], + afterCreate: function () { + var self = this; + //Ctrl+回车提交 + Nkeditor.ctrl(document, 13, function () { + self.sync(); + $(that).closest("form").submit(); + }); + Nkeditor.ctrl(self.edit.doc, 13, function () { + self.sync(); + $(that).closest("form").submit(); + }); + //粘贴上传 + $("body", self.edit.doc).bind('paste', function (event) { + var image, pasteEvent; + pasteEvent = event.originalEvent; + if (pasteEvent.clipboardData && pasteEvent.clipboardData.items) { + image = getImageFromClipboard(pasteEvent); + if (image) { + event.preventDefault(); + Upload.api.send(image, function (data) { + self.exec("insertimage", Fast.api.cdnurl(data.url)); + }); + } + } + }); + //挺拽上传 + $("body", self.edit.doc).bind('drop', function (event) { + var image, pasteEvent; + pasteEvent = event.originalEvent; + if (pasteEvent.dataTransfer && pasteEvent.dataTransfer.files) { + images = getImageFromDrop(pasteEvent); + if (images.length > 0) { + event.preventDefault(); + $.each(images, function (i, image) { + Upload.api.send(image, function (data) { + self.exec("insertimage", Fast.api.cdnurl(data.url)); + }); + }); + } + } + }); + }, + //FastAdmin自定义处理 + beforeUpload: function (callback, file) { + var file = file ? file : $("input.ke-upload-file", this.form).prop('files')[0]; + Upload.api.send(file, function (data) { + var data = {code: '000', data: {url: Fast.api.cdnurl(data.url)}, title: '', width: '', height: '', border: '', align: ''}; + callback(data); + }); + + }, + //错误处理 handler + errorMsgHandler: function (message, type) { + try { + console.log(message, type); + } catch (Error) { + alert(message); + } + } + }); + }); + }); +} }); \ No newline at end of file diff --git a/public/assets/libs/Sortable/.bower.json b/public/assets/libs/Sortable/.bower.json new file mode 100644 index 0000000000000000000000000000000000000000..b2bb5d5b4969b27b3f9f9798fdded601b04651b0 --- /dev/null +++ b/public/assets/libs/Sortable/.bower.json @@ -0,0 +1,40 @@ +{ + "name": "Sortable", + "main": [ + "Sortable.js" + ], + "homepage": "http://SortableJS.github.io/Sortable/", + "authors": [ + "RubaXa ", + "owenm " + ], + "description": "JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap.", + "keywords": [ + "sortable", + "reorder", + "list", + "html5", + "drag", + "and", + "drop", + "dnd", + "web-components" + ], + "license": "MIT", + "ignore": [ + "node_modules", + "bower_components", + "test", + "tests" + ], + "version": "1.10.2", + "_release": "1.10.2", + "_resolution": { + "type": "version", + "tag": "1.10.2", + "commit": "2addddd67387b6e4b6b5e51806eb698f0a3eee88" + }, + "_source": "https://github.com/RubaXa/Sortable.git", + "_target": "~1.10.0", + "_originalSource": "Sortable" +} \ No newline at end of file diff --git a/public/assets/libs/Sortable/.circleci/config.yml b/public/assets/libs/Sortable/.circleci/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..ffbb4f1a7ca9efe8a21ad91c0895e7ac6691b6fa --- /dev/null +++ b/public/assets/libs/Sortable/.circleci/config.yml @@ -0,0 +1,33 @@ +version: 2.0 +jobs: + build: + docker: + - image: circleci/node:10.16-browsers + steps: + - checkout + + - restore_cache: + keys: + - v1-dependencies-{{ checksum "package.json" }} + - v1-dependencies- + + - run: npm install + + - save_cache: + paths: + - node_modules + key: v1-dependencies-{{ checksum "package.json" }} + + - run: npm run build:umd + + - run: + name: Compatibility Test + command: | + if [ -z "$CIRCLE_PR_NUMBER" ]; + then + npm run test:compat + fi + - run: npm run test + + - store_test_results: + path: /tmp/test-results diff --git a/public/assets/libs/Sortable/.editorconfig b/public/assets/libs/Sortable/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..09d2751869b00f4891863cd233253edce15d4c32 --- /dev/null +++ b/public/assets/libs/Sortable/.editorconfig @@ -0,0 +1,15 @@ +# editorconfig.org +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[*.yml] +indent_style = space diff --git a/public/assets/libs/Sortable/.gitignore b/public/assets/libs/Sortable/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..bb83eae77fa4396d680255e778a1d7dae5ab60ba --- /dev/null +++ b/public/assets/libs/Sortable/.gitignore @@ -0,0 +1,6 @@ +node_modules +mock.png +.*.sw* +.build* +jquery.fn.* +.idea/ diff --git a/public/assets/libs/Sortable/.jshintrc b/public/assets/libs/Sortable/.jshintrc new file mode 100644 index 0000000000000000000000000000000000000000..ffbcc18f99b1945f675a325335fb19280cf9ced4 --- /dev/null +++ b/public/assets/libs/Sortable/.jshintrc @@ -0,0 +1,25 @@ +{ + "strict": false, + "newcap": false, + "node": true, + "expr": true, + "supernew": true, + "laxbreak": true, + "esversion": 9, + "white": true, + "globals": { + "define": true, + "test": true, + "expect": true, + "module": true, + "asyncTest": true, + "start": true, + "ok": true, + "equal": true, + "notEqual": true, + "deepEqual": true, + "window": true, + "document": true, + "performance": true + } +} diff --git a/public/assets/libs/Sortable/.testcaferc.json b/public/assets/libs/Sortable/.testcaferc.json new file mode 100644 index 0000000000000000000000000000000000000000..58a061e621e5fe13736c1efc123679d38bd53b8f --- /dev/null +++ b/public/assets/libs/Sortable/.testcaferc.json @@ -0,0 +1,7 @@ +{ + "speed": 0.4, + "reporter": { + "name": "xunit", + "output": "/tmp/test-results/res.xml" + } +} diff --git a/public/assets/libs/Sortable/CONTRIBUTING.md b/public/assets/libs/Sortable/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..25c1490145b54feaa8c204a82575b7e68c9f57c1 --- /dev/null +++ b/public/assets/libs/Sortable/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# Contribution Guidelines + +### Issue + + 1. Try [master](https://github.com/SortableJS/Sortable/tree/master/)-branch, perhaps the problem has been solved; + 2. [Use the search](https://github.com/SortableJS/Sortable/search?type=Issues&q=problem), maybe already have an answer; + 3. If not found, create example on [jsbin.com (draft)](https://jsbin.com/kamiwez/edit?html,js,output) and describe the problem. + +--- + +### Pull Request + + 1. Only request to merge with the [master](https://github.com/SortableJS/Sortable/tree/master/)-branch. + 2. Only modify source files, **do not commit the resulting build** + +### Setup + + 1. Fork the repo on [github](https://github.com) + 2. Clone locally + 3. Run `npm i` in the local repo + +### Building + + - For development, build the `./Sortable.js` file using the command `npm run build:umd:watch` + - To build everything and minify it, run `npm run build` + - Do not commit the resulting builds in any pull request – they will be generated at release diff --git a/public/assets/libs/Sortable/ISSUE_TEMPLATE.md b/public/assets/libs/Sortable/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000000000000000000000000000000000..a4ff620d3d756d27cfb569b0374e639de9765bdd --- /dev/null +++ b/public/assets/libs/Sortable/ISSUE_TEMPLATE.md @@ -0,0 +1,24 @@ +#### Problem: + + + +#### JSBin/JSFiddle demonstrating the problem: + + +--- +Before you create an issue, check it: + + 1. Try [master](https://github.com/SortableJS/Sortable/tree/master/)-branch, perhaps the problem has been solved; + 2. [Use the search](https://github.com/SortableJS/Sortable/search?q=problem), maybe we already have an answer; + 3. If not found, create an example on [jsbin.com (draft)](http://jsbin.com/vojixek/edit?html,js,output) and describe the problem. + +Bindings: + - Angular + - 2.0+: https://github.com/SortableJS/angular-sortablejs/issues + - legacy: https://github.com/SortableJS/angular-legacy-sortablejs/issues + - React + - ES2015+: https://github.com/SortableJS/react-sortablejs/issues + - mixin: https://github.com/SortableJS/react-mixin-sortablejs/issues + - Polymer: https://github.com/SortableJS/polymer-sortablejs/issues + - Knockout: https://github.com/SortableJS/knockout-sortablejs/issues + - Meteor: https://github.com/SortableJS/meteor-sortablejs/issues diff --git a/public/assets/libs/Sortable/LICENSE b/public/assets/libs/Sortable/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..91bffc2c9d82be21845b0226af5763ddd37594d4 --- /dev/null +++ b/public/assets/libs/Sortable/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 All contributors to Sortable + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/public/assets/libs/Sortable/README.md b/public/assets/libs/Sortable/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ada20d694305d57ca060a2538ca50b4f80b0d42f --- /dev/null +++ b/public/assets/libs/Sortable/README.md @@ -0,0 +1,782 @@ +# Sortable   [![CircleCI](https://circleci.com/gh/SortableJS/Sortable.svg?style=svg)](https://circleci.com/gh/SortableJS/Sortable) [![DeepScan grade](https://deepscan.io/api/teams/3901/projects/5666/branches/43977/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=3901&pid=5666&bid=43977) [![](https://data.jsdelivr.com/v1/package/npm/sortablejs/badge)](https://www.jsdelivr.com/package/npm/sortablejs) [![npm](https://img.shields.io/npm/v/sortablejs.svg)](https://www.npmjs.com/package/sortablejs) + +Sortable is a JavaScript library for reorderable drag-and-drop lists. + +Demo: http://sortablejs.github.io/Sortable/ + +[](https://saucelabs.com/) + +## Features + + * Supports touch devices and [modern](http://caniuse.com/#search=drag) browsers (including IE9) + * Can drag from one list to another or within the same list + * CSS animation when moving items + * Supports drag handles *and selectable text* (better than voidberg's html5sortable) + * Smart auto-scrolling + * Advanced swap detection + * Smooth animations + * [Multi-drag](https://github.com/SortableJS/Sortable/tree/master/plugins/MultiDrag) support + * Support for CSS transforms + * Built using native HTML5 drag and drop API + * Supports + * [Meteor](https://github.com/SortableJS/meteor-sortablejs) + * Angular + * [2.0+](https://github.com/SortableJS/angular-sortablejs) + * [1.*](https://github.com/SortableJS/angular-legacy-sortablejs) + * React + * [ES2015+](https://github.com/SortableJS/react-sortablejs) + * [Mixin](https://github.com/SortableJS/react-mixin-sortablejs) + * [Knockout](https://github.com/SortableJS/knockout-sortablejs) + * [Polymer](https://github.com/SortableJS/polymer-sortablejs) + * [Vue](https://github.com/SortableJS/Vue.Draggable) + * [Ember](https://github.com/SortableJS/ember-sortablejs) + * Supports any CSS library, e.g. [Bootstrap](#bs) + * Simple API + * Support for [plugins](#plugins) + * [CDN](#cdn) + * No jQuery required (but there is [support](https://github.com/SortableJS/jquery-sortablejs)) + + +
            + + +### Articles + + * [Dragging Multiple Items in Sortable](https://github.com/SortableJS/Sortable/wiki/Dragging-Multiple-Items-in-Sortable) (April 26, 2019) + * [Swap Thresholds and Direction](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction) (December 2, 2018) + * [Sortable v1.0 — New capabilities](https://github.com/SortableJS/Sortable/wiki/Sortable-v1.0-—-New-capabilities/) (December 22, 2014) + * [Sorting with the help of HTML5 Drag'n'Drop API](https://github.com/SortableJS/Sortable/wiki/Sorting-with-the-help-of-HTML5-Drag'n'Drop-API/) (December 23, 2013) + +
            + +### Getting Started + +Install with NPM: +```bash +$ npm install sortablejs --save +``` + +Install with Bower: +```bash +$ bower install --save sortablejs +``` + +Import into your project: +```js +// Default SortableJS +import Sortable from 'sortablejs'; + +// Core SortableJS (without default plugins) +import Sortable from 'sortablejs/modular/sortable.core.esm.js'; + +// Complete SortableJS (with all plugins) +import Sortable from 'sortablejs/modular/sortable.complete.esm.js'; +``` + +Cherrypick plugins: +```js +// Cherrypick extra plugins +import Sortable, { MultiDrag, Swap } from 'sortablejs'; + +Sortable.mount(new MultiDrag(), new Swap()); + + +// Cherrypick default plugins +import Sortable, { AutoScroll } from 'sortablejs/modular/sortable.core.esm.js'; + +Sortable.mount(new AutoScroll()); +``` + + +--- + + +### Usage +```html +
              +
            • item 1
            • +
            • item 2
            • +
            • item 3
            • +
            +``` + +```js +var el = document.getElementById('items'); +var sortable = Sortable.create(el); +``` + +You can use any element for the list and its elements, not just `ul`/`li`. Here is an [example with `div`s](https://jsbin.com/visimub/edit?html,js,output). + + +--- + + +### Options +```js +var sortable = new Sortable(el, { + group: "name", // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] } + sort: true, // sorting inside list + delay: 0, // time in milliseconds to define when the sorting should start + delayOnTouchOnly: false, // only delay if user is using touch + touchStartThreshold: 0, // px, how many pixels the point should move before cancelling a delayed drag event + disabled: false, // Disables the sortable if set to true. + store: null, // @see Store + animation: 150, // ms, animation speed moving items when sorting, `0` — without animation + easing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples. + handle: ".my-handle", // Drag handle selector within list items + filter: ".ignore-elements", // Selectors that do not lead to dragging (String or Function) + preventOnFilter: true, // Call `event.preventDefault()` when triggered `filter` + draggable: ".item", // Specifies which items inside the element should be draggable + + dataIdAttr: 'data-id', + + ghostClass: "sortable-ghost", // Class name for the drop placeholder + chosenClass: "sortable-chosen", // Class name for the chosen item + dragClass: "sortable-drag", // Class name for the dragging item + + swapThreshold: 1, // Threshold of the swap zone + invertSwap: false, // Will always use inverted swap zone if set to true + invertedSwapThreshold: 1, // Threshold of the inverted swap zone (will be set to swapThreshold value by default) + direction: 'horizontal', // Direction of Sortable (will be detected automatically if not given) + + forceFallback: false, // ignore the HTML5 DnD behaviour and force the fallback to kick in + + fallbackClass: "sortable-fallback", // Class name for the cloned DOM Element when using forceFallback + fallbackOnBody: false, // Appends the cloned DOM Element into the Document's Body + fallbackTolerance: 0, // Specify in pixels how far the mouse should move before it's considered as a drag. + + dragoverBubble: false, + removeCloneOnHide: true, // Remove the clone element when it is not showing, rather than just hiding it + emptyInsertThreshold: 5, // px, distance mouse must be from empty sortable to insert drag element into it + + + setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) { + dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent + }, + + // Element is chosen + onChoose: function (/**Event*/evt) { + evt.oldIndex; // element index within parent + }, + + // Element is unchosen + onUnchoose: function(/**Event*/evt) { + // same properties as onEnd + }, + + // Element dragging started + onStart: function (/**Event*/evt) { + evt.oldIndex; // element index within parent + }, + + // Element dragging ended + onEnd: function (/**Event*/evt) { + var itemEl = evt.item; // dragged HTMLElement + evt.to; // target list + evt.from; // previous list + evt.oldIndex; // element's old index within old parent + evt.newIndex; // element's new index within new parent + evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements + evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements + evt.clone // the clone element + evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving + }, + + // Element is dropped into the list from another list + onAdd: function (/**Event*/evt) { + // same properties as onEnd + }, + + // Changed sorting within list + onUpdate: function (/**Event*/evt) { + // same properties as onEnd + }, + + // Called by any change to the list (add / update / remove) + onSort: function (/**Event*/evt) { + // same properties as onEnd + }, + + // Element is removed from the list into another list + onRemove: function (/**Event*/evt) { + // same properties as onEnd + }, + + // Attempt to drag a filtered element + onFilter: function (/**Event*/evt) { + var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event. + }, + + // Event when you move an item in the list or between lists + onMove: function (/**Event*/evt, /**Event*/originalEvent) { + // Example: https://jsbin.com/nawahef/edit?js,output + evt.dragged; // dragged HTMLElement + evt.draggedRect; // DOMRect {left, top, right, bottom} + evt.related; // HTMLElement on which have guided + evt.relatedRect; // DOMRect + evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default + originalEvent.clientY; // mouse position + // return false; — for cancel + // return -1; — insert before target + // return 1; — insert after target + }, + + // Called when creating a clone of element + onClone: function (/**Event*/evt) { + var origEl = evt.item; + var cloneEl = evt.clone; + }, + + // Called when dragging element changes position + onChange: function(/**Event*/evt) { + evt.newIndex // most likely why this event is used is to get the dragging element's current index + // same properties as onEnd + } +}); +``` + + +--- + + +#### `group` option +To drag elements from one list into another, both lists must have the same `group` value. +You can also define whether lists can give away, give and keep a copy (`clone`), and receive elements. + + * name: `String` — group name + * pull: `true|false|["foo", "bar"]|'clone'|function` — ability to move from the list. `clone` — copy the item, rather than move. Or an array of group names which the elements may be put in. Defaults to `true`. + * put: `true|false|["baz", "qux"]|function` — whether elements can be added from other lists, or an array of group names from which elements can be added. + * revertClone: `boolean` — revert cloned element to initial position after moving to a another list. + + +Demo: + - https://jsbin.com/hijetos/edit?js,output + - https://jsbin.com/nacoyah/edit?js,output — use of complex logic in the `pull` and` put` + - https://jsbin.com/bifuyab/edit?js,output — use `revertClone: true` + + +--- + + +#### `sort` option +Allow sorting inside list. + +Demo: https://jsbin.com/jayedig/edit?js,output + + +--- + + +#### `delay` option +Time in milliseconds to define when the sorting should start. +Unfortunately, due to browser restrictions, delaying is not possible on IE or Edge with native drag & drop. + +Demo: https://jsbin.com/zosiwah/edit?js,output + + +--- + + +#### `delayOnTouchOnly` option +Whether or not the delay should be applied only if the user is using touch (eg. on a mobile device). No delay will be applied in any other case. Defaults to `false`. + + +--- + + +#### `swapThreshold` option +Percentage of the target that the swap zone will take up, as a float between `0` and `1`. + +[Read more](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#swap-threshold) + +Demo: http://sortablejs.github.io/Sortable#thresholds + + +--- + + +#### `invertSwap` option +Set to `true` to set the swap zone to the sides of the target, for the effect of sorting "in between" items. + +[Read more](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#forcing-inverted-swap-zone) + +Demo: http://sortablejs.github.io/Sortable#thresholds + + +--- + + +#### `invertedSwapThreshold` option +Percentage of the target that the inverted swap zone will take up, as a float between `0` and `1`. If not given, will default to `swapThreshold`. + +[Read more](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#dealing-with-swap-glitching) + + +--- + + +#### `direction` option +Direction that the Sortable should sort in. Can be set to `'vertical'`, `'horizontal'`, or a function, which will be called whenever a target is dragged over. Must return `'vertical'` or `'horizontal'`. + +[Read more](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#direction) + + +Example of direction detection for vertical list that includes full column and half column elements: + +```js +Sortable.create(el, { + direction: function(evt, target, dragEl) { + if (target !== null && target.className.includes('half-column') && dragEl.className.includes('half-column')) { + return 'horizontal'; + } + return 'vertical'; + } +}); +``` + + +--- + + +#### `touchStartThreshold` option +This option is similar to `fallbackTolerance` option. + +When the `delay` option is set, some phones with very sensitive touch displays like the Samsung Galaxy S8 will fire +unwanted touchmove events even when your finger is not moving, resulting in the sort not triggering. + +This option sets the minimum pointer movement that must occur before the delayed sorting is cancelled. + +Values between 3 to 5 are good. + + +--- + + +#### `disabled` options +Disables the sortable if set to `true`. + +Demo: https://jsbin.com/sewokud/edit?js,output + +```js +var sortable = Sortable.create(list); + +document.getElementById("switcher").onclick = function () { + var state = sortable.option("disabled"); // get + + sortable.option("disabled", !state); // set +}; +``` + + +--- + + +#### `handle` option +To make list items draggable, Sortable disables text selection by the user. +That's not always desirable. To allow text selection, define a drag handler, +which is an area of every list element that allows it to be dragged around. + +Demo: https://jsbin.com/numakuh/edit?html,js,output + +```js +Sortable.create(el, { + handle: ".my-handle" +}); +``` + +```html +
              +
            • :: list item text one +
            • :: list item text two +
            +``` + +```css +.my-handle { + cursor: move; + cursor: -webkit-grabbing; +} +``` + + +--- + + +#### `filter` option + + +```js +Sortable.create(list, { + filter: ".js-remove, .js-edit", + onFilter: function (evt) { + var item = evt.item, + ctrl = evt.target; + + if (Sortable.utils.is(ctrl, ".js-remove")) { // Click on remove button + item.parentNode.removeChild(item); // remove sortable item + } + else if (Sortable.utils.is(ctrl, ".js-edit")) { // Click on edit link + // ... + } + } +}) +``` + + +--- + + +#### `ghostClass` option +Class name for the drop placeholder (default `sortable-ghost`). + +Demo: https://jsbin.com/henuyiw/edit?css,js,output + +```css +.ghost { + opacity: 0.4; +} +``` + +```js +Sortable.create(list, { + ghostClass: "ghost" +}); +``` + + +--- + + +#### `chosenClass` option +Class name for the chosen item (default `sortable-chosen`). + +Demo: https://jsbin.com/hoqufox/edit?css,js,output + +```css +.chosen { + color: #fff; + background-color: #c00; +} +``` + +```js +Sortable.create(list, { + delay: 500, + chosenClass: "chosen" +}); +``` + + +--- + + +#### `forceFallback` option +If set to `true`, the Fallback for non HTML5 Browser will be used, even if we are using an HTML5 Browser. +This gives us the possibility to test the behaviour for older Browsers even in newer Browser, or make the Drag 'n Drop feel more consistent between Desktop , Mobile and old Browsers. + +On top of that, the Fallback always generates a copy of that DOM Element and appends the class `fallbackClass` defined in the options. This behaviour controls the look of this 'dragged' Element. + +Demo: https://jsbin.com/sibiput/edit?html,css,js,output + + +--- + + +#### `fallbackTolerance` option +Emulates the native drag threshold. Specify in pixels how far the mouse should move before it's considered as a drag. +Useful if the items are also clickable like in a list of links. + +When the user clicks inside a sortable element, it's not uncommon for your hand to move a little between the time you press and the time you release. +Dragging only starts if you move the pointer past a certain tolerance, so that you don't accidentally start dragging every time you click. + +3 to 5 are probably good values. + + +--- + + +#### `dragoverBubble` option +If set to `true`, the dragover event will bubble to parent sortables. Works on both fallback and native dragover event. +By default, it is false, but Sortable will only stop bubbling the event once the element has been inserted into a parent Sortable, or *can* be inserted into a parent Sortable, but isn't at that specific time (due to animation, etc). + +Since 1.8.0, you will probably want to leave this option as false. Before 1.8.0, it may need to be `true` for nested sortables to work. + + +--- + + +#### `removeCloneOnHide` option +If set to `false`, the clone is hidden by having it's CSS `display` property set to `none`. +By default, this option is `true`, meaning Sortable will remove the cloned element from the DOM when it is supposed to be hidden. + + +--- + + +#### `emptyInsertThreshold` option +The distance (in pixels) the mouse must be from an empty sortable while dragging for the drag element to be inserted into that sortable. Defaults to `5`. Set to `0` to disable this feature. + +Demo: https://jsbin.com/becavoj/edit?js,output + + +--- +### Event object ([demo](https://jsbin.com/fogujiv/edit?js,output)) + + - to:`HTMLElement` — list, in which moved element + - from:`HTMLElement` — previous list + - item:`HTMLElement` — dragged element + - clone:`HTMLElement` + - oldIndex:`Number|undefined` — old index within parent + - newIndex:`Number|undefined` — new index within parent + - oldDraggableIndex: `Number|undefined` — old index within parent, only counting draggable elements + - newDraggableIndex: `Number|undefined` — new index within parent, only counting draggable elements + - pullMode:`String|Boolean|undefined` — Pull mode if dragging into another sortable (`"clone"`, `true`, or `false`), otherwise undefined + + +#### `move` event object + - to:`HTMLElement` + - from:`HTMLElement` + - dragged:`HTMLElement` + - draggedRect:`DOMRect` + - related:`HTMLElement` — element on which have guided + - relatedRect:`DOMRect` + - willInsertAfter:`Boolean` — `true` if will element be inserted after target (or `false` if before) + + +--- + + +### Method + + +##### option(name:`String`[, value:`*`]):`*` +Get or set the option. + + + +##### closest(el:`String`[, selector:`HTMLElement`]):`HTMLElement|null` +For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + + +##### toArray():`String[]` +Serializes the sortable's item `data-id`'s (`dataIdAttr` option) into an array of string. + + +##### sort(order:`String[]`) +Sorts the elements according to the array. + +```js +var order = sortable.toArray(); +sortable.sort(order.reverse()); // apply +``` + + +##### save() +Save the current sorting (see [store](#store)) + + +##### destroy() +Removes the sortable functionality completely. + + +--- + + + +### Store +Saving and restoring of the sort. + +```html +
              +
            • order
            • +
            • save
            • +
            • restore
            • +
            +``` + +```js +Sortable.create(el, { + group: "localStorage-example", + store: { + /** + * Get the order of elements. Called once during initialization. + * @param {Sortable} sortable + * @returns {Array} + */ + get: function (sortable) { + var order = localStorage.getItem(sortable.options.group.name); + return order ? order.split('|') : []; + }, + + /** + * Save the order of elements. Called onEnd (when the item is dropped). + * @param {Sortable} sortable + */ + set: function (sortable) { + var order = sortable.toArray(); + localStorage.setItem(sortable.options.group.name, order.join('|')); + } + } +}) +``` + + +--- + + + +### Bootstrap +Demo: https://jsbin.com/visimub/edit?html,js,output + +```html + + + + + + + + + +
              +
            • This is Sortable
            • +
            • It works with Bootstrap...
            • +
            • ...out of the box.
            • +
            • It has support for touch devices.
            • +
            • Just drag some elements around.
            • +
            + + +``` + + +--- + + +### Static methods & properties + + + +##### Sortable.create(el:`HTMLElement`[, options:`Object`]):`Sortable` +Create new instance. + + +--- + + +##### Sortable.active:`Sortable` +The active Sortable instance. + + +--- + + +##### Sortable.dragged:`HTMLElement` +The element being dragged. + + +--- + + +##### Sortable.ghost:`HTMLElement` +The ghost element. + + +--- + + +##### Sortable.clone:`HTMLElement` +The clone element. + + +--- + + +##### Sortable.get(element:`HTMLElement`):`Sortable` +Get the Sortable instance on an element. + + +--- + + +##### Sortable.mount(plugin:`...SortablePlugin|SortablePlugin[]`) +Mounts a plugin to Sortable. + + +--- + + +##### Sortable.utils +* on(el`:HTMLElement`, event`:String`, fn`:Function`) — attach an event handler function +* off(el`:HTMLElement`, event`:String`, fn`:Function`) — remove an event handler +* css(el`:HTMLElement`)`:Object` — get the values of all the CSS properties +* css(el`:HTMLElement`, prop`:String`)`:Mixed` — get the value of style properties +* css(el`:HTMLElement`, prop`:String`, value`:String`) — set one CSS properties +* css(el`:HTMLElement`, props`:Object`) — set more CSS properties +* find(ctx`:HTMLElement`, tagName`:String`[, iterator`:Function`])`:Array` — get elements by tag name +* bind(ctx`:Mixed`, fn`:Function`)`:Function` — Takes a function and returns a new one that will always have a particular context +* is(el`:HTMLElement`, selector`:String`)`:Boolean` — check the current matched set of elements against a selector +* closest(el`:HTMLElement`, selector`:String`[, ctx`:HTMLElement`])`:HTMLElement|Null` — for each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree +* clone(el`:HTMLElement`)`:HTMLElement` — create a deep copy of the set of matched elements +* toggleClass(el`:HTMLElement`, name`:String`, state`:Boolean`) — add or remove one classes from each element +* detectDirection(el`:HTMLElement`)`:String` — automatically detect the [direction](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#direction) of the element as either `'vertical'` or `'horizontal'` + + +--- + + +### Plugins +#### Extra Plugins (included in complete versions) + - [MultiDrag](https://github.com/SortableJS/Sortable/tree/master/plugins/MultiDrag) + - [Swap](https://github.com/SortableJS/Sortable/tree/master/plugins/Swap) + +#### Default Plugins (included in default versions) + - [AutoScroll](https://github.com/SortableJS/Sortable/tree/master/plugins/AutoScroll) + - [OnSpill](https://github.com/SortableJS/Sortable/tree/master/plugins/OnSpill) + + +--- + + + +### CDN + +```html + + +``` + + +--- + + +### Contributing (Issue/PR) + +Please, [read this](CONTRIBUTING.md). + + +--- + + +## MIT LICENSE +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/public/assets/libs/Sortable/Sortable.js b/public/assets/libs/Sortable/Sortable.js new file mode 100644 index 0000000000000000000000000000000000000000..e1804bf5c5720b7a85ae0693d3196ed6628fbaea --- /dev/null +++ b/public/assets/libs/Sortable/Sortable.js @@ -0,0 +1,3703 @@ +/**! + * Sortable 1.10.1 + * @author RubaXa + * @author owenm + * @license MIT + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.Sortable = factory()); +}(this, function () { 'use strict'; + + function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); + } + + function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + + ownKeys.forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } + + return target; + } + + function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; + } + + function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + var version = "1.10.1"; + + function userAgent(pattern) { + if (typeof window !== 'undefined' && window.navigator) { + return !! + /*@__PURE__*/ + navigator.userAgent.match(pattern); + } + } + + var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); + var Edge = userAgent(/Edge/i); + var FireFox = userAgent(/firefox/i); + var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); + var IOS = userAgent(/iP(ad|od|hone)/i); + var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i); + + var captureMode = { + capture: false, + passive: false + }; + + function on(el, event, fn) { + el.addEventListener(event, fn, !IE11OrLess && captureMode); + } + + function off(el, event, fn) { + el.removeEventListener(event, fn, !IE11OrLess && captureMode); + } + + function matches( + /**HTMLElement*/ + el, + /**String*/ + selector) { + if (!selector) return; + selector[0] === '>' && (selector = selector.substring(1)); + + if (el) { + try { + if (el.matches) { + return el.matches(selector); + } else if (el.msMatchesSelector) { + return el.msMatchesSelector(selector); + } else if (el.webkitMatchesSelector) { + return el.webkitMatchesSelector(selector); + } + } catch (_) { + return false; + } + } + + return false; + } + + function getParentOrHost(el) { + return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode; + } + + function closest( + /**HTMLElement*/ + el, + /**String*/ + selector, + /**HTMLElement*/ + ctx, includeCTX) { + if (el) { + ctx = ctx || document; + + do { + if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) { + return el; + } + + if (el === ctx) break; + /* jshint boss:true */ + } while (el = getParentOrHost(el)); + } + + return null; + } + + var R_SPACE = /\s+/g; + + function toggleClass(el, name, state) { + if (el && name) { + if (el.classList) { + el.classList[state ? 'add' : 'remove'](name); + } else { + var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); + el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); + } + } + } + + function css(el, prop, val) { + var style = el && el.style; + + if (style) { + if (val === void 0) { + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(el, ''); + } else if (el.currentStyle) { + val = el.currentStyle; + } + + return prop === void 0 ? val : val[prop]; + } else { + if (!(prop in style) && prop.indexOf('webkit') === -1) { + prop = '-webkit-' + prop; + } + + style[prop] = val + (typeof val === 'string' ? '' : 'px'); + } + } + } + + function matrix(el, selfOnly) { + var appliedTransforms = ''; + + if (typeof el === 'string') { + appliedTransforms = el; + } else { + do { + var transform = css(el, 'transform'); + + if (transform && transform !== 'none') { + appliedTransforms = transform + ' ' + appliedTransforms; + } + /* jshint boss:true */ + + } while (!selfOnly && (el = el.parentNode)); + } + + var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix; + /*jshint -W056 */ + + return matrixFn && new matrixFn(appliedTransforms); + } + + function find(ctx, tagName, iterator) { + if (ctx) { + var list = ctx.getElementsByTagName(tagName), + i = 0, + n = list.length; + + if (iterator) { + for (; i < n; i++) { + iterator(list[i], i); + } + } + + return list; + } + + return []; + } + + function getWindowScrollingElement() { + if (IE11OrLess) { + return document.documentElement; + } else { + return document.scrollingElement; + } + } + /** + * Returns the "bounding client rect" of given element + * @param {HTMLElement} el The element whose boundingClientRect is wanted + * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container + * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr + * @param {[Boolean]} undoScale Whether the container's scale() should be undone + * @param {[HTMLElement]} container The parent the element will be placed in + * @return {Object} The boundingClientRect of el, with specified adjustments + */ + + + function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) { + if (!el.getBoundingClientRect && el !== window) return; + var elRect, top, left, bottom, right, height, width; + + if (el !== window && el !== getWindowScrollingElement()) { + elRect = el.getBoundingClientRect(); + top = elRect.top; + left = elRect.left; + bottom = elRect.bottom; + right = elRect.right; + height = elRect.height; + width = elRect.width; + } else { + top = 0; + left = 0; + bottom = window.innerHeight; + right = window.innerWidth; + height = window.innerHeight; + width = window.innerWidth; + } + + if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) { + // Adjust for translate() + container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) + // Not needed on <= IE11 + + if (!IE11OrLess) { + do { + if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) { + var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container + + top -= containerRect.top + parseInt(css(container, 'border-top-width')); + left -= containerRect.left + parseInt(css(container, 'border-left-width')); + bottom = top + elRect.height; + right = left + elRect.width; + break; + } + /* jshint boss:true */ + + } while (container = container.parentNode); + } + } + + if (undoScale && el !== window) { + // Adjust for scale() + var elMatrix = matrix(container || el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d; + + if (elMatrix) { + top /= scaleY; + left /= scaleX; + width /= scaleX; + height /= scaleY; + bottom = top + height; + right = left + width; + } + } + + return { + top: top, + left: left, + bottom: bottom, + right: right, + width: width, + height: height + }; + } + /** + * Checks if a side of an element is scrolled past a side of its parents + * @param {HTMLElement} el The element who's side being scrolled out of view is in question + * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom') + * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') + * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element + */ + + + function isScrolledPast(el, elSide, parentSide) { + var parent = getParentAutoScrollElement(el, true), + elSideVal = getRect(el)[elSide]; + /* jshint boss:true */ + + while (parent) { + var parentSideVal = getRect(parent)[parentSide], + visible = void 0; + + if (parentSide === 'top' || parentSide === 'left') { + visible = elSideVal >= parentSideVal; + } else { + visible = elSideVal <= parentSideVal; + } + + if (!visible) return parent; + if (parent === getWindowScrollingElement()) break; + parent = getParentAutoScrollElement(parent, false); + } + + return false; + } + /** + * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) + * and non-draggable elements + * @param {HTMLElement} el The parent element + * @param {Number} childNum The index of the child + * @param {Object} options Parent Sortable's options + * @return {HTMLElement} The child at index childNum, or null if not found + */ + + + function getChild(el, childNum, options) { + var currentChild = 0, + i = 0, + children = el.children; + + while (i < children.length) { + if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && children[i] !== Sortable.dragged && closest(children[i], options.draggable, el, false)) { + if (currentChild === childNum) { + return children[i]; + } + + currentChild++; + } + + i++; + } + + return null; + } + /** + * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) + * @param {HTMLElement} el Parent element + * @param {selector} selector Any other elements that should be ignored + * @return {HTMLElement} The last child, ignoring ghostEl + */ + + + function lastChild(el, selector) { + var last = el.lastElementChild; + + while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { + last = last.previousElementSibling; + } + + return last || null; + } + /** + * Returns the index of an element within its parent for a selected set of + * elements + * @param {HTMLElement} el + * @param {selector} selector + * @return {number} + */ + + + function index(el, selector) { + var index = 0; + + if (!el || !el.parentNode) { + return -1; + } + /* jshint boss:true */ + + + while (el = el.previousElementSibling) { + if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) { + index++; + } + } + + return index; + } + /** + * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. + * The value is returned in real pixels. + * @param {HTMLElement} el + * @return {Array} Offsets in the format of [left, top] + */ + + + function getRelativeScrollOffset(el) { + var offsetLeft = 0, + offsetTop = 0, + winScroller = getWindowScrollingElement(); + + if (el) { + do { + var elMatrix = matrix(el), + scaleX = elMatrix.a, + scaleY = elMatrix.d; + offsetLeft += el.scrollLeft * scaleX; + offsetTop += el.scrollTop * scaleY; + } while (el !== winScroller && (el = el.parentNode)); + } + + return [offsetLeft, offsetTop]; + } + /** + * Returns the index of the object within the given array + * @param {Array} arr Array that may or may not hold the object + * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find + * @return {Number} The index of the object in the array, or -1 + */ + + + function indexOfObject(arr, obj) { + for (var i in arr) { + if (!arr.hasOwnProperty(i)) continue; + + for (var key in obj) { + if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i); + } + } + + return -1; + } + + function getParentAutoScrollElement(el, includeSelf) { + // skip to window + if (!el || !el.getBoundingClientRect) return getWindowScrollingElement(); + var elem = el; + var gotSelf = false; + + do { + // we don't need to get elem css if it isn't even overflowing in the first place (performance) + if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { + var elemCSS = css(elem); + + if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) { + if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement(); + if (gotSelf || includeSelf) return elem; + gotSelf = true; + } + } + /* jshint boss:true */ + + } while (elem = elem.parentNode); + + return getWindowScrollingElement(); + } + + function extend(dst, src) { + if (dst && src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dst[key] = src[key]; + } + } + } + + return dst; + } + + function isRectEqual(rect1, rect2) { + return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width); + } + + var _throttleTimeout; + + function throttle(callback, ms) { + return function () { + if (!_throttleTimeout) { + var args = arguments, + _this = this; + + if (args.length === 1) { + callback.call(_this, args[0]); + } else { + callback.apply(_this, args); + } + + _throttleTimeout = setTimeout(function () { + _throttleTimeout = void 0; + }, ms); + } + }; + } + + function cancelThrottle() { + clearTimeout(_throttleTimeout); + _throttleTimeout = void 0; + } + + function scrollBy(el, x, y) { + el.scrollLeft += x; + el.scrollTop += y; + } + + function clone(el) { + var Polymer = window.Polymer; + var $ = window.jQuery || window.Zepto; + + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } else if ($) { + return $(el).clone(true)[0]; + } else { + return el.cloneNode(true); + } + } + + function setRect(el, rect) { + css(el, 'position', 'absolute'); + css(el, 'top', rect.top); + css(el, 'left', rect.left); + css(el, 'width', rect.width); + css(el, 'height', rect.height); + } + + function unsetRect(el) { + css(el, 'position', ''); + css(el, 'top', ''); + css(el, 'left', ''); + css(el, 'width', ''); + css(el, 'height', ''); + } + + var expando = 'Sortable' + new Date().getTime(); + + function AnimationStateManager() { + var animationStates = [], + animationCallbackId; + return { + captureAnimationState: function captureAnimationState() { + animationStates = []; + if (!this.options.animation) return; + var children = [].slice.call(this.el.children); + children.forEach(function (child) { + if (css(child, 'display') === 'none' || child === Sortable.ghost) return; + animationStates.push({ + target: child, + rect: getRect(child) + }); + + var fromRect = _objectSpread({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation + + + if (child.thisAnimationDuration) { + var childMatrix = matrix(child, true); + + if (childMatrix) { + fromRect.top -= childMatrix.f; + fromRect.left -= childMatrix.e; + } + } + + child.fromRect = fromRect; + }); + }, + addAnimationState: function addAnimationState(state) { + animationStates.push(state); + }, + removeAnimationState: function removeAnimationState(target) { + animationStates.splice(indexOfObject(animationStates, { + target: target + }), 1); + }, + animateAll: function animateAll(callback) { + var _this = this; + + if (!this.options.animation) { + clearTimeout(animationCallbackId); + if (typeof callback === 'function') callback(); + return; + } + + var animating = false, + animationTime = 0; + animationStates.forEach(function (state) { + var time = 0, + target = state.target, + fromRect = target.fromRect, + toRect = getRect(target), + prevFromRect = target.prevFromRect, + prevToRect = target.prevToRect, + animatingRect = state.rect, + targetMatrix = matrix(target, true); + + if (targetMatrix) { + // Compensate for current animation + toRect.top -= targetMatrix.f; + toRect.left -= targetMatrix.e; + } + + target.toRect = toRect; + + if (target.thisAnimationDuration) { + // Could also check if animatingRect is between fromRect and toRect + if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect + (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) { + // If returning to same place as started from animation and on same axis + time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options); + } + } // if fromRect != toRect: animate + + + if (!isRectEqual(toRect, fromRect)) { + target.prevFromRect = fromRect; + target.prevToRect = toRect; + + if (!time) { + time = _this.options.animation; + } + + _this.animate(target, animatingRect, toRect, time); + } + + if (time) { + animating = true; + animationTime = Math.max(animationTime, time); + clearTimeout(target.animationResetTimer); + target.animationResetTimer = setTimeout(function () { + target.animationTime = 0; + target.prevFromRect = null; + target.fromRect = null; + target.prevToRect = null; + target.thisAnimationDuration = null; + }, time); + target.thisAnimationDuration = time; + } + }); + clearTimeout(animationCallbackId); + + if (!animating) { + if (typeof callback === 'function') callback(); + } else { + animationCallbackId = setTimeout(function () { + if (typeof callback === 'function') callback(); + }, animationTime); + } + + animationStates = []; + }, + animate: function animate(target, currentRect, toRect, duration) { + if (duration) { + css(target, 'transition', ''); + css(target, 'transform', ''); + var elMatrix = matrix(this.el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d, + translateX = (currentRect.left - toRect.left) / (scaleX || 1), + translateY = (currentRect.top - toRect.top) / (scaleY || 1); + target.animatingX = !!translateX; + target.animatingY = !!translateY; + css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); + repaint(target); // repaint + + css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); + css(target, 'transform', 'translate3d(0,0,0)'); + typeof target.animated === 'number' && clearTimeout(target.animated); + target.animated = setTimeout(function () { + css(target, 'transition', ''); + css(target, 'transform', ''); + target.animated = false; + target.animatingX = false; + target.animatingY = false; + }, duration); + } + } + }; + } + + function repaint(target) { + return target.offsetWidth; + } + + function calculateRealTime(animatingRect, fromRect, toRect, options) { + return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation; + } + + var plugins = []; + var defaults = { + initializeByDefault: true + }; + var PluginManager = { + mount: function mount(plugin) { + // Set default static properties + for (var option in defaults) { + if (defaults.hasOwnProperty(option) && !(option in plugin)) { + plugin[option] = defaults[option]; + } + } + + plugins.push(plugin); + }, + pluginEvent: function pluginEvent(eventName, sortable, evt) { + var _this = this; + + this.eventCanceled = false; + + evt.cancel = function () { + _this.eventCanceled = true; + }; + + var eventNameGlobal = eventName + 'Global'; + plugins.forEach(function (plugin) { + if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable + + if (sortable[plugin.pluginName][eventNameGlobal]) { + sortable[plugin.pluginName][eventNameGlobal](_objectSpread({ + sortable: sortable + }, evt)); + } // Only fire plugin event if plugin is enabled in this sortable, + // and plugin has event defined + + + if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { + sortable[plugin.pluginName][eventName](_objectSpread({ + sortable: sortable + }, evt)); + } + }); + }, + initializePlugins: function initializePlugins(sortable, el, defaults, options) { + plugins.forEach(function (plugin) { + var pluginName = plugin.pluginName; + if (!sortable.options[pluginName] && !plugin.initializeByDefault) return; + var initialized = new plugin(sortable, el, sortable.options); + initialized.sortable = sortable; + initialized.options = sortable.options; + sortable[pluginName] = initialized; // Add default options from plugin + + _extends(defaults, initialized.defaults); + }); + + for (var option in sortable.options) { + if (!sortable.options.hasOwnProperty(option)) continue; + var modified = this.modifyOption(sortable, option, sortable.options[option]); + + if (typeof modified !== 'undefined') { + sortable.options[option] = modified; + } + } + }, + getEventProperties: function getEventProperties(name, sortable) { + var eventProperties = {}; + plugins.forEach(function (plugin) { + if (typeof plugin.eventProperties !== 'function') return; + + _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name)); + }); + return eventProperties; + }, + modifyOption: function modifyOption(sortable, name, value) { + var modifiedValue; + plugins.forEach(function (plugin) { + // Plugin must exist on the Sortable + if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin + + if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') { + modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value); + } + }); + return modifiedValue; + } + }; + + function dispatchEvent(_ref) { + var sortable = _ref.sortable, + rootEl = _ref.rootEl, + name = _ref.name, + targetEl = _ref.targetEl, + cloneEl = _ref.cloneEl, + toEl = _ref.toEl, + fromEl = _ref.fromEl, + oldIndex = _ref.oldIndex, + newIndex = _ref.newIndex, + oldDraggableIndex = _ref.oldDraggableIndex, + newDraggableIndex = _ref.newDraggableIndex, + originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + extraEventProperties = _ref.extraEventProperties; + sortable = sortable || rootEl && rootEl[expando]; + if (!sortable) return; + var evt, + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent(name, { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(name, true, true); + } + + evt.to = toEl || rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + evt.oldIndex = oldIndex; + evt.newIndex = newIndex; + evt.oldDraggableIndex = oldDraggableIndex; + evt.newDraggableIndex = newDraggableIndex; + evt.originalEvent = originalEvent; + evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; + + var allEventProperties = _objectSpread({}, extraEventProperties, PluginManager.getEventProperties(name, sortable)); + + for (var option in allEventProperties) { + evt[option] = allEventProperties[option]; + } + + if (rootEl) { + rootEl.dispatchEvent(evt); + } + + if (options[onName]) { + options[onName].call(sortable, evt); + } + } + + var pluginEvent = function pluginEvent(eventName, sortable) { + var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + originalEvent = _ref.evt, + data = _objectWithoutProperties(_ref, ["evt"]); + + PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread({ + dragEl: dragEl, + parentEl: parentEl, + ghostEl: ghostEl, + rootEl: rootEl, + nextEl: nextEl, + lastDownEl: lastDownEl, + cloneEl: cloneEl, + cloneHidden: cloneHidden, + dragStarted: moved, + putSortable: putSortable, + activeSortable: Sortable.active, + originalEvent: originalEvent, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + hideGhostForTarget: _hideGhostForTarget, + unhideGhostForTarget: _unhideGhostForTarget, + cloneNowHidden: function cloneNowHidden() { + cloneHidden = true; + }, + cloneNowShown: function cloneNowShown() { + cloneHidden = false; + }, + dispatchSortableEvent: function dispatchSortableEvent(name) { + _dispatchEvent({ + sortable: sortable, + name: name, + originalEvent: originalEvent + }); + } + }, data)); + }; + + function _dispatchEvent(info) { + dispatchEvent(_objectSpread({ + putSortable: putSortable, + cloneEl: cloneEl, + targetEl: dragEl, + rootEl: rootEl, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex + }, info)); + } + + var dragEl, + parentEl, + ghostEl, + rootEl, + nextEl, + lastDownEl, + cloneEl, + cloneHidden, + oldIndex, + newIndex, + oldDraggableIndex, + newDraggableIndex, + activeGroup, + putSortable, + awaitingDragStarted = false, + ignoreNextClick = false, + sortables = [], + tapEvt, + touchEvt, + lastDx, + lastDy, + tapDistanceLeft, + tapDistanceTop, + moved, + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + targetMoveDistance, + // For positioning ghost absolutely + ghostRelativeParent, + ghostRelativeParentInitialScroll = [], + // (left, top) + _silent = false, + savedInputChecked = []; + /** @const */ + + var documentExists = typeof document !== 'undefined', + PositionGhostAbsolutely = IOS, + CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', + // This will not pass for IE9, because IE9 DnD only works on anchors + supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), + supportCssPointerEvents = function () { + if (!documentExists) return; // false when <= IE11 + + if (IE11OrLess) { + return false; + } + + var el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; + }(), + _detectDirection = function _detectDirection(el, options) { + var elCSS = css(el), + elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), + child1 = getChild(el, 0, options), + child2 = getChild(el, 1, options), + firstChildCSS = child1 && css(child1), + secondChildCSS = child2 && css(child2), + firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, + secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; + + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; + } + + if (elCSS.display === 'grid') { + return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; + } + + if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') { + var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; + return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; + } + + return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal'; + }, + _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) { + var dragElS1Opp = vertical ? dragRect.left : dragRect.top, + dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, + dragElOppLength = vertical ? dragRect.width : dragRect.height, + targetS1Opp = vertical ? targetRect.left : targetRect.top, + targetS2Opp = vertical ? targetRect.right : targetRect.bottom, + targetOppLength = vertical ? targetRect.width : targetRect.height; + return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2; + }, + + /** + * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. + * @param {Number} x X position + * @param {Number} y Y position + * @return {HTMLElement} Element of the first found nearest Sortable + */ + _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { + var ret; + sortables.some(function (sortable) { + if (lastChild(sortable)) return; + var rect = getRect(sortable), + threshold = sortable[expando].options.emptyInsertThreshold, + insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, + insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; + + if (threshold && insideHorizontally && insideVertically) { + return ret = sortable; + } + }); + return ret; + }, + _prepareGroup = function _prepareGroup(options) { + function toFn(value, pull) { + return function (to, from, dragEl, evt) { + var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name; + + if (value == null && (pull || sameGroup)) { + // Default pull value + // Default pull and put value if same group + return true; + } else if (value == null || value === false) { + return false; + } else if (pull && value === 'clone') { + return value; + } else if (typeof value === 'function') { + return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); + } else { + var otherGroup = (pull ? to : from).options.group.name; + return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1; + } + }; + } + + var group = {}; + var originalGroup = options.group; + + if (!originalGroup || _typeof(originalGroup) != 'object') { + originalGroup = { + name: originalGroup + }; + } + + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + options.group = group; + }, + _hideGhostForTarget = function _hideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', 'none'); + } + }, + _unhideGhostForTarget = function _unhideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', ''); + } + }; // #1184 fix - Prevent click event on fallback if dragged but item not changed position + + + if (documentExists) { + document.addEventListener('click', function (evt) { + if (ignoreNextClick) { + evt.preventDefault(); + evt.stopPropagation && evt.stopPropagation(); + evt.stopImmediatePropagation && evt.stopImmediatePropagation(); + ignoreNextClick = false; + return false; + } + }, true); + } + + var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) { + if (dragEl) { + evt = evt.touches ? evt.touches[0] : evt; + + var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); + + if (nearest) { + // Create imitation event + var event = {}; + + for (var i in evt) { + if (evt.hasOwnProperty(i)) { + event[i] = evt[i]; + } + } + + event.target = event.rootEl = nearest; + event.preventDefault = void 0; + event.stopPropagation = void 0; + + nearest[expando]._onDragOver(event); + } + } + }; + + var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) { + if (dragEl) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); + } + }; + /** + * @class Sortable + * @param {HTMLElement} el + * @param {Object} [options] + */ + + + function Sortable(el, options) { + if (!(el && el.nodeType && el.nodeType === 1)) { + throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); + } + + this.el = el; // root element + + this.options = options = _extends({}, options); // Export instance + + el[expando] = this; + var defaults = { + group: null, + sort: true, + disabled: false, + store: null, + handle: null, + draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*', + swapThreshold: 1, + // percentage; 0 <= x <= 1 + invertSwap: false, + // invert always + invertedSwapThreshold: null, + // will be set to same as swapThreshold if default + removeCloneOnHide: true, + direction: function direction() { + return _detectDirection(el, this.options); + }, + ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', + dragClass: 'sortable-drag', + ignore: 'a, img', + filter: null, + preventOnFilter: true, + animation: 0, + easing: null, + setData: function setData(dataTransfer, dragEl) { + dataTransfer.setData('Text', dragEl.textContent); + }, + dropBubble: false, + dragoverBubble: false, + dataIdAttr: 'data-id', + delay: 0, + delayOnTouchOnly: false, + touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false, + fallbackTolerance: 0, + fallbackOffset: { + x: 0, + y: 0 + }, + supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window, + emptyInsertThreshold: 5 + }; + PluginManager.initializePlugins(this, el, defaults); // Set default options + + for (var name in defaults) { + !(name in options) && (options[name] = defaults[name]); + } + + _prepareGroup(options); // Bind all private methods + + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } // Setup drag mode + + + this.nativeDraggable = options.forceFallback ? false : supportDraggable; + + if (this.nativeDraggable) { + // Touch start threshold cannot be greater than the native dragstart threshold + this.options.touchStartThreshold = 1; + } // Bind events + + + if (options.supportPointer) { + on(el, 'pointerdown', this._onTapStart); + } else { + on(el, 'mousedown', this._onTapStart); + on(el, 'touchstart', this._onTapStart); + } + + if (this.nativeDraggable) { + on(el, 'dragover', this); + on(el, 'dragenter', this); + } + + sortables.push(this.el); // Restore sorting + + options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager + + _extends(this, AnimationStateManager()); + } + + Sortable.prototype = + /** @lends Sortable.prototype */ + { + constructor: Sortable, + _isOutsideThisEl: function _isOutsideThisEl(target) { + if (!this.el.contains(target) && target !== this.el) { + lastTarget = null; + } + }, + _getDirection: function _getDirection(evt, target) { + return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; + }, + _onTapStart: function _onTapStart( + /** Event|TouchEvent */ + evt) { + if (!evt.cancelable) return; + + var _this = this, + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt, + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, + filter = options.filter; + + _saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. + + + if (dragEl) { + return; + } + + if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { + return; // only left button and enabled + } // cancel dnd if original target is content editable + + + if (originalTarget.isContentEditable) { + return; + } + + target = closest(target, options.draggable, el, false); + + if (target && target.animated) { + return; + } + + if (lastDownEl === target) { + // Ignoring duplicate `down` + return; + } // Get the index of the dragged element within its parent + + + oldIndex = index(target); + oldDraggableIndex = index(target, options.draggable); // Check filter + + if (typeof filter === 'function') { + if (filter.call(this, evt, target, this)) { + _dispatchEvent({ + sortable: _this, + rootEl: originalTarget, + name: 'filter', + targetEl: target, + toEl: el, + fromEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } else if (filter) { + filter = filter.split(',').some(function (criteria) { + criteria = closest(originalTarget, criteria.trim(), el, false); + + if (criteria) { + _dispatchEvent({ + sortable: _this, + rootEl: criteria, + name: 'filter', + targetEl: target, + fromEl: el, + toEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + return true; + } + }); + + if (filter) { + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + + if (options.handle && !closest(originalTarget, options.handle, el, false)) { + return; + } // Prepare `dragstart` + + + this._prepareDragStart(evt, touch, target); + }, + _prepareDragStart: function _prepareDragStart( + /** Event */ + evt, + /** Touch */ + touch, + /** HTMLElement */ + target) { + var _this = this, + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; + + if (target && !dragEl && target.parentNode === el) { + var dragRect = getRect(target); + rootEl = el; + dragEl = target; + parentEl = dragEl.parentNode; + nextEl = dragEl.nextSibling; + lastDownEl = target; + activeGroup = options.group; + Sortable.dragged = dragEl; + tapEvt = { + target: dragEl, + clientX: (touch || evt).clientX, + clientY: (touch || evt).clientY + }; + tapDistanceLeft = tapEvt.clientX - dragRect.left; + tapDistanceTop = tapEvt.clientY - dragRect.top; + this._lastX = (touch || evt).clientX; + this._lastY = (touch || evt).clientY; + dragEl.style['will-change'] = 'all'; + + dragStartFn = function dragStartFn() { + pluginEvent('delayEnded', _this, { + evt: evt + }); + + if (Sortable.eventCanceled) { + _this._onDrop(); + + return; + } // Delayed drag has been triggered + // we can re-enable the events: touchmove/mousemove + + + _this._disableDelayedDragEvents(); + + if (!FireFox && _this.nativeDraggable) { + dragEl.draggable = true; + } // Bind the events: dragstart/dragend + + + _this._triggerDragStart(evt, touch); // Drag start event + + + _dispatchEvent({ + sortable: _this, + name: 'choose', + originalEvent: evt + }); // Chosen item + + + toggleClass(dragEl, options.chosenClass, true); + }; // Disable "draggable" + + + options.ignore.split(',').forEach(function (criteria) { + find(dragEl, criteria.trim(), _disableDraggable); + }); + on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mouseup', _this._onDrop); + on(ownerDocument, 'touchend', _this._onDrop); + on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox) + + if (FireFox && this.nativeDraggable) { + this.options.touchStartThreshold = 4; + dragEl.draggable = true; + } + + pluginEvent('delayStart', this, { + evt: evt + }); // Delay is impossible for native DnD in Edge or IE + + if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { + if (Sortable.eventCanceled) { + this._onDrop(); + + return; + } // If the user moves the pointer or let go the click or touch + // before the delay has been reached: + // disable the delayed drag + + + on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + on(ownerDocument, 'touchend', _this._disableDelayedDrag); + on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); + on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); + options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); + _this._dragStartTimer = setTimeout(dragStartFn, options.delay); + } else { + dragStartFn(); + } + } + }, + _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( + /** TouchEvent|PointerEvent **/ + e) { + var touch = e.touches ? e.touches[0] : e; + + if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) { + this._disableDelayedDrag(); + } + }, + _disableDelayedDrag: function _disableDelayedDrag() { + dragEl && _disableDraggable(dragEl); + clearTimeout(this._dragStartTimer); + + this._disableDelayedDragEvents(); + }, + _disableDelayedDragEvents: function _disableDelayedDragEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._disableDelayedDrag); + off(ownerDocument, 'touchend', this._disableDelayedDrag); + off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); + }, + _triggerDragStart: function _triggerDragStart( + /** Event */ + evt, + /** Touch */ + touch) { + touch = touch || evt.pointerType == 'touch' && evt; + + if (!this.nativeDraggable || touch) { + if (this.options.supportPointer) { + on(document, 'pointermove', this._onTouchMove); + } else if (touch) { + on(document, 'touchmove', this._onTouchMove); + } else { + on(document, 'mousemove', this._onTouchMove); + } + } else { + on(dragEl, 'dragend', this); + on(rootEl, 'dragstart', this._onDragStart); + } + + try { + if (document.selection) { + // Timeout neccessary for IE9 + _nextTick(function () { + document.selection.empty(); + }); + } else { + window.getSelection().removeAllRanges(); + } + } catch (err) {} + }, + _dragStarted: function _dragStarted(fallback, evt) { + + awaitingDragStarted = false; + + if (rootEl && dragEl) { + pluginEvent('dragStarted', this, { + evt: evt + }); + + if (this.nativeDraggable) { + on(document, 'dragover', _checkOutsideTargetEl); + } + + var options = this.options; // Apply effect + + !fallback && toggleClass(dragEl, options.dragClass, false); + toggleClass(dragEl, options.ghostClass, true); + Sortable.active = this; + fallback && this._appendGhost(); // Drag start event + + _dispatchEvent({ + sortable: this, + name: 'start', + originalEvent: evt + }); + } else { + this._nulling(); + } + }, + _emulateDragOver: function _emulateDragOver() { + if (touchEvt) { + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + _hideGhostForTarget(); + + var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + var parent = target; + + while (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + if (target === parent) break; + parent = target; + } + + dragEl.parentNode[expando]._isOutsideThisEl(target); + + if (parent) { + do { + if (parent[expando]) { + var inserted = void 0; + inserted = parent[expando]._onDragOver({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + + if (inserted && !this.options.dragoverBubble) { + break; + } + } + + target = parent; // store last element + } + /* jshint boss:true */ + while (parent = parent.parentNode); + } + + _unhideGhostForTarget(); + } + }, + _onTouchMove: function _onTouchMove( + /**TouchEvent*/ + evt) { + if (tapEvt) { + var options = this.options, + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + ghostMatrix = ghostEl && matrix(ghostEl), + scaleX = ghostEl && ghostMatrix && ghostMatrix.a, + scaleY = ghostEl && ghostMatrix && ghostMatrix.d, + relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), + dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), + dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging + + if (!Sortable.active && !awaitingDragStarted) { + if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { + return; + } + + this._onDragStart(evt, true); + } + + if (ghostEl) { + if (ghostMatrix) { + ghostMatrix.e += dx - (lastDx || 0); + ghostMatrix.f += dy - (lastDy || 0); + } else { + ghostMatrix = { + a: 1, + b: 0, + c: 0, + d: 1, + e: dx, + f: dy + }; + } + + var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")"); + css(ghostEl, 'webkitTransform', cssMatrix); + css(ghostEl, 'mozTransform', cssMatrix); + css(ghostEl, 'msTransform', cssMatrix); + css(ghostEl, 'transform', cssMatrix); + lastDx = dx; + lastDy = dy; + touchEvt = touch; + } + + evt.cancelable && evt.preventDefault(); + } + }, + _appendGhost: function _appendGhost() { + // Bug if using scale(): https://stackoverflow.com/questions/2637058 + // Not being adjusted for + if (!ghostEl) { + var container = this.options.fallbackOnBody ? document.body : rootEl, + rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), + options = this.options; // Position absolutely + + if (PositionGhostAbsolutely) { + // Get relatively positioned parent + ghostRelativeParent = container; + + while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) { + ghostRelativeParent = ghostRelativeParent.parentNode; + } + + if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { + if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement(); + rect.top += ghostRelativeParent.scrollTop; + rect.left += ghostRelativeParent.scrollLeft; + } else { + ghostRelativeParent = getWindowScrollingElement(); + } + + ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent); + } + + ghostEl = dragEl.cloneNode(true); + toggleClass(ghostEl, options.ghostClass, false); + toggleClass(ghostEl, options.fallbackClass, true); + toggleClass(ghostEl, options.dragClass, true); + css(ghostEl, 'transition', ''); + css(ghostEl, 'transform', ''); + css(ghostEl, 'box-sizing', 'border-box'); + css(ghostEl, 'margin', 0); + css(ghostEl, 'top', rect.top); + css(ghostEl, 'left', rect.left); + css(ghostEl, 'width', rect.width); + css(ghostEl, 'height', rect.height); + css(ghostEl, 'opacity', '0.8'); + css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed'); + css(ghostEl, 'zIndex', '100000'); + css(ghostEl, 'pointerEvents', 'none'); + Sortable.ghost = ghostEl; + container.appendChild(ghostEl); // Set transform-origin + + css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%'); + } + }, + _onDragStart: function _onDragStart( + /**Event*/ + evt, + /**boolean*/ + fallback) { + var _this = this; + + var dataTransfer = evt.dataTransfer; + var options = _this.options; + pluginEvent('dragStart', this, { + evt: evt + }); + + if (Sortable.eventCanceled) { + this._onDrop(); + + return; + } + + pluginEvent('setupClone', this); + + if (!Sortable.eventCanceled) { + cloneEl = clone(dragEl); + cloneEl.draggable = false; + cloneEl.style['will-change'] = ''; + + this._hideClone(); + + toggleClass(cloneEl, this.options.chosenClass, false); + Sortable.clone = cloneEl; + } // #1143: IFrame support workaround + + + _this.cloneId = _nextTick(function () { + pluginEvent('clone', _this); + if (Sortable.eventCanceled) return; + + if (!_this.options.removeCloneOnHide) { + rootEl.insertBefore(cloneEl, dragEl); + } + + _this._hideClone(); + + _dispatchEvent({ + sortable: _this, + name: 'clone' + }); + }); + !fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events + + if (fallback) { + ignoreNextClick = true; + _this._loopId = setInterval(_this._emulateDragOver, 50); + } else { + // Undo what was set in _prepareDragStart before drag started + off(document, 'mouseup', _this._onDrop); + off(document, 'touchend', _this._onDrop); + off(document, 'touchcancel', _this._onDrop); + + if (dataTransfer) { + dataTransfer.effectAllowed = 'move'; + options.setData && options.setData.call(_this, dataTransfer, dragEl); + } + + on(document, 'drop', _this); // #1276 fix: + + css(dragEl, 'transform', 'translateZ(0)'); + } + + awaitingDragStarted = true; + _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); + on(document, 'selectstart', _this); + moved = true; + + if (Safari) { + css(document.body, 'user-select', 'none'); + } + }, + // Returns true - if no further action is needed (either inserted or another condition) + _onDragOver: function _onDragOver( + /**Event*/ + evt) { + var el = this.el, + target = evt.target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable.active, + isOwner = activeGroup === group, + canSort = options.sort, + fromSortable = putSortable || activeSortable, + vertical, + _this = this, + completedFired = false; + + if (_silent) return; + + function dragOverEvent(name, extra) { + pluginEvent(name, _this, _objectSpread({ + evt: evt, + isOwner: isOwner, + axis: vertical ? 'vertical' : 'horizontal', + revert: revert, + dragRect: dragRect, + targetRect: targetRect, + canSort: canSort, + fromSortable: fromSortable, + target: target, + completed: completed, + onMove: function onMove(target, after) { + return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after); + }, + changed: changed + }, extra)); + } // Capture animation state + + + function capture() { + dragOverEvent('dragOverAnimationCapture'); + + _this.captureAnimationState(); + + if (_this !== fromSortable) { + fromSortable.captureAnimationState(); + } + } // Return invocation when dragEl is inserted (or completed) + + + function completed(insertion) { + dragOverEvent('dragOverCompleted', { + insertion: insertion + }); + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(_this); + } + + if (_this !== fromSortable) { + // Set ghost class to new sortable's ghost class + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); + toggleClass(dragEl, options.ghostClass, true); + } + + if (putSortable !== _this && _this !== Sortable.active) { + putSortable = _this; + } else if (_this === Sortable.active && putSortable) { + putSortable = null; + } // Animation + + + if (fromSortable === _this) { + _this._ignoreWhileAnimating = target; + } + + _this.animateAll(function () { + dragOverEvent('dragOverAnimationComplete'); + _this._ignoreWhileAnimating = null; + }); + + if (_this !== fromSortable) { + fromSortable.animateAll(); + fromSortable._ignoreWhileAnimating = null; + } + } // Null lastTarget if it is not inside a previously swapped element + + + if (target === dragEl && !dragEl.animated || target === el && !target.animated) { + lastTarget = null; + } // no bubbling and not fallback + + + if (!options.dragoverBubble && !evt.rootEl && target !== document) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted + + + !insertion && nearestEmptyInsertDetectEvent(evt); + } + + !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); + return completedFired = true; + } // Call when dragEl has been inserted + + + function changed() { + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + _dispatchEvent({ + sortable: _this, + name: 'change', + toEl: el, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + originalEvent: evt + }); + } + + if (evt.preventDefault !== void 0) { + evt.cancelable && evt.preventDefault(); + } + + target = closest(target, options.draggable, el, true); + dragOverEvent('dragOver'); + if (Sortable.eventCanceled) return completedFired; + + if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) { + return completed(false); + } + + ignoreNextClick = false; + + if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) { + vertical = this._getDirection(evt, target) === 'vertical'; + dragRect = getRect(dragEl); + dragOverEvent('dragOverValid'); + if (Sortable.eventCanceled) return completedFired; + + if (revert) { + parentEl = rootEl; // actualization + + capture(); + + this._hideClone(); + + dragOverEvent('revert'); + + if (!Sortable.eventCanceled) { + if (nextEl) { + rootEl.insertBefore(dragEl, nextEl); + } else { + rootEl.appendChild(dragEl); + } + } + + return completed(true); + } + + var elLastChild = lastChild(el, options.draggable); + + if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { + // If already at end of list: Do not insert + if (elLastChild === dragEl) { + return completed(false); + } // assign target only if condition is true + + + if (elLastChild && el === evt.target) { + target = elLastChild; + } + + if (target) { + targetRect = getRect(target); + } + + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { + capture(); + el.appendChild(dragEl); + parentEl = el; // actualization + + changed(); + return completed(true); + } + } else if (target.parentNode === el) { + targetRect = getRect(target); + var direction = 0, + targetBeforeFirstSwap, + differentLevel = dragEl.parentNode !== el, + differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), + side1 = vertical ? 'top' : 'left', + scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), + scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; + + if (lastTarget !== target) { + targetBeforeFirstSwap = targetRect[side1]; + pastFirstInvertThresh = false; + isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel; + } + + direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); + var sibling; + + if (direction !== 0) { + // Check if target is beside dragEl in respective direction (ignoring hidden elements) + var dragIndex = index(dragEl); + + do { + dragIndex -= direction; + sibling = parentEl.children[dragIndex]; + } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl)); + } // If dragEl is already beside target: Do not insert + + + if (direction === 0 || sibling === target) { + return completed(false); + } + + lastTarget = target; + lastDirection = direction; + var nextSibling = target.nextElementSibling, + after = false; + after = direction === 1; + + var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); + + if (moveVector !== false) { + if (moveVector === 1 || moveVector === -1) { + after = moveVector === 1; + } + + _silent = true; + setTimeout(_unsilent, 30); + capture(); + + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } // Undo chrome's scroll adjustment (has no effect on other browsers) + + + if (scrolledPastTop) { + scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); + } + + parentEl = dragEl.parentNode; // actualization + // must be done before animation + + if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { + targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]); + } + + changed(); + return completed(true); + } + } + + if (el.contains(dragEl)) { + return completed(false); + } + } + + return false; + }, + _ignoreWhileAnimating: null, + _offMoveEvents: function _offMoveEvents() { + off(document, 'mousemove', this._onTouchMove); + off(document, 'touchmove', this._onTouchMove); + off(document, 'pointermove', this._onTouchMove); + off(document, 'dragover', nearestEmptyInsertDetectEvent); + off(document, 'mousemove', nearestEmptyInsertDetectEvent); + off(document, 'touchmove', nearestEmptyInsertDetectEvent); + }, + _offUpEvents: function _offUpEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._onDrop); + off(ownerDocument, 'touchend', this._onDrop); + off(ownerDocument, 'pointerup', this._onDrop); + off(ownerDocument, 'touchcancel', this._onDrop); + off(document, 'selectstart', this); + }, + _onDrop: function _onDrop( + /**Event*/ + evt) { + var el = this.el, + options = this.options; // Get the index of the dragged element within its parent + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + pluginEvent('drop', this, { + evt: evt + }); + parentEl = dragEl && dragEl.parentNode; // Get again after plugin event + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + if (Sortable.eventCanceled) { + this._nulling(); + + return; + } + + awaitingDragStarted = false; + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + clearInterval(this._loopId); + clearTimeout(this._dragStartTimer); + + _cancelNextTick(this.cloneId); + + _cancelNextTick(this._dragStartId); // Unbind events + + + if (this.nativeDraggable) { + off(document, 'drop', this); + off(el, 'dragstart', this._onDragStart); + } + + this._offMoveEvents(); + + this._offUpEvents(); + + if (Safari) { + css(document.body, 'user-select', ''); + } + + if (evt) { + if (moved) { + evt.cancelable && evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } + + ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + // Remove clone(s) + cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); + } + + if (dragEl) { + if (this.nativeDraggable) { + off(dragEl, 'dragend', this); + } + + _disableDraggable(dragEl); + + dragEl.style['will-change'] = ''; // Remove classes + // ghostClass is added in dragStarted + + if (moved && !awaitingDragStarted) { + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); + } + + toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event + + _dispatchEvent({ + sortable: this, + name: 'unchoose', + toEl: parentEl, + newIndex: null, + newDraggableIndex: null, + originalEvent: evt + }); + + if (rootEl !== parentEl) { + if (newIndex >= 0) { + // Add event + _dispatchEvent({ + rootEl: parentEl, + name: 'add', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); // Remove event + + + _dispatchEvent({ + sortable: this, + name: 'remove', + toEl: parentEl, + originalEvent: evt + }); // drag from one list and drop into another + + + _dispatchEvent({ + rootEl: parentEl, + name: 'sort', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + + putSortable && putSortable.save(); + } else { + if (newIndex !== oldIndex) { + if (newIndex >= 0) { + // drag & drop within the same list + _dispatchEvent({ + sortable: this, + name: 'update', + toEl: parentEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + } + } + + if (Sortable.active) { + /* jshint eqnull:true */ + if (newIndex == null || newIndex === -1) { + newIndex = oldIndex; + newDraggableIndex = oldDraggableIndex; + } + + _dispatchEvent({ + sortable: this, + name: 'end', + toEl: parentEl, + originalEvent: evt + }); // Save sorting + + + this.save(); + } + } + } + + this._nulling(); + }, + _nulling: function _nulling() { + pluginEvent('nulling', this); + rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null; + savedInputChecked.forEach(function (el) { + el.checked = true; + }); + savedInputChecked.length = lastDx = lastDy = 0; + }, + handleEvent: function handleEvent( + /**Event*/ + evt) { + switch (evt.type) { + case 'drop': + case 'dragend': + this._onDrop(evt); + + break; + + case 'dragenter': + case 'dragover': + if (dragEl) { + this._onDragOver(evt); + + _globalDragOver(evt); + } + + break; + + case 'selectstart': + evt.preventDefault(); + break; + } + }, + + /** + * Serializes the item into an array of string. + * @returns {String[]} + */ + toArray: function toArray() { + var order = [], + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; + + for (; i < n; i++) { + el = children[i]; + + if (closest(el, options.draggable, this.el, false)) { + order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); + } + } + + return order; + }, + + /** + * Sorts the elements according to the array. + * @param {String[]} order order of the items + */ + sort: function sort(order) { + var items = {}, + rootEl = this.el; + this.toArray().forEach(function (id, i) { + var el = rootEl.children[i]; + + if (closest(el, this.options.draggable, rootEl, false)) { + items[id] = el; + } + }, this); + order.forEach(function (id) { + if (items[id]) { + rootEl.removeChild(items[id]); + rootEl.appendChild(items[id]); + } + }); + }, + + /** + * Save the current sorting + */ + save: function save() { + var store = this.options.store; + store && store.set && store.set(this); + }, + + /** + * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + * @param {HTMLElement} el + * @param {String} [selector] default: `options.draggable` + * @returns {HTMLElement|null} + */ + closest: function closest$1(el, selector) { + return closest(el, selector || this.options.draggable, this.el, false); + }, + + /** + * Set/get option + * @param {string} name + * @param {*} [value] + * @returns {*} + */ + option: function option(name, value) { + var options = this.options; + + if (value === void 0) { + return options[name]; + } else { + var modifiedValue = PluginManager.modifyOption(this, name, value); + + if (typeof modifiedValue !== 'undefined') { + options[name] = modifiedValue; + } else { + options[name] = value; + } + + if (name === 'group') { + _prepareGroup(options); + } + } + }, + + /** + * Destroy + */ + destroy: function destroy() { + pluginEvent('destroy', this); + var el = this.el; + el[expando] = null; + off(el, 'mousedown', this._onTapStart); + off(el, 'touchstart', this._onTapStart); + off(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + off(el, 'dragover', this); + off(el, 'dragenter', this); + } // Remove draggable attributes + + + Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { + el.removeAttribute('draggable'); + }); + + this._onDrop(); + + sortables.splice(sortables.indexOf(this.el), 1); + this.el = el = null; + }, + _hideClone: function _hideClone() { + if (!cloneHidden) { + pluginEvent('hideClone', this); + if (Sortable.eventCanceled) return; + css(cloneEl, 'display', 'none'); + + if (this.options.removeCloneOnHide && cloneEl.parentNode) { + cloneEl.parentNode.removeChild(cloneEl); + } + + cloneHidden = true; + } + }, + _showClone: function _showClone(putSortable) { + if (putSortable.lastPutMode !== 'clone') { + this._hideClone(); + + return; + } + + if (cloneHidden) { + pluginEvent('showClone', this); + if (Sortable.eventCanceled) return; // show clone at dragEl or original position + + if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + rootEl.insertBefore(cloneEl, dragEl); + } else if (nextEl) { + rootEl.insertBefore(cloneEl, nextEl); + } else { + rootEl.appendChild(cloneEl); + } + + if (this.options.group.revertClone) { + this.animate(dragEl, cloneEl); + } + + css(cloneEl, 'display', ''); + cloneHidden = false; + } + } + }; + + function _globalDragOver( + /**Event*/ + evt) { + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } + + evt.cancelable && evt.preventDefault(); + } + + function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) { + var evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent('move', { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + } + + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || getRect(toEl); + evt.willInsertAfter = willInsertAfter; + evt.originalEvent = originalEvent; + fromEl.dispatchEvent(evt); + + if (onMoveFn) { + retVal = onMoveFn.call(sortable, evt, originalEvent); + } + + return retVal; + } + + function _disableDraggable(el) { + el.draggable = false; + } + + function _unsilent() { + _silent = false; + } + + function _ghostIsLast(evt, vertical, sortable) { + var rect = getRect(lastChild(sortable.el, sortable.options.draggable)); + var spacer = 10; + return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer; + } + + function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { + var mouseOnAxis = vertical ? evt.clientY : evt.clientX, + targetLength = vertical ? targetRect.height : targetRect.width, + targetS1 = vertical ? targetRect.top : targetRect.left, + targetS2 = vertical ? targetRect.bottom : targetRect.right, + invert = false; + + if (!invertSwap) { + // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold + if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { + // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 + // check if past first invert threshold on side opposite of lastDirection + if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) { + // past first invert threshold, do not restrict inverted threshold to dragEl shadow + pastFirstInvertThresh = true; + } + + if (!pastFirstInvertThresh) { + // dragEl shadow (target move distance shadow) + if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow + : mouseOnAxis > targetS2 - targetMoveDistance) { + return -lastDirection; + } + } else { + invert = true; + } + } else { + // Regular + if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) { + return _getInsertDirection(target); + } + } + } + + invert = invert || invertSwap; + + if (invert) { + // Invert of regular + if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) { + return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1; + } + } + + return 0; + } + /** + * Gets the direction dragEl must be swapped relative to target in order to make it + * seem that dragEl has been "inserted" into that element's position + * @param {HTMLElement} target The target whose position dragEl is being inserted at + * @return {Number} Direction dragEl must be swapped + */ + + + function _getInsertDirection(target) { + if (index(dragEl) < index(target)) { + return 1; + } else { + return -1; + } + } + /** + * Generate id + * @param {HTMLElement} el + * @returns {String} + * @private + */ + + + function _generateId(el) { + var str = el.tagName + el.className + el.src + el.href + el.textContent, + i = str.length, + sum = 0; + + while (i--) { + sum += str.charCodeAt(i); + } + + return sum.toString(36); + } + + function _saveInputCheckedState(root) { + savedInputChecked.length = 0; + var inputs = root.getElementsByTagName('input'); + var idx = inputs.length; + + while (idx--) { + var el = inputs[idx]; + el.checked && savedInputChecked.push(el); + } + } + + function _nextTick(fn) { + return setTimeout(fn, 0); + } + + function _cancelNextTick(id) { + return clearTimeout(id); + } // Fixed #973: + + + if (documentExists) { + on(document, 'touchmove', function (evt) { + if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { + evt.preventDefault(); + } + }); + } // Export utils + + + Sortable.utils = { + on: on, + off: off, + css: css, + find: find, + is: function is(el, selector) { + return !!closest(el, selector, el, false); + }, + extend: extend, + throttle: throttle, + closest: closest, + toggleClass: toggleClass, + clone: clone, + index: index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick, + detectDirection: _detectDirection, + getChild: getChild + }; + /** + * Get the Sortable instance of an element + * @param {HTMLElement} element The element + * @return {Sortable|undefined} The instance of Sortable + */ + + Sortable.get = function (element) { + return element[expando]; + }; + /** + * Mount a plugin to Sortable + * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted + */ + + + Sortable.mount = function () { + for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { + plugins[_key] = arguments[_key]; + } + + if (plugins[0].constructor === Array) plugins = plugins[0]; + plugins.forEach(function (plugin) { + if (!plugin.prototype || !plugin.prototype.constructor) { + throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin)); + } + + if (plugin.utils) Sortable.utils = _objectSpread({}, Sortable.utils, plugin.utils); + PluginManager.mount(plugin); + }); + }; + /** + * Create sortable instance + * @param {HTMLElement} el + * @param {Object} [options] + */ + + + Sortable.create = function (el, options) { + return new Sortable(el, options); + }; // Export + + + Sortable.version = version; + + var autoScrolls = [], + scrollEl, + scrollRootEl, + scrolling = false, + lastAutoScrollX, + lastAutoScrollY, + touchEvt$1, + pointerElemChangedInterval; + + function AutoScrollPlugin() { + function AutoScroll() { + this.defaults = { + scroll: true, + scrollSensitivity: 30, + scrollSpeed: 10, + bubbleScroll: true + }; // Bind all private methods + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + } + + AutoScroll.prototype = { + dragStarted: function dragStarted(_ref) { + var originalEvent = _ref.originalEvent; + + if (this.sortable.nativeDraggable) { + on(document, 'dragover', this._handleAutoScroll); + } else { + if (this.options.supportPointer) { + on(document, 'pointermove', this._handleFallbackAutoScroll); + } else if (originalEvent.touches) { + on(document, 'touchmove', this._handleFallbackAutoScroll); + } else { + on(document, 'mousemove', this._handleFallbackAutoScroll); + } + } + }, + dragOverCompleted: function dragOverCompleted(_ref2) { + var originalEvent = _ref2.originalEvent; + + // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) + if (!this.options.dragOverBubble && !originalEvent.rootEl) { + this._handleAutoScroll(originalEvent); + } + }, + drop: function drop() { + if (this.sortable.nativeDraggable) { + off(document, 'dragover', this._handleAutoScroll); + } else { + off(document, 'pointermove', this._handleFallbackAutoScroll); + off(document, 'touchmove', this._handleFallbackAutoScroll); + off(document, 'mousemove', this._handleFallbackAutoScroll); + } + + clearPointerElemChangedInterval(); + clearAutoScrolls(); + cancelThrottle(); + }, + nulling: function nulling() { + touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null; + autoScrolls.length = 0; + }, + _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) { + this._handleAutoScroll(evt, true); + }, + _handleAutoScroll: function _handleAutoScroll(evt, fallback) { + var _this = this; + + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + elem = document.elementFromPoint(x, y); + touchEvt$1 = evt; // IE does not seem to have native autoscroll, + // Edge's autoscroll seems too conditional, + // MACOS Safari does not have autoscroll, + // Firefox and Chrome are good + + if (fallback || Edge || IE11OrLess || Safari) { + autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change + + var ogElemScroller = getParentAutoScrollElement(elem, true); + + if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) { + pointerElemChangedInterval && clearPointerElemChangedInterval(); // Detect for pointer elem change, emulating native DnD behaviour + + pointerElemChangedInterval = setInterval(function () { + var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true); + + if (newElem !== ogElemScroller) { + ogElemScroller = newElem; + clearAutoScrolls(); + } + + autoScroll(evt, _this.options, newElem, fallback); + }, 10); + lastAutoScrollX = x; + lastAutoScrollY = y; + } + } else { + // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll + if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { + clearAutoScrolls(); + return; + } + + autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false); + } + } + }; + return _extends(AutoScroll, { + pluginName: 'scroll', + initializeByDefault: true + }); + } + + function clearAutoScrolls() { + autoScrolls.forEach(function (autoScroll) { + clearInterval(autoScroll.pid); + }); + autoScrolls = []; + } + + function clearPointerElemChangedInterval() { + clearInterval(pointerElemChangedInterval); + } + + var autoScroll = throttle(function (evt, options, rootEl, isFallback) { + // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + if (!options.scroll) return; + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + sens = options.scrollSensitivity, + speed = options.scrollSpeed, + winScroller = getWindowScrollingElement(); + var scrollThisInstance = false, + scrollCustomFn; // New scroll root, set scrollEl + + if (scrollRootEl !== rootEl) { + scrollRootEl = rootEl; + clearAutoScrolls(); + scrollEl = options.scroll; + scrollCustomFn = options.scrollFn; + + if (scrollEl === true) { + scrollEl = getParentAutoScrollElement(rootEl, true); + } + } + + var layersOut = 0; + var currentParent = scrollEl; + + do { + var el = currentParent, + rect = getRect(el), + top = rect.top, + bottom = rect.bottom, + left = rect.left, + right = rect.right, + width = rect.width, + height = rect.height, + canScrollX = void 0, + canScrollY = void 0, + scrollWidth = el.scrollWidth, + scrollHeight = el.scrollHeight, + elCSS = css(el), + scrollPosX = el.scrollLeft, + scrollPosY = el.scrollTop; + + if (el === winScroller) { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible'); + } else { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); + } + + var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX); + var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY); + + if (!autoScrolls[layersOut]) { + for (var i = 0; i <= layersOut; i++) { + if (!autoScrolls[i]) { + autoScrolls[i] = {}; + } + } + } + + if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { + autoScrolls[layersOut].el = el; + autoScrolls[layersOut].vx = vx; + autoScrolls[layersOut].vy = vy; + clearInterval(autoScrolls[layersOut].pid); + + if (vx != 0 || vy != 0) { + scrollThisInstance = true; + /* jshint loopfunc:true */ + + autoScrolls[layersOut].pid = setInterval(function () { + // emulate drag over during autoscroll (fallback), emulating native DnD behaviour + if (isFallback && this.layer === 0) { + Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely + + } + + var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; + var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; + + if (typeof scrollCustomFn === 'function') { + if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') { + return; + } + } + + scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); + }.bind({ + layer: layersOut + }), 24); + } + } + + layersOut++; + } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false))); + + scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not + }, 30); + + var drop = function drop(_ref) { + var originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + dragEl = _ref.dragEl, + activeSortable = _ref.activeSortable, + dispatchSortableEvent = _ref.dispatchSortableEvent, + hideGhostForTarget = _ref.hideGhostForTarget, + unhideGhostForTarget = _ref.unhideGhostForTarget; + if (!originalEvent) return; + var toSortable = putSortable || activeSortable; + hideGhostForTarget(); + var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent; + var target = document.elementFromPoint(touch.clientX, touch.clientY); + unhideGhostForTarget(); + + if (toSortable && !toSortable.el.contains(target)) { + dispatchSortableEvent('spill'); + this.onSpill({ + dragEl: dragEl, + putSortable: putSortable + }); + } + }; + + function Revert() {} + + Revert.prototype = { + startIndex: null, + dragStart: function dragStart(_ref2) { + var oldDraggableIndex = _ref2.oldDraggableIndex; + this.startIndex = oldDraggableIndex; + }, + onSpill: function onSpill(_ref3) { + var dragEl = _ref3.dragEl, + putSortable = _ref3.putSortable; + this.sortable.captureAnimationState(); + + if (putSortable) { + putSortable.captureAnimationState(); + } + + var nextSibling = getChild(this.sortable.el, this.startIndex, this.options); + + if (nextSibling) { + this.sortable.el.insertBefore(dragEl, nextSibling); + } else { + this.sortable.el.appendChild(dragEl); + } + + this.sortable.animateAll(); + + if (putSortable) { + putSortable.animateAll(); + } + }, + drop: drop + }; + + _extends(Revert, { + pluginName: 'revertOnSpill' + }); + + function Remove() {} + + Remove.prototype = { + onSpill: function onSpill(_ref4) { + var dragEl = _ref4.dragEl, + putSortable = _ref4.putSortable; + var parentSortable = putSortable || this.sortable; + parentSortable.captureAnimationState(); + dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); + parentSortable.animateAll(); + }, + drop: drop + }; + + _extends(Remove, { + pluginName: 'removeOnSpill' + }); + + var lastSwapEl; + + function SwapPlugin() { + function Swap() { + this.defaults = { + swapClass: 'sortable-swap-highlight' + }; + } + + Swap.prototype = { + dragStart: function dragStart(_ref) { + var dragEl = _ref.dragEl; + lastSwapEl = dragEl; + }, + dragOverValid: function dragOverValid(_ref2) { + var completed = _ref2.completed, + target = _ref2.target, + onMove = _ref2.onMove, + activeSortable = _ref2.activeSortable, + changed = _ref2.changed, + cancel = _ref2.cancel; + if (!activeSortable.options.swap) return; + var el = this.sortable.el, + options = this.options; + + if (target && target !== el) { + var prevSwapEl = lastSwapEl; + + if (onMove(target) !== false) { + toggleClass(target, options.swapClass, true); + lastSwapEl = target; + } else { + lastSwapEl = null; + } + + if (prevSwapEl && prevSwapEl !== lastSwapEl) { + toggleClass(prevSwapEl, options.swapClass, false); + } + } + + changed(); + completed(true); + cancel(); + }, + drop: function drop(_ref3) { + var activeSortable = _ref3.activeSortable, + putSortable = _ref3.putSortable, + dragEl = _ref3.dragEl; + var toSortable = putSortable || this.sortable; + var options = this.options; + lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); + + if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { + if (dragEl !== lastSwapEl) { + toSortable.captureAnimationState(); + if (toSortable !== activeSortable) activeSortable.captureAnimationState(); + swapNodes(dragEl, lastSwapEl); + toSortable.animateAll(); + if (toSortable !== activeSortable) activeSortable.animateAll(); + } + } + }, + nulling: function nulling() { + lastSwapEl = null; + } + }; + return _extends(Swap, { + pluginName: 'swap', + eventProperties: function eventProperties() { + return { + swapItem: lastSwapEl + }; + } + }); + } + + function swapNodes(n1, n2) { + var p1 = n1.parentNode, + p2 = n2.parentNode, + i1, + i2; + if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; + i1 = index(n1); + i2 = index(n2); + + if (p1.isEqualNode(p2) && i1 < i2) { + i2++; + } + + p1.insertBefore(n2, p1.children[i1]); + p2.insertBefore(n1, p2.children[i2]); + } + + var multiDragElements = [], + multiDragClones = [], + lastMultiDragSelect, + // for selection with modifier key down (SHIFT) + multiDragSortable, + initialFolding = false, + // Initial multi-drag fold when drag started + folding = false, + // Folding any other time + dragStarted = false, + dragEl$1, + clonesFromRect, + clonesHidden; + + function MultiDragPlugin() { + function MultiDrag(sortable) { + // Bind all private methods + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + if (sortable.options.supportPointer) { + on(document, 'pointerup', this._deselectMultiDrag); + } else { + on(document, 'mouseup', this._deselectMultiDrag); + on(document, 'touchend', this._deselectMultiDrag); + } + + on(document, 'keydown', this._checkKeyDown); + on(document, 'keyup', this._checkKeyUp); + this.defaults = { + selectedClass: 'sortable-selected', + multiDragKey: null, + setData: function setData(dataTransfer, dragEl) { + var data = ''; + + if (multiDragElements.length && multiDragSortable === sortable) { + multiDragElements.forEach(function (multiDragElement, i) { + data += (!i ? '' : ', ') + multiDragElement.textContent; + }); + } else { + data = dragEl.textContent; + } + + dataTransfer.setData('Text', data); + } + }; + } + + MultiDrag.prototype = { + multiDragKeyDown: false, + isMultiDrag: false, + delayStartGlobal: function delayStartGlobal(_ref) { + var dragged = _ref.dragEl; + dragEl$1 = dragged; + }, + delayEnded: function delayEnded() { + this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1); + }, + setupClone: function setupClone(_ref2) { + var sortable = _ref2.sortable, + cancel = _ref2.cancel; + if (!this.isMultiDrag) return; + + for (var i = 0; i < multiDragElements.length; i++) { + multiDragClones.push(clone(multiDragElements[i])); + multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; + multiDragClones[i].draggable = false; + multiDragClones[i].style['will-change'] = ''; + toggleClass(multiDragClones[i], this.options.selectedClass, false); + multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false); + } + + sortable._hideClone(); + + cancel(); + }, + clone: function clone(_ref3) { + var sortable = _ref3.sortable, + rootEl = _ref3.rootEl, + dispatchSortableEvent = _ref3.dispatchSortableEvent, + cancel = _ref3.cancel; + if (!this.isMultiDrag) return; + + if (!this.options.removeCloneOnHide) { + if (multiDragElements.length && multiDragSortable === sortable) { + insertMultiDragClones(true, rootEl); + dispatchSortableEvent('clone'); + cancel(); + } + } + }, + showClone: function showClone(_ref4) { + var cloneNowShown = _ref4.cloneNowShown, + rootEl = _ref4.rootEl, + cancel = _ref4.cancel; + if (!this.isMultiDrag) return; + insertMultiDragClones(false, rootEl); + multiDragClones.forEach(function (clone) { + css(clone, 'display', ''); + }); + cloneNowShown(); + clonesHidden = false; + cancel(); + }, + hideClone: function hideClone(_ref5) { + var _this = this; + + var sortable = _ref5.sortable, + cloneNowHidden = _ref5.cloneNowHidden, + cancel = _ref5.cancel; + if (!this.isMultiDrag) return; + multiDragClones.forEach(function (clone) { + css(clone, 'display', 'none'); + + if (_this.options.removeCloneOnHide && clone.parentNode) { + clone.parentNode.removeChild(clone); + } + }); + cloneNowHidden(); + clonesHidden = true; + cancel(); + }, + dragStartGlobal: function dragStartGlobal(_ref6) { + var sortable = _ref6.sortable; + + if (!this.isMultiDrag && multiDragSortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + } + + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.sortableIndex = index(multiDragElement); + }); // Sort multi-drag elements + + multiDragElements = multiDragElements.sort(function (a, b) { + return a.sortableIndex - b.sortableIndex; + }); + dragStarted = true; + }, + dragStarted: function dragStarted(_ref7) { + var _this2 = this; + + var sortable = _ref7.sortable; + if (!this.isMultiDrag) return; + + if (this.options.sort) { + // Capture rects, + // hide multi drag elements (by positioning them absolute), + // set multi drag elements rects to dragRect, + // show multi drag elements, + // animate to rects, + // unset rects & remove from DOM + sortable.captureAnimationState(); + + if (this.options.animation) { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + css(multiDragElement, 'position', 'absolute'); + }); + var dragRect = getRect(dragEl$1, false, true, true); + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRect); + }); + folding = true; + initialFolding = true; + } + } + + sortable.animateAll(function () { + folding = false; + initialFolding = false; + + if (_this2.options.animation) { + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); + } // Remove all auxiliary multidrag items from el, if sorting enabled + + + if (_this2.options.sort) { + removeMultiDragElements(); + } + }); + }, + dragOver: function dragOver(_ref8) { + var target = _ref8.target, + completed = _ref8.completed, + cancel = _ref8.cancel; + + if (folding && ~multiDragElements.indexOf(target)) { + completed(false); + cancel(); + } + }, + revert: function revert(_ref9) { + var fromSortable = _ref9.fromSortable, + rootEl = _ref9.rootEl, + sortable = _ref9.sortable, + dragRect = _ref9.dragRect; + + if (multiDragElements.length > 1) { + // Setup unfold animation + multiDragElements.forEach(function (multiDragElement) { + sortable.addAnimationState({ + target: multiDragElement, + rect: folding ? getRect(multiDragElement) : dragRect + }); + unsetRect(multiDragElement); + multiDragElement.fromRect = dragRect; + fromSortable.removeAnimationState(multiDragElement); + }); + folding = false; + insertMultiDragElements(!this.options.removeCloneOnHide, rootEl); + } + }, + dragOverCompleted: function dragOverCompleted(_ref10) { + var sortable = _ref10.sortable, + isOwner = _ref10.isOwner, + insertion = _ref10.insertion, + activeSortable = _ref10.activeSortable, + parentEl = _ref10.parentEl, + putSortable = _ref10.putSortable; + var options = this.options; + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } + + initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location + + if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { + // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible + var dragRectAbsolute = getRect(dragEl$1, false, true, true); + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted + // while folding, and so that we can capture them again because old sortable will no longer be fromSortable + + parentEl.appendChild(multiDragElement); + }); + folding = true; + } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out + + + if (!isOwner) { + // Only remove if not folding (folding will remove them anyways) + if (!folding) { + removeMultiDragElements(); + } + + if (multiDragElements.length > 1) { + var clonesHiddenBefore = clonesHidden; + + activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden + + + if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { + multiDragClones.forEach(function (clone) { + activeSortable.addAnimationState({ + target: clone, + rect: clonesFromRect + }); + clone.fromRect = clonesFromRect; + clone.thisAnimationDuration = null; + }); + } + } else { + activeSortable._showClone(sortable); + } + } + } + }, + dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) { + var dragRect = _ref11.dragRect, + isOwner = _ref11.isOwner, + activeSortable = _ref11.activeSortable; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + }); + + if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { + clonesFromRect = _extends({}, dragRect); + var dragMatrix = matrix(dragEl$1, true); + clonesFromRect.top -= dragMatrix.f; + clonesFromRect.left -= dragMatrix.e; + } + }, + dragOverAnimationComplete: function dragOverAnimationComplete() { + if (folding) { + folding = false; + removeMultiDragElements(); + } + }, + drop: function drop(_ref12) { + var evt = _ref12.originalEvent, + rootEl = _ref12.rootEl, + parentEl = _ref12.parentEl, + sortable = _ref12.sortable, + dispatchSortableEvent = _ref12.dispatchSortableEvent, + oldIndex = _ref12.oldIndex, + putSortable = _ref12.putSortable; + var toSortable = putSortable || this.sortable; + if (!evt) return; + var options = this.options, + children = parentEl.children; // Multi-drag selection + + if (!dragStarted) { + if (options.multiDragKey && !this.multiDragKeyDown) { + this._deselectMultiDrag(); + } + + toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1)); + + if (!~multiDragElements.indexOf(dragEl$1)) { + multiDragElements.push(dragEl$1); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: dragEl$1, + originalEvt: evt + }); // Modifier activated, select from last to dragEl + + if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { + var lastIndex = index(lastMultiDragSelect), + currentIndex = index(dragEl$1); + + if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { + // Must include lastMultiDragSelect (select it), in case modified selection from no selection + // (but previous selection existed) + var n, i; + + if (currentIndex > lastIndex) { + i = lastIndex; + n = currentIndex; + } else { + i = currentIndex; + n = lastIndex + 1; + } + + for (; i < n; i++) { + if (~multiDragElements.indexOf(children[i])) continue; + toggleClass(children[i], options.selectedClass, true); + multiDragElements.push(children[i]); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: children[i], + originalEvt: evt + }); + } + } + } else { + lastMultiDragSelect = dragEl$1; + } + + multiDragSortable = toSortable; + } else { + multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1); + lastMultiDragSelect = null; + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'deselect', + targetEl: dragEl$1, + originalEvt: evt + }); + } + } // Multi-drag drop + + + if (dragStarted && this.isMultiDrag) { + // Do not "unfold" after around dragEl if reverted + if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { + var dragRect = getRect(dragEl$1), + multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); + if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null; + toSortable.captureAnimationState(); + + if (!initialFolding) { + if (options.animation) { + dragEl$1.fromRect = dragRect; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + + if (multiDragElement !== dragEl$1) { + var rect = folding ? getRect(multiDragElement) : dragRect; + multiDragElement.fromRect = rect; // Prepare unfold animation + + toSortable.addAnimationState({ + target: multiDragElement, + rect: rect + }); + } + }); + } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert + // properly they must all be removed + + + removeMultiDragElements(); + multiDragElements.forEach(function (multiDragElement) { + if (children[multiDragIndex]) { + parentEl.insertBefore(multiDragElement, children[multiDragIndex]); + } else { + parentEl.appendChild(multiDragElement); + } + + multiDragIndex++; + }); // If initial folding is done, the elements may have changed position because they are now + // unfolding around dragEl, even though dragEl may not have his index changed, so update event + // must be fired here as Sortable will not. + + if (oldIndex === index(dragEl$1)) { + var update = false; + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement.sortableIndex !== index(multiDragElement)) { + update = true; + return; + } + }); + + if (update) { + dispatchSortableEvent('update'); + } + } + } // Must be done after capturing individual rects (scroll bar) + + + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); + toSortable.animateAll(); + } + + multiDragSortable = toSortable; + } // Remove clones if necessary + + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + multiDragClones.forEach(function (clone) { + clone.parentNode && clone.parentNode.removeChild(clone); + }); + } + }, + nullingGlobal: function nullingGlobal() { + this.isMultiDrag = dragStarted = false; + multiDragClones.length = 0; + }, + destroyGlobal: function destroyGlobal() { + this._deselectMultiDrag(); + + off(document, 'pointerup', this._deselectMultiDrag); + off(document, 'mouseup', this._deselectMultiDrag); + off(document, 'touchend', this._deselectMultiDrag); + off(document, 'keydown', this._checkKeyDown); + off(document, 'keyup', this._checkKeyUp); + }, + _deselectMultiDrag: function _deselectMultiDrag(evt) { + if (dragStarted) return; // Only deselect if selection is in this sortable + + if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable + + if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click + + if (evt && evt.button !== 0) return; + + while (multiDragElements.length) { + var el = multiDragElements[0]; + toggleClass(el, this.options.selectedClass, false); + multiDragElements.shift(); + dispatchEvent({ + sortable: this.sortable, + rootEl: this.sortable.el, + name: 'deselect', + targetEl: el, + originalEvt: evt + }); + } + }, + _checkKeyDown: function _checkKeyDown(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = true; + } + }, + _checkKeyUp: function _checkKeyUp(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = false; + } + } + }; + return _extends(MultiDrag, { + // Static methods & properties + pluginName: 'multiDrag', + utils: { + /** + * Selects the provided multi-drag item + * @param {HTMLElement} el The element to be selected + */ + select: function select(el) { + var sortable = el.parentNode[expando]; + if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return; + + if (multiDragSortable && multiDragSortable !== sortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + + multiDragSortable = sortable; + } + + toggleClass(el, sortable.options.selectedClass, true); + multiDragElements.push(el); + }, + + /** + * Deselects the provided multi-drag item + * @param {HTMLElement} el The element to be deselected + */ + deselect: function deselect(el) { + var sortable = el.parentNode[expando], + index = multiDragElements.indexOf(el); + if (!sortable || !sortable.options.multiDrag || !~index) return; + toggleClass(el, sortable.options.selectedClass, false); + multiDragElements.splice(index, 1); + } + }, + eventProperties: function eventProperties() { + var _this3 = this; + + var oldIndicies = [], + newIndicies = []; + multiDragElements.forEach(function (multiDragElement) { + oldIndicies.push({ + multiDragElement: multiDragElement, + index: multiDragElement.sortableIndex + }); // multiDragElements will already be sorted if folding + + var newIndex; + + if (folding && multiDragElement !== dragEl$1) { + newIndex = -1; + } else if (folding) { + newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')'); + } else { + newIndex = index(multiDragElement); + } + + newIndicies.push({ + multiDragElement: multiDragElement, + index: newIndex + }); + }); + return { + items: _toConsumableArray(multiDragElements), + clones: [].concat(multiDragClones), + oldIndicies: oldIndicies, + newIndicies: newIndicies + }; + }, + optionListeners: { + multiDragKey: function multiDragKey(key) { + key = key.toLowerCase(); + + if (key === 'ctrl') { + key = 'Control'; + } else if (key.length > 1) { + key = key.charAt(0).toUpperCase() + key.substr(1); + } + + return key; + } + } + }); + } + + function insertMultiDragElements(clonesInserted, rootEl) { + multiDragElements.forEach(function (multiDragElement, i) { + var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(multiDragElement, target); + } else { + rootEl.appendChild(multiDragElement); + } + }); + } + /** + * Insert multi-drag clones + * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted + * @param {HTMLElement} rootEl + */ + + + function insertMultiDragClones(elementsInserted, rootEl) { + multiDragClones.forEach(function (clone, i) { + var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(clone, target); + } else { + rootEl.appendChild(clone); + } + }); + } + + function removeMultiDragElements() { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement); + }); + } + + Sortable.mount(new AutoScrollPlugin()); + Sortable.mount(Remove, Revert); + + Sortable.mount(new SwapPlugin()); + Sortable.mount(new MultiDragPlugin()); + + return Sortable; + +})); diff --git a/public/assets/libs/Sortable/Sortable.min.js b/public/assets/libs/Sortable/Sortable.min.js new file mode 100644 index 0000000000000000000000000000000000000000..79898819ab3506eab882726243faa1aa54c02da6 --- /dev/null +++ b/public/assets/libs/Sortable/Sortable.min.js @@ -0,0 +1,2 @@ +/*! Sortable 1.10.1 - MIT | git://github.com/SortableJS/Sortable.git */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&h(t,e):h(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var f,p=/\s+/g;function k(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(p," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(p," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix;return i&&new i(n)}function g(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=e.left-n&&r<=e.right+n,i=a>=e.top-n&&a<=e.bottom+n;return n&&o&&i?l=t:void 0}}),l}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[j]._onDragOver(n)}}}function kt(t){z&&z.parentNode[j]._isOutsideThisEl(t.target)}function Rt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Ot(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Rt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var o in O.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in At(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&xt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?u(t,"pointerdown",this._onTapStart):(u(t,"mousedown",this._onTapStart),u(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(u(t,"dragover",this),u(t,"dragenter",this)),bt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,T())}function Xt(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||w||E?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function Yt(t){t.draggable=!1}function Bt(){Dt=!1}function Ft(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Ht(t){return setTimeout(t,0)}function Lt(t){return clearTimeout(t)}Rt.prototype={constructor:Rt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ht=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,z):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){_t.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&_t.push(o)}}(o),!z&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled||s.isContentEditable||(l=P(l,t.draggable,o,!1))&&l.animated||Z===l)){if(J=F(l),et=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return W({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),K("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return W({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),K("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!z&&n.parentNode===r){var s=X(n);if(q=r,G=(z=n).parentNode,V=z.nextSibling,Z=n,ot=a.group,rt={target:Rt.dragged=z,clientX:(e||t).clientX,clientY:(e||t).clientY},ct=rt.clientX-s.left,ut=rt.clientY-s.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,z.style["will-change"]="all",o=function(){K("delayEnded",i,{evt:t}),Rt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&(z.draggable=!0),i._triggerDragStart(t,e),W({sortable:i,name:"choose",originalEvent:t}),k(z,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){g(z,t.trim(),Yt)}),u(l,"dragover",Pt),u(l,"mousemove",Pt),u(l,"touchmove",Pt),u(l,"mouseup",i._onDrop),u(l,"touchend",i._onDrop),u(l,"touchcancel",i._onDrop),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,z.draggable=!0),K("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(E||w))o();else{if(Rt.eventCanceled)return void this._onDrop();u(l,"mouseup",i._disableDelayedDrag),u(l,"touchend",i._disableDelayedDrag),u(l,"touchcancel",i._disableDelayedDrag),u(l,"mousemove",i._delayedDragTouchMoveHandler),u(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&u(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){z&&Yt(z),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;d(t,"mouseup",this._disableDelayedDrag),d(t,"touchend",this._disableDelayedDrag),d(t,"touchcancel",this._disableDelayedDrag),d(t,"mousemove",this._delayedDragTouchMoveHandler),d(t,"touchmove",this._delayedDragTouchMoveHandler),d(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?u(document,"pointermove",this._onTouchMove):u(document,e?"touchmove":"mousemove",this._onTouchMove):(u(z,"dragend",this),u(q,"dragstart",this._onDragStart));try{document.selection?Ht(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(vt=!1,q&&z){K("dragStarted",this,{evt:e}),this.nativeDraggable&&u(document,"dragover",kt);var n=this.options;t||k(z,n.dragClass,!1),k(z,n.ghostClass,!0),Rt.active=this,t&&this._appendGhost(),W({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(at){this._lastX=at.clientX,this._lastY=at.clientY,Nt();for(var t=document.elementFromPoint(at.clientX,at.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(at.clientX,at.clientY))!==e;)e=t;if(z.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j]){if(e[j]._onDragOver({clientX:at.clientX,clientY:at.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);It()}},_onTouchMove:function(t){if(rt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=U&&v(U),a=U&&r&&r.a,l=U&&r&&r.d,s=Ct&>&&b(gt),c=(i.clientX-rt.clientX+o.x)/(a||1)+(s?s[0]-Et[0]:0)/(a||1),u=(i.clientY-rt.clientY+o.y)/(l||1)+(s?s[1]-Et[1]:0)/(l||1);if(!Rt.active&&!vt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===z)return A(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==Xt(q,l,z,o,s,i,n,!!s))return O(),l.appendChild(z),G=l,N(),A(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,y=z.parentNode!==l,w=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(z.animated&&z.toRect||o,s.animated&&s.toRect||i,a),E=a?"top":"left",D=Y(s,"top","top")||Y(z,"top","top"),_=D?D.scrollTop:void 0;if(ht!==s&&(m=i[E],yt=!1,wt=!w&&e.invertSwap||y),0!==(v=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,u=o?n.top:n.left,d=o?n.bottom:n.right,h=!1;if(!a)if(l&&pt", + "owenm " + ], + "description": "JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap.", + "keywords": [ + "sortable", + "reorder", + "list", + "html5", + "drag", + "and", + "drop", + "dnd", + "web-components" + ], + "license": "MIT", + "ignore": [ + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/public/assets/libs/Sortable/entry/entry-complete.js b/public/assets/libs/Sortable/entry/entry-complete.js new file mode 100644 index 0000000000000000000000000000000000000000..bf3dc5c13422947069f0d46ccdef64e90c60c6a5 --- /dev/null +++ b/public/assets/libs/Sortable/entry/entry-complete.js @@ -0,0 +1,8 @@ +import Sortable from './entry-defaults.js'; +import Swap from '../plugins/Swap'; +import MultiDrag from '../plugins/MultiDrag'; + +Sortable.mount(new Swap()); +Sortable.mount(new MultiDrag()); + +export default Sortable; diff --git a/public/assets/libs/Sortable/entry/entry-core.js b/public/assets/libs/Sortable/entry/entry-core.js new file mode 100644 index 0000000000000000000000000000000000000000..b5c3f77f791c8dcbdd0a1de741a41f3b8e4f53b8 --- /dev/null +++ b/public/assets/libs/Sortable/entry/entry-core.js @@ -0,0 +1,19 @@ +import Sortable from '../src/Sortable.js'; +import AutoScroll from '../plugins/AutoScroll'; +import OnSpill from '../plugins/OnSpill'; +import Swap from '../plugins/Swap'; +import MultiDrag from '../plugins/MultiDrag'; + +export default Sortable; + +export { + Sortable, + + // Default + AutoScroll, + OnSpill, + + // Extra + Swap, + MultiDrag +}; diff --git a/public/assets/libs/Sortable/entry/entry-defaults.js b/public/assets/libs/Sortable/entry/entry-defaults.js new file mode 100644 index 0000000000000000000000000000000000000000..9d3fb683002b742d63caeb83d896318044247781 --- /dev/null +++ b/public/assets/libs/Sortable/entry/entry-defaults.js @@ -0,0 +1,19 @@ +import Sortable from '../src/Sortable.js'; +import AutoScroll from '../plugins/AutoScroll'; +import { RemoveOnSpill, RevertOnSpill } from '../plugins/OnSpill'; +// Extra +import Swap from '../plugins/Swap'; +import MultiDrag from '../plugins/MultiDrag'; + +Sortable.mount(new AutoScroll()); +Sortable.mount(RemoveOnSpill, RevertOnSpill); + +export default Sortable; + +export { + Sortable, + + // Extra + Swap, + MultiDrag +}; diff --git a/public/assets/libs/Sortable/index.html b/public/assets/libs/Sortable/index.html new file mode 100644 index 0000000000000000000000000000000000000000..b52fe585085f82984ea55cab78ba6525f965a8c4 --- /dev/null +++ b/public/assets/libs/Sortable/index.html @@ -0,0 +1,459 @@ + + + + + SortableJS + + + + + + + + + + + + + + Fork me on GitHub + +
            +
            + +

            SortableJS

            +

            JavaScript library for reorderable drag-and-drop lists

            + + +
            + +
            +

            Features

            +
            +
            +
            +

            Simple list example

            +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            +
            +
            new Sortable(example1, {
            +    animation: 150,
            +    ghostClass: 'blue-background-class'
            +});
            +
            +
            +
            + +
            +

            Shared lists

            +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            + +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            +
            +
            new Sortable(example2Left, {
            +    group: 'shared', // set both lists to same group
            +    animation: 150
            +});
            +
            +new Sortable(example2Right, {
            +    group: 'shared',
            +    animation: 150
            +});
            +
            +
            +
            + +
            +

            Cloning

            +

            Try dragging from one list to another. The item you drag will be cloned and the clone will stay in the original list.

            +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            + +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            +
            +
            new Sortable(example3Left, {
            +    group: {
            +        name: 'shared',
            +        pull: 'clone' // To clone: set pull to 'clone'
            +    },
            +    animation: 150
            +});
            +
            +new Sortable(example3Right, {
            +    group: {
            +        name: 'shared',
            +        pull: 'clone'
            +    },
            +    animation: 150
            +});
            +
            +
            +
            + +
            +

            Disabling Sorting

            +

            Try sorting the list on the left. It is not possible because it has it's sort option set to false. However, you can still drag from the list on the left to the list on the right.

            +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            + +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            +
            +
            new Sortable(example4Left, {
            +    group: {
            +        name: 'shared',
            +        pull: 'clone',
            +        put: false // Do not allow items to be put into this list
            +    },
            +    animation: 150,
            +    sort: false // To disable sorting: set sort to false
            +});
            +
            +new Sortable(example4Right, {
            +    group: 'shared',
            +    animation: 150
            +});
            +
            +
            +
            + +
            +

            Handle

            +
            +
              Item 1
            +
              Item 2
            +
              Item 3
            +
              Item 4
            +
              Item 5
            +
              Item 6
            +
            +
            +
            new Sortable(example5, {
            +    handle: '.handle', // handle's class
            +    animation: 150
            +});
            +
            +
            +
            + +
            +

            Filter

            +

            Try dragging the item with a red background. It cannot be done, because that item is filtered out using the filter option.

            +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Filtered
            +
            Item 4
            +
            Item 5
            +
            +
            +
            new Sortable(example6, {
            +    filter: '.filtered', // 'filtered' class is not draggable
            +    animation: 150
            +});
            +
            +
            +
            + +
            +

            Thresholds

            +

            Try modifying the inputs below to affect the swap thresholds. You can see the swap zones of the squares colored in dark blue, while the "dead zones" (that do not cause a swap) are colored in light blue.

            +
            +
            + +
            + +
            1
            +
            + +
            + +
            2
            +
            +
            +
            +
            +
            + +
            + +
            +
            +
            +
            Invert Swap
            +
            +
            + +
            +
            +
            +
            + + +
            +
            +
            +
            +
            new Sortable(example7, {
            +    swapThreshold: 1,
            +    animation: 150
            +});
            +
            +
            + + +
            +

            Examples

            +
            +
            + +
            +

            Grid Example

            +
            +
            Item 1
            Item 2
            Item 3
            Item 4
            Item 5
            Item 6
            Item 7
            Item 8
            Item 9
            Item 10
            Item 11
            Item 12
            Item 13
            Item 14
            Item 15
            Item 16
            Item 17
            Item 18
            Item 19
            Item 20
            +
            +
            +
            + +
            +

            Nested Sortables Example

            +

            NOTE: When using nested Sortables with animation, it is recommended that the fallbackOnBody option is set to true.
            It is also always recommended that either the invertSwap option is set to true, or the swapThreshold option is lower than the default value of 1 (eg 0.65).

            +
            +
            Item 1.1 +
            +
            Item 2.1
            +
            Item 2.2 +
            +
            Item 3.1
            +
            Item 3.2
            +
            Item 3.3
            +
            Item 3.4
            +
            +
            +
            Item 2.3
            +
            Item 2.4
            +
            +
            +
            Item 1.2
            +
            Item 1.3
            +
            Item 1.4 +
            +
            Item 2.1
            +
            Item 2.2
            +
            Item 2.3
            +
            Item 2.4
            +
            +
            +
            Item 1.5
            +
            +
            +
            // Loop through each nested sortable element
            +for (var i = 0; i < nestedSortables.length; i++) {
            +	new Sortable(nestedSortables[i], {
            +		group: 'nested',
            +		animation: 150,
            +		fallbackOnBody: true,
            +		swapThreshold: 0.65
            +	});
            +}
            +
            +
            + +
            +

            Plugins

            +
            +
            + +
            +

            MultiDrag

            +

            The MultiDrag plugin allows for multiple items to be dragged at a time. You can click to "select" multiple items, and then drag them as one item.

            +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            +
            +
            new Sortable(multiDragDemo, {
            +	multiDrag: true, // Enable multi-drag
            +	selectedClass: 'selected', // The class applied to the selected items
            +	animation: 150
            +});
            +
            +
            +
            + +
            +

            Swap

            +

            The Swap plugin changes the behaviour of Sortable to allow for items to be swapped with eachother rather than sorted.

            +
            +
            Item 1
            +
            Item 2
            +
            Item 3
            +
            Item 4
            +
            Item 5
            +
            Item 6
            +
            +
            +
            new Sortable(swapDemo, {
            +	swap: true, // Enable swap plugin
            +	swapClass: 'highlight', // The class applied to the hovered swap item
            +	animation: 150
            +});
            +
            +
            +
            + + + +
            + +
            +

            Comparisons

            +
            +
            + + +
            +

            jQuery-UI

            + + +

            Dragula

            + +
            + +
            + +
            +

            Framework Support

            +
            +
            + +
            + +

            Vue

            +

            Vue.Draggable

            + +

            React

            +

            react-sortablejs

            + +

            Angular

            +

            ngx-sortablejs

            + +

            jQuery

            +

            jquery-sortablejs

            + +

            Knockout

            +

            knockout-sortablejs

            + +

            Meteor

            +

            meteor-sortablejs

            + +

            Polymer

            +

            polymer-sortablejs

            + +

            Ember

            +

            ember-sortablejs

            +
            + +
            + + + + + + + + + + + diff --git a/public/assets/libs/Sortable/modular/sortable.complete.esm.js b/public/assets/libs/Sortable/modular/sortable.complete.esm.js new file mode 100644 index 0000000000000000000000000000000000000000..17f1e46383bc155f7debc6d8df5689e1037abf53 --- /dev/null +++ b/public/assets/libs/Sortable/modular/sortable.complete.esm.js @@ -0,0 +1,3695 @@ +/**! + * Sortable 1.10.1 + * @author RubaXa + * @author owenm + * @license MIT + */ +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); +} + +function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + + ownKeys.forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } + + return target; +} + +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; +} + +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +var version = "1.10.1"; + +function userAgent(pattern) { + if (typeof window !== 'undefined' && window.navigator) { + return !! + /*@__PURE__*/ + navigator.userAgent.match(pattern); + } +} + +var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); +var Edge = userAgent(/Edge/i); +var FireFox = userAgent(/firefox/i); +var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); +var IOS = userAgent(/iP(ad|od|hone)/i); +var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i); + +var captureMode = { + capture: false, + passive: false +}; + +function on(el, event, fn) { + el.addEventListener(event, fn, !IE11OrLess && captureMode); +} + +function off(el, event, fn) { + el.removeEventListener(event, fn, !IE11OrLess && captureMode); +} + +function matches( +/**HTMLElement*/ +el, +/**String*/ +selector) { + if (!selector) return; + selector[0] === '>' && (selector = selector.substring(1)); + + if (el) { + try { + if (el.matches) { + return el.matches(selector); + } else if (el.msMatchesSelector) { + return el.msMatchesSelector(selector); + } else if (el.webkitMatchesSelector) { + return el.webkitMatchesSelector(selector); + } + } catch (_) { + return false; + } + } + + return false; +} + +function getParentOrHost(el) { + return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode; +} + +function closest( +/**HTMLElement*/ +el, +/**String*/ +selector, +/**HTMLElement*/ +ctx, includeCTX) { + if (el) { + ctx = ctx || document; + + do { + if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) { + return el; + } + + if (el === ctx) break; + /* jshint boss:true */ + } while (el = getParentOrHost(el)); + } + + return null; +} + +var R_SPACE = /\s+/g; + +function toggleClass(el, name, state) { + if (el && name) { + if (el.classList) { + el.classList[state ? 'add' : 'remove'](name); + } else { + var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); + el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); + } + } +} + +function css(el, prop, val) { + var style = el && el.style; + + if (style) { + if (val === void 0) { + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(el, ''); + } else if (el.currentStyle) { + val = el.currentStyle; + } + + return prop === void 0 ? val : val[prop]; + } else { + if (!(prop in style) && prop.indexOf('webkit') === -1) { + prop = '-webkit-' + prop; + } + + style[prop] = val + (typeof val === 'string' ? '' : 'px'); + } + } +} + +function matrix(el, selfOnly) { + var appliedTransforms = ''; + + if (typeof el === 'string') { + appliedTransforms = el; + } else { + do { + var transform = css(el, 'transform'); + + if (transform && transform !== 'none') { + appliedTransforms = transform + ' ' + appliedTransforms; + } + /* jshint boss:true */ + + } while (!selfOnly && (el = el.parentNode)); + } + + var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix; + /*jshint -W056 */ + + return matrixFn && new matrixFn(appliedTransforms); +} + +function find(ctx, tagName, iterator) { + if (ctx) { + var list = ctx.getElementsByTagName(tagName), + i = 0, + n = list.length; + + if (iterator) { + for (; i < n; i++) { + iterator(list[i], i); + } + } + + return list; + } + + return []; +} + +function getWindowScrollingElement() { + if (IE11OrLess) { + return document.documentElement; + } else { + return document.scrollingElement; + } +} +/** + * Returns the "bounding client rect" of given element + * @param {HTMLElement} el The element whose boundingClientRect is wanted + * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container + * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr + * @param {[Boolean]} undoScale Whether the container's scale() should be undone + * @param {[HTMLElement]} container The parent the element will be placed in + * @return {Object} The boundingClientRect of el, with specified adjustments + */ + + +function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) { + if (!el.getBoundingClientRect && el !== window) return; + var elRect, top, left, bottom, right, height, width; + + if (el !== window && el !== getWindowScrollingElement()) { + elRect = el.getBoundingClientRect(); + top = elRect.top; + left = elRect.left; + bottom = elRect.bottom; + right = elRect.right; + height = elRect.height; + width = elRect.width; + } else { + top = 0; + left = 0; + bottom = window.innerHeight; + right = window.innerWidth; + height = window.innerHeight; + width = window.innerWidth; + } + + if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) { + // Adjust for translate() + container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) + // Not needed on <= IE11 + + if (!IE11OrLess) { + do { + if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) { + var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container + + top -= containerRect.top + parseInt(css(container, 'border-top-width')); + left -= containerRect.left + parseInt(css(container, 'border-left-width')); + bottom = top + elRect.height; + right = left + elRect.width; + break; + } + /* jshint boss:true */ + + } while (container = container.parentNode); + } + } + + if (undoScale && el !== window) { + // Adjust for scale() + var elMatrix = matrix(container || el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d; + + if (elMatrix) { + top /= scaleY; + left /= scaleX; + width /= scaleX; + height /= scaleY; + bottom = top + height; + right = left + width; + } + } + + return { + top: top, + left: left, + bottom: bottom, + right: right, + width: width, + height: height + }; +} +/** + * Checks if a side of an element is scrolled past a side of its parents + * @param {HTMLElement} el The element who's side being scrolled out of view is in question + * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom') + * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') + * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element + */ + + +function isScrolledPast(el, elSide, parentSide) { + var parent = getParentAutoScrollElement(el, true), + elSideVal = getRect(el)[elSide]; + /* jshint boss:true */ + + while (parent) { + var parentSideVal = getRect(parent)[parentSide], + visible = void 0; + + if (parentSide === 'top' || parentSide === 'left') { + visible = elSideVal >= parentSideVal; + } else { + visible = elSideVal <= parentSideVal; + } + + if (!visible) return parent; + if (parent === getWindowScrollingElement()) break; + parent = getParentAutoScrollElement(parent, false); + } + + return false; +} +/** + * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) + * and non-draggable elements + * @param {HTMLElement} el The parent element + * @param {Number} childNum The index of the child + * @param {Object} options Parent Sortable's options + * @return {HTMLElement} The child at index childNum, or null if not found + */ + + +function getChild(el, childNum, options) { + var currentChild = 0, + i = 0, + children = el.children; + + while (i < children.length) { + if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && children[i] !== Sortable.dragged && closest(children[i], options.draggable, el, false)) { + if (currentChild === childNum) { + return children[i]; + } + + currentChild++; + } + + i++; + } + + return null; +} +/** + * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) + * @param {HTMLElement} el Parent element + * @param {selector} selector Any other elements that should be ignored + * @return {HTMLElement} The last child, ignoring ghostEl + */ + + +function lastChild(el, selector) { + var last = el.lastElementChild; + + while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { + last = last.previousElementSibling; + } + + return last || null; +} +/** + * Returns the index of an element within its parent for a selected set of + * elements + * @param {HTMLElement} el + * @param {selector} selector + * @return {number} + */ + + +function index(el, selector) { + var index = 0; + + if (!el || !el.parentNode) { + return -1; + } + /* jshint boss:true */ + + + while (el = el.previousElementSibling) { + if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) { + index++; + } + } + + return index; +} +/** + * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. + * The value is returned in real pixels. + * @param {HTMLElement} el + * @return {Array} Offsets in the format of [left, top] + */ + + +function getRelativeScrollOffset(el) { + var offsetLeft = 0, + offsetTop = 0, + winScroller = getWindowScrollingElement(); + + if (el) { + do { + var elMatrix = matrix(el), + scaleX = elMatrix.a, + scaleY = elMatrix.d; + offsetLeft += el.scrollLeft * scaleX; + offsetTop += el.scrollTop * scaleY; + } while (el !== winScroller && (el = el.parentNode)); + } + + return [offsetLeft, offsetTop]; +} +/** + * Returns the index of the object within the given array + * @param {Array} arr Array that may or may not hold the object + * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find + * @return {Number} The index of the object in the array, or -1 + */ + + +function indexOfObject(arr, obj) { + for (var i in arr) { + if (!arr.hasOwnProperty(i)) continue; + + for (var key in obj) { + if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i); + } + } + + return -1; +} + +function getParentAutoScrollElement(el, includeSelf) { + // skip to window + if (!el || !el.getBoundingClientRect) return getWindowScrollingElement(); + var elem = el; + var gotSelf = false; + + do { + // we don't need to get elem css if it isn't even overflowing in the first place (performance) + if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { + var elemCSS = css(elem); + + if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) { + if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement(); + if (gotSelf || includeSelf) return elem; + gotSelf = true; + } + } + /* jshint boss:true */ + + } while (elem = elem.parentNode); + + return getWindowScrollingElement(); +} + +function extend(dst, src) { + if (dst && src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dst[key] = src[key]; + } + } + } + + return dst; +} + +function isRectEqual(rect1, rect2) { + return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width); +} + +var _throttleTimeout; + +function throttle(callback, ms) { + return function () { + if (!_throttleTimeout) { + var args = arguments, + _this = this; + + if (args.length === 1) { + callback.call(_this, args[0]); + } else { + callback.apply(_this, args); + } + + _throttleTimeout = setTimeout(function () { + _throttleTimeout = void 0; + }, ms); + } + }; +} + +function cancelThrottle() { + clearTimeout(_throttleTimeout); + _throttleTimeout = void 0; +} + +function scrollBy(el, x, y) { + el.scrollLeft += x; + el.scrollTop += y; +} + +function clone(el) { + var Polymer = window.Polymer; + var $ = window.jQuery || window.Zepto; + + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } else if ($) { + return $(el).clone(true)[0]; + } else { + return el.cloneNode(true); + } +} + +function setRect(el, rect) { + css(el, 'position', 'absolute'); + css(el, 'top', rect.top); + css(el, 'left', rect.left); + css(el, 'width', rect.width); + css(el, 'height', rect.height); +} + +function unsetRect(el) { + css(el, 'position', ''); + css(el, 'top', ''); + css(el, 'left', ''); + css(el, 'width', ''); + css(el, 'height', ''); +} + +var expando = 'Sortable' + new Date().getTime(); + +function AnimationStateManager() { + var animationStates = [], + animationCallbackId; + return { + captureAnimationState: function captureAnimationState() { + animationStates = []; + if (!this.options.animation) return; + var children = [].slice.call(this.el.children); + children.forEach(function (child) { + if (css(child, 'display') === 'none' || child === Sortable.ghost) return; + animationStates.push({ + target: child, + rect: getRect(child) + }); + + var fromRect = _objectSpread({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation + + + if (child.thisAnimationDuration) { + var childMatrix = matrix(child, true); + + if (childMatrix) { + fromRect.top -= childMatrix.f; + fromRect.left -= childMatrix.e; + } + } + + child.fromRect = fromRect; + }); + }, + addAnimationState: function addAnimationState(state) { + animationStates.push(state); + }, + removeAnimationState: function removeAnimationState(target) { + animationStates.splice(indexOfObject(animationStates, { + target: target + }), 1); + }, + animateAll: function animateAll(callback) { + var _this = this; + + if (!this.options.animation) { + clearTimeout(animationCallbackId); + if (typeof callback === 'function') callback(); + return; + } + + var animating = false, + animationTime = 0; + animationStates.forEach(function (state) { + var time = 0, + target = state.target, + fromRect = target.fromRect, + toRect = getRect(target), + prevFromRect = target.prevFromRect, + prevToRect = target.prevToRect, + animatingRect = state.rect, + targetMatrix = matrix(target, true); + + if (targetMatrix) { + // Compensate for current animation + toRect.top -= targetMatrix.f; + toRect.left -= targetMatrix.e; + } + + target.toRect = toRect; + + if (target.thisAnimationDuration) { + // Could also check if animatingRect is between fromRect and toRect + if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect + (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) { + // If returning to same place as started from animation and on same axis + time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options); + } + } // if fromRect != toRect: animate + + + if (!isRectEqual(toRect, fromRect)) { + target.prevFromRect = fromRect; + target.prevToRect = toRect; + + if (!time) { + time = _this.options.animation; + } + + _this.animate(target, animatingRect, toRect, time); + } + + if (time) { + animating = true; + animationTime = Math.max(animationTime, time); + clearTimeout(target.animationResetTimer); + target.animationResetTimer = setTimeout(function () { + target.animationTime = 0; + target.prevFromRect = null; + target.fromRect = null; + target.prevToRect = null; + target.thisAnimationDuration = null; + }, time); + target.thisAnimationDuration = time; + } + }); + clearTimeout(animationCallbackId); + + if (!animating) { + if (typeof callback === 'function') callback(); + } else { + animationCallbackId = setTimeout(function () { + if (typeof callback === 'function') callback(); + }, animationTime); + } + + animationStates = []; + }, + animate: function animate(target, currentRect, toRect, duration) { + if (duration) { + css(target, 'transition', ''); + css(target, 'transform', ''); + var elMatrix = matrix(this.el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d, + translateX = (currentRect.left - toRect.left) / (scaleX || 1), + translateY = (currentRect.top - toRect.top) / (scaleY || 1); + target.animatingX = !!translateX; + target.animatingY = !!translateY; + css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); + repaint(target); // repaint + + css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); + css(target, 'transform', 'translate3d(0,0,0)'); + typeof target.animated === 'number' && clearTimeout(target.animated); + target.animated = setTimeout(function () { + css(target, 'transition', ''); + css(target, 'transform', ''); + target.animated = false; + target.animatingX = false; + target.animatingY = false; + }, duration); + } + } + }; +} + +function repaint(target) { + return target.offsetWidth; +} + +function calculateRealTime(animatingRect, fromRect, toRect, options) { + return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation; +} + +var plugins = []; +var defaults = { + initializeByDefault: true +}; +var PluginManager = { + mount: function mount(plugin) { + // Set default static properties + for (var option in defaults) { + if (defaults.hasOwnProperty(option) && !(option in plugin)) { + plugin[option] = defaults[option]; + } + } + + plugins.push(plugin); + }, + pluginEvent: function pluginEvent(eventName, sortable, evt) { + var _this = this; + + this.eventCanceled = false; + + evt.cancel = function () { + _this.eventCanceled = true; + }; + + var eventNameGlobal = eventName + 'Global'; + plugins.forEach(function (plugin) { + if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable + + if (sortable[plugin.pluginName][eventNameGlobal]) { + sortable[plugin.pluginName][eventNameGlobal](_objectSpread({ + sortable: sortable + }, evt)); + } // Only fire plugin event if plugin is enabled in this sortable, + // and plugin has event defined + + + if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { + sortable[plugin.pluginName][eventName](_objectSpread({ + sortable: sortable + }, evt)); + } + }); + }, + initializePlugins: function initializePlugins(sortable, el, defaults, options) { + plugins.forEach(function (plugin) { + var pluginName = plugin.pluginName; + if (!sortable.options[pluginName] && !plugin.initializeByDefault) return; + var initialized = new plugin(sortable, el, sortable.options); + initialized.sortable = sortable; + initialized.options = sortable.options; + sortable[pluginName] = initialized; // Add default options from plugin + + _extends(defaults, initialized.defaults); + }); + + for (var option in sortable.options) { + if (!sortable.options.hasOwnProperty(option)) continue; + var modified = this.modifyOption(sortable, option, sortable.options[option]); + + if (typeof modified !== 'undefined') { + sortable.options[option] = modified; + } + } + }, + getEventProperties: function getEventProperties(name, sortable) { + var eventProperties = {}; + plugins.forEach(function (plugin) { + if (typeof plugin.eventProperties !== 'function') return; + + _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name)); + }); + return eventProperties; + }, + modifyOption: function modifyOption(sortable, name, value) { + var modifiedValue; + plugins.forEach(function (plugin) { + // Plugin must exist on the Sortable + if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin + + if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') { + modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value); + } + }); + return modifiedValue; + } +}; + +function dispatchEvent(_ref) { + var sortable = _ref.sortable, + rootEl = _ref.rootEl, + name = _ref.name, + targetEl = _ref.targetEl, + cloneEl = _ref.cloneEl, + toEl = _ref.toEl, + fromEl = _ref.fromEl, + oldIndex = _ref.oldIndex, + newIndex = _ref.newIndex, + oldDraggableIndex = _ref.oldDraggableIndex, + newDraggableIndex = _ref.newDraggableIndex, + originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + extraEventProperties = _ref.extraEventProperties; + sortable = sortable || rootEl && rootEl[expando]; + if (!sortable) return; + var evt, + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent(name, { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(name, true, true); + } + + evt.to = toEl || rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + evt.oldIndex = oldIndex; + evt.newIndex = newIndex; + evt.oldDraggableIndex = oldDraggableIndex; + evt.newDraggableIndex = newDraggableIndex; + evt.originalEvent = originalEvent; + evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; + + var allEventProperties = _objectSpread({}, extraEventProperties, PluginManager.getEventProperties(name, sortable)); + + for (var option in allEventProperties) { + evt[option] = allEventProperties[option]; + } + + if (rootEl) { + rootEl.dispatchEvent(evt); + } + + if (options[onName]) { + options[onName].call(sortable, evt); + } +} + +var pluginEvent = function pluginEvent(eventName, sortable) { + var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + originalEvent = _ref.evt, + data = _objectWithoutProperties(_ref, ["evt"]); + + PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread({ + dragEl: dragEl, + parentEl: parentEl, + ghostEl: ghostEl, + rootEl: rootEl, + nextEl: nextEl, + lastDownEl: lastDownEl, + cloneEl: cloneEl, + cloneHidden: cloneHidden, + dragStarted: moved, + putSortable: putSortable, + activeSortable: Sortable.active, + originalEvent: originalEvent, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + hideGhostForTarget: _hideGhostForTarget, + unhideGhostForTarget: _unhideGhostForTarget, + cloneNowHidden: function cloneNowHidden() { + cloneHidden = true; + }, + cloneNowShown: function cloneNowShown() { + cloneHidden = false; + }, + dispatchSortableEvent: function dispatchSortableEvent(name) { + _dispatchEvent({ + sortable: sortable, + name: name, + originalEvent: originalEvent + }); + } + }, data)); +}; + +function _dispatchEvent(info) { + dispatchEvent(_objectSpread({ + putSortable: putSortable, + cloneEl: cloneEl, + targetEl: dragEl, + rootEl: rootEl, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex + }, info)); +} + +var dragEl, + parentEl, + ghostEl, + rootEl, + nextEl, + lastDownEl, + cloneEl, + cloneHidden, + oldIndex, + newIndex, + oldDraggableIndex, + newDraggableIndex, + activeGroup, + putSortable, + awaitingDragStarted = false, + ignoreNextClick = false, + sortables = [], + tapEvt, + touchEvt, + lastDx, + lastDy, + tapDistanceLeft, + tapDistanceTop, + moved, + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + targetMoveDistance, + // For positioning ghost absolutely +ghostRelativeParent, + ghostRelativeParentInitialScroll = [], + // (left, top) +_silent = false, + savedInputChecked = []; +/** @const */ + +var documentExists = typeof document !== 'undefined', + PositionGhostAbsolutely = IOS, + CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', + // This will not pass for IE9, because IE9 DnD only works on anchors +supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), + supportCssPointerEvents = function () { + if (!documentExists) return; // false when <= IE11 + + if (IE11OrLess) { + return false; + } + + var el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; +}(), + _detectDirection = function _detectDirection(el, options) { + var elCSS = css(el), + elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), + child1 = getChild(el, 0, options), + child2 = getChild(el, 1, options), + firstChildCSS = child1 && css(child1), + secondChildCSS = child2 && css(child2), + firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, + secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; + + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; + } + + if (elCSS.display === 'grid') { + return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; + } + + if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') { + var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; + return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; + } + + return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal'; +}, + _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) { + var dragElS1Opp = vertical ? dragRect.left : dragRect.top, + dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, + dragElOppLength = vertical ? dragRect.width : dragRect.height, + targetS1Opp = vertical ? targetRect.left : targetRect.top, + targetS2Opp = vertical ? targetRect.right : targetRect.bottom, + targetOppLength = vertical ? targetRect.width : targetRect.height; + return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2; +}, + +/** + * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. + * @param {Number} x X position + * @param {Number} y Y position + * @return {HTMLElement} Element of the first found nearest Sortable + */ +_detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { + var ret; + sortables.some(function (sortable) { + if (lastChild(sortable)) return; + var rect = getRect(sortable), + threshold = sortable[expando].options.emptyInsertThreshold, + insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, + insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; + + if (threshold && insideHorizontally && insideVertically) { + return ret = sortable; + } + }); + return ret; +}, + _prepareGroup = function _prepareGroup(options) { + function toFn(value, pull) { + return function (to, from, dragEl, evt) { + var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name; + + if (value == null && (pull || sameGroup)) { + // Default pull value + // Default pull and put value if same group + return true; + } else if (value == null || value === false) { + return false; + } else if (pull && value === 'clone') { + return value; + } else if (typeof value === 'function') { + return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); + } else { + var otherGroup = (pull ? to : from).options.group.name; + return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1; + } + }; + } + + var group = {}; + var originalGroup = options.group; + + if (!originalGroup || _typeof(originalGroup) != 'object') { + originalGroup = { + name: originalGroup + }; + } + + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + options.group = group; +}, + _hideGhostForTarget = function _hideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', 'none'); + } +}, + _unhideGhostForTarget = function _unhideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', ''); + } +}; // #1184 fix - Prevent click event on fallback if dragged but item not changed position + + +if (documentExists) { + document.addEventListener('click', function (evt) { + if (ignoreNextClick) { + evt.preventDefault(); + evt.stopPropagation && evt.stopPropagation(); + evt.stopImmediatePropagation && evt.stopImmediatePropagation(); + ignoreNextClick = false; + return false; + } + }, true); +} + +var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) { + if (dragEl) { + evt = evt.touches ? evt.touches[0] : evt; + + var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); + + if (nearest) { + // Create imitation event + var event = {}; + + for (var i in evt) { + if (evt.hasOwnProperty(i)) { + event[i] = evt[i]; + } + } + + event.target = event.rootEl = nearest; + event.preventDefault = void 0; + event.stopPropagation = void 0; + + nearest[expando]._onDragOver(event); + } + } +}; + +var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) { + if (dragEl) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); + } +}; +/** + * @class Sortable + * @param {HTMLElement} el + * @param {Object} [options] + */ + + +function Sortable(el, options) { + if (!(el && el.nodeType && el.nodeType === 1)) { + throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); + } + + this.el = el; // root element + + this.options = options = _extends({}, options); // Export instance + + el[expando] = this; + var defaults = { + group: null, + sort: true, + disabled: false, + store: null, + handle: null, + draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*', + swapThreshold: 1, + // percentage; 0 <= x <= 1 + invertSwap: false, + // invert always + invertedSwapThreshold: null, + // will be set to same as swapThreshold if default + removeCloneOnHide: true, + direction: function direction() { + return _detectDirection(el, this.options); + }, + ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', + dragClass: 'sortable-drag', + ignore: 'a, img', + filter: null, + preventOnFilter: true, + animation: 0, + easing: null, + setData: function setData(dataTransfer, dragEl) { + dataTransfer.setData('Text', dragEl.textContent); + }, + dropBubble: false, + dragoverBubble: false, + dataIdAttr: 'data-id', + delay: 0, + delayOnTouchOnly: false, + touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false, + fallbackTolerance: 0, + fallbackOffset: { + x: 0, + y: 0 + }, + supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window, + emptyInsertThreshold: 5 + }; + PluginManager.initializePlugins(this, el, defaults); // Set default options + + for (var name in defaults) { + !(name in options) && (options[name] = defaults[name]); + } + + _prepareGroup(options); // Bind all private methods + + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } // Setup drag mode + + + this.nativeDraggable = options.forceFallback ? false : supportDraggable; + + if (this.nativeDraggable) { + // Touch start threshold cannot be greater than the native dragstart threshold + this.options.touchStartThreshold = 1; + } // Bind events + + + if (options.supportPointer) { + on(el, 'pointerdown', this._onTapStart); + } else { + on(el, 'mousedown', this._onTapStart); + on(el, 'touchstart', this._onTapStart); + } + + if (this.nativeDraggable) { + on(el, 'dragover', this); + on(el, 'dragenter', this); + } + + sortables.push(this.el); // Restore sorting + + options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager + + _extends(this, AnimationStateManager()); +} + +Sortable.prototype = +/** @lends Sortable.prototype */ +{ + constructor: Sortable, + _isOutsideThisEl: function _isOutsideThisEl(target) { + if (!this.el.contains(target) && target !== this.el) { + lastTarget = null; + } + }, + _getDirection: function _getDirection(evt, target) { + return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; + }, + _onTapStart: function _onTapStart( + /** Event|TouchEvent */ + evt) { + if (!evt.cancelable) return; + + var _this = this, + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt, + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, + filter = options.filter; + + _saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. + + + if (dragEl) { + return; + } + + if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { + return; // only left button and enabled + } // cancel dnd if original target is content editable + + + if (originalTarget.isContentEditable) { + return; + } + + target = closest(target, options.draggable, el, false); + + if (target && target.animated) { + return; + } + + if (lastDownEl === target) { + // Ignoring duplicate `down` + return; + } // Get the index of the dragged element within its parent + + + oldIndex = index(target); + oldDraggableIndex = index(target, options.draggable); // Check filter + + if (typeof filter === 'function') { + if (filter.call(this, evt, target, this)) { + _dispatchEvent({ + sortable: _this, + rootEl: originalTarget, + name: 'filter', + targetEl: target, + toEl: el, + fromEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } else if (filter) { + filter = filter.split(',').some(function (criteria) { + criteria = closest(originalTarget, criteria.trim(), el, false); + + if (criteria) { + _dispatchEvent({ + sortable: _this, + rootEl: criteria, + name: 'filter', + targetEl: target, + fromEl: el, + toEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + return true; + } + }); + + if (filter) { + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + + if (options.handle && !closest(originalTarget, options.handle, el, false)) { + return; + } // Prepare `dragstart` + + + this._prepareDragStart(evt, touch, target); + }, + _prepareDragStart: function _prepareDragStart( + /** Event */ + evt, + /** Touch */ + touch, + /** HTMLElement */ + target) { + var _this = this, + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; + + if (target && !dragEl && target.parentNode === el) { + var dragRect = getRect(target); + rootEl = el; + dragEl = target; + parentEl = dragEl.parentNode; + nextEl = dragEl.nextSibling; + lastDownEl = target; + activeGroup = options.group; + Sortable.dragged = dragEl; + tapEvt = { + target: dragEl, + clientX: (touch || evt).clientX, + clientY: (touch || evt).clientY + }; + tapDistanceLeft = tapEvt.clientX - dragRect.left; + tapDistanceTop = tapEvt.clientY - dragRect.top; + this._lastX = (touch || evt).clientX; + this._lastY = (touch || evt).clientY; + dragEl.style['will-change'] = 'all'; + + dragStartFn = function dragStartFn() { + pluginEvent('delayEnded', _this, { + evt: evt + }); + + if (Sortable.eventCanceled) { + _this._onDrop(); + + return; + } // Delayed drag has been triggered + // we can re-enable the events: touchmove/mousemove + + + _this._disableDelayedDragEvents(); + + if (!FireFox && _this.nativeDraggable) { + dragEl.draggable = true; + } // Bind the events: dragstart/dragend + + + _this._triggerDragStart(evt, touch); // Drag start event + + + _dispatchEvent({ + sortable: _this, + name: 'choose', + originalEvent: evt + }); // Chosen item + + + toggleClass(dragEl, options.chosenClass, true); + }; // Disable "draggable" + + + options.ignore.split(',').forEach(function (criteria) { + find(dragEl, criteria.trim(), _disableDraggable); + }); + on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mouseup', _this._onDrop); + on(ownerDocument, 'touchend', _this._onDrop); + on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox) + + if (FireFox && this.nativeDraggable) { + this.options.touchStartThreshold = 4; + dragEl.draggable = true; + } + + pluginEvent('delayStart', this, { + evt: evt + }); // Delay is impossible for native DnD in Edge or IE + + if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { + if (Sortable.eventCanceled) { + this._onDrop(); + + return; + } // If the user moves the pointer or let go the click or touch + // before the delay has been reached: + // disable the delayed drag + + + on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + on(ownerDocument, 'touchend', _this._disableDelayedDrag); + on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); + on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); + options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); + _this._dragStartTimer = setTimeout(dragStartFn, options.delay); + } else { + dragStartFn(); + } + } + }, + _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( + /** TouchEvent|PointerEvent **/ + e) { + var touch = e.touches ? e.touches[0] : e; + + if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) { + this._disableDelayedDrag(); + } + }, + _disableDelayedDrag: function _disableDelayedDrag() { + dragEl && _disableDraggable(dragEl); + clearTimeout(this._dragStartTimer); + + this._disableDelayedDragEvents(); + }, + _disableDelayedDragEvents: function _disableDelayedDragEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._disableDelayedDrag); + off(ownerDocument, 'touchend', this._disableDelayedDrag); + off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); + }, + _triggerDragStart: function _triggerDragStart( + /** Event */ + evt, + /** Touch */ + touch) { + touch = touch || evt.pointerType == 'touch' && evt; + + if (!this.nativeDraggable || touch) { + if (this.options.supportPointer) { + on(document, 'pointermove', this._onTouchMove); + } else if (touch) { + on(document, 'touchmove', this._onTouchMove); + } else { + on(document, 'mousemove', this._onTouchMove); + } + } else { + on(dragEl, 'dragend', this); + on(rootEl, 'dragstart', this._onDragStart); + } + + try { + if (document.selection) { + // Timeout neccessary for IE9 + _nextTick(function () { + document.selection.empty(); + }); + } else { + window.getSelection().removeAllRanges(); + } + } catch (err) {} + }, + _dragStarted: function _dragStarted(fallback, evt) { + + awaitingDragStarted = false; + + if (rootEl && dragEl) { + pluginEvent('dragStarted', this, { + evt: evt + }); + + if (this.nativeDraggable) { + on(document, 'dragover', _checkOutsideTargetEl); + } + + var options = this.options; // Apply effect + + !fallback && toggleClass(dragEl, options.dragClass, false); + toggleClass(dragEl, options.ghostClass, true); + Sortable.active = this; + fallback && this._appendGhost(); // Drag start event + + _dispatchEvent({ + sortable: this, + name: 'start', + originalEvent: evt + }); + } else { + this._nulling(); + } + }, + _emulateDragOver: function _emulateDragOver() { + if (touchEvt) { + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + _hideGhostForTarget(); + + var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + var parent = target; + + while (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + if (target === parent) break; + parent = target; + } + + dragEl.parentNode[expando]._isOutsideThisEl(target); + + if (parent) { + do { + if (parent[expando]) { + var inserted = void 0; + inserted = parent[expando]._onDragOver({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + + if (inserted && !this.options.dragoverBubble) { + break; + } + } + + target = parent; // store last element + } + /* jshint boss:true */ + while (parent = parent.parentNode); + } + + _unhideGhostForTarget(); + } + }, + _onTouchMove: function _onTouchMove( + /**TouchEvent*/ + evt) { + if (tapEvt) { + var options = this.options, + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + ghostMatrix = ghostEl && matrix(ghostEl), + scaleX = ghostEl && ghostMatrix && ghostMatrix.a, + scaleY = ghostEl && ghostMatrix && ghostMatrix.d, + relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), + dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), + dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging + + if (!Sortable.active && !awaitingDragStarted) { + if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { + return; + } + + this._onDragStart(evt, true); + } + + if (ghostEl) { + if (ghostMatrix) { + ghostMatrix.e += dx - (lastDx || 0); + ghostMatrix.f += dy - (lastDy || 0); + } else { + ghostMatrix = { + a: 1, + b: 0, + c: 0, + d: 1, + e: dx, + f: dy + }; + } + + var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")"); + css(ghostEl, 'webkitTransform', cssMatrix); + css(ghostEl, 'mozTransform', cssMatrix); + css(ghostEl, 'msTransform', cssMatrix); + css(ghostEl, 'transform', cssMatrix); + lastDx = dx; + lastDy = dy; + touchEvt = touch; + } + + evt.cancelable && evt.preventDefault(); + } + }, + _appendGhost: function _appendGhost() { + // Bug if using scale(): https://stackoverflow.com/questions/2637058 + // Not being adjusted for + if (!ghostEl) { + var container = this.options.fallbackOnBody ? document.body : rootEl, + rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), + options = this.options; // Position absolutely + + if (PositionGhostAbsolutely) { + // Get relatively positioned parent + ghostRelativeParent = container; + + while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) { + ghostRelativeParent = ghostRelativeParent.parentNode; + } + + if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { + if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement(); + rect.top += ghostRelativeParent.scrollTop; + rect.left += ghostRelativeParent.scrollLeft; + } else { + ghostRelativeParent = getWindowScrollingElement(); + } + + ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent); + } + + ghostEl = dragEl.cloneNode(true); + toggleClass(ghostEl, options.ghostClass, false); + toggleClass(ghostEl, options.fallbackClass, true); + toggleClass(ghostEl, options.dragClass, true); + css(ghostEl, 'transition', ''); + css(ghostEl, 'transform', ''); + css(ghostEl, 'box-sizing', 'border-box'); + css(ghostEl, 'margin', 0); + css(ghostEl, 'top', rect.top); + css(ghostEl, 'left', rect.left); + css(ghostEl, 'width', rect.width); + css(ghostEl, 'height', rect.height); + css(ghostEl, 'opacity', '0.8'); + css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed'); + css(ghostEl, 'zIndex', '100000'); + css(ghostEl, 'pointerEvents', 'none'); + Sortable.ghost = ghostEl; + container.appendChild(ghostEl); // Set transform-origin + + css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%'); + } + }, + _onDragStart: function _onDragStart( + /**Event*/ + evt, + /**boolean*/ + fallback) { + var _this = this; + + var dataTransfer = evt.dataTransfer; + var options = _this.options; + pluginEvent('dragStart', this, { + evt: evt + }); + + if (Sortable.eventCanceled) { + this._onDrop(); + + return; + } + + pluginEvent('setupClone', this); + + if (!Sortable.eventCanceled) { + cloneEl = clone(dragEl); + cloneEl.draggable = false; + cloneEl.style['will-change'] = ''; + + this._hideClone(); + + toggleClass(cloneEl, this.options.chosenClass, false); + Sortable.clone = cloneEl; + } // #1143: IFrame support workaround + + + _this.cloneId = _nextTick(function () { + pluginEvent('clone', _this); + if (Sortable.eventCanceled) return; + + if (!_this.options.removeCloneOnHide) { + rootEl.insertBefore(cloneEl, dragEl); + } + + _this._hideClone(); + + _dispatchEvent({ + sortable: _this, + name: 'clone' + }); + }); + !fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events + + if (fallback) { + ignoreNextClick = true; + _this._loopId = setInterval(_this._emulateDragOver, 50); + } else { + // Undo what was set in _prepareDragStart before drag started + off(document, 'mouseup', _this._onDrop); + off(document, 'touchend', _this._onDrop); + off(document, 'touchcancel', _this._onDrop); + + if (dataTransfer) { + dataTransfer.effectAllowed = 'move'; + options.setData && options.setData.call(_this, dataTransfer, dragEl); + } + + on(document, 'drop', _this); // #1276 fix: + + css(dragEl, 'transform', 'translateZ(0)'); + } + + awaitingDragStarted = true; + _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); + on(document, 'selectstart', _this); + moved = true; + + if (Safari) { + css(document.body, 'user-select', 'none'); + } + }, + // Returns true - if no further action is needed (either inserted or another condition) + _onDragOver: function _onDragOver( + /**Event*/ + evt) { + var el = this.el, + target = evt.target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable.active, + isOwner = activeGroup === group, + canSort = options.sort, + fromSortable = putSortable || activeSortable, + vertical, + _this = this, + completedFired = false; + + if (_silent) return; + + function dragOverEvent(name, extra) { + pluginEvent(name, _this, _objectSpread({ + evt: evt, + isOwner: isOwner, + axis: vertical ? 'vertical' : 'horizontal', + revert: revert, + dragRect: dragRect, + targetRect: targetRect, + canSort: canSort, + fromSortable: fromSortable, + target: target, + completed: completed, + onMove: function onMove(target, after) { + return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after); + }, + changed: changed + }, extra)); + } // Capture animation state + + + function capture() { + dragOverEvent('dragOverAnimationCapture'); + + _this.captureAnimationState(); + + if (_this !== fromSortable) { + fromSortable.captureAnimationState(); + } + } // Return invocation when dragEl is inserted (or completed) + + + function completed(insertion) { + dragOverEvent('dragOverCompleted', { + insertion: insertion + }); + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(_this); + } + + if (_this !== fromSortable) { + // Set ghost class to new sortable's ghost class + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); + toggleClass(dragEl, options.ghostClass, true); + } + + if (putSortable !== _this && _this !== Sortable.active) { + putSortable = _this; + } else if (_this === Sortable.active && putSortable) { + putSortable = null; + } // Animation + + + if (fromSortable === _this) { + _this._ignoreWhileAnimating = target; + } + + _this.animateAll(function () { + dragOverEvent('dragOverAnimationComplete'); + _this._ignoreWhileAnimating = null; + }); + + if (_this !== fromSortable) { + fromSortable.animateAll(); + fromSortable._ignoreWhileAnimating = null; + } + } // Null lastTarget if it is not inside a previously swapped element + + + if (target === dragEl && !dragEl.animated || target === el && !target.animated) { + lastTarget = null; + } // no bubbling and not fallback + + + if (!options.dragoverBubble && !evt.rootEl && target !== document) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted + + + !insertion && nearestEmptyInsertDetectEvent(evt); + } + + !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); + return completedFired = true; + } // Call when dragEl has been inserted + + + function changed() { + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + _dispatchEvent({ + sortable: _this, + name: 'change', + toEl: el, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + originalEvent: evt + }); + } + + if (evt.preventDefault !== void 0) { + evt.cancelable && evt.preventDefault(); + } + + target = closest(target, options.draggable, el, true); + dragOverEvent('dragOver'); + if (Sortable.eventCanceled) return completedFired; + + if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) { + return completed(false); + } + + ignoreNextClick = false; + + if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) { + vertical = this._getDirection(evt, target) === 'vertical'; + dragRect = getRect(dragEl); + dragOverEvent('dragOverValid'); + if (Sortable.eventCanceled) return completedFired; + + if (revert) { + parentEl = rootEl; // actualization + + capture(); + + this._hideClone(); + + dragOverEvent('revert'); + + if (!Sortable.eventCanceled) { + if (nextEl) { + rootEl.insertBefore(dragEl, nextEl); + } else { + rootEl.appendChild(dragEl); + } + } + + return completed(true); + } + + var elLastChild = lastChild(el, options.draggable); + + if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { + // If already at end of list: Do not insert + if (elLastChild === dragEl) { + return completed(false); + } // assign target only if condition is true + + + if (elLastChild && el === evt.target) { + target = elLastChild; + } + + if (target) { + targetRect = getRect(target); + } + + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { + capture(); + el.appendChild(dragEl); + parentEl = el; // actualization + + changed(); + return completed(true); + } + } else if (target.parentNode === el) { + targetRect = getRect(target); + var direction = 0, + targetBeforeFirstSwap, + differentLevel = dragEl.parentNode !== el, + differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), + side1 = vertical ? 'top' : 'left', + scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), + scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; + + if (lastTarget !== target) { + targetBeforeFirstSwap = targetRect[side1]; + pastFirstInvertThresh = false; + isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel; + } + + direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); + var sibling; + + if (direction !== 0) { + // Check if target is beside dragEl in respective direction (ignoring hidden elements) + var dragIndex = index(dragEl); + + do { + dragIndex -= direction; + sibling = parentEl.children[dragIndex]; + } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl)); + } // If dragEl is already beside target: Do not insert + + + if (direction === 0 || sibling === target) { + return completed(false); + } + + lastTarget = target; + lastDirection = direction; + var nextSibling = target.nextElementSibling, + after = false; + after = direction === 1; + + var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); + + if (moveVector !== false) { + if (moveVector === 1 || moveVector === -1) { + after = moveVector === 1; + } + + _silent = true; + setTimeout(_unsilent, 30); + capture(); + + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } // Undo chrome's scroll adjustment (has no effect on other browsers) + + + if (scrolledPastTop) { + scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); + } + + parentEl = dragEl.parentNode; // actualization + // must be done before animation + + if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { + targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]); + } + + changed(); + return completed(true); + } + } + + if (el.contains(dragEl)) { + return completed(false); + } + } + + return false; + }, + _ignoreWhileAnimating: null, + _offMoveEvents: function _offMoveEvents() { + off(document, 'mousemove', this._onTouchMove); + off(document, 'touchmove', this._onTouchMove); + off(document, 'pointermove', this._onTouchMove); + off(document, 'dragover', nearestEmptyInsertDetectEvent); + off(document, 'mousemove', nearestEmptyInsertDetectEvent); + off(document, 'touchmove', nearestEmptyInsertDetectEvent); + }, + _offUpEvents: function _offUpEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._onDrop); + off(ownerDocument, 'touchend', this._onDrop); + off(ownerDocument, 'pointerup', this._onDrop); + off(ownerDocument, 'touchcancel', this._onDrop); + off(document, 'selectstart', this); + }, + _onDrop: function _onDrop( + /**Event*/ + evt) { + var el = this.el, + options = this.options; // Get the index of the dragged element within its parent + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + pluginEvent('drop', this, { + evt: evt + }); + parentEl = dragEl && dragEl.parentNode; // Get again after plugin event + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + if (Sortable.eventCanceled) { + this._nulling(); + + return; + } + + awaitingDragStarted = false; + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + clearInterval(this._loopId); + clearTimeout(this._dragStartTimer); + + _cancelNextTick(this.cloneId); + + _cancelNextTick(this._dragStartId); // Unbind events + + + if (this.nativeDraggable) { + off(document, 'drop', this); + off(el, 'dragstart', this._onDragStart); + } + + this._offMoveEvents(); + + this._offUpEvents(); + + if (Safari) { + css(document.body, 'user-select', ''); + } + + if (evt) { + if (moved) { + evt.cancelable && evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } + + ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + // Remove clone(s) + cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); + } + + if (dragEl) { + if (this.nativeDraggable) { + off(dragEl, 'dragend', this); + } + + _disableDraggable(dragEl); + + dragEl.style['will-change'] = ''; // Remove classes + // ghostClass is added in dragStarted + + if (moved && !awaitingDragStarted) { + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); + } + + toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event + + _dispatchEvent({ + sortable: this, + name: 'unchoose', + toEl: parentEl, + newIndex: null, + newDraggableIndex: null, + originalEvent: evt + }); + + if (rootEl !== parentEl) { + if (newIndex >= 0) { + // Add event + _dispatchEvent({ + rootEl: parentEl, + name: 'add', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); // Remove event + + + _dispatchEvent({ + sortable: this, + name: 'remove', + toEl: parentEl, + originalEvent: evt + }); // drag from one list and drop into another + + + _dispatchEvent({ + rootEl: parentEl, + name: 'sort', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + + putSortable && putSortable.save(); + } else { + if (newIndex !== oldIndex) { + if (newIndex >= 0) { + // drag & drop within the same list + _dispatchEvent({ + sortable: this, + name: 'update', + toEl: parentEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + } + } + + if (Sortable.active) { + /* jshint eqnull:true */ + if (newIndex == null || newIndex === -1) { + newIndex = oldIndex; + newDraggableIndex = oldDraggableIndex; + } + + _dispatchEvent({ + sortable: this, + name: 'end', + toEl: parentEl, + originalEvent: evt + }); // Save sorting + + + this.save(); + } + } + } + + this._nulling(); + }, + _nulling: function _nulling() { + pluginEvent('nulling', this); + rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null; + savedInputChecked.forEach(function (el) { + el.checked = true; + }); + savedInputChecked.length = lastDx = lastDy = 0; + }, + handleEvent: function handleEvent( + /**Event*/ + evt) { + switch (evt.type) { + case 'drop': + case 'dragend': + this._onDrop(evt); + + break; + + case 'dragenter': + case 'dragover': + if (dragEl) { + this._onDragOver(evt); + + _globalDragOver(evt); + } + + break; + + case 'selectstart': + evt.preventDefault(); + break; + } + }, + + /** + * Serializes the item into an array of string. + * @returns {String[]} + */ + toArray: function toArray() { + var order = [], + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; + + for (; i < n; i++) { + el = children[i]; + + if (closest(el, options.draggable, this.el, false)) { + order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); + } + } + + return order; + }, + + /** + * Sorts the elements according to the array. + * @param {String[]} order order of the items + */ + sort: function sort(order) { + var items = {}, + rootEl = this.el; + this.toArray().forEach(function (id, i) { + var el = rootEl.children[i]; + + if (closest(el, this.options.draggable, rootEl, false)) { + items[id] = el; + } + }, this); + order.forEach(function (id) { + if (items[id]) { + rootEl.removeChild(items[id]); + rootEl.appendChild(items[id]); + } + }); + }, + + /** + * Save the current sorting + */ + save: function save() { + var store = this.options.store; + store && store.set && store.set(this); + }, + + /** + * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + * @param {HTMLElement} el + * @param {String} [selector] default: `options.draggable` + * @returns {HTMLElement|null} + */ + closest: function closest$1(el, selector) { + return closest(el, selector || this.options.draggable, this.el, false); + }, + + /** + * Set/get option + * @param {string} name + * @param {*} [value] + * @returns {*} + */ + option: function option(name, value) { + var options = this.options; + + if (value === void 0) { + return options[name]; + } else { + var modifiedValue = PluginManager.modifyOption(this, name, value); + + if (typeof modifiedValue !== 'undefined') { + options[name] = modifiedValue; + } else { + options[name] = value; + } + + if (name === 'group') { + _prepareGroup(options); + } + } + }, + + /** + * Destroy + */ + destroy: function destroy() { + pluginEvent('destroy', this); + var el = this.el; + el[expando] = null; + off(el, 'mousedown', this._onTapStart); + off(el, 'touchstart', this._onTapStart); + off(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + off(el, 'dragover', this); + off(el, 'dragenter', this); + } // Remove draggable attributes + + + Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { + el.removeAttribute('draggable'); + }); + + this._onDrop(); + + sortables.splice(sortables.indexOf(this.el), 1); + this.el = el = null; + }, + _hideClone: function _hideClone() { + if (!cloneHidden) { + pluginEvent('hideClone', this); + if (Sortable.eventCanceled) return; + css(cloneEl, 'display', 'none'); + + if (this.options.removeCloneOnHide && cloneEl.parentNode) { + cloneEl.parentNode.removeChild(cloneEl); + } + + cloneHidden = true; + } + }, + _showClone: function _showClone(putSortable) { + if (putSortable.lastPutMode !== 'clone') { + this._hideClone(); + + return; + } + + if (cloneHidden) { + pluginEvent('showClone', this); + if (Sortable.eventCanceled) return; // show clone at dragEl or original position + + if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + rootEl.insertBefore(cloneEl, dragEl); + } else if (nextEl) { + rootEl.insertBefore(cloneEl, nextEl); + } else { + rootEl.appendChild(cloneEl); + } + + if (this.options.group.revertClone) { + this.animate(dragEl, cloneEl); + } + + css(cloneEl, 'display', ''); + cloneHidden = false; + } + } +}; + +function _globalDragOver( +/**Event*/ +evt) { + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } + + evt.cancelable && evt.preventDefault(); +} + +function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) { + var evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent('move', { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + } + + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || getRect(toEl); + evt.willInsertAfter = willInsertAfter; + evt.originalEvent = originalEvent; + fromEl.dispatchEvent(evt); + + if (onMoveFn) { + retVal = onMoveFn.call(sortable, evt, originalEvent); + } + + return retVal; +} + +function _disableDraggable(el) { + el.draggable = false; +} + +function _unsilent() { + _silent = false; +} + +function _ghostIsLast(evt, vertical, sortable) { + var rect = getRect(lastChild(sortable.el, sortable.options.draggable)); + var spacer = 10; + return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer; +} + +function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { + var mouseOnAxis = vertical ? evt.clientY : evt.clientX, + targetLength = vertical ? targetRect.height : targetRect.width, + targetS1 = vertical ? targetRect.top : targetRect.left, + targetS2 = vertical ? targetRect.bottom : targetRect.right, + invert = false; + + if (!invertSwap) { + // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold + if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { + // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 + // check if past first invert threshold on side opposite of lastDirection + if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) { + // past first invert threshold, do not restrict inverted threshold to dragEl shadow + pastFirstInvertThresh = true; + } + + if (!pastFirstInvertThresh) { + // dragEl shadow (target move distance shadow) + if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow + : mouseOnAxis > targetS2 - targetMoveDistance) { + return -lastDirection; + } + } else { + invert = true; + } + } else { + // Regular + if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) { + return _getInsertDirection(target); + } + } + } + + invert = invert || invertSwap; + + if (invert) { + // Invert of regular + if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) { + return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1; + } + } + + return 0; +} +/** + * Gets the direction dragEl must be swapped relative to target in order to make it + * seem that dragEl has been "inserted" into that element's position + * @param {HTMLElement} target The target whose position dragEl is being inserted at + * @return {Number} Direction dragEl must be swapped + */ + + +function _getInsertDirection(target) { + if (index(dragEl) < index(target)) { + return 1; + } else { + return -1; + } +} +/** + * Generate id + * @param {HTMLElement} el + * @returns {String} + * @private + */ + + +function _generateId(el) { + var str = el.tagName + el.className + el.src + el.href + el.textContent, + i = str.length, + sum = 0; + + while (i--) { + sum += str.charCodeAt(i); + } + + return sum.toString(36); +} + +function _saveInputCheckedState(root) { + savedInputChecked.length = 0; + var inputs = root.getElementsByTagName('input'); + var idx = inputs.length; + + while (idx--) { + var el = inputs[idx]; + el.checked && savedInputChecked.push(el); + } +} + +function _nextTick(fn) { + return setTimeout(fn, 0); +} + +function _cancelNextTick(id) { + return clearTimeout(id); +} // Fixed #973: + + +if (documentExists) { + on(document, 'touchmove', function (evt) { + if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { + evt.preventDefault(); + } + }); +} // Export utils + + +Sortable.utils = { + on: on, + off: off, + css: css, + find: find, + is: function is(el, selector) { + return !!closest(el, selector, el, false); + }, + extend: extend, + throttle: throttle, + closest: closest, + toggleClass: toggleClass, + clone: clone, + index: index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick, + detectDirection: _detectDirection, + getChild: getChild +}; +/** + * Get the Sortable instance of an element + * @param {HTMLElement} element The element + * @return {Sortable|undefined} The instance of Sortable + */ + +Sortable.get = function (element) { + return element[expando]; +}; +/** + * Mount a plugin to Sortable + * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted + */ + + +Sortable.mount = function () { + for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { + plugins[_key] = arguments[_key]; + } + + if (plugins[0].constructor === Array) plugins = plugins[0]; + plugins.forEach(function (plugin) { + if (!plugin.prototype || !plugin.prototype.constructor) { + throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin)); + } + + if (plugin.utils) Sortable.utils = _objectSpread({}, Sortable.utils, plugin.utils); + PluginManager.mount(plugin); + }); +}; +/** + * Create sortable instance + * @param {HTMLElement} el + * @param {Object} [options] + */ + + +Sortable.create = function (el, options) { + return new Sortable(el, options); +}; // Export + + +Sortable.version = version; + +var autoScrolls = [], + scrollEl, + scrollRootEl, + scrolling = false, + lastAutoScrollX, + lastAutoScrollY, + touchEvt$1, + pointerElemChangedInterval; + +function AutoScrollPlugin() { + function AutoScroll() { + this.defaults = { + scroll: true, + scrollSensitivity: 30, + scrollSpeed: 10, + bubbleScroll: true + }; // Bind all private methods + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + } + + AutoScroll.prototype = { + dragStarted: function dragStarted(_ref) { + var originalEvent = _ref.originalEvent; + + if (this.sortable.nativeDraggable) { + on(document, 'dragover', this._handleAutoScroll); + } else { + if (this.options.supportPointer) { + on(document, 'pointermove', this._handleFallbackAutoScroll); + } else if (originalEvent.touches) { + on(document, 'touchmove', this._handleFallbackAutoScroll); + } else { + on(document, 'mousemove', this._handleFallbackAutoScroll); + } + } + }, + dragOverCompleted: function dragOverCompleted(_ref2) { + var originalEvent = _ref2.originalEvent; + + // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) + if (!this.options.dragOverBubble && !originalEvent.rootEl) { + this._handleAutoScroll(originalEvent); + } + }, + drop: function drop() { + if (this.sortable.nativeDraggable) { + off(document, 'dragover', this._handleAutoScroll); + } else { + off(document, 'pointermove', this._handleFallbackAutoScroll); + off(document, 'touchmove', this._handleFallbackAutoScroll); + off(document, 'mousemove', this._handleFallbackAutoScroll); + } + + clearPointerElemChangedInterval(); + clearAutoScrolls(); + cancelThrottle(); + }, + nulling: function nulling() { + touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null; + autoScrolls.length = 0; + }, + _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) { + this._handleAutoScroll(evt, true); + }, + _handleAutoScroll: function _handleAutoScroll(evt, fallback) { + var _this = this; + + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + elem = document.elementFromPoint(x, y); + touchEvt$1 = evt; // IE does not seem to have native autoscroll, + // Edge's autoscroll seems too conditional, + // MACOS Safari does not have autoscroll, + // Firefox and Chrome are good + + if (fallback || Edge || IE11OrLess || Safari) { + autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change + + var ogElemScroller = getParentAutoScrollElement(elem, true); + + if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) { + pointerElemChangedInterval && clearPointerElemChangedInterval(); // Detect for pointer elem change, emulating native DnD behaviour + + pointerElemChangedInterval = setInterval(function () { + var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true); + + if (newElem !== ogElemScroller) { + ogElemScroller = newElem; + clearAutoScrolls(); + } + + autoScroll(evt, _this.options, newElem, fallback); + }, 10); + lastAutoScrollX = x; + lastAutoScrollY = y; + } + } else { + // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll + if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { + clearAutoScrolls(); + return; + } + + autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false); + } + } + }; + return _extends(AutoScroll, { + pluginName: 'scroll', + initializeByDefault: true + }); +} + +function clearAutoScrolls() { + autoScrolls.forEach(function (autoScroll) { + clearInterval(autoScroll.pid); + }); + autoScrolls = []; +} + +function clearPointerElemChangedInterval() { + clearInterval(pointerElemChangedInterval); +} + +var autoScroll = throttle(function (evt, options, rootEl, isFallback) { + // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + if (!options.scroll) return; + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + sens = options.scrollSensitivity, + speed = options.scrollSpeed, + winScroller = getWindowScrollingElement(); + var scrollThisInstance = false, + scrollCustomFn; // New scroll root, set scrollEl + + if (scrollRootEl !== rootEl) { + scrollRootEl = rootEl; + clearAutoScrolls(); + scrollEl = options.scroll; + scrollCustomFn = options.scrollFn; + + if (scrollEl === true) { + scrollEl = getParentAutoScrollElement(rootEl, true); + } + } + + var layersOut = 0; + var currentParent = scrollEl; + + do { + var el = currentParent, + rect = getRect(el), + top = rect.top, + bottom = rect.bottom, + left = rect.left, + right = rect.right, + width = rect.width, + height = rect.height, + canScrollX = void 0, + canScrollY = void 0, + scrollWidth = el.scrollWidth, + scrollHeight = el.scrollHeight, + elCSS = css(el), + scrollPosX = el.scrollLeft, + scrollPosY = el.scrollTop; + + if (el === winScroller) { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible'); + } else { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); + } + + var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX); + var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY); + + if (!autoScrolls[layersOut]) { + for (var i = 0; i <= layersOut; i++) { + if (!autoScrolls[i]) { + autoScrolls[i] = {}; + } + } + } + + if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { + autoScrolls[layersOut].el = el; + autoScrolls[layersOut].vx = vx; + autoScrolls[layersOut].vy = vy; + clearInterval(autoScrolls[layersOut].pid); + + if (vx != 0 || vy != 0) { + scrollThisInstance = true; + /* jshint loopfunc:true */ + + autoScrolls[layersOut].pid = setInterval(function () { + // emulate drag over during autoscroll (fallback), emulating native DnD behaviour + if (isFallback && this.layer === 0) { + Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely + + } + + var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; + var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; + + if (typeof scrollCustomFn === 'function') { + if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') { + return; + } + } + + scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); + }.bind({ + layer: layersOut + }), 24); + } + } + + layersOut++; + } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false))); + + scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not +}, 30); + +var drop = function drop(_ref) { + var originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + dragEl = _ref.dragEl, + activeSortable = _ref.activeSortable, + dispatchSortableEvent = _ref.dispatchSortableEvent, + hideGhostForTarget = _ref.hideGhostForTarget, + unhideGhostForTarget = _ref.unhideGhostForTarget; + if (!originalEvent) return; + var toSortable = putSortable || activeSortable; + hideGhostForTarget(); + var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent; + var target = document.elementFromPoint(touch.clientX, touch.clientY); + unhideGhostForTarget(); + + if (toSortable && !toSortable.el.contains(target)) { + dispatchSortableEvent('spill'); + this.onSpill({ + dragEl: dragEl, + putSortable: putSortable + }); + } +}; + +function Revert() {} + +Revert.prototype = { + startIndex: null, + dragStart: function dragStart(_ref2) { + var oldDraggableIndex = _ref2.oldDraggableIndex; + this.startIndex = oldDraggableIndex; + }, + onSpill: function onSpill(_ref3) { + var dragEl = _ref3.dragEl, + putSortable = _ref3.putSortable; + this.sortable.captureAnimationState(); + + if (putSortable) { + putSortable.captureAnimationState(); + } + + var nextSibling = getChild(this.sortable.el, this.startIndex, this.options); + + if (nextSibling) { + this.sortable.el.insertBefore(dragEl, nextSibling); + } else { + this.sortable.el.appendChild(dragEl); + } + + this.sortable.animateAll(); + + if (putSortable) { + putSortable.animateAll(); + } + }, + drop: drop +}; + +_extends(Revert, { + pluginName: 'revertOnSpill' +}); + +function Remove() {} + +Remove.prototype = { + onSpill: function onSpill(_ref4) { + var dragEl = _ref4.dragEl, + putSortable = _ref4.putSortable; + var parentSortable = putSortable || this.sortable; + parentSortable.captureAnimationState(); + dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); + parentSortable.animateAll(); + }, + drop: drop +}; + +_extends(Remove, { + pluginName: 'removeOnSpill' +}); + +var lastSwapEl; + +function SwapPlugin() { + function Swap() { + this.defaults = { + swapClass: 'sortable-swap-highlight' + }; + } + + Swap.prototype = { + dragStart: function dragStart(_ref) { + var dragEl = _ref.dragEl; + lastSwapEl = dragEl; + }, + dragOverValid: function dragOverValid(_ref2) { + var completed = _ref2.completed, + target = _ref2.target, + onMove = _ref2.onMove, + activeSortable = _ref2.activeSortable, + changed = _ref2.changed, + cancel = _ref2.cancel; + if (!activeSortable.options.swap) return; + var el = this.sortable.el, + options = this.options; + + if (target && target !== el) { + var prevSwapEl = lastSwapEl; + + if (onMove(target) !== false) { + toggleClass(target, options.swapClass, true); + lastSwapEl = target; + } else { + lastSwapEl = null; + } + + if (prevSwapEl && prevSwapEl !== lastSwapEl) { + toggleClass(prevSwapEl, options.swapClass, false); + } + } + + changed(); + completed(true); + cancel(); + }, + drop: function drop(_ref3) { + var activeSortable = _ref3.activeSortable, + putSortable = _ref3.putSortable, + dragEl = _ref3.dragEl; + var toSortable = putSortable || this.sortable; + var options = this.options; + lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); + + if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { + if (dragEl !== lastSwapEl) { + toSortable.captureAnimationState(); + if (toSortable !== activeSortable) activeSortable.captureAnimationState(); + swapNodes(dragEl, lastSwapEl); + toSortable.animateAll(); + if (toSortable !== activeSortable) activeSortable.animateAll(); + } + } + }, + nulling: function nulling() { + lastSwapEl = null; + } + }; + return _extends(Swap, { + pluginName: 'swap', + eventProperties: function eventProperties() { + return { + swapItem: lastSwapEl + }; + } + }); +} + +function swapNodes(n1, n2) { + var p1 = n1.parentNode, + p2 = n2.parentNode, + i1, + i2; + if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; + i1 = index(n1); + i2 = index(n2); + + if (p1.isEqualNode(p2) && i1 < i2) { + i2++; + } + + p1.insertBefore(n2, p1.children[i1]); + p2.insertBefore(n1, p2.children[i2]); +} + +var multiDragElements = [], + multiDragClones = [], + lastMultiDragSelect, + // for selection with modifier key down (SHIFT) +multiDragSortable, + initialFolding = false, + // Initial multi-drag fold when drag started +folding = false, + // Folding any other time +dragStarted = false, + dragEl$1, + clonesFromRect, + clonesHidden; + +function MultiDragPlugin() { + function MultiDrag(sortable) { + // Bind all private methods + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + if (sortable.options.supportPointer) { + on(document, 'pointerup', this._deselectMultiDrag); + } else { + on(document, 'mouseup', this._deselectMultiDrag); + on(document, 'touchend', this._deselectMultiDrag); + } + + on(document, 'keydown', this._checkKeyDown); + on(document, 'keyup', this._checkKeyUp); + this.defaults = { + selectedClass: 'sortable-selected', + multiDragKey: null, + setData: function setData(dataTransfer, dragEl) { + var data = ''; + + if (multiDragElements.length && multiDragSortable === sortable) { + multiDragElements.forEach(function (multiDragElement, i) { + data += (!i ? '' : ', ') + multiDragElement.textContent; + }); + } else { + data = dragEl.textContent; + } + + dataTransfer.setData('Text', data); + } + }; + } + + MultiDrag.prototype = { + multiDragKeyDown: false, + isMultiDrag: false, + delayStartGlobal: function delayStartGlobal(_ref) { + var dragged = _ref.dragEl; + dragEl$1 = dragged; + }, + delayEnded: function delayEnded() { + this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1); + }, + setupClone: function setupClone(_ref2) { + var sortable = _ref2.sortable, + cancel = _ref2.cancel; + if (!this.isMultiDrag) return; + + for (var i = 0; i < multiDragElements.length; i++) { + multiDragClones.push(clone(multiDragElements[i])); + multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; + multiDragClones[i].draggable = false; + multiDragClones[i].style['will-change'] = ''; + toggleClass(multiDragClones[i], this.options.selectedClass, false); + multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false); + } + + sortable._hideClone(); + + cancel(); + }, + clone: function clone(_ref3) { + var sortable = _ref3.sortable, + rootEl = _ref3.rootEl, + dispatchSortableEvent = _ref3.dispatchSortableEvent, + cancel = _ref3.cancel; + if (!this.isMultiDrag) return; + + if (!this.options.removeCloneOnHide) { + if (multiDragElements.length && multiDragSortable === sortable) { + insertMultiDragClones(true, rootEl); + dispatchSortableEvent('clone'); + cancel(); + } + } + }, + showClone: function showClone(_ref4) { + var cloneNowShown = _ref4.cloneNowShown, + rootEl = _ref4.rootEl, + cancel = _ref4.cancel; + if (!this.isMultiDrag) return; + insertMultiDragClones(false, rootEl); + multiDragClones.forEach(function (clone) { + css(clone, 'display', ''); + }); + cloneNowShown(); + clonesHidden = false; + cancel(); + }, + hideClone: function hideClone(_ref5) { + var _this = this; + + var sortable = _ref5.sortable, + cloneNowHidden = _ref5.cloneNowHidden, + cancel = _ref5.cancel; + if (!this.isMultiDrag) return; + multiDragClones.forEach(function (clone) { + css(clone, 'display', 'none'); + + if (_this.options.removeCloneOnHide && clone.parentNode) { + clone.parentNode.removeChild(clone); + } + }); + cloneNowHidden(); + clonesHidden = true; + cancel(); + }, + dragStartGlobal: function dragStartGlobal(_ref6) { + var sortable = _ref6.sortable; + + if (!this.isMultiDrag && multiDragSortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + } + + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.sortableIndex = index(multiDragElement); + }); // Sort multi-drag elements + + multiDragElements = multiDragElements.sort(function (a, b) { + return a.sortableIndex - b.sortableIndex; + }); + dragStarted = true; + }, + dragStarted: function dragStarted(_ref7) { + var _this2 = this; + + var sortable = _ref7.sortable; + if (!this.isMultiDrag) return; + + if (this.options.sort) { + // Capture rects, + // hide multi drag elements (by positioning them absolute), + // set multi drag elements rects to dragRect, + // show multi drag elements, + // animate to rects, + // unset rects & remove from DOM + sortable.captureAnimationState(); + + if (this.options.animation) { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + css(multiDragElement, 'position', 'absolute'); + }); + var dragRect = getRect(dragEl$1, false, true, true); + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRect); + }); + folding = true; + initialFolding = true; + } + } + + sortable.animateAll(function () { + folding = false; + initialFolding = false; + + if (_this2.options.animation) { + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); + } // Remove all auxiliary multidrag items from el, if sorting enabled + + + if (_this2.options.sort) { + removeMultiDragElements(); + } + }); + }, + dragOver: function dragOver(_ref8) { + var target = _ref8.target, + completed = _ref8.completed, + cancel = _ref8.cancel; + + if (folding && ~multiDragElements.indexOf(target)) { + completed(false); + cancel(); + } + }, + revert: function revert(_ref9) { + var fromSortable = _ref9.fromSortable, + rootEl = _ref9.rootEl, + sortable = _ref9.sortable, + dragRect = _ref9.dragRect; + + if (multiDragElements.length > 1) { + // Setup unfold animation + multiDragElements.forEach(function (multiDragElement) { + sortable.addAnimationState({ + target: multiDragElement, + rect: folding ? getRect(multiDragElement) : dragRect + }); + unsetRect(multiDragElement); + multiDragElement.fromRect = dragRect; + fromSortable.removeAnimationState(multiDragElement); + }); + folding = false; + insertMultiDragElements(!this.options.removeCloneOnHide, rootEl); + } + }, + dragOverCompleted: function dragOverCompleted(_ref10) { + var sortable = _ref10.sortable, + isOwner = _ref10.isOwner, + insertion = _ref10.insertion, + activeSortable = _ref10.activeSortable, + parentEl = _ref10.parentEl, + putSortable = _ref10.putSortable; + var options = this.options; + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } + + initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location + + if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { + // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible + var dragRectAbsolute = getRect(dragEl$1, false, true, true); + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted + // while folding, and so that we can capture them again because old sortable will no longer be fromSortable + + parentEl.appendChild(multiDragElement); + }); + folding = true; + } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out + + + if (!isOwner) { + // Only remove if not folding (folding will remove them anyways) + if (!folding) { + removeMultiDragElements(); + } + + if (multiDragElements.length > 1) { + var clonesHiddenBefore = clonesHidden; + + activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden + + + if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { + multiDragClones.forEach(function (clone) { + activeSortable.addAnimationState({ + target: clone, + rect: clonesFromRect + }); + clone.fromRect = clonesFromRect; + clone.thisAnimationDuration = null; + }); + } + } else { + activeSortable._showClone(sortable); + } + } + } + }, + dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) { + var dragRect = _ref11.dragRect, + isOwner = _ref11.isOwner, + activeSortable = _ref11.activeSortable; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + }); + + if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { + clonesFromRect = _extends({}, dragRect); + var dragMatrix = matrix(dragEl$1, true); + clonesFromRect.top -= dragMatrix.f; + clonesFromRect.left -= dragMatrix.e; + } + }, + dragOverAnimationComplete: function dragOverAnimationComplete() { + if (folding) { + folding = false; + removeMultiDragElements(); + } + }, + drop: function drop(_ref12) { + var evt = _ref12.originalEvent, + rootEl = _ref12.rootEl, + parentEl = _ref12.parentEl, + sortable = _ref12.sortable, + dispatchSortableEvent = _ref12.dispatchSortableEvent, + oldIndex = _ref12.oldIndex, + putSortable = _ref12.putSortable; + var toSortable = putSortable || this.sortable; + if (!evt) return; + var options = this.options, + children = parentEl.children; // Multi-drag selection + + if (!dragStarted) { + if (options.multiDragKey && !this.multiDragKeyDown) { + this._deselectMultiDrag(); + } + + toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1)); + + if (!~multiDragElements.indexOf(dragEl$1)) { + multiDragElements.push(dragEl$1); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: dragEl$1, + originalEvt: evt + }); // Modifier activated, select from last to dragEl + + if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { + var lastIndex = index(lastMultiDragSelect), + currentIndex = index(dragEl$1); + + if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { + // Must include lastMultiDragSelect (select it), in case modified selection from no selection + // (but previous selection existed) + var n, i; + + if (currentIndex > lastIndex) { + i = lastIndex; + n = currentIndex; + } else { + i = currentIndex; + n = lastIndex + 1; + } + + for (; i < n; i++) { + if (~multiDragElements.indexOf(children[i])) continue; + toggleClass(children[i], options.selectedClass, true); + multiDragElements.push(children[i]); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: children[i], + originalEvt: evt + }); + } + } + } else { + lastMultiDragSelect = dragEl$1; + } + + multiDragSortable = toSortable; + } else { + multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1); + lastMultiDragSelect = null; + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'deselect', + targetEl: dragEl$1, + originalEvt: evt + }); + } + } // Multi-drag drop + + + if (dragStarted && this.isMultiDrag) { + // Do not "unfold" after around dragEl if reverted + if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { + var dragRect = getRect(dragEl$1), + multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); + if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null; + toSortable.captureAnimationState(); + + if (!initialFolding) { + if (options.animation) { + dragEl$1.fromRect = dragRect; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + + if (multiDragElement !== dragEl$1) { + var rect = folding ? getRect(multiDragElement) : dragRect; + multiDragElement.fromRect = rect; // Prepare unfold animation + + toSortable.addAnimationState({ + target: multiDragElement, + rect: rect + }); + } + }); + } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert + // properly they must all be removed + + + removeMultiDragElements(); + multiDragElements.forEach(function (multiDragElement) { + if (children[multiDragIndex]) { + parentEl.insertBefore(multiDragElement, children[multiDragIndex]); + } else { + parentEl.appendChild(multiDragElement); + } + + multiDragIndex++; + }); // If initial folding is done, the elements may have changed position because they are now + // unfolding around dragEl, even though dragEl may not have his index changed, so update event + // must be fired here as Sortable will not. + + if (oldIndex === index(dragEl$1)) { + var update = false; + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement.sortableIndex !== index(multiDragElement)) { + update = true; + return; + } + }); + + if (update) { + dispatchSortableEvent('update'); + } + } + } // Must be done after capturing individual rects (scroll bar) + + + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); + toSortable.animateAll(); + } + + multiDragSortable = toSortable; + } // Remove clones if necessary + + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + multiDragClones.forEach(function (clone) { + clone.parentNode && clone.parentNode.removeChild(clone); + }); + } + }, + nullingGlobal: function nullingGlobal() { + this.isMultiDrag = dragStarted = false; + multiDragClones.length = 0; + }, + destroyGlobal: function destroyGlobal() { + this._deselectMultiDrag(); + + off(document, 'pointerup', this._deselectMultiDrag); + off(document, 'mouseup', this._deselectMultiDrag); + off(document, 'touchend', this._deselectMultiDrag); + off(document, 'keydown', this._checkKeyDown); + off(document, 'keyup', this._checkKeyUp); + }, + _deselectMultiDrag: function _deselectMultiDrag(evt) { + if (dragStarted) return; // Only deselect if selection is in this sortable + + if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable + + if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click + + if (evt && evt.button !== 0) return; + + while (multiDragElements.length) { + var el = multiDragElements[0]; + toggleClass(el, this.options.selectedClass, false); + multiDragElements.shift(); + dispatchEvent({ + sortable: this.sortable, + rootEl: this.sortable.el, + name: 'deselect', + targetEl: el, + originalEvt: evt + }); + } + }, + _checkKeyDown: function _checkKeyDown(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = true; + } + }, + _checkKeyUp: function _checkKeyUp(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = false; + } + } + }; + return _extends(MultiDrag, { + // Static methods & properties + pluginName: 'multiDrag', + utils: { + /** + * Selects the provided multi-drag item + * @param {HTMLElement} el The element to be selected + */ + select: function select(el) { + var sortable = el.parentNode[expando]; + if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return; + + if (multiDragSortable && multiDragSortable !== sortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + + multiDragSortable = sortable; + } + + toggleClass(el, sortable.options.selectedClass, true); + multiDragElements.push(el); + }, + + /** + * Deselects the provided multi-drag item + * @param {HTMLElement} el The element to be deselected + */ + deselect: function deselect(el) { + var sortable = el.parentNode[expando], + index = multiDragElements.indexOf(el); + if (!sortable || !sortable.options.multiDrag || !~index) return; + toggleClass(el, sortable.options.selectedClass, false); + multiDragElements.splice(index, 1); + } + }, + eventProperties: function eventProperties() { + var _this3 = this; + + var oldIndicies = [], + newIndicies = []; + multiDragElements.forEach(function (multiDragElement) { + oldIndicies.push({ + multiDragElement: multiDragElement, + index: multiDragElement.sortableIndex + }); // multiDragElements will already be sorted if folding + + var newIndex; + + if (folding && multiDragElement !== dragEl$1) { + newIndex = -1; + } else if (folding) { + newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')'); + } else { + newIndex = index(multiDragElement); + } + + newIndicies.push({ + multiDragElement: multiDragElement, + index: newIndex + }); + }); + return { + items: _toConsumableArray(multiDragElements), + clones: [].concat(multiDragClones), + oldIndicies: oldIndicies, + newIndicies: newIndicies + }; + }, + optionListeners: { + multiDragKey: function multiDragKey(key) { + key = key.toLowerCase(); + + if (key === 'ctrl') { + key = 'Control'; + } else if (key.length > 1) { + key = key.charAt(0).toUpperCase() + key.substr(1); + } + + return key; + } + } + }); +} + +function insertMultiDragElements(clonesInserted, rootEl) { + multiDragElements.forEach(function (multiDragElement, i) { + var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(multiDragElement, target); + } else { + rootEl.appendChild(multiDragElement); + } + }); +} +/** + * Insert multi-drag clones + * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted + * @param {HTMLElement} rootEl + */ + + +function insertMultiDragClones(elementsInserted, rootEl) { + multiDragClones.forEach(function (clone, i) { + var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(clone, target); + } else { + rootEl.appendChild(clone); + } + }); +} + +function removeMultiDragElements() { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement); + }); +} + +Sortable.mount(new AutoScrollPlugin()); +Sortable.mount(Remove, Revert); + +Sortable.mount(new SwapPlugin()); +Sortable.mount(new MultiDragPlugin()); + +export default Sortable; diff --git a/public/assets/libs/Sortable/modular/sortable.core.esm.js b/public/assets/libs/Sortable/modular/sortable.core.esm.js new file mode 100644 index 0000000000000000000000000000000000000000..48852e2f4ee032ba5fd8f7d25949be0be4aa20f9 --- /dev/null +++ b/public/assets/libs/Sortable/modular/sortable.core.esm.js @@ -0,0 +1,3692 @@ +/**! + * Sortable 1.10.1 + * @author RubaXa + * @author owenm + * @license MIT + */ +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); +} + +function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + + ownKeys.forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } + + return target; +} + +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; +} + +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +var version = "1.10.1"; + +function userAgent(pattern) { + if (typeof window !== 'undefined' && window.navigator) { + return !! + /*@__PURE__*/ + navigator.userAgent.match(pattern); + } +} + +var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); +var Edge = userAgent(/Edge/i); +var FireFox = userAgent(/firefox/i); +var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); +var IOS = userAgent(/iP(ad|od|hone)/i); +var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i); + +var captureMode = { + capture: false, + passive: false +}; + +function on(el, event, fn) { + el.addEventListener(event, fn, !IE11OrLess && captureMode); +} + +function off(el, event, fn) { + el.removeEventListener(event, fn, !IE11OrLess && captureMode); +} + +function matches( +/**HTMLElement*/ +el, +/**String*/ +selector) { + if (!selector) return; + selector[0] === '>' && (selector = selector.substring(1)); + + if (el) { + try { + if (el.matches) { + return el.matches(selector); + } else if (el.msMatchesSelector) { + return el.msMatchesSelector(selector); + } else if (el.webkitMatchesSelector) { + return el.webkitMatchesSelector(selector); + } + } catch (_) { + return false; + } + } + + return false; +} + +function getParentOrHost(el) { + return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode; +} + +function closest( +/**HTMLElement*/ +el, +/**String*/ +selector, +/**HTMLElement*/ +ctx, includeCTX) { + if (el) { + ctx = ctx || document; + + do { + if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) { + return el; + } + + if (el === ctx) break; + /* jshint boss:true */ + } while (el = getParentOrHost(el)); + } + + return null; +} + +var R_SPACE = /\s+/g; + +function toggleClass(el, name, state) { + if (el && name) { + if (el.classList) { + el.classList[state ? 'add' : 'remove'](name); + } else { + var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); + el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); + } + } +} + +function css(el, prop, val) { + var style = el && el.style; + + if (style) { + if (val === void 0) { + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(el, ''); + } else if (el.currentStyle) { + val = el.currentStyle; + } + + return prop === void 0 ? val : val[prop]; + } else { + if (!(prop in style) && prop.indexOf('webkit') === -1) { + prop = '-webkit-' + prop; + } + + style[prop] = val + (typeof val === 'string' ? '' : 'px'); + } + } +} + +function matrix(el, selfOnly) { + var appliedTransforms = ''; + + if (typeof el === 'string') { + appliedTransforms = el; + } else { + do { + var transform = css(el, 'transform'); + + if (transform && transform !== 'none') { + appliedTransforms = transform + ' ' + appliedTransforms; + } + /* jshint boss:true */ + + } while (!selfOnly && (el = el.parentNode)); + } + + var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix; + /*jshint -W056 */ + + return matrixFn && new matrixFn(appliedTransforms); +} + +function find(ctx, tagName, iterator) { + if (ctx) { + var list = ctx.getElementsByTagName(tagName), + i = 0, + n = list.length; + + if (iterator) { + for (; i < n; i++) { + iterator(list[i], i); + } + } + + return list; + } + + return []; +} + +function getWindowScrollingElement() { + if (IE11OrLess) { + return document.documentElement; + } else { + return document.scrollingElement; + } +} +/** + * Returns the "bounding client rect" of given element + * @param {HTMLElement} el The element whose boundingClientRect is wanted + * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container + * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr + * @param {[Boolean]} undoScale Whether the container's scale() should be undone + * @param {[HTMLElement]} container The parent the element will be placed in + * @return {Object} The boundingClientRect of el, with specified adjustments + */ + + +function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) { + if (!el.getBoundingClientRect && el !== window) return; + var elRect, top, left, bottom, right, height, width; + + if (el !== window && el !== getWindowScrollingElement()) { + elRect = el.getBoundingClientRect(); + top = elRect.top; + left = elRect.left; + bottom = elRect.bottom; + right = elRect.right; + height = elRect.height; + width = elRect.width; + } else { + top = 0; + left = 0; + bottom = window.innerHeight; + right = window.innerWidth; + height = window.innerHeight; + width = window.innerWidth; + } + + if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) { + // Adjust for translate() + container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) + // Not needed on <= IE11 + + if (!IE11OrLess) { + do { + if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) { + var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container + + top -= containerRect.top + parseInt(css(container, 'border-top-width')); + left -= containerRect.left + parseInt(css(container, 'border-left-width')); + bottom = top + elRect.height; + right = left + elRect.width; + break; + } + /* jshint boss:true */ + + } while (container = container.parentNode); + } + } + + if (undoScale && el !== window) { + // Adjust for scale() + var elMatrix = matrix(container || el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d; + + if (elMatrix) { + top /= scaleY; + left /= scaleX; + width /= scaleX; + height /= scaleY; + bottom = top + height; + right = left + width; + } + } + + return { + top: top, + left: left, + bottom: bottom, + right: right, + width: width, + height: height + }; +} +/** + * Checks if a side of an element is scrolled past a side of its parents + * @param {HTMLElement} el The element who's side being scrolled out of view is in question + * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom') + * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') + * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element + */ + + +function isScrolledPast(el, elSide, parentSide) { + var parent = getParentAutoScrollElement(el, true), + elSideVal = getRect(el)[elSide]; + /* jshint boss:true */ + + while (parent) { + var parentSideVal = getRect(parent)[parentSide], + visible = void 0; + + if (parentSide === 'top' || parentSide === 'left') { + visible = elSideVal >= parentSideVal; + } else { + visible = elSideVal <= parentSideVal; + } + + if (!visible) return parent; + if (parent === getWindowScrollingElement()) break; + parent = getParentAutoScrollElement(parent, false); + } + + return false; +} +/** + * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) + * and non-draggable elements + * @param {HTMLElement} el The parent element + * @param {Number} childNum The index of the child + * @param {Object} options Parent Sortable's options + * @return {HTMLElement} The child at index childNum, or null if not found + */ + + +function getChild(el, childNum, options) { + var currentChild = 0, + i = 0, + children = el.children; + + while (i < children.length) { + if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && children[i] !== Sortable.dragged && closest(children[i], options.draggable, el, false)) { + if (currentChild === childNum) { + return children[i]; + } + + currentChild++; + } + + i++; + } + + return null; +} +/** + * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) + * @param {HTMLElement} el Parent element + * @param {selector} selector Any other elements that should be ignored + * @return {HTMLElement} The last child, ignoring ghostEl + */ + + +function lastChild(el, selector) { + var last = el.lastElementChild; + + while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { + last = last.previousElementSibling; + } + + return last || null; +} +/** + * Returns the index of an element within its parent for a selected set of + * elements + * @param {HTMLElement} el + * @param {selector} selector + * @return {number} + */ + + +function index(el, selector) { + var index = 0; + + if (!el || !el.parentNode) { + return -1; + } + /* jshint boss:true */ + + + while (el = el.previousElementSibling) { + if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) { + index++; + } + } + + return index; +} +/** + * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. + * The value is returned in real pixels. + * @param {HTMLElement} el + * @return {Array} Offsets in the format of [left, top] + */ + + +function getRelativeScrollOffset(el) { + var offsetLeft = 0, + offsetTop = 0, + winScroller = getWindowScrollingElement(); + + if (el) { + do { + var elMatrix = matrix(el), + scaleX = elMatrix.a, + scaleY = elMatrix.d; + offsetLeft += el.scrollLeft * scaleX; + offsetTop += el.scrollTop * scaleY; + } while (el !== winScroller && (el = el.parentNode)); + } + + return [offsetLeft, offsetTop]; +} +/** + * Returns the index of the object within the given array + * @param {Array} arr Array that may or may not hold the object + * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find + * @return {Number} The index of the object in the array, or -1 + */ + + +function indexOfObject(arr, obj) { + for (var i in arr) { + if (!arr.hasOwnProperty(i)) continue; + + for (var key in obj) { + if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i); + } + } + + return -1; +} + +function getParentAutoScrollElement(el, includeSelf) { + // skip to window + if (!el || !el.getBoundingClientRect) return getWindowScrollingElement(); + var elem = el; + var gotSelf = false; + + do { + // we don't need to get elem css if it isn't even overflowing in the first place (performance) + if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { + var elemCSS = css(elem); + + if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) { + if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement(); + if (gotSelf || includeSelf) return elem; + gotSelf = true; + } + } + /* jshint boss:true */ + + } while (elem = elem.parentNode); + + return getWindowScrollingElement(); +} + +function extend(dst, src) { + if (dst && src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dst[key] = src[key]; + } + } + } + + return dst; +} + +function isRectEqual(rect1, rect2) { + return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width); +} + +var _throttleTimeout; + +function throttle(callback, ms) { + return function () { + if (!_throttleTimeout) { + var args = arguments, + _this = this; + + if (args.length === 1) { + callback.call(_this, args[0]); + } else { + callback.apply(_this, args); + } + + _throttleTimeout = setTimeout(function () { + _throttleTimeout = void 0; + }, ms); + } + }; +} + +function cancelThrottle() { + clearTimeout(_throttleTimeout); + _throttleTimeout = void 0; +} + +function scrollBy(el, x, y) { + el.scrollLeft += x; + el.scrollTop += y; +} + +function clone(el) { + var Polymer = window.Polymer; + var $ = window.jQuery || window.Zepto; + + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } else if ($) { + return $(el).clone(true)[0]; + } else { + return el.cloneNode(true); + } +} + +function setRect(el, rect) { + css(el, 'position', 'absolute'); + css(el, 'top', rect.top); + css(el, 'left', rect.left); + css(el, 'width', rect.width); + css(el, 'height', rect.height); +} + +function unsetRect(el) { + css(el, 'position', ''); + css(el, 'top', ''); + css(el, 'left', ''); + css(el, 'width', ''); + css(el, 'height', ''); +} + +var expando = 'Sortable' + new Date().getTime(); + +function AnimationStateManager() { + var animationStates = [], + animationCallbackId; + return { + captureAnimationState: function captureAnimationState() { + animationStates = []; + if (!this.options.animation) return; + var children = [].slice.call(this.el.children); + children.forEach(function (child) { + if (css(child, 'display') === 'none' || child === Sortable.ghost) return; + animationStates.push({ + target: child, + rect: getRect(child) + }); + + var fromRect = _objectSpread({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation + + + if (child.thisAnimationDuration) { + var childMatrix = matrix(child, true); + + if (childMatrix) { + fromRect.top -= childMatrix.f; + fromRect.left -= childMatrix.e; + } + } + + child.fromRect = fromRect; + }); + }, + addAnimationState: function addAnimationState(state) { + animationStates.push(state); + }, + removeAnimationState: function removeAnimationState(target) { + animationStates.splice(indexOfObject(animationStates, { + target: target + }), 1); + }, + animateAll: function animateAll(callback) { + var _this = this; + + if (!this.options.animation) { + clearTimeout(animationCallbackId); + if (typeof callback === 'function') callback(); + return; + } + + var animating = false, + animationTime = 0; + animationStates.forEach(function (state) { + var time = 0, + target = state.target, + fromRect = target.fromRect, + toRect = getRect(target), + prevFromRect = target.prevFromRect, + prevToRect = target.prevToRect, + animatingRect = state.rect, + targetMatrix = matrix(target, true); + + if (targetMatrix) { + // Compensate for current animation + toRect.top -= targetMatrix.f; + toRect.left -= targetMatrix.e; + } + + target.toRect = toRect; + + if (target.thisAnimationDuration) { + // Could also check if animatingRect is between fromRect and toRect + if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect + (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) { + // If returning to same place as started from animation and on same axis + time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options); + } + } // if fromRect != toRect: animate + + + if (!isRectEqual(toRect, fromRect)) { + target.prevFromRect = fromRect; + target.prevToRect = toRect; + + if (!time) { + time = _this.options.animation; + } + + _this.animate(target, animatingRect, toRect, time); + } + + if (time) { + animating = true; + animationTime = Math.max(animationTime, time); + clearTimeout(target.animationResetTimer); + target.animationResetTimer = setTimeout(function () { + target.animationTime = 0; + target.prevFromRect = null; + target.fromRect = null; + target.prevToRect = null; + target.thisAnimationDuration = null; + }, time); + target.thisAnimationDuration = time; + } + }); + clearTimeout(animationCallbackId); + + if (!animating) { + if (typeof callback === 'function') callback(); + } else { + animationCallbackId = setTimeout(function () { + if (typeof callback === 'function') callback(); + }, animationTime); + } + + animationStates = []; + }, + animate: function animate(target, currentRect, toRect, duration) { + if (duration) { + css(target, 'transition', ''); + css(target, 'transform', ''); + var elMatrix = matrix(this.el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d, + translateX = (currentRect.left - toRect.left) / (scaleX || 1), + translateY = (currentRect.top - toRect.top) / (scaleY || 1); + target.animatingX = !!translateX; + target.animatingY = !!translateY; + css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); + repaint(target); // repaint + + css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); + css(target, 'transform', 'translate3d(0,0,0)'); + typeof target.animated === 'number' && clearTimeout(target.animated); + target.animated = setTimeout(function () { + css(target, 'transition', ''); + css(target, 'transform', ''); + target.animated = false; + target.animatingX = false; + target.animatingY = false; + }, duration); + } + } + }; +} + +function repaint(target) { + return target.offsetWidth; +} + +function calculateRealTime(animatingRect, fromRect, toRect, options) { + return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation; +} + +var plugins = []; +var defaults = { + initializeByDefault: true +}; +var PluginManager = { + mount: function mount(plugin) { + // Set default static properties + for (var option in defaults) { + if (defaults.hasOwnProperty(option) && !(option in plugin)) { + plugin[option] = defaults[option]; + } + } + + plugins.push(plugin); + }, + pluginEvent: function pluginEvent(eventName, sortable, evt) { + var _this = this; + + this.eventCanceled = false; + + evt.cancel = function () { + _this.eventCanceled = true; + }; + + var eventNameGlobal = eventName + 'Global'; + plugins.forEach(function (plugin) { + if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable + + if (sortable[plugin.pluginName][eventNameGlobal]) { + sortable[plugin.pluginName][eventNameGlobal](_objectSpread({ + sortable: sortable + }, evt)); + } // Only fire plugin event if plugin is enabled in this sortable, + // and plugin has event defined + + + if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { + sortable[plugin.pluginName][eventName](_objectSpread({ + sortable: sortable + }, evt)); + } + }); + }, + initializePlugins: function initializePlugins(sortable, el, defaults, options) { + plugins.forEach(function (plugin) { + var pluginName = plugin.pluginName; + if (!sortable.options[pluginName] && !plugin.initializeByDefault) return; + var initialized = new plugin(sortable, el, sortable.options); + initialized.sortable = sortable; + initialized.options = sortable.options; + sortable[pluginName] = initialized; // Add default options from plugin + + _extends(defaults, initialized.defaults); + }); + + for (var option in sortable.options) { + if (!sortable.options.hasOwnProperty(option)) continue; + var modified = this.modifyOption(sortable, option, sortable.options[option]); + + if (typeof modified !== 'undefined') { + sortable.options[option] = modified; + } + } + }, + getEventProperties: function getEventProperties(name, sortable) { + var eventProperties = {}; + plugins.forEach(function (plugin) { + if (typeof plugin.eventProperties !== 'function') return; + + _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name)); + }); + return eventProperties; + }, + modifyOption: function modifyOption(sortable, name, value) { + var modifiedValue; + plugins.forEach(function (plugin) { + // Plugin must exist on the Sortable + if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin + + if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') { + modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value); + } + }); + return modifiedValue; + } +}; + +function dispatchEvent(_ref) { + var sortable = _ref.sortable, + rootEl = _ref.rootEl, + name = _ref.name, + targetEl = _ref.targetEl, + cloneEl = _ref.cloneEl, + toEl = _ref.toEl, + fromEl = _ref.fromEl, + oldIndex = _ref.oldIndex, + newIndex = _ref.newIndex, + oldDraggableIndex = _ref.oldDraggableIndex, + newDraggableIndex = _ref.newDraggableIndex, + originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + extraEventProperties = _ref.extraEventProperties; + sortable = sortable || rootEl && rootEl[expando]; + if (!sortable) return; + var evt, + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent(name, { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(name, true, true); + } + + evt.to = toEl || rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + evt.oldIndex = oldIndex; + evt.newIndex = newIndex; + evt.oldDraggableIndex = oldDraggableIndex; + evt.newDraggableIndex = newDraggableIndex; + evt.originalEvent = originalEvent; + evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; + + var allEventProperties = _objectSpread({}, extraEventProperties, PluginManager.getEventProperties(name, sortable)); + + for (var option in allEventProperties) { + evt[option] = allEventProperties[option]; + } + + if (rootEl) { + rootEl.dispatchEvent(evt); + } + + if (options[onName]) { + options[onName].call(sortable, evt); + } +} + +var pluginEvent = function pluginEvent(eventName, sortable) { + var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + originalEvent = _ref.evt, + data = _objectWithoutProperties(_ref, ["evt"]); + + PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread({ + dragEl: dragEl, + parentEl: parentEl, + ghostEl: ghostEl, + rootEl: rootEl, + nextEl: nextEl, + lastDownEl: lastDownEl, + cloneEl: cloneEl, + cloneHidden: cloneHidden, + dragStarted: moved, + putSortable: putSortable, + activeSortable: Sortable.active, + originalEvent: originalEvent, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + hideGhostForTarget: _hideGhostForTarget, + unhideGhostForTarget: _unhideGhostForTarget, + cloneNowHidden: function cloneNowHidden() { + cloneHidden = true; + }, + cloneNowShown: function cloneNowShown() { + cloneHidden = false; + }, + dispatchSortableEvent: function dispatchSortableEvent(name) { + _dispatchEvent({ + sortable: sortable, + name: name, + originalEvent: originalEvent + }); + } + }, data)); +}; + +function _dispatchEvent(info) { + dispatchEvent(_objectSpread({ + putSortable: putSortable, + cloneEl: cloneEl, + targetEl: dragEl, + rootEl: rootEl, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex + }, info)); +} + +var dragEl, + parentEl, + ghostEl, + rootEl, + nextEl, + lastDownEl, + cloneEl, + cloneHidden, + oldIndex, + newIndex, + oldDraggableIndex, + newDraggableIndex, + activeGroup, + putSortable, + awaitingDragStarted = false, + ignoreNextClick = false, + sortables = [], + tapEvt, + touchEvt, + lastDx, + lastDy, + tapDistanceLeft, + tapDistanceTop, + moved, + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + targetMoveDistance, + // For positioning ghost absolutely +ghostRelativeParent, + ghostRelativeParentInitialScroll = [], + // (left, top) +_silent = false, + savedInputChecked = []; +/** @const */ + +var documentExists = typeof document !== 'undefined', + PositionGhostAbsolutely = IOS, + CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', + // This will not pass for IE9, because IE9 DnD only works on anchors +supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), + supportCssPointerEvents = function () { + if (!documentExists) return; // false when <= IE11 + + if (IE11OrLess) { + return false; + } + + var el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; +}(), + _detectDirection = function _detectDirection(el, options) { + var elCSS = css(el), + elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), + child1 = getChild(el, 0, options), + child2 = getChild(el, 1, options), + firstChildCSS = child1 && css(child1), + secondChildCSS = child2 && css(child2), + firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, + secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; + + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; + } + + if (elCSS.display === 'grid') { + return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; + } + + if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') { + var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; + return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; + } + + return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal'; +}, + _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) { + var dragElS1Opp = vertical ? dragRect.left : dragRect.top, + dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, + dragElOppLength = vertical ? dragRect.width : dragRect.height, + targetS1Opp = vertical ? targetRect.left : targetRect.top, + targetS2Opp = vertical ? targetRect.right : targetRect.bottom, + targetOppLength = vertical ? targetRect.width : targetRect.height; + return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2; +}, + +/** + * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. + * @param {Number} x X position + * @param {Number} y Y position + * @return {HTMLElement} Element of the first found nearest Sortable + */ +_detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { + var ret; + sortables.some(function (sortable) { + if (lastChild(sortable)) return; + var rect = getRect(sortable), + threshold = sortable[expando].options.emptyInsertThreshold, + insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, + insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; + + if (threshold && insideHorizontally && insideVertically) { + return ret = sortable; + } + }); + return ret; +}, + _prepareGroup = function _prepareGroup(options) { + function toFn(value, pull) { + return function (to, from, dragEl, evt) { + var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name; + + if (value == null && (pull || sameGroup)) { + // Default pull value + // Default pull and put value if same group + return true; + } else if (value == null || value === false) { + return false; + } else if (pull && value === 'clone') { + return value; + } else if (typeof value === 'function') { + return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); + } else { + var otherGroup = (pull ? to : from).options.group.name; + return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1; + } + }; + } + + var group = {}; + var originalGroup = options.group; + + if (!originalGroup || _typeof(originalGroup) != 'object') { + originalGroup = { + name: originalGroup + }; + } + + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + options.group = group; +}, + _hideGhostForTarget = function _hideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', 'none'); + } +}, + _unhideGhostForTarget = function _unhideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', ''); + } +}; // #1184 fix - Prevent click event on fallback if dragged but item not changed position + + +if (documentExists) { + document.addEventListener('click', function (evt) { + if (ignoreNextClick) { + evt.preventDefault(); + evt.stopPropagation && evt.stopPropagation(); + evt.stopImmediatePropagation && evt.stopImmediatePropagation(); + ignoreNextClick = false; + return false; + } + }, true); +} + +var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) { + if (dragEl) { + evt = evt.touches ? evt.touches[0] : evt; + + var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); + + if (nearest) { + // Create imitation event + var event = {}; + + for (var i in evt) { + if (evt.hasOwnProperty(i)) { + event[i] = evt[i]; + } + } + + event.target = event.rootEl = nearest; + event.preventDefault = void 0; + event.stopPropagation = void 0; + + nearest[expando]._onDragOver(event); + } + } +}; + +var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) { + if (dragEl) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); + } +}; +/** + * @class Sortable + * @param {HTMLElement} el + * @param {Object} [options] + */ + + +function Sortable(el, options) { + if (!(el && el.nodeType && el.nodeType === 1)) { + throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); + } + + this.el = el; // root element + + this.options = options = _extends({}, options); // Export instance + + el[expando] = this; + var defaults = { + group: null, + sort: true, + disabled: false, + store: null, + handle: null, + draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*', + swapThreshold: 1, + // percentage; 0 <= x <= 1 + invertSwap: false, + // invert always + invertedSwapThreshold: null, + // will be set to same as swapThreshold if default + removeCloneOnHide: true, + direction: function direction() { + return _detectDirection(el, this.options); + }, + ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', + dragClass: 'sortable-drag', + ignore: 'a, img', + filter: null, + preventOnFilter: true, + animation: 0, + easing: null, + setData: function setData(dataTransfer, dragEl) { + dataTransfer.setData('Text', dragEl.textContent); + }, + dropBubble: false, + dragoverBubble: false, + dataIdAttr: 'data-id', + delay: 0, + delayOnTouchOnly: false, + touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false, + fallbackTolerance: 0, + fallbackOffset: { + x: 0, + y: 0 + }, + supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window, + emptyInsertThreshold: 5 + }; + PluginManager.initializePlugins(this, el, defaults); // Set default options + + for (var name in defaults) { + !(name in options) && (options[name] = defaults[name]); + } + + _prepareGroup(options); // Bind all private methods + + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } // Setup drag mode + + + this.nativeDraggable = options.forceFallback ? false : supportDraggable; + + if (this.nativeDraggable) { + // Touch start threshold cannot be greater than the native dragstart threshold + this.options.touchStartThreshold = 1; + } // Bind events + + + if (options.supportPointer) { + on(el, 'pointerdown', this._onTapStart); + } else { + on(el, 'mousedown', this._onTapStart); + on(el, 'touchstart', this._onTapStart); + } + + if (this.nativeDraggable) { + on(el, 'dragover', this); + on(el, 'dragenter', this); + } + + sortables.push(this.el); // Restore sorting + + options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager + + _extends(this, AnimationStateManager()); +} + +Sortable.prototype = +/** @lends Sortable.prototype */ +{ + constructor: Sortable, + _isOutsideThisEl: function _isOutsideThisEl(target) { + if (!this.el.contains(target) && target !== this.el) { + lastTarget = null; + } + }, + _getDirection: function _getDirection(evt, target) { + return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; + }, + _onTapStart: function _onTapStart( + /** Event|TouchEvent */ + evt) { + if (!evt.cancelable) return; + + var _this = this, + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt, + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, + filter = options.filter; + + _saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. + + + if (dragEl) { + return; + } + + if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { + return; // only left button and enabled + } // cancel dnd if original target is content editable + + + if (originalTarget.isContentEditable) { + return; + } + + target = closest(target, options.draggable, el, false); + + if (target && target.animated) { + return; + } + + if (lastDownEl === target) { + // Ignoring duplicate `down` + return; + } // Get the index of the dragged element within its parent + + + oldIndex = index(target); + oldDraggableIndex = index(target, options.draggable); // Check filter + + if (typeof filter === 'function') { + if (filter.call(this, evt, target, this)) { + _dispatchEvent({ + sortable: _this, + rootEl: originalTarget, + name: 'filter', + targetEl: target, + toEl: el, + fromEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } else if (filter) { + filter = filter.split(',').some(function (criteria) { + criteria = closest(originalTarget, criteria.trim(), el, false); + + if (criteria) { + _dispatchEvent({ + sortable: _this, + rootEl: criteria, + name: 'filter', + targetEl: target, + fromEl: el, + toEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + return true; + } + }); + + if (filter) { + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + + if (options.handle && !closest(originalTarget, options.handle, el, false)) { + return; + } // Prepare `dragstart` + + + this._prepareDragStart(evt, touch, target); + }, + _prepareDragStart: function _prepareDragStart( + /** Event */ + evt, + /** Touch */ + touch, + /** HTMLElement */ + target) { + var _this = this, + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; + + if (target && !dragEl && target.parentNode === el) { + var dragRect = getRect(target); + rootEl = el; + dragEl = target; + parentEl = dragEl.parentNode; + nextEl = dragEl.nextSibling; + lastDownEl = target; + activeGroup = options.group; + Sortable.dragged = dragEl; + tapEvt = { + target: dragEl, + clientX: (touch || evt).clientX, + clientY: (touch || evt).clientY + }; + tapDistanceLeft = tapEvt.clientX - dragRect.left; + tapDistanceTop = tapEvt.clientY - dragRect.top; + this._lastX = (touch || evt).clientX; + this._lastY = (touch || evt).clientY; + dragEl.style['will-change'] = 'all'; + + dragStartFn = function dragStartFn() { + pluginEvent('delayEnded', _this, { + evt: evt + }); + + if (Sortable.eventCanceled) { + _this._onDrop(); + + return; + } // Delayed drag has been triggered + // we can re-enable the events: touchmove/mousemove + + + _this._disableDelayedDragEvents(); + + if (!FireFox && _this.nativeDraggable) { + dragEl.draggable = true; + } // Bind the events: dragstart/dragend + + + _this._triggerDragStart(evt, touch); // Drag start event + + + _dispatchEvent({ + sortable: _this, + name: 'choose', + originalEvent: evt + }); // Chosen item + + + toggleClass(dragEl, options.chosenClass, true); + }; // Disable "draggable" + + + options.ignore.split(',').forEach(function (criteria) { + find(dragEl, criteria.trim(), _disableDraggable); + }); + on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mouseup', _this._onDrop); + on(ownerDocument, 'touchend', _this._onDrop); + on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox) + + if (FireFox && this.nativeDraggable) { + this.options.touchStartThreshold = 4; + dragEl.draggable = true; + } + + pluginEvent('delayStart', this, { + evt: evt + }); // Delay is impossible for native DnD in Edge or IE + + if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { + if (Sortable.eventCanceled) { + this._onDrop(); + + return; + } // If the user moves the pointer or let go the click or touch + // before the delay has been reached: + // disable the delayed drag + + + on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + on(ownerDocument, 'touchend', _this._disableDelayedDrag); + on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); + on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); + options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); + _this._dragStartTimer = setTimeout(dragStartFn, options.delay); + } else { + dragStartFn(); + } + } + }, + _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( + /** TouchEvent|PointerEvent **/ + e) { + var touch = e.touches ? e.touches[0] : e; + + if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) { + this._disableDelayedDrag(); + } + }, + _disableDelayedDrag: function _disableDelayedDrag() { + dragEl && _disableDraggable(dragEl); + clearTimeout(this._dragStartTimer); + + this._disableDelayedDragEvents(); + }, + _disableDelayedDragEvents: function _disableDelayedDragEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._disableDelayedDrag); + off(ownerDocument, 'touchend', this._disableDelayedDrag); + off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); + }, + _triggerDragStart: function _triggerDragStart( + /** Event */ + evt, + /** Touch */ + touch) { + touch = touch || evt.pointerType == 'touch' && evt; + + if (!this.nativeDraggable || touch) { + if (this.options.supportPointer) { + on(document, 'pointermove', this._onTouchMove); + } else if (touch) { + on(document, 'touchmove', this._onTouchMove); + } else { + on(document, 'mousemove', this._onTouchMove); + } + } else { + on(dragEl, 'dragend', this); + on(rootEl, 'dragstart', this._onDragStart); + } + + try { + if (document.selection) { + // Timeout neccessary for IE9 + _nextTick(function () { + document.selection.empty(); + }); + } else { + window.getSelection().removeAllRanges(); + } + } catch (err) {} + }, + _dragStarted: function _dragStarted(fallback, evt) { + + awaitingDragStarted = false; + + if (rootEl && dragEl) { + pluginEvent('dragStarted', this, { + evt: evt + }); + + if (this.nativeDraggable) { + on(document, 'dragover', _checkOutsideTargetEl); + } + + var options = this.options; // Apply effect + + !fallback && toggleClass(dragEl, options.dragClass, false); + toggleClass(dragEl, options.ghostClass, true); + Sortable.active = this; + fallback && this._appendGhost(); // Drag start event + + _dispatchEvent({ + sortable: this, + name: 'start', + originalEvent: evt + }); + } else { + this._nulling(); + } + }, + _emulateDragOver: function _emulateDragOver() { + if (touchEvt) { + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + _hideGhostForTarget(); + + var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + var parent = target; + + while (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + if (target === parent) break; + parent = target; + } + + dragEl.parentNode[expando]._isOutsideThisEl(target); + + if (parent) { + do { + if (parent[expando]) { + var inserted = void 0; + inserted = parent[expando]._onDragOver({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + + if (inserted && !this.options.dragoverBubble) { + break; + } + } + + target = parent; // store last element + } + /* jshint boss:true */ + while (parent = parent.parentNode); + } + + _unhideGhostForTarget(); + } + }, + _onTouchMove: function _onTouchMove( + /**TouchEvent*/ + evt) { + if (tapEvt) { + var options = this.options, + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + ghostMatrix = ghostEl && matrix(ghostEl), + scaleX = ghostEl && ghostMatrix && ghostMatrix.a, + scaleY = ghostEl && ghostMatrix && ghostMatrix.d, + relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), + dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), + dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging + + if (!Sortable.active && !awaitingDragStarted) { + if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { + return; + } + + this._onDragStart(evt, true); + } + + if (ghostEl) { + if (ghostMatrix) { + ghostMatrix.e += dx - (lastDx || 0); + ghostMatrix.f += dy - (lastDy || 0); + } else { + ghostMatrix = { + a: 1, + b: 0, + c: 0, + d: 1, + e: dx, + f: dy + }; + } + + var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")"); + css(ghostEl, 'webkitTransform', cssMatrix); + css(ghostEl, 'mozTransform', cssMatrix); + css(ghostEl, 'msTransform', cssMatrix); + css(ghostEl, 'transform', cssMatrix); + lastDx = dx; + lastDy = dy; + touchEvt = touch; + } + + evt.cancelable && evt.preventDefault(); + } + }, + _appendGhost: function _appendGhost() { + // Bug if using scale(): https://stackoverflow.com/questions/2637058 + // Not being adjusted for + if (!ghostEl) { + var container = this.options.fallbackOnBody ? document.body : rootEl, + rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), + options = this.options; // Position absolutely + + if (PositionGhostAbsolutely) { + // Get relatively positioned parent + ghostRelativeParent = container; + + while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) { + ghostRelativeParent = ghostRelativeParent.parentNode; + } + + if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { + if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement(); + rect.top += ghostRelativeParent.scrollTop; + rect.left += ghostRelativeParent.scrollLeft; + } else { + ghostRelativeParent = getWindowScrollingElement(); + } + + ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent); + } + + ghostEl = dragEl.cloneNode(true); + toggleClass(ghostEl, options.ghostClass, false); + toggleClass(ghostEl, options.fallbackClass, true); + toggleClass(ghostEl, options.dragClass, true); + css(ghostEl, 'transition', ''); + css(ghostEl, 'transform', ''); + css(ghostEl, 'box-sizing', 'border-box'); + css(ghostEl, 'margin', 0); + css(ghostEl, 'top', rect.top); + css(ghostEl, 'left', rect.left); + css(ghostEl, 'width', rect.width); + css(ghostEl, 'height', rect.height); + css(ghostEl, 'opacity', '0.8'); + css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed'); + css(ghostEl, 'zIndex', '100000'); + css(ghostEl, 'pointerEvents', 'none'); + Sortable.ghost = ghostEl; + container.appendChild(ghostEl); // Set transform-origin + + css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%'); + } + }, + _onDragStart: function _onDragStart( + /**Event*/ + evt, + /**boolean*/ + fallback) { + var _this = this; + + var dataTransfer = evt.dataTransfer; + var options = _this.options; + pluginEvent('dragStart', this, { + evt: evt + }); + + if (Sortable.eventCanceled) { + this._onDrop(); + + return; + } + + pluginEvent('setupClone', this); + + if (!Sortable.eventCanceled) { + cloneEl = clone(dragEl); + cloneEl.draggable = false; + cloneEl.style['will-change'] = ''; + + this._hideClone(); + + toggleClass(cloneEl, this.options.chosenClass, false); + Sortable.clone = cloneEl; + } // #1143: IFrame support workaround + + + _this.cloneId = _nextTick(function () { + pluginEvent('clone', _this); + if (Sortable.eventCanceled) return; + + if (!_this.options.removeCloneOnHide) { + rootEl.insertBefore(cloneEl, dragEl); + } + + _this._hideClone(); + + _dispatchEvent({ + sortable: _this, + name: 'clone' + }); + }); + !fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events + + if (fallback) { + ignoreNextClick = true; + _this._loopId = setInterval(_this._emulateDragOver, 50); + } else { + // Undo what was set in _prepareDragStart before drag started + off(document, 'mouseup', _this._onDrop); + off(document, 'touchend', _this._onDrop); + off(document, 'touchcancel', _this._onDrop); + + if (dataTransfer) { + dataTransfer.effectAllowed = 'move'; + options.setData && options.setData.call(_this, dataTransfer, dragEl); + } + + on(document, 'drop', _this); // #1276 fix: + + css(dragEl, 'transform', 'translateZ(0)'); + } + + awaitingDragStarted = true; + _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); + on(document, 'selectstart', _this); + moved = true; + + if (Safari) { + css(document.body, 'user-select', 'none'); + } + }, + // Returns true - if no further action is needed (either inserted or another condition) + _onDragOver: function _onDragOver( + /**Event*/ + evt) { + var el = this.el, + target = evt.target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable.active, + isOwner = activeGroup === group, + canSort = options.sort, + fromSortable = putSortable || activeSortable, + vertical, + _this = this, + completedFired = false; + + if (_silent) return; + + function dragOverEvent(name, extra) { + pluginEvent(name, _this, _objectSpread({ + evt: evt, + isOwner: isOwner, + axis: vertical ? 'vertical' : 'horizontal', + revert: revert, + dragRect: dragRect, + targetRect: targetRect, + canSort: canSort, + fromSortable: fromSortable, + target: target, + completed: completed, + onMove: function onMove(target, after) { + return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after); + }, + changed: changed + }, extra)); + } // Capture animation state + + + function capture() { + dragOverEvent('dragOverAnimationCapture'); + + _this.captureAnimationState(); + + if (_this !== fromSortable) { + fromSortable.captureAnimationState(); + } + } // Return invocation when dragEl is inserted (or completed) + + + function completed(insertion) { + dragOverEvent('dragOverCompleted', { + insertion: insertion + }); + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(_this); + } + + if (_this !== fromSortable) { + // Set ghost class to new sortable's ghost class + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); + toggleClass(dragEl, options.ghostClass, true); + } + + if (putSortable !== _this && _this !== Sortable.active) { + putSortable = _this; + } else if (_this === Sortable.active && putSortable) { + putSortable = null; + } // Animation + + + if (fromSortable === _this) { + _this._ignoreWhileAnimating = target; + } + + _this.animateAll(function () { + dragOverEvent('dragOverAnimationComplete'); + _this._ignoreWhileAnimating = null; + }); + + if (_this !== fromSortable) { + fromSortable.animateAll(); + fromSortable._ignoreWhileAnimating = null; + } + } // Null lastTarget if it is not inside a previously swapped element + + + if (target === dragEl && !dragEl.animated || target === el && !target.animated) { + lastTarget = null; + } // no bubbling and not fallback + + + if (!options.dragoverBubble && !evt.rootEl && target !== document) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted + + + !insertion && nearestEmptyInsertDetectEvent(evt); + } + + !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); + return completedFired = true; + } // Call when dragEl has been inserted + + + function changed() { + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + _dispatchEvent({ + sortable: _this, + name: 'change', + toEl: el, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + originalEvent: evt + }); + } + + if (evt.preventDefault !== void 0) { + evt.cancelable && evt.preventDefault(); + } + + target = closest(target, options.draggable, el, true); + dragOverEvent('dragOver'); + if (Sortable.eventCanceled) return completedFired; + + if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) { + return completed(false); + } + + ignoreNextClick = false; + + if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) { + vertical = this._getDirection(evt, target) === 'vertical'; + dragRect = getRect(dragEl); + dragOverEvent('dragOverValid'); + if (Sortable.eventCanceled) return completedFired; + + if (revert) { + parentEl = rootEl; // actualization + + capture(); + + this._hideClone(); + + dragOverEvent('revert'); + + if (!Sortable.eventCanceled) { + if (nextEl) { + rootEl.insertBefore(dragEl, nextEl); + } else { + rootEl.appendChild(dragEl); + } + } + + return completed(true); + } + + var elLastChild = lastChild(el, options.draggable); + + if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { + // If already at end of list: Do not insert + if (elLastChild === dragEl) { + return completed(false); + } // assign target only if condition is true + + + if (elLastChild && el === evt.target) { + target = elLastChild; + } + + if (target) { + targetRect = getRect(target); + } + + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { + capture(); + el.appendChild(dragEl); + parentEl = el; // actualization + + changed(); + return completed(true); + } + } else if (target.parentNode === el) { + targetRect = getRect(target); + var direction = 0, + targetBeforeFirstSwap, + differentLevel = dragEl.parentNode !== el, + differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), + side1 = vertical ? 'top' : 'left', + scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), + scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; + + if (lastTarget !== target) { + targetBeforeFirstSwap = targetRect[side1]; + pastFirstInvertThresh = false; + isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel; + } + + direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); + var sibling; + + if (direction !== 0) { + // Check if target is beside dragEl in respective direction (ignoring hidden elements) + var dragIndex = index(dragEl); + + do { + dragIndex -= direction; + sibling = parentEl.children[dragIndex]; + } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl)); + } // If dragEl is already beside target: Do not insert + + + if (direction === 0 || sibling === target) { + return completed(false); + } + + lastTarget = target; + lastDirection = direction; + var nextSibling = target.nextElementSibling, + after = false; + after = direction === 1; + + var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); + + if (moveVector !== false) { + if (moveVector === 1 || moveVector === -1) { + after = moveVector === 1; + } + + _silent = true; + setTimeout(_unsilent, 30); + capture(); + + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } // Undo chrome's scroll adjustment (has no effect on other browsers) + + + if (scrolledPastTop) { + scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); + } + + parentEl = dragEl.parentNode; // actualization + // must be done before animation + + if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { + targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]); + } + + changed(); + return completed(true); + } + } + + if (el.contains(dragEl)) { + return completed(false); + } + } + + return false; + }, + _ignoreWhileAnimating: null, + _offMoveEvents: function _offMoveEvents() { + off(document, 'mousemove', this._onTouchMove); + off(document, 'touchmove', this._onTouchMove); + off(document, 'pointermove', this._onTouchMove); + off(document, 'dragover', nearestEmptyInsertDetectEvent); + off(document, 'mousemove', nearestEmptyInsertDetectEvent); + off(document, 'touchmove', nearestEmptyInsertDetectEvent); + }, + _offUpEvents: function _offUpEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._onDrop); + off(ownerDocument, 'touchend', this._onDrop); + off(ownerDocument, 'pointerup', this._onDrop); + off(ownerDocument, 'touchcancel', this._onDrop); + off(document, 'selectstart', this); + }, + _onDrop: function _onDrop( + /**Event*/ + evt) { + var el = this.el, + options = this.options; // Get the index of the dragged element within its parent + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + pluginEvent('drop', this, { + evt: evt + }); + parentEl = dragEl && dragEl.parentNode; // Get again after plugin event + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + if (Sortable.eventCanceled) { + this._nulling(); + + return; + } + + awaitingDragStarted = false; + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + clearInterval(this._loopId); + clearTimeout(this._dragStartTimer); + + _cancelNextTick(this.cloneId); + + _cancelNextTick(this._dragStartId); // Unbind events + + + if (this.nativeDraggable) { + off(document, 'drop', this); + off(el, 'dragstart', this._onDragStart); + } + + this._offMoveEvents(); + + this._offUpEvents(); + + if (Safari) { + css(document.body, 'user-select', ''); + } + + if (evt) { + if (moved) { + evt.cancelable && evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } + + ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + // Remove clone(s) + cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); + } + + if (dragEl) { + if (this.nativeDraggable) { + off(dragEl, 'dragend', this); + } + + _disableDraggable(dragEl); + + dragEl.style['will-change'] = ''; // Remove classes + // ghostClass is added in dragStarted + + if (moved && !awaitingDragStarted) { + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); + } + + toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event + + _dispatchEvent({ + sortable: this, + name: 'unchoose', + toEl: parentEl, + newIndex: null, + newDraggableIndex: null, + originalEvent: evt + }); + + if (rootEl !== parentEl) { + if (newIndex >= 0) { + // Add event + _dispatchEvent({ + rootEl: parentEl, + name: 'add', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); // Remove event + + + _dispatchEvent({ + sortable: this, + name: 'remove', + toEl: parentEl, + originalEvent: evt + }); // drag from one list and drop into another + + + _dispatchEvent({ + rootEl: parentEl, + name: 'sort', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + + putSortable && putSortable.save(); + } else { + if (newIndex !== oldIndex) { + if (newIndex >= 0) { + // drag & drop within the same list + _dispatchEvent({ + sortable: this, + name: 'update', + toEl: parentEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + } + } + + if (Sortable.active) { + /* jshint eqnull:true */ + if (newIndex == null || newIndex === -1) { + newIndex = oldIndex; + newDraggableIndex = oldDraggableIndex; + } + + _dispatchEvent({ + sortable: this, + name: 'end', + toEl: parentEl, + originalEvent: evt + }); // Save sorting + + + this.save(); + } + } + } + + this._nulling(); + }, + _nulling: function _nulling() { + pluginEvent('nulling', this); + rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null; + savedInputChecked.forEach(function (el) { + el.checked = true; + }); + savedInputChecked.length = lastDx = lastDy = 0; + }, + handleEvent: function handleEvent( + /**Event*/ + evt) { + switch (evt.type) { + case 'drop': + case 'dragend': + this._onDrop(evt); + + break; + + case 'dragenter': + case 'dragover': + if (dragEl) { + this._onDragOver(evt); + + _globalDragOver(evt); + } + + break; + + case 'selectstart': + evt.preventDefault(); + break; + } + }, + + /** + * Serializes the item into an array of string. + * @returns {String[]} + */ + toArray: function toArray() { + var order = [], + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; + + for (; i < n; i++) { + el = children[i]; + + if (closest(el, options.draggable, this.el, false)) { + order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); + } + } + + return order; + }, + + /** + * Sorts the elements according to the array. + * @param {String[]} order order of the items + */ + sort: function sort(order) { + var items = {}, + rootEl = this.el; + this.toArray().forEach(function (id, i) { + var el = rootEl.children[i]; + + if (closest(el, this.options.draggable, rootEl, false)) { + items[id] = el; + } + }, this); + order.forEach(function (id) { + if (items[id]) { + rootEl.removeChild(items[id]); + rootEl.appendChild(items[id]); + } + }); + }, + + /** + * Save the current sorting + */ + save: function save() { + var store = this.options.store; + store && store.set && store.set(this); + }, + + /** + * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + * @param {HTMLElement} el + * @param {String} [selector] default: `options.draggable` + * @returns {HTMLElement|null} + */ + closest: function closest$1(el, selector) { + return closest(el, selector || this.options.draggable, this.el, false); + }, + + /** + * Set/get option + * @param {string} name + * @param {*} [value] + * @returns {*} + */ + option: function option(name, value) { + var options = this.options; + + if (value === void 0) { + return options[name]; + } else { + var modifiedValue = PluginManager.modifyOption(this, name, value); + + if (typeof modifiedValue !== 'undefined') { + options[name] = modifiedValue; + } else { + options[name] = value; + } + + if (name === 'group') { + _prepareGroup(options); + } + } + }, + + /** + * Destroy + */ + destroy: function destroy() { + pluginEvent('destroy', this); + var el = this.el; + el[expando] = null; + off(el, 'mousedown', this._onTapStart); + off(el, 'touchstart', this._onTapStart); + off(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + off(el, 'dragover', this); + off(el, 'dragenter', this); + } // Remove draggable attributes + + + Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { + el.removeAttribute('draggable'); + }); + + this._onDrop(); + + sortables.splice(sortables.indexOf(this.el), 1); + this.el = el = null; + }, + _hideClone: function _hideClone() { + if (!cloneHidden) { + pluginEvent('hideClone', this); + if (Sortable.eventCanceled) return; + css(cloneEl, 'display', 'none'); + + if (this.options.removeCloneOnHide && cloneEl.parentNode) { + cloneEl.parentNode.removeChild(cloneEl); + } + + cloneHidden = true; + } + }, + _showClone: function _showClone(putSortable) { + if (putSortable.lastPutMode !== 'clone') { + this._hideClone(); + + return; + } + + if (cloneHidden) { + pluginEvent('showClone', this); + if (Sortable.eventCanceled) return; // show clone at dragEl or original position + + if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + rootEl.insertBefore(cloneEl, dragEl); + } else if (nextEl) { + rootEl.insertBefore(cloneEl, nextEl); + } else { + rootEl.appendChild(cloneEl); + } + + if (this.options.group.revertClone) { + this.animate(dragEl, cloneEl); + } + + css(cloneEl, 'display', ''); + cloneHidden = false; + } + } +}; + +function _globalDragOver( +/**Event*/ +evt) { + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } + + evt.cancelable && evt.preventDefault(); +} + +function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) { + var evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent('move', { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + } + + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || getRect(toEl); + evt.willInsertAfter = willInsertAfter; + evt.originalEvent = originalEvent; + fromEl.dispatchEvent(evt); + + if (onMoveFn) { + retVal = onMoveFn.call(sortable, evt, originalEvent); + } + + return retVal; +} + +function _disableDraggable(el) { + el.draggable = false; +} + +function _unsilent() { + _silent = false; +} + +function _ghostIsLast(evt, vertical, sortable) { + var rect = getRect(lastChild(sortable.el, sortable.options.draggable)); + var spacer = 10; + return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer; +} + +function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { + var mouseOnAxis = vertical ? evt.clientY : evt.clientX, + targetLength = vertical ? targetRect.height : targetRect.width, + targetS1 = vertical ? targetRect.top : targetRect.left, + targetS2 = vertical ? targetRect.bottom : targetRect.right, + invert = false; + + if (!invertSwap) { + // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold + if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { + // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 + // check if past first invert threshold on side opposite of lastDirection + if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) { + // past first invert threshold, do not restrict inverted threshold to dragEl shadow + pastFirstInvertThresh = true; + } + + if (!pastFirstInvertThresh) { + // dragEl shadow (target move distance shadow) + if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow + : mouseOnAxis > targetS2 - targetMoveDistance) { + return -lastDirection; + } + } else { + invert = true; + } + } else { + // Regular + if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) { + return _getInsertDirection(target); + } + } + } + + invert = invert || invertSwap; + + if (invert) { + // Invert of regular + if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) { + return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1; + } + } + + return 0; +} +/** + * Gets the direction dragEl must be swapped relative to target in order to make it + * seem that dragEl has been "inserted" into that element's position + * @param {HTMLElement} target The target whose position dragEl is being inserted at + * @return {Number} Direction dragEl must be swapped + */ + + +function _getInsertDirection(target) { + if (index(dragEl) < index(target)) { + return 1; + } else { + return -1; + } +} +/** + * Generate id + * @param {HTMLElement} el + * @returns {String} + * @private + */ + + +function _generateId(el) { + var str = el.tagName + el.className + el.src + el.href + el.textContent, + i = str.length, + sum = 0; + + while (i--) { + sum += str.charCodeAt(i); + } + + return sum.toString(36); +} + +function _saveInputCheckedState(root) { + savedInputChecked.length = 0; + var inputs = root.getElementsByTagName('input'); + var idx = inputs.length; + + while (idx--) { + var el = inputs[idx]; + el.checked && savedInputChecked.push(el); + } +} + +function _nextTick(fn) { + return setTimeout(fn, 0); +} + +function _cancelNextTick(id) { + return clearTimeout(id); +} // Fixed #973: + + +if (documentExists) { + on(document, 'touchmove', function (evt) { + if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { + evt.preventDefault(); + } + }); +} // Export utils + + +Sortable.utils = { + on: on, + off: off, + css: css, + find: find, + is: function is(el, selector) { + return !!closest(el, selector, el, false); + }, + extend: extend, + throttle: throttle, + closest: closest, + toggleClass: toggleClass, + clone: clone, + index: index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick, + detectDirection: _detectDirection, + getChild: getChild +}; +/** + * Get the Sortable instance of an element + * @param {HTMLElement} element The element + * @return {Sortable|undefined} The instance of Sortable + */ + +Sortable.get = function (element) { + return element[expando]; +}; +/** + * Mount a plugin to Sortable + * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted + */ + + +Sortable.mount = function () { + for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { + plugins[_key] = arguments[_key]; + } + + if (plugins[0].constructor === Array) plugins = plugins[0]; + plugins.forEach(function (plugin) { + if (!plugin.prototype || !plugin.prototype.constructor) { + throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin)); + } + + if (plugin.utils) Sortable.utils = _objectSpread({}, Sortable.utils, plugin.utils); + PluginManager.mount(plugin); + }); +}; +/** + * Create sortable instance + * @param {HTMLElement} el + * @param {Object} [options] + */ + + +Sortable.create = function (el, options) { + return new Sortable(el, options); +}; // Export + + +Sortable.version = version; + +var autoScrolls = [], + scrollEl, + scrollRootEl, + scrolling = false, + lastAutoScrollX, + lastAutoScrollY, + touchEvt$1, + pointerElemChangedInterval; + +function AutoScrollPlugin() { + function AutoScroll() { + this.defaults = { + scroll: true, + scrollSensitivity: 30, + scrollSpeed: 10, + bubbleScroll: true + }; // Bind all private methods + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + } + + AutoScroll.prototype = { + dragStarted: function dragStarted(_ref) { + var originalEvent = _ref.originalEvent; + + if (this.sortable.nativeDraggable) { + on(document, 'dragover', this._handleAutoScroll); + } else { + if (this.options.supportPointer) { + on(document, 'pointermove', this._handleFallbackAutoScroll); + } else if (originalEvent.touches) { + on(document, 'touchmove', this._handleFallbackAutoScroll); + } else { + on(document, 'mousemove', this._handleFallbackAutoScroll); + } + } + }, + dragOverCompleted: function dragOverCompleted(_ref2) { + var originalEvent = _ref2.originalEvent; + + // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) + if (!this.options.dragOverBubble && !originalEvent.rootEl) { + this._handleAutoScroll(originalEvent); + } + }, + drop: function drop() { + if (this.sortable.nativeDraggable) { + off(document, 'dragover', this._handleAutoScroll); + } else { + off(document, 'pointermove', this._handleFallbackAutoScroll); + off(document, 'touchmove', this._handleFallbackAutoScroll); + off(document, 'mousemove', this._handleFallbackAutoScroll); + } + + clearPointerElemChangedInterval(); + clearAutoScrolls(); + cancelThrottle(); + }, + nulling: function nulling() { + touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null; + autoScrolls.length = 0; + }, + _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) { + this._handleAutoScroll(evt, true); + }, + _handleAutoScroll: function _handleAutoScroll(evt, fallback) { + var _this = this; + + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + elem = document.elementFromPoint(x, y); + touchEvt$1 = evt; // IE does not seem to have native autoscroll, + // Edge's autoscroll seems too conditional, + // MACOS Safari does not have autoscroll, + // Firefox and Chrome are good + + if (fallback || Edge || IE11OrLess || Safari) { + autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change + + var ogElemScroller = getParentAutoScrollElement(elem, true); + + if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) { + pointerElemChangedInterval && clearPointerElemChangedInterval(); // Detect for pointer elem change, emulating native DnD behaviour + + pointerElemChangedInterval = setInterval(function () { + var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true); + + if (newElem !== ogElemScroller) { + ogElemScroller = newElem; + clearAutoScrolls(); + } + + autoScroll(evt, _this.options, newElem, fallback); + }, 10); + lastAutoScrollX = x; + lastAutoScrollY = y; + } + } else { + // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll + if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { + clearAutoScrolls(); + return; + } + + autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false); + } + } + }; + return _extends(AutoScroll, { + pluginName: 'scroll', + initializeByDefault: true + }); +} + +function clearAutoScrolls() { + autoScrolls.forEach(function (autoScroll) { + clearInterval(autoScroll.pid); + }); + autoScrolls = []; +} + +function clearPointerElemChangedInterval() { + clearInterval(pointerElemChangedInterval); +} + +var autoScroll = throttle(function (evt, options, rootEl, isFallback) { + // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + if (!options.scroll) return; + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + sens = options.scrollSensitivity, + speed = options.scrollSpeed, + winScroller = getWindowScrollingElement(); + var scrollThisInstance = false, + scrollCustomFn; // New scroll root, set scrollEl + + if (scrollRootEl !== rootEl) { + scrollRootEl = rootEl; + clearAutoScrolls(); + scrollEl = options.scroll; + scrollCustomFn = options.scrollFn; + + if (scrollEl === true) { + scrollEl = getParentAutoScrollElement(rootEl, true); + } + } + + var layersOut = 0; + var currentParent = scrollEl; + + do { + var el = currentParent, + rect = getRect(el), + top = rect.top, + bottom = rect.bottom, + left = rect.left, + right = rect.right, + width = rect.width, + height = rect.height, + canScrollX = void 0, + canScrollY = void 0, + scrollWidth = el.scrollWidth, + scrollHeight = el.scrollHeight, + elCSS = css(el), + scrollPosX = el.scrollLeft, + scrollPosY = el.scrollTop; + + if (el === winScroller) { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible'); + } else { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); + } + + var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX); + var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY); + + if (!autoScrolls[layersOut]) { + for (var i = 0; i <= layersOut; i++) { + if (!autoScrolls[i]) { + autoScrolls[i] = {}; + } + } + } + + if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { + autoScrolls[layersOut].el = el; + autoScrolls[layersOut].vx = vx; + autoScrolls[layersOut].vy = vy; + clearInterval(autoScrolls[layersOut].pid); + + if (vx != 0 || vy != 0) { + scrollThisInstance = true; + /* jshint loopfunc:true */ + + autoScrolls[layersOut].pid = setInterval(function () { + // emulate drag over during autoscroll (fallback), emulating native DnD behaviour + if (isFallback && this.layer === 0) { + Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely + + } + + var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; + var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; + + if (typeof scrollCustomFn === 'function') { + if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') { + return; + } + } + + scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); + }.bind({ + layer: layersOut + }), 24); + } + } + + layersOut++; + } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false))); + + scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not +}, 30); + +var drop = function drop(_ref) { + var originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + dragEl = _ref.dragEl, + activeSortable = _ref.activeSortable, + dispatchSortableEvent = _ref.dispatchSortableEvent, + hideGhostForTarget = _ref.hideGhostForTarget, + unhideGhostForTarget = _ref.unhideGhostForTarget; + if (!originalEvent) return; + var toSortable = putSortable || activeSortable; + hideGhostForTarget(); + var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent; + var target = document.elementFromPoint(touch.clientX, touch.clientY); + unhideGhostForTarget(); + + if (toSortable && !toSortable.el.contains(target)) { + dispatchSortableEvent('spill'); + this.onSpill({ + dragEl: dragEl, + putSortable: putSortable + }); + } +}; + +function Revert() {} + +Revert.prototype = { + startIndex: null, + dragStart: function dragStart(_ref2) { + var oldDraggableIndex = _ref2.oldDraggableIndex; + this.startIndex = oldDraggableIndex; + }, + onSpill: function onSpill(_ref3) { + var dragEl = _ref3.dragEl, + putSortable = _ref3.putSortable; + this.sortable.captureAnimationState(); + + if (putSortable) { + putSortable.captureAnimationState(); + } + + var nextSibling = getChild(this.sortable.el, this.startIndex, this.options); + + if (nextSibling) { + this.sortable.el.insertBefore(dragEl, nextSibling); + } else { + this.sortable.el.appendChild(dragEl); + } + + this.sortable.animateAll(); + + if (putSortable) { + putSortable.animateAll(); + } + }, + drop: drop +}; + +_extends(Revert, { + pluginName: 'revertOnSpill' +}); + +function Remove() {} + +Remove.prototype = { + onSpill: function onSpill(_ref4) { + var dragEl = _ref4.dragEl, + putSortable = _ref4.putSortable; + var parentSortable = putSortable || this.sortable; + parentSortable.captureAnimationState(); + dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); + parentSortable.animateAll(); + }, + drop: drop +}; + +_extends(Remove, { + pluginName: 'removeOnSpill' +}); + +var OnSpill = [Remove, Revert]; + +var lastSwapEl; + +function SwapPlugin() { + function Swap() { + this.defaults = { + swapClass: 'sortable-swap-highlight' + }; + } + + Swap.prototype = { + dragStart: function dragStart(_ref) { + var dragEl = _ref.dragEl; + lastSwapEl = dragEl; + }, + dragOverValid: function dragOverValid(_ref2) { + var completed = _ref2.completed, + target = _ref2.target, + onMove = _ref2.onMove, + activeSortable = _ref2.activeSortable, + changed = _ref2.changed, + cancel = _ref2.cancel; + if (!activeSortable.options.swap) return; + var el = this.sortable.el, + options = this.options; + + if (target && target !== el) { + var prevSwapEl = lastSwapEl; + + if (onMove(target) !== false) { + toggleClass(target, options.swapClass, true); + lastSwapEl = target; + } else { + lastSwapEl = null; + } + + if (prevSwapEl && prevSwapEl !== lastSwapEl) { + toggleClass(prevSwapEl, options.swapClass, false); + } + } + + changed(); + completed(true); + cancel(); + }, + drop: function drop(_ref3) { + var activeSortable = _ref3.activeSortable, + putSortable = _ref3.putSortable, + dragEl = _ref3.dragEl; + var toSortable = putSortable || this.sortable; + var options = this.options; + lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); + + if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { + if (dragEl !== lastSwapEl) { + toSortable.captureAnimationState(); + if (toSortable !== activeSortable) activeSortable.captureAnimationState(); + swapNodes(dragEl, lastSwapEl); + toSortable.animateAll(); + if (toSortable !== activeSortable) activeSortable.animateAll(); + } + } + }, + nulling: function nulling() { + lastSwapEl = null; + } + }; + return _extends(Swap, { + pluginName: 'swap', + eventProperties: function eventProperties() { + return { + swapItem: lastSwapEl + }; + } + }); +} + +function swapNodes(n1, n2) { + var p1 = n1.parentNode, + p2 = n2.parentNode, + i1, + i2; + if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; + i1 = index(n1); + i2 = index(n2); + + if (p1.isEqualNode(p2) && i1 < i2) { + i2++; + } + + p1.insertBefore(n2, p1.children[i1]); + p2.insertBefore(n1, p2.children[i2]); +} + +var multiDragElements = [], + multiDragClones = [], + lastMultiDragSelect, + // for selection with modifier key down (SHIFT) +multiDragSortable, + initialFolding = false, + // Initial multi-drag fold when drag started +folding = false, + // Folding any other time +dragStarted = false, + dragEl$1, + clonesFromRect, + clonesHidden; + +function MultiDragPlugin() { + function MultiDrag(sortable) { + // Bind all private methods + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + if (sortable.options.supportPointer) { + on(document, 'pointerup', this._deselectMultiDrag); + } else { + on(document, 'mouseup', this._deselectMultiDrag); + on(document, 'touchend', this._deselectMultiDrag); + } + + on(document, 'keydown', this._checkKeyDown); + on(document, 'keyup', this._checkKeyUp); + this.defaults = { + selectedClass: 'sortable-selected', + multiDragKey: null, + setData: function setData(dataTransfer, dragEl) { + var data = ''; + + if (multiDragElements.length && multiDragSortable === sortable) { + multiDragElements.forEach(function (multiDragElement, i) { + data += (!i ? '' : ', ') + multiDragElement.textContent; + }); + } else { + data = dragEl.textContent; + } + + dataTransfer.setData('Text', data); + } + }; + } + + MultiDrag.prototype = { + multiDragKeyDown: false, + isMultiDrag: false, + delayStartGlobal: function delayStartGlobal(_ref) { + var dragged = _ref.dragEl; + dragEl$1 = dragged; + }, + delayEnded: function delayEnded() { + this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1); + }, + setupClone: function setupClone(_ref2) { + var sortable = _ref2.sortable, + cancel = _ref2.cancel; + if (!this.isMultiDrag) return; + + for (var i = 0; i < multiDragElements.length; i++) { + multiDragClones.push(clone(multiDragElements[i])); + multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; + multiDragClones[i].draggable = false; + multiDragClones[i].style['will-change'] = ''; + toggleClass(multiDragClones[i], this.options.selectedClass, false); + multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false); + } + + sortable._hideClone(); + + cancel(); + }, + clone: function clone(_ref3) { + var sortable = _ref3.sortable, + rootEl = _ref3.rootEl, + dispatchSortableEvent = _ref3.dispatchSortableEvent, + cancel = _ref3.cancel; + if (!this.isMultiDrag) return; + + if (!this.options.removeCloneOnHide) { + if (multiDragElements.length && multiDragSortable === sortable) { + insertMultiDragClones(true, rootEl); + dispatchSortableEvent('clone'); + cancel(); + } + } + }, + showClone: function showClone(_ref4) { + var cloneNowShown = _ref4.cloneNowShown, + rootEl = _ref4.rootEl, + cancel = _ref4.cancel; + if (!this.isMultiDrag) return; + insertMultiDragClones(false, rootEl); + multiDragClones.forEach(function (clone) { + css(clone, 'display', ''); + }); + cloneNowShown(); + clonesHidden = false; + cancel(); + }, + hideClone: function hideClone(_ref5) { + var _this = this; + + var sortable = _ref5.sortable, + cloneNowHidden = _ref5.cloneNowHidden, + cancel = _ref5.cancel; + if (!this.isMultiDrag) return; + multiDragClones.forEach(function (clone) { + css(clone, 'display', 'none'); + + if (_this.options.removeCloneOnHide && clone.parentNode) { + clone.parentNode.removeChild(clone); + } + }); + cloneNowHidden(); + clonesHidden = true; + cancel(); + }, + dragStartGlobal: function dragStartGlobal(_ref6) { + var sortable = _ref6.sortable; + + if (!this.isMultiDrag && multiDragSortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + } + + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.sortableIndex = index(multiDragElement); + }); // Sort multi-drag elements + + multiDragElements = multiDragElements.sort(function (a, b) { + return a.sortableIndex - b.sortableIndex; + }); + dragStarted = true; + }, + dragStarted: function dragStarted(_ref7) { + var _this2 = this; + + var sortable = _ref7.sortable; + if (!this.isMultiDrag) return; + + if (this.options.sort) { + // Capture rects, + // hide multi drag elements (by positioning them absolute), + // set multi drag elements rects to dragRect, + // show multi drag elements, + // animate to rects, + // unset rects & remove from DOM + sortable.captureAnimationState(); + + if (this.options.animation) { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + css(multiDragElement, 'position', 'absolute'); + }); + var dragRect = getRect(dragEl$1, false, true, true); + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRect); + }); + folding = true; + initialFolding = true; + } + } + + sortable.animateAll(function () { + folding = false; + initialFolding = false; + + if (_this2.options.animation) { + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); + } // Remove all auxiliary multidrag items from el, if sorting enabled + + + if (_this2.options.sort) { + removeMultiDragElements(); + } + }); + }, + dragOver: function dragOver(_ref8) { + var target = _ref8.target, + completed = _ref8.completed, + cancel = _ref8.cancel; + + if (folding && ~multiDragElements.indexOf(target)) { + completed(false); + cancel(); + } + }, + revert: function revert(_ref9) { + var fromSortable = _ref9.fromSortable, + rootEl = _ref9.rootEl, + sortable = _ref9.sortable, + dragRect = _ref9.dragRect; + + if (multiDragElements.length > 1) { + // Setup unfold animation + multiDragElements.forEach(function (multiDragElement) { + sortable.addAnimationState({ + target: multiDragElement, + rect: folding ? getRect(multiDragElement) : dragRect + }); + unsetRect(multiDragElement); + multiDragElement.fromRect = dragRect; + fromSortable.removeAnimationState(multiDragElement); + }); + folding = false; + insertMultiDragElements(!this.options.removeCloneOnHide, rootEl); + } + }, + dragOverCompleted: function dragOverCompleted(_ref10) { + var sortable = _ref10.sortable, + isOwner = _ref10.isOwner, + insertion = _ref10.insertion, + activeSortable = _ref10.activeSortable, + parentEl = _ref10.parentEl, + putSortable = _ref10.putSortable; + var options = this.options; + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } + + initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location + + if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { + // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible + var dragRectAbsolute = getRect(dragEl$1, false, true, true); + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted + // while folding, and so that we can capture them again because old sortable will no longer be fromSortable + + parentEl.appendChild(multiDragElement); + }); + folding = true; + } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out + + + if (!isOwner) { + // Only remove if not folding (folding will remove them anyways) + if (!folding) { + removeMultiDragElements(); + } + + if (multiDragElements.length > 1) { + var clonesHiddenBefore = clonesHidden; + + activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden + + + if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { + multiDragClones.forEach(function (clone) { + activeSortable.addAnimationState({ + target: clone, + rect: clonesFromRect + }); + clone.fromRect = clonesFromRect; + clone.thisAnimationDuration = null; + }); + } + } else { + activeSortable._showClone(sortable); + } + } + } + }, + dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) { + var dragRect = _ref11.dragRect, + isOwner = _ref11.isOwner, + activeSortable = _ref11.activeSortable; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + }); + + if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { + clonesFromRect = _extends({}, dragRect); + var dragMatrix = matrix(dragEl$1, true); + clonesFromRect.top -= dragMatrix.f; + clonesFromRect.left -= dragMatrix.e; + } + }, + dragOverAnimationComplete: function dragOverAnimationComplete() { + if (folding) { + folding = false; + removeMultiDragElements(); + } + }, + drop: function drop(_ref12) { + var evt = _ref12.originalEvent, + rootEl = _ref12.rootEl, + parentEl = _ref12.parentEl, + sortable = _ref12.sortable, + dispatchSortableEvent = _ref12.dispatchSortableEvent, + oldIndex = _ref12.oldIndex, + putSortable = _ref12.putSortable; + var toSortable = putSortable || this.sortable; + if (!evt) return; + var options = this.options, + children = parentEl.children; // Multi-drag selection + + if (!dragStarted) { + if (options.multiDragKey && !this.multiDragKeyDown) { + this._deselectMultiDrag(); + } + + toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1)); + + if (!~multiDragElements.indexOf(dragEl$1)) { + multiDragElements.push(dragEl$1); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: dragEl$1, + originalEvt: evt + }); // Modifier activated, select from last to dragEl + + if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { + var lastIndex = index(lastMultiDragSelect), + currentIndex = index(dragEl$1); + + if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { + // Must include lastMultiDragSelect (select it), in case modified selection from no selection + // (but previous selection existed) + var n, i; + + if (currentIndex > lastIndex) { + i = lastIndex; + n = currentIndex; + } else { + i = currentIndex; + n = lastIndex + 1; + } + + for (; i < n; i++) { + if (~multiDragElements.indexOf(children[i])) continue; + toggleClass(children[i], options.selectedClass, true); + multiDragElements.push(children[i]); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: children[i], + originalEvt: evt + }); + } + } + } else { + lastMultiDragSelect = dragEl$1; + } + + multiDragSortable = toSortable; + } else { + multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1); + lastMultiDragSelect = null; + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'deselect', + targetEl: dragEl$1, + originalEvt: evt + }); + } + } // Multi-drag drop + + + if (dragStarted && this.isMultiDrag) { + // Do not "unfold" after around dragEl if reverted + if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { + var dragRect = getRect(dragEl$1), + multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); + if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null; + toSortable.captureAnimationState(); + + if (!initialFolding) { + if (options.animation) { + dragEl$1.fromRect = dragRect; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + + if (multiDragElement !== dragEl$1) { + var rect = folding ? getRect(multiDragElement) : dragRect; + multiDragElement.fromRect = rect; // Prepare unfold animation + + toSortable.addAnimationState({ + target: multiDragElement, + rect: rect + }); + } + }); + } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert + // properly they must all be removed + + + removeMultiDragElements(); + multiDragElements.forEach(function (multiDragElement) { + if (children[multiDragIndex]) { + parentEl.insertBefore(multiDragElement, children[multiDragIndex]); + } else { + parentEl.appendChild(multiDragElement); + } + + multiDragIndex++; + }); // If initial folding is done, the elements may have changed position because they are now + // unfolding around dragEl, even though dragEl may not have his index changed, so update event + // must be fired here as Sortable will not. + + if (oldIndex === index(dragEl$1)) { + var update = false; + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement.sortableIndex !== index(multiDragElement)) { + update = true; + return; + } + }); + + if (update) { + dispatchSortableEvent('update'); + } + } + } // Must be done after capturing individual rects (scroll bar) + + + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); + toSortable.animateAll(); + } + + multiDragSortable = toSortable; + } // Remove clones if necessary + + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + multiDragClones.forEach(function (clone) { + clone.parentNode && clone.parentNode.removeChild(clone); + }); + } + }, + nullingGlobal: function nullingGlobal() { + this.isMultiDrag = dragStarted = false; + multiDragClones.length = 0; + }, + destroyGlobal: function destroyGlobal() { + this._deselectMultiDrag(); + + off(document, 'pointerup', this._deselectMultiDrag); + off(document, 'mouseup', this._deselectMultiDrag); + off(document, 'touchend', this._deselectMultiDrag); + off(document, 'keydown', this._checkKeyDown); + off(document, 'keyup', this._checkKeyUp); + }, + _deselectMultiDrag: function _deselectMultiDrag(evt) { + if (dragStarted) return; // Only deselect if selection is in this sortable + + if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable + + if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click + + if (evt && evt.button !== 0) return; + + while (multiDragElements.length) { + var el = multiDragElements[0]; + toggleClass(el, this.options.selectedClass, false); + multiDragElements.shift(); + dispatchEvent({ + sortable: this.sortable, + rootEl: this.sortable.el, + name: 'deselect', + targetEl: el, + originalEvt: evt + }); + } + }, + _checkKeyDown: function _checkKeyDown(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = true; + } + }, + _checkKeyUp: function _checkKeyUp(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = false; + } + } + }; + return _extends(MultiDrag, { + // Static methods & properties + pluginName: 'multiDrag', + utils: { + /** + * Selects the provided multi-drag item + * @param {HTMLElement} el The element to be selected + */ + select: function select(el) { + var sortable = el.parentNode[expando]; + if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return; + + if (multiDragSortable && multiDragSortable !== sortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + + multiDragSortable = sortable; + } + + toggleClass(el, sortable.options.selectedClass, true); + multiDragElements.push(el); + }, + + /** + * Deselects the provided multi-drag item + * @param {HTMLElement} el The element to be deselected + */ + deselect: function deselect(el) { + var sortable = el.parentNode[expando], + index = multiDragElements.indexOf(el); + if (!sortable || !sortable.options.multiDrag || !~index) return; + toggleClass(el, sortable.options.selectedClass, false); + multiDragElements.splice(index, 1); + } + }, + eventProperties: function eventProperties() { + var _this3 = this; + + var oldIndicies = [], + newIndicies = []; + multiDragElements.forEach(function (multiDragElement) { + oldIndicies.push({ + multiDragElement: multiDragElement, + index: multiDragElement.sortableIndex + }); // multiDragElements will already be sorted if folding + + var newIndex; + + if (folding && multiDragElement !== dragEl$1) { + newIndex = -1; + } else if (folding) { + newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')'); + } else { + newIndex = index(multiDragElement); + } + + newIndicies.push({ + multiDragElement: multiDragElement, + index: newIndex + }); + }); + return { + items: _toConsumableArray(multiDragElements), + clones: [].concat(multiDragClones), + oldIndicies: oldIndicies, + newIndicies: newIndicies + }; + }, + optionListeners: { + multiDragKey: function multiDragKey(key) { + key = key.toLowerCase(); + + if (key === 'ctrl') { + key = 'Control'; + } else if (key.length > 1) { + key = key.charAt(0).toUpperCase() + key.substr(1); + } + + return key; + } + } + }); +} + +function insertMultiDragElements(clonesInserted, rootEl) { + multiDragElements.forEach(function (multiDragElement, i) { + var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(multiDragElement, target); + } else { + rootEl.appendChild(multiDragElement); + } + }); +} +/** + * Insert multi-drag clones + * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted + * @param {HTMLElement} rootEl + */ + + +function insertMultiDragClones(elementsInserted, rootEl) { + multiDragClones.forEach(function (clone, i) { + var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(clone, target); + } else { + rootEl.appendChild(clone); + } + }); +} + +function removeMultiDragElements() { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement); + }); +} + +export default Sortable; +export { AutoScrollPlugin as AutoScroll, MultiDragPlugin as MultiDrag, OnSpill, Sortable, SwapPlugin as Swap }; diff --git a/public/assets/libs/Sortable/modular/sortable.esm.js b/public/assets/libs/Sortable/modular/sortable.esm.js new file mode 100644 index 0000000000000000000000000000000000000000..0104e85df74e6983704d49311191324ee025ea0f --- /dev/null +++ b/public/assets/libs/Sortable/modular/sortable.esm.js @@ -0,0 +1,3693 @@ +/**! + * Sortable 1.10.1 + * @author RubaXa + * @author owenm + * @license MIT + */ +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); +} + +function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + + ownKeys.forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } + + return target; +} + +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; +} + +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; +} + +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); +} + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } +} + +function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); +} + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); +} + +var version = "1.10.1"; + +function userAgent(pattern) { + if (typeof window !== 'undefined' && window.navigator) { + return !! + /*@__PURE__*/ + navigator.userAgent.match(pattern); + } +} + +var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); +var Edge = userAgent(/Edge/i); +var FireFox = userAgent(/firefox/i); +var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); +var IOS = userAgent(/iP(ad|od|hone)/i); +var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i); + +var captureMode = { + capture: false, + passive: false +}; + +function on(el, event, fn) { + el.addEventListener(event, fn, !IE11OrLess && captureMode); +} + +function off(el, event, fn) { + el.removeEventListener(event, fn, !IE11OrLess && captureMode); +} + +function matches( +/**HTMLElement*/ +el, +/**String*/ +selector) { + if (!selector) return; + selector[0] === '>' && (selector = selector.substring(1)); + + if (el) { + try { + if (el.matches) { + return el.matches(selector); + } else if (el.msMatchesSelector) { + return el.msMatchesSelector(selector); + } else if (el.webkitMatchesSelector) { + return el.webkitMatchesSelector(selector); + } + } catch (_) { + return false; + } + } + + return false; +} + +function getParentOrHost(el) { + return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode; +} + +function closest( +/**HTMLElement*/ +el, +/**String*/ +selector, +/**HTMLElement*/ +ctx, includeCTX) { + if (el) { + ctx = ctx || document; + + do { + if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) { + return el; + } + + if (el === ctx) break; + /* jshint boss:true */ + } while (el = getParentOrHost(el)); + } + + return null; +} + +var R_SPACE = /\s+/g; + +function toggleClass(el, name, state) { + if (el && name) { + if (el.classList) { + el.classList[state ? 'add' : 'remove'](name); + } else { + var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); + el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); + } + } +} + +function css(el, prop, val) { + var style = el && el.style; + + if (style) { + if (val === void 0) { + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(el, ''); + } else if (el.currentStyle) { + val = el.currentStyle; + } + + return prop === void 0 ? val : val[prop]; + } else { + if (!(prop in style) && prop.indexOf('webkit') === -1) { + prop = '-webkit-' + prop; + } + + style[prop] = val + (typeof val === 'string' ? '' : 'px'); + } + } +} + +function matrix(el, selfOnly) { + var appliedTransforms = ''; + + if (typeof el === 'string') { + appliedTransforms = el; + } else { + do { + var transform = css(el, 'transform'); + + if (transform && transform !== 'none') { + appliedTransforms = transform + ' ' + appliedTransforms; + } + /* jshint boss:true */ + + } while (!selfOnly && (el = el.parentNode)); + } + + var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix; + /*jshint -W056 */ + + return matrixFn && new matrixFn(appliedTransforms); +} + +function find(ctx, tagName, iterator) { + if (ctx) { + var list = ctx.getElementsByTagName(tagName), + i = 0, + n = list.length; + + if (iterator) { + for (; i < n; i++) { + iterator(list[i], i); + } + } + + return list; + } + + return []; +} + +function getWindowScrollingElement() { + if (IE11OrLess) { + return document.documentElement; + } else { + return document.scrollingElement; + } +} +/** + * Returns the "bounding client rect" of given element + * @param {HTMLElement} el The element whose boundingClientRect is wanted + * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container + * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr + * @param {[Boolean]} undoScale Whether the container's scale() should be undone + * @param {[HTMLElement]} container The parent the element will be placed in + * @return {Object} The boundingClientRect of el, with specified adjustments + */ + + +function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) { + if (!el.getBoundingClientRect && el !== window) return; + var elRect, top, left, bottom, right, height, width; + + if (el !== window && el !== getWindowScrollingElement()) { + elRect = el.getBoundingClientRect(); + top = elRect.top; + left = elRect.left; + bottom = elRect.bottom; + right = elRect.right; + height = elRect.height; + width = elRect.width; + } else { + top = 0; + left = 0; + bottom = window.innerHeight; + right = window.innerWidth; + height = window.innerHeight; + width = window.innerWidth; + } + + if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) { + // Adjust for translate() + container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) + // Not needed on <= IE11 + + if (!IE11OrLess) { + do { + if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) { + var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container + + top -= containerRect.top + parseInt(css(container, 'border-top-width')); + left -= containerRect.left + parseInt(css(container, 'border-left-width')); + bottom = top + elRect.height; + right = left + elRect.width; + break; + } + /* jshint boss:true */ + + } while (container = container.parentNode); + } + } + + if (undoScale && el !== window) { + // Adjust for scale() + var elMatrix = matrix(container || el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d; + + if (elMatrix) { + top /= scaleY; + left /= scaleX; + width /= scaleX; + height /= scaleY; + bottom = top + height; + right = left + width; + } + } + + return { + top: top, + left: left, + bottom: bottom, + right: right, + width: width, + height: height + }; +} +/** + * Checks if a side of an element is scrolled past a side of its parents + * @param {HTMLElement} el The element who's side being scrolled out of view is in question + * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom') + * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') + * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element + */ + + +function isScrolledPast(el, elSide, parentSide) { + var parent = getParentAutoScrollElement(el, true), + elSideVal = getRect(el)[elSide]; + /* jshint boss:true */ + + while (parent) { + var parentSideVal = getRect(parent)[parentSide], + visible = void 0; + + if (parentSide === 'top' || parentSide === 'left') { + visible = elSideVal >= parentSideVal; + } else { + visible = elSideVal <= parentSideVal; + } + + if (!visible) return parent; + if (parent === getWindowScrollingElement()) break; + parent = getParentAutoScrollElement(parent, false); + } + + return false; +} +/** + * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) + * and non-draggable elements + * @param {HTMLElement} el The parent element + * @param {Number} childNum The index of the child + * @param {Object} options Parent Sortable's options + * @return {HTMLElement} The child at index childNum, or null if not found + */ + + +function getChild(el, childNum, options) { + var currentChild = 0, + i = 0, + children = el.children; + + while (i < children.length) { + if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && children[i] !== Sortable.dragged && closest(children[i], options.draggable, el, false)) { + if (currentChild === childNum) { + return children[i]; + } + + currentChild++; + } + + i++; + } + + return null; +} +/** + * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) + * @param {HTMLElement} el Parent element + * @param {selector} selector Any other elements that should be ignored + * @return {HTMLElement} The last child, ignoring ghostEl + */ + + +function lastChild(el, selector) { + var last = el.lastElementChild; + + while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { + last = last.previousElementSibling; + } + + return last || null; +} +/** + * Returns the index of an element within its parent for a selected set of + * elements + * @param {HTMLElement} el + * @param {selector} selector + * @return {number} + */ + + +function index(el, selector) { + var index = 0; + + if (!el || !el.parentNode) { + return -1; + } + /* jshint boss:true */ + + + while (el = el.previousElementSibling) { + if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) { + index++; + } + } + + return index; +} +/** + * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. + * The value is returned in real pixels. + * @param {HTMLElement} el + * @return {Array} Offsets in the format of [left, top] + */ + + +function getRelativeScrollOffset(el) { + var offsetLeft = 0, + offsetTop = 0, + winScroller = getWindowScrollingElement(); + + if (el) { + do { + var elMatrix = matrix(el), + scaleX = elMatrix.a, + scaleY = elMatrix.d; + offsetLeft += el.scrollLeft * scaleX; + offsetTop += el.scrollTop * scaleY; + } while (el !== winScroller && (el = el.parentNode)); + } + + return [offsetLeft, offsetTop]; +} +/** + * Returns the index of the object within the given array + * @param {Array} arr Array that may or may not hold the object + * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find + * @return {Number} The index of the object in the array, or -1 + */ + + +function indexOfObject(arr, obj) { + for (var i in arr) { + if (!arr.hasOwnProperty(i)) continue; + + for (var key in obj) { + if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i); + } + } + + return -1; +} + +function getParentAutoScrollElement(el, includeSelf) { + // skip to window + if (!el || !el.getBoundingClientRect) return getWindowScrollingElement(); + var elem = el; + var gotSelf = false; + + do { + // we don't need to get elem css if it isn't even overflowing in the first place (performance) + if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { + var elemCSS = css(elem); + + if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) { + if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement(); + if (gotSelf || includeSelf) return elem; + gotSelf = true; + } + } + /* jshint boss:true */ + + } while (elem = elem.parentNode); + + return getWindowScrollingElement(); +} + +function extend(dst, src) { + if (dst && src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dst[key] = src[key]; + } + } + } + + return dst; +} + +function isRectEqual(rect1, rect2) { + return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width); +} + +var _throttleTimeout; + +function throttle(callback, ms) { + return function () { + if (!_throttleTimeout) { + var args = arguments, + _this = this; + + if (args.length === 1) { + callback.call(_this, args[0]); + } else { + callback.apply(_this, args); + } + + _throttleTimeout = setTimeout(function () { + _throttleTimeout = void 0; + }, ms); + } + }; +} + +function cancelThrottle() { + clearTimeout(_throttleTimeout); + _throttleTimeout = void 0; +} + +function scrollBy(el, x, y) { + el.scrollLeft += x; + el.scrollTop += y; +} + +function clone(el) { + var Polymer = window.Polymer; + var $ = window.jQuery || window.Zepto; + + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } else if ($) { + return $(el).clone(true)[0]; + } else { + return el.cloneNode(true); + } +} + +function setRect(el, rect) { + css(el, 'position', 'absolute'); + css(el, 'top', rect.top); + css(el, 'left', rect.left); + css(el, 'width', rect.width); + css(el, 'height', rect.height); +} + +function unsetRect(el) { + css(el, 'position', ''); + css(el, 'top', ''); + css(el, 'left', ''); + css(el, 'width', ''); + css(el, 'height', ''); +} + +var expando = 'Sortable' + new Date().getTime(); + +function AnimationStateManager() { + var animationStates = [], + animationCallbackId; + return { + captureAnimationState: function captureAnimationState() { + animationStates = []; + if (!this.options.animation) return; + var children = [].slice.call(this.el.children); + children.forEach(function (child) { + if (css(child, 'display') === 'none' || child === Sortable.ghost) return; + animationStates.push({ + target: child, + rect: getRect(child) + }); + + var fromRect = _objectSpread({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation + + + if (child.thisAnimationDuration) { + var childMatrix = matrix(child, true); + + if (childMatrix) { + fromRect.top -= childMatrix.f; + fromRect.left -= childMatrix.e; + } + } + + child.fromRect = fromRect; + }); + }, + addAnimationState: function addAnimationState(state) { + animationStates.push(state); + }, + removeAnimationState: function removeAnimationState(target) { + animationStates.splice(indexOfObject(animationStates, { + target: target + }), 1); + }, + animateAll: function animateAll(callback) { + var _this = this; + + if (!this.options.animation) { + clearTimeout(animationCallbackId); + if (typeof callback === 'function') callback(); + return; + } + + var animating = false, + animationTime = 0; + animationStates.forEach(function (state) { + var time = 0, + target = state.target, + fromRect = target.fromRect, + toRect = getRect(target), + prevFromRect = target.prevFromRect, + prevToRect = target.prevToRect, + animatingRect = state.rect, + targetMatrix = matrix(target, true); + + if (targetMatrix) { + // Compensate for current animation + toRect.top -= targetMatrix.f; + toRect.left -= targetMatrix.e; + } + + target.toRect = toRect; + + if (target.thisAnimationDuration) { + // Could also check if animatingRect is between fromRect and toRect + if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect + (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) { + // If returning to same place as started from animation and on same axis + time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options); + } + } // if fromRect != toRect: animate + + + if (!isRectEqual(toRect, fromRect)) { + target.prevFromRect = fromRect; + target.prevToRect = toRect; + + if (!time) { + time = _this.options.animation; + } + + _this.animate(target, animatingRect, toRect, time); + } + + if (time) { + animating = true; + animationTime = Math.max(animationTime, time); + clearTimeout(target.animationResetTimer); + target.animationResetTimer = setTimeout(function () { + target.animationTime = 0; + target.prevFromRect = null; + target.fromRect = null; + target.prevToRect = null; + target.thisAnimationDuration = null; + }, time); + target.thisAnimationDuration = time; + } + }); + clearTimeout(animationCallbackId); + + if (!animating) { + if (typeof callback === 'function') callback(); + } else { + animationCallbackId = setTimeout(function () { + if (typeof callback === 'function') callback(); + }, animationTime); + } + + animationStates = []; + }, + animate: function animate(target, currentRect, toRect, duration) { + if (duration) { + css(target, 'transition', ''); + css(target, 'transform', ''); + var elMatrix = matrix(this.el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d, + translateX = (currentRect.left - toRect.left) / (scaleX || 1), + translateY = (currentRect.top - toRect.top) / (scaleY || 1); + target.animatingX = !!translateX; + target.animatingY = !!translateY; + css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); + repaint(target); // repaint + + css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); + css(target, 'transform', 'translate3d(0,0,0)'); + typeof target.animated === 'number' && clearTimeout(target.animated); + target.animated = setTimeout(function () { + css(target, 'transition', ''); + css(target, 'transform', ''); + target.animated = false; + target.animatingX = false; + target.animatingY = false; + }, duration); + } + } + }; +} + +function repaint(target) { + return target.offsetWidth; +} + +function calculateRealTime(animatingRect, fromRect, toRect, options) { + return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation; +} + +var plugins = []; +var defaults = { + initializeByDefault: true +}; +var PluginManager = { + mount: function mount(plugin) { + // Set default static properties + for (var option in defaults) { + if (defaults.hasOwnProperty(option) && !(option in plugin)) { + plugin[option] = defaults[option]; + } + } + + plugins.push(plugin); + }, + pluginEvent: function pluginEvent(eventName, sortable, evt) { + var _this = this; + + this.eventCanceled = false; + + evt.cancel = function () { + _this.eventCanceled = true; + }; + + var eventNameGlobal = eventName + 'Global'; + plugins.forEach(function (plugin) { + if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable + + if (sortable[plugin.pluginName][eventNameGlobal]) { + sortable[plugin.pluginName][eventNameGlobal](_objectSpread({ + sortable: sortable + }, evt)); + } // Only fire plugin event if plugin is enabled in this sortable, + // and plugin has event defined + + + if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { + sortable[plugin.pluginName][eventName](_objectSpread({ + sortable: sortable + }, evt)); + } + }); + }, + initializePlugins: function initializePlugins(sortable, el, defaults, options) { + plugins.forEach(function (plugin) { + var pluginName = plugin.pluginName; + if (!sortable.options[pluginName] && !plugin.initializeByDefault) return; + var initialized = new plugin(sortable, el, sortable.options); + initialized.sortable = sortable; + initialized.options = sortable.options; + sortable[pluginName] = initialized; // Add default options from plugin + + _extends(defaults, initialized.defaults); + }); + + for (var option in sortable.options) { + if (!sortable.options.hasOwnProperty(option)) continue; + var modified = this.modifyOption(sortable, option, sortable.options[option]); + + if (typeof modified !== 'undefined') { + sortable.options[option] = modified; + } + } + }, + getEventProperties: function getEventProperties(name, sortable) { + var eventProperties = {}; + plugins.forEach(function (plugin) { + if (typeof plugin.eventProperties !== 'function') return; + + _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name)); + }); + return eventProperties; + }, + modifyOption: function modifyOption(sortable, name, value) { + var modifiedValue; + plugins.forEach(function (plugin) { + // Plugin must exist on the Sortable + if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin + + if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') { + modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value); + } + }); + return modifiedValue; + } +}; + +function dispatchEvent(_ref) { + var sortable = _ref.sortable, + rootEl = _ref.rootEl, + name = _ref.name, + targetEl = _ref.targetEl, + cloneEl = _ref.cloneEl, + toEl = _ref.toEl, + fromEl = _ref.fromEl, + oldIndex = _ref.oldIndex, + newIndex = _ref.newIndex, + oldDraggableIndex = _ref.oldDraggableIndex, + newDraggableIndex = _ref.newDraggableIndex, + originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + extraEventProperties = _ref.extraEventProperties; + sortable = sortable || rootEl && rootEl[expando]; + if (!sortable) return; + var evt, + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent(name, { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(name, true, true); + } + + evt.to = toEl || rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + evt.oldIndex = oldIndex; + evt.newIndex = newIndex; + evt.oldDraggableIndex = oldDraggableIndex; + evt.newDraggableIndex = newDraggableIndex; + evt.originalEvent = originalEvent; + evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; + + var allEventProperties = _objectSpread({}, extraEventProperties, PluginManager.getEventProperties(name, sortable)); + + for (var option in allEventProperties) { + evt[option] = allEventProperties[option]; + } + + if (rootEl) { + rootEl.dispatchEvent(evt); + } + + if (options[onName]) { + options[onName].call(sortable, evt); + } +} + +var pluginEvent = function pluginEvent(eventName, sortable) { + var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + originalEvent = _ref.evt, + data = _objectWithoutProperties(_ref, ["evt"]); + + PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread({ + dragEl: dragEl, + parentEl: parentEl, + ghostEl: ghostEl, + rootEl: rootEl, + nextEl: nextEl, + lastDownEl: lastDownEl, + cloneEl: cloneEl, + cloneHidden: cloneHidden, + dragStarted: moved, + putSortable: putSortable, + activeSortable: Sortable.active, + originalEvent: originalEvent, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + hideGhostForTarget: _hideGhostForTarget, + unhideGhostForTarget: _unhideGhostForTarget, + cloneNowHidden: function cloneNowHidden() { + cloneHidden = true; + }, + cloneNowShown: function cloneNowShown() { + cloneHidden = false; + }, + dispatchSortableEvent: function dispatchSortableEvent(name) { + _dispatchEvent({ + sortable: sortable, + name: name, + originalEvent: originalEvent + }); + } + }, data)); +}; + +function _dispatchEvent(info) { + dispatchEvent(_objectSpread({ + putSortable: putSortable, + cloneEl: cloneEl, + targetEl: dragEl, + rootEl: rootEl, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex + }, info)); +} + +var dragEl, + parentEl, + ghostEl, + rootEl, + nextEl, + lastDownEl, + cloneEl, + cloneHidden, + oldIndex, + newIndex, + oldDraggableIndex, + newDraggableIndex, + activeGroup, + putSortable, + awaitingDragStarted = false, + ignoreNextClick = false, + sortables = [], + tapEvt, + touchEvt, + lastDx, + lastDy, + tapDistanceLeft, + tapDistanceTop, + moved, + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + targetMoveDistance, + // For positioning ghost absolutely +ghostRelativeParent, + ghostRelativeParentInitialScroll = [], + // (left, top) +_silent = false, + savedInputChecked = []; +/** @const */ + +var documentExists = typeof document !== 'undefined', + PositionGhostAbsolutely = IOS, + CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', + // This will not pass for IE9, because IE9 DnD only works on anchors +supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), + supportCssPointerEvents = function () { + if (!documentExists) return; // false when <= IE11 + + if (IE11OrLess) { + return false; + } + + var el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; +}(), + _detectDirection = function _detectDirection(el, options) { + var elCSS = css(el), + elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), + child1 = getChild(el, 0, options), + child2 = getChild(el, 1, options), + firstChildCSS = child1 && css(child1), + secondChildCSS = child2 && css(child2), + firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, + secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; + + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; + } + + if (elCSS.display === 'grid') { + return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; + } + + if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') { + var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; + return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; + } + + return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal'; +}, + _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) { + var dragElS1Opp = vertical ? dragRect.left : dragRect.top, + dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, + dragElOppLength = vertical ? dragRect.width : dragRect.height, + targetS1Opp = vertical ? targetRect.left : targetRect.top, + targetS2Opp = vertical ? targetRect.right : targetRect.bottom, + targetOppLength = vertical ? targetRect.width : targetRect.height; + return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2; +}, + +/** + * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. + * @param {Number} x X position + * @param {Number} y Y position + * @return {HTMLElement} Element of the first found nearest Sortable + */ +_detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { + var ret; + sortables.some(function (sortable) { + if (lastChild(sortable)) return; + var rect = getRect(sortable), + threshold = sortable[expando].options.emptyInsertThreshold, + insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, + insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; + + if (threshold && insideHorizontally && insideVertically) { + return ret = sortable; + } + }); + return ret; +}, + _prepareGroup = function _prepareGroup(options) { + function toFn(value, pull) { + return function (to, from, dragEl, evt) { + var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name; + + if (value == null && (pull || sameGroup)) { + // Default pull value + // Default pull and put value if same group + return true; + } else if (value == null || value === false) { + return false; + } else if (pull && value === 'clone') { + return value; + } else if (typeof value === 'function') { + return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); + } else { + var otherGroup = (pull ? to : from).options.group.name; + return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1; + } + }; + } + + var group = {}; + var originalGroup = options.group; + + if (!originalGroup || _typeof(originalGroup) != 'object') { + originalGroup = { + name: originalGroup + }; + } + + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + options.group = group; +}, + _hideGhostForTarget = function _hideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', 'none'); + } +}, + _unhideGhostForTarget = function _unhideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', ''); + } +}; // #1184 fix - Prevent click event on fallback if dragged but item not changed position + + +if (documentExists) { + document.addEventListener('click', function (evt) { + if (ignoreNextClick) { + evt.preventDefault(); + evt.stopPropagation && evt.stopPropagation(); + evt.stopImmediatePropagation && evt.stopImmediatePropagation(); + ignoreNextClick = false; + return false; + } + }, true); +} + +var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) { + if (dragEl) { + evt = evt.touches ? evt.touches[0] : evt; + + var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); + + if (nearest) { + // Create imitation event + var event = {}; + + for (var i in evt) { + if (evt.hasOwnProperty(i)) { + event[i] = evt[i]; + } + } + + event.target = event.rootEl = nearest; + event.preventDefault = void 0; + event.stopPropagation = void 0; + + nearest[expando]._onDragOver(event); + } + } +}; + +var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) { + if (dragEl) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); + } +}; +/** + * @class Sortable + * @param {HTMLElement} el + * @param {Object} [options] + */ + + +function Sortable(el, options) { + if (!(el && el.nodeType && el.nodeType === 1)) { + throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); + } + + this.el = el; // root element + + this.options = options = _extends({}, options); // Export instance + + el[expando] = this; + var defaults = { + group: null, + sort: true, + disabled: false, + store: null, + handle: null, + draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*', + swapThreshold: 1, + // percentage; 0 <= x <= 1 + invertSwap: false, + // invert always + invertedSwapThreshold: null, + // will be set to same as swapThreshold if default + removeCloneOnHide: true, + direction: function direction() { + return _detectDirection(el, this.options); + }, + ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', + dragClass: 'sortable-drag', + ignore: 'a, img', + filter: null, + preventOnFilter: true, + animation: 0, + easing: null, + setData: function setData(dataTransfer, dragEl) { + dataTransfer.setData('Text', dragEl.textContent); + }, + dropBubble: false, + dragoverBubble: false, + dataIdAttr: 'data-id', + delay: 0, + delayOnTouchOnly: false, + touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false, + fallbackTolerance: 0, + fallbackOffset: { + x: 0, + y: 0 + }, + supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window, + emptyInsertThreshold: 5 + }; + PluginManager.initializePlugins(this, el, defaults); // Set default options + + for (var name in defaults) { + !(name in options) && (options[name] = defaults[name]); + } + + _prepareGroup(options); // Bind all private methods + + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } // Setup drag mode + + + this.nativeDraggable = options.forceFallback ? false : supportDraggable; + + if (this.nativeDraggable) { + // Touch start threshold cannot be greater than the native dragstart threshold + this.options.touchStartThreshold = 1; + } // Bind events + + + if (options.supportPointer) { + on(el, 'pointerdown', this._onTapStart); + } else { + on(el, 'mousedown', this._onTapStart); + on(el, 'touchstart', this._onTapStart); + } + + if (this.nativeDraggable) { + on(el, 'dragover', this); + on(el, 'dragenter', this); + } + + sortables.push(this.el); // Restore sorting + + options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager + + _extends(this, AnimationStateManager()); +} + +Sortable.prototype = +/** @lends Sortable.prototype */ +{ + constructor: Sortable, + _isOutsideThisEl: function _isOutsideThisEl(target) { + if (!this.el.contains(target) && target !== this.el) { + lastTarget = null; + } + }, + _getDirection: function _getDirection(evt, target) { + return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; + }, + _onTapStart: function _onTapStart( + /** Event|TouchEvent */ + evt) { + if (!evt.cancelable) return; + + var _this = this, + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt, + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, + filter = options.filter; + + _saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. + + + if (dragEl) { + return; + } + + if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { + return; // only left button and enabled + } // cancel dnd if original target is content editable + + + if (originalTarget.isContentEditable) { + return; + } + + target = closest(target, options.draggable, el, false); + + if (target && target.animated) { + return; + } + + if (lastDownEl === target) { + // Ignoring duplicate `down` + return; + } // Get the index of the dragged element within its parent + + + oldIndex = index(target); + oldDraggableIndex = index(target, options.draggable); // Check filter + + if (typeof filter === 'function') { + if (filter.call(this, evt, target, this)) { + _dispatchEvent({ + sortable: _this, + rootEl: originalTarget, + name: 'filter', + targetEl: target, + toEl: el, + fromEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } else if (filter) { + filter = filter.split(',').some(function (criteria) { + criteria = closest(originalTarget, criteria.trim(), el, false); + + if (criteria) { + _dispatchEvent({ + sortable: _this, + rootEl: criteria, + name: 'filter', + targetEl: target, + fromEl: el, + toEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + return true; + } + }); + + if (filter) { + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + + if (options.handle && !closest(originalTarget, options.handle, el, false)) { + return; + } // Prepare `dragstart` + + + this._prepareDragStart(evt, touch, target); + }, + _prepareDragStart: function _prepareDragStart( + /** Event */ + evt, + /** Touch */ + touch, + /** HTMLElement */ + target) { + var _this = this, + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; + + if (target && !dragEl && target.parentNode === el) { + var dragRect = getRect(target); + rootEl = el; + dragEl = target; + parentEl = dragEl.parentNode; + nextEl = dragEl.nextSibling; + lastDownEl = target; + activeGroup = options.group; + Sortable.dragged = dragEl; + tapEvt = { + target: dragEl, + clientX: (touch || evt).clientX, + clientY: (touch || evt).clientY + }; + tapDistanceLeft = tapEvt.clientX - dragRect.left; + tapDistanceTop = tapEvt.clientY - dragRect.top; + this._lastX = (touch || evt).clientX; + this._lastY = (touch || evt).clientY; + dragEl.style['will-change'] = 'all'; + + dragStartFn = function dragStartFn() { + pluginEvent('delayEnded', _this, { + evt: evt + }); + + if (Sortable.eventCanceled) { + _this._onDrop(); + + return; + } // Delayed drag has been triggered + // we can re-enable the events: touchmove/mousemove + + + _this._disableDelayedDragEvents(); + + if (!FireFox && _this.nativeDraggable) { + dragEl.draggable = true; + } // Bind the events: dragstart/dragend + + + _this._triggerDragStart(evt, touch); // Drag start event + + + _dispatchEvent({ + sortable: _this, + name: 'choose', + originalEvent: evt + }); // Chosen item + + + toggleClass(dragEl, options.chosenClass, true); + }; // Disable "draggable" + + + options.ignore.split(',').forEach(function (criteria) { + find(dragEl, criteria.trim(), _disableDraggable); + }); + on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mouseup', _this._onDrop); + on(ownerDocument, 'touchend', _this._onDrop); + on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox) + + if (FireFox && this.nativeDraggable) { + this.options.touchStartThreshold = 4; + dragEl.draggable = true; + } + + pluginEvent('delayStart', this, { + evt: evt + }); // Delay is impossible for native DnD in Edge or IE + + if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { + if (Sortable.eventCanceled) { + this._onDrop(); + + return; + } // If the user moves the pointer or let go the click or touch + // before the delay has been reached: + // disable the delayed drag + + + on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + on(ownerDocument, 'touchend', _this._disableDelayedDrag); + on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); + on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); + options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); + _this._dragStartTimer = setTimeout(dragStartFn, options.delay); + } else { + dragStartFn(); + } + } + }, + _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( + /** TouchEvent|PointerEvent **/ + e) { + var touch = e.touches ? e.touches[0] : e; + + if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) { + this._disableDelayedDrag(); + } + }, + _disableDelayedDrag: function _disableDelayedDrag() { + dragEl && _disableDraggable(dragEl); + clearTimeout(this._dragStartTimer); + + this._disableDelayedDragEvents(); + }, + _disableDelayedDragEvents: function _disableDelayedDragEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._disableDelayedDrag); + off(ownerDocument, 'touchend', this._disableDelayedDrag); + off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); + }, + _triggerDragStart: function _triggerDragStart( + /** Event */ + evt, + /** Touch */ + touch) { + touch = touch || evt.pointerType == 'touch' && evt; + + if (!this.nativeDraggable || touch) { + if (this.options.supportPointer) { + on(document, 'pointermove', this._onTouchMove); + } else if (touch) { + on(document, 'touchmove', this._onTouchMove); + } else { + on(document, 'mousemove', this._onTouchMove); + } + } else { + on(dragEl, 'dragend', this); + on(rootEl, 'dragstart', this._onDragStart); + } + + try { + if (document.selection) { + // Timeout neccessary for IE9 + _nextTick(function () { + document.selection.empty(); + }); + } else { + window.getSelection().removeAllRanges(); + } + } catch (err) {} + }, + _dragStarted: function _dragStarted(fallback, evt) { + + awaitingDragStarted = false; + + if (rootEl && dragEl) { + pluginEvent('dragStarted', this, { + evt: evt + }); + + if (this.nativeDraggable) { + on(document, 'dragover', _checkOutsideTargetEl); + } + + var options = this.options; // Apply effect + + !fallback && toggleClass(dragEl, options.dragClass, false); + toggleClass(dragEl, options.ghostClass, true); + Sortable.active = this; + fallback && this._appendGhost(); // Drag start event + + _dispatchEvent({ + sortable: this, + name: 'start', + originalEvent: evt + }); + } else { + this._nulling(); + } + }, + _emulateDragOver: function _emulateDragOver() { + if (touchEvt) { + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + _hideGhostForTarget(); + + var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + var parent = target; + + while (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + if (target === parent) break; + parent = target; + } + + dragEl.parentNode[expando]._isOutsideThisEl(target); + + if (parent) { + do { + if (parent[expando]) { + var inserted = void 0; + inserted = parent[expando]._onDragOver({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + + if (inserted && !this.options.dragoverBubble) { + break; + } + } + + target = parent; // store last element + } + /* jshint boss:true */ + while (parent = parent.parentNode); + } + + _unhideGhostForTarget(); + } + }, + _onTouchMove: function _onTouchMove( + /**TouchEvent*/ + evt) { + if (tapEvt) { + var options = this.options, + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + ghostMatrix = ghostEl && matrix(ghostEl), + scaleX = ghostEl && ghostMatrix && ghostMatrix.a, + scaleY = ghostEl && ghostMatrix && ghostMatrix.d, + relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), + dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), + dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging + + if (!Sortable.active && !awaitingDragStarted) { + if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { + return; + } + + this._onDragStart(evt, true); + } + + if (ghostEl) { + if (ghostMatrix) { + ghostMatrix.e += dx - (lastDx || 0); + ghostMatrix.f += dy - (lastDy || 0); + } else { + ghostMatrix = { + a: 1, + b: 0, + c: 0, + d: 1, + e: dx, + f: dy + }; + } + + var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")"); + css(ghostEl, 'webkitTransform', cssMatrix); + css(ghostEl, 'mozTransform', cssMatrix); + css(ghostEl, 'msTransform', cssMatrix); + css(ghostEl, 'transform', cssMatrix); + lastDx = dx; + lastDy = dy; + touchEvt = touch; + } + + evt.cancelable && evt.preventDefault(); + } + }, + _appendGhost: function _appendGhost() { + // Bug if using scale(): https://stackoverflow.com/questions/2637058 + // Not being adjusted for + if (!ghostEl) { + var container = this.options.fallbackOnBody ? document.body : rootEl, + rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), + options = this.options; // Position absolutely + + if (PositionGhostAbsolutely) { + // Get relatively positioned parent + ghostRelativeParent = container; + + while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) { + ghostRelativeParent = ghostRelativeParent.parentNode; + } + + if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { + if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement(); + rect.top += ghostRelativeParent.scrollTop; + rect.left += ghostRelativeParent.scrollLeft; + } else { + ghostRelativeParent = getWindowScrollingElement(); + } + + ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent); + } + + ghostEl = dragEl.cloneNode(true); + toggleClass(ghostEl, options.ghostClass, false); + toggleClass(ghostEl, options.fallbackClass, true); + toggleClass(ghostEl, options.dragClass, true); + css(ghostEl, 'transition', ''); + css(ghostEl, 'transform', ''); + css(ghostEl, 'box-sizing', 'border-box'); + css(ghostEl, 'margin', 0); + css(ghostEl, 'top', rect.top); + css(ghostEl, 'left', rect.left); + css(ghostEl, 'width', rect.width); + css(ghostEl, 'height', rect.height); + css(ghostEl, 'opacity', '0.8'); + css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed'); + css(ghostEl, 'zIndex', '100000'); + css(ghostEl, 'pointerEvents', 'none'); + Sortable.ghost = ghostEl; + container.appendChild(ghostEl); // Set transform-origin + + css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%'); + } + }, + _onDragStart: function _onDragStart( + /**Event*/ + evt, + /**boolean*/ + fallback) { + var _this = this; + + var dataTransfer = evt.dataTransfer; + var options = _this.options; + pluginEvent('dragStart', this, { + evt: evt + }); + + if (Sortable.eventCanceled) { + this._onDrop(); + + return; + } + + pluginEvent('setupClone', this); + + if (!Sortable.eventCanceled) { + cloneEl = clone(dragEl); + cloneEl.draggable = false; + cloneEl.style['will-change'] = ''; + + this._hideClone(); + + toggleClass(cloneEl, this.options.chosenClass, false); + Sortable.clone = cloneEl; + } // #1143: IFrame support workaround + + + _this.cloneId = _nextTick(function () { + pluginEvent('clone', _this); + if (Sortable.eventCanceled) return; + + if (!_this.options.removeCloneOnHide) { + rootEl.insertBefore(cloneEl, dragEl); + } + + _this._hideClone(); + + _dispatchEvent({ + sortable: _this, + name: 'clone' + }); + }); + !fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events + + if (fallback) { + ignoreNextClick = true; + _this._loopId = setInterval(_this._emulateDragOver, 50); + } else { + // Undo what was set in _prepareDragStart before drag started + off(document, 'mouseup', _this._onDrop); + off(document, 'touchend', _this._onDrop); + off(document, 'touchcancel', _this._onDrop); + + if (dataTransfer) { + dataTransfer.effectAllowed = 'move'; + options.setData && options.setData.call(_this, dataTransfer, dragEl); + } + + on(document, 'drop', _this); // #1276 fix: + + css(dragEl, 'transform', 'translateZ(0)'); + } + + awaitingDragStarted = true; + _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); + on(document, 'selectstart', _this); + moved = true; + + if (Safari) { + css(document.body, 'user-select', 'none'); + } + }, + // Returns true - if no further action is needed (either inserted or another condition) + _onDragOver: function _onDragOver( + /**Event*/ + evt) { + var el = this.el, + target = evt.target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable.active, + isOwner = activeGroup === group, + canSort = options.sort, + fromSortable = putSortable || activeSortable, + vertical, + _this = this, + completedFired = false; + + if (_silent) return; + + function dragOverEvent(name, extra) { + pluginEvent(name, _this, _objectSpread({ + evt: evt, + isOwner: isOwner, + axis: vertical ? 'vertical' : 'horizontal', + revert: revert, + dragRect: dragRect, + targetRect: targetRect, + canSort: canSort, + fromSortable: fromSortable, + target: target, + completed: completed, + onMove: function onMove(target, after) { + return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after); + }, + changed: changed + }, extra)); + } // Capture animation state + + + function capture() { + dragOverEvent('dragOverAnimationCapture'); + + _this.captureAnimationState(); + + if (_this !== fromSortable) { + fromSortable.captureAnimationState(); + } + } // Return invocation when dragEl is inserted (or completed) + + + function completed(insertion) { + dragOverEvent('dragOverCompleted', { + insertion: insertion + }); + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(_this); + } + + if (_this !== fromSortable) { + // Set ghost class to new sortable's ghost class + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); + toggleClass(dragEl, options.ghostClass, true); + } + + if (putSortable !== _this && _this !== Sortable.active) { + putSortable = _this; + } else if (_this === Sortable.active && putSortable) { + putSortable = null; + } // Animation + + + if (fromSortable === _this) { + _this._ignoreWhileAnimating = target; + } + + _this.animateAll(function () { + dragOverEvent('dragOverAnimationComplete'); + _this._ignoreWhileAnimating = null; + }); + + if (_this !== fromSortable) { + fromSortable.animateAll(); + fromSortable._ignoreWhileAnimating = null; + } + } // Null lastTarget if it is not inside a previously swapped element + + + if (target === dragEl && !dragEl.animated || target === el && !target.animated) { + lastTarget = null; + } // no bubbling and not fallback + + + if (!options.dragoverBubble && !evt.rootEl && target !== document) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted + + + !insertion && nearestEmptyInsertDetectEvent(evt); + } + + !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); + return completedFired = true; + } // Call when dragEl has been inserted + + + function changed() { + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + _dispatchEvent({ + sortable: _this, + name: 'change', + toEl: el, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + originalEvent: evt + }); + } + + if (evt.preventDefault !== void 0) { + evt.cancelable && evt.preventDefault(); + } + + target = closest(target, options.draggable, el, true); + dragOverEvent('dragOver'); + if (Sortable.eventCanceled) return completedFired; + + if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) { + return completed(false); + } + + ignoreNextClick = false; + + if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) { + vertical = this._getDirection(evt, target) === 'vertical'; + dragRect = getRect(dragEl); + dragOverEvent('dragOverValid'); + if (Sortable.eventCanceled) return completedFired; + + if (revert) { + parentEl = rootEl; // actualization + + capture(); + + this._hideClone(); + + dragOverEvent('revert'); + + if (!Sortable.eventCanceled) { + if (nextEl) { + rootEl.insertBefore(dragEl, nextEl); + } else { + rootEl.appendChild(dragEl); + } + } + + return completed(true); + } + + var elLastChild = lastChild(el, options.draggable); + + if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { + // If already at end of list: Do not insert + if (elLastChild === dragEl) { + return completed(false); + } // assign target only if condition is true + + + if (elLastChild && el === evt.target) { + target = elLastChild; + } + + if (target) { + targetRect = getRect(target); + } + + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { + capture(); + el.appendChild(dragEl); + parentEl = el; // actualization + + changed(); + return completed(true); + } + } else if (target.parentNode === el) { + targetRect = getRect(target); + var direction = 0, + targetBeforeFirstSwap, + differentLevel = dragEl.parentNode !== el, + differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), + side1 = vertical ? 'top' : 'left', + scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), + scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; + + if (lastTarget !== target) { + targetBeforeFirstSwap = targetRect[side1]; + pastFirstInvertThresh = false; + isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel; + } + + direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); + var sibling; + + if (direction !== 0) { + // Check if target is beside dragEl in respective direction (ignoring hidden elements) + var dragIndex = index(dragEl); + + do { + dragIndex -= direction; + sibling = parentEl.children[dragIndex]; + } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl)); + } // If dragEl is already beside target: Do not insert + + + if (direction === 0 || sibling === target) { + return completed(false); + } + + lastTarget = target; + lastDirection = direction; + var nextSibling = target.nextElementSibling, + after = false; + after = direction === 1; + + var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); + + if (moveVector !== false) { + if (moveVector === 1 || moveVector === -1) { + after = moveVector === 1; + } + + _silent = true; + setTimeout(_unsilent, 30); + capture(); + + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } // Undo chrome's scroll adjustment (has no effect on other browsers) + + + if (scrolledPastTop) { + scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); + } + + parentEl = dragEl.parentNode; // actualization + // must be done before animation + + if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { + targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]); + } + + changed(); + return completed(true); + } + } + + if (el.contains(dragEl)) { + return completed(false); + } + } + + return false; + }, + _ignoreWhileAnimating: null, + _offMoveEvents: function _offMoveEvents() { + off(document, 'mousemove', this._onTouchMove); + off(document, 'touchmove', this._onTouchMove); + off(document, 'pointermove', this._onTouchMove); + off(document, 'dragover', nearestEmptyInsertDetectEvent); + off(document, 'mousemove', nearestEmptyInsertDetectEvent); + off(document, 'touchmove', nearestEmptyInsertDetectEvent); + }, + _offUpEvents: function _offUpEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._onDrop); + off(ownerDocument, 'touchend', this._onDrop); + off(ownerDocument, 'pointerup', this._onDrop); + off(ownerDocument, 'touchcancel', this._onDrop); + off(document, 'selectstart', this); + }, + _onDrop: function _onDrop( + /**Event*/ + evt) { + var el = this.el, + options = this.options; // Get the index of the dragged element within its parent + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + pluginEvent('drop', this, { + evt: evt + }); + parentEl = dragEl && dragEl.parentNode; // Get again after plugin event + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + if (Sortable.eventCanceled) { + this._nulling(); + + return; + } + + awaitingDragStarted = false; + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + clearInterval(this._loopId); + clearTimeout(this._dragStartTimer); + + _cancelNextTick(this.cloneId); + + _cancelNextTick(this._dragStartId); // Unbind events + + + if (this.nativeDraggable) { + off(document, 'drop', this); + off(el, 'dragstart', this._onDragStart); + } + + this._offMoveEvents(); + + this._offUpEvents(); + + if (Safari) { + css(document.body, 'user-select', ''); + } + + if (evt) { + if (moved) { + evt.cancelable && evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } + + ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + // Remove clone(s) + cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); + } + + if (dragEl) { + if (this.nativeDraggable) { + off(dragEl, 'dragend', this); + } + + _disableDraggable(dragEl); + + dragEl.style['will-change'] = ''; // Remove classes + // ghostClass is added in dragStarted + + if (moved && !awaitingDragStarted) { + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); + } + + toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event + + _dispatchEvent({ + sortable: this, + name: 'unchoose', + toEl: parentEl, + newIndex: null, + newDraggableIndex: null, + originalEvent: evt + }); + + if (rootEl !== parentEl) { + if (newIndex >= 0) { + // Add event + _dispatchEvent({ + rootEl: parentEl, + name: 'add', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); // Remove event + + + _dispatchEvent({ + sortable: this, + name: 'remove', + toEl: parentEl, + originalEvent: evt + }); // drag from one list and drop into another + + + _dispatchEvent({ + rootEl: parentEl, + name: 'sort', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + + putSortable && putSortable.save(); + } else { + if (newIndex !== oldIndex) { + if (newIndex >= 0) { + // drag & drop within the same list + _dispatchEvent({ + sortable: this, + name: 'update', + toEl: parentEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + } + } + + if (Sortable.active) { + /* jshint eqnull:true */ + if (newIndex == null || newIndex === -1) { + newIndex = oldIndex; + newDraggableIndex = oldDraggableIndex; + } + + _dispatchEvent({ + sortable: this, + name: 'end', + toEl: parentEl, + originalEvent: evt + }); // Save sorting + + + this.save(); + } + } + } + + this._nulling(); + }, + _nulling: function _nulling() { + pluginEvent('nulling', this); + rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null; + savedInputChecked.forEach(function (el) { + el.checked = true; + }); + savedInputChecked.length = lastDx = lastDy = 0; + }, + handleEvent: function handleEvent( + /**Event*/ + evt) { + switch (evt.type) { + case 'drop': + case 'dragend': + this._onDrop(evt); + + break; + + case 'dragenter': + case 'dragover': + if (dragEl) { + this._onDragOver(evt); + + _globalDragOver(evt); + } + + break; + + case 'selectstart': + evt.preventDefault(); + break; + } + }, + + /** + * Serializes the item into an array of string. + * @returns {String[]} + */ + toArray: function toArray() { + var order = [], + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; + + for (; i < n; i++) { + el = children[i]; + + if (closest(el, options.draggable, this.el, false)) { + order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); + } + } + + return order; + }, + + /** + * Sorts the elements according to the array. + * @param {String[]} order order of the items + */ + sort: function sort(order) { + var items = {}, + rootEl = this.el; + this.toArray().forEach(function (id, i) { + var el = rootEl.children[i]; + + if (closest(el, this.options.draggable, rootEl, false)) { + items[id] = el; + } + }, this); + order.forEach(function (id) { + if (items[id]) { + rootEl.removeChild(items[id]); + rootEl.appendChild(items[id]); + } + }); + }, + + /** + * Save the current sorting + */ + save: function save() { + var store = this.options.store; + store && store.set && store.set(this); + }, + + /** + * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + * @param {HTMLElement} el + * @param {String} [selector] default: `options.draggable` + * @returns {HTMLElement|null} + */ + closest: function closest$1(el, selector) { + return closest(el, selector || this.options.draggable, this.el, false); + }, + + /** + * Set/get option + * @param {string} name + * @param {*} [value] + * @returns {*} + */ + option: function option(name, value) { + var options = this.options; + + if (value === void 0) { + return options[name]; + } else { + var modifiedValue = PluginManager.modifyOption(this, name, value); + + if (typeof modifiedValue !== 'undefined') { + options[name] = modifiedValue; + } else { + options[name] = value; + } + + if (name === 'group') { + _prepareGroup(options); + } + } + }, + + /** + * Destroy + */ + destroy: function destroy() { + pluginEvent('destroy', this); + var el = this.el; + el[expando] = null; + off(el, 'mousedown', this._onTapStart); + off(el, 'touchstart', this._onTapStart); + off(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + off(el, 'dragover', this); + off(el, 'dragenter', this); + } // Remove draggable attributes + + + Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { + el.removeAttribute('draggable'); + }); + + this._onDrop(); + + sortables.splice(sortables.indexOf(this.el), 1); + this.el = el = null; + }, + _hideClone: function _hideClone() { + if (!cloneHidden) { + pluginEvent('hideClone', this); + if (Sortable.eventCanceled) return; + css(cloneEl, 'display', 'none'); + + if (this.options.removeCloneOnHide && cloneEl.parentNode) { + cloneEl.parentNode.removeChild(cloneEl); + } + + cloneHidden = true; + } + }, + _showClone: function _showClone(putSortable) { + if (putSortable.lastPutMode !== 'clone') { + this._hideClone(); + + return; + } + + if (cloneHidden) { + pluginEvent('showClone', this); + if (Sortable.eventCanceled) return; // show clone at dragEl or original position + + if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + rootEl.insertBefore(cloneEl, dragEl); + } else if (nextEl) { + rootEl.insertBefore(cloneEl, nextEl); + } else { + rootEl.appendChild(cloneEl); + } + + if (this.options.group.revertClone) { + this.animate(dragEl, cloneEl); + } + + css(cloneEl, 'display', ''); + cloneHidden = false; + } + } +}; + +function _globalDragOver( +/**Event*/ +evt) { + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } + + evt.cancelable && evt.preventDefault(); +} + +function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) { + var evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent('move', { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + } + + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || getRect(toEl); + evt.willInsertAfter = willInsertAfter; + evt.originalEvent = originalEvent; + fromEl.dispatchEvent(evt); + + if (onMoveFn) { + retVal = onMoveFn.call(sortable, evt, originalEvent); + } + + return retVal; +} + +function _disableDraggable(el) { + el.draggable = false; +} + +function _unsilent() { + _silent = false; +} + +function _ghostIsLast(evt, vertical, sortable) { + var rect = getRect(lastChild(sortable.el, sortable.options.draggable)); + var spacer = 10; + return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer; +} + +function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { + var mouseOnAxis = vertical ? evt.clientY : evt.clientX, + targetLength = vertical ? targetRect.height : targetRect.width, + targetS1 = vertical ? targetRect.top : targetRect.left, + targetS2 = vertical ? targetRect.bottom : targetRect.right, + invert = false; + + if (!invertSwap) { + // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold + if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { + // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 + // check if past first invert threshold on side opposite of lastDirection + if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) { + // past first invert threshold, do not restrict inverted threshold to dragEl shadow + pastFirstInvertThresh = true; + } + + if (!pastFirstInvertThresh) { + // dragEl shadow (target move distance shadow) + if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow + : mouseOnAxis > targetS2 - targetMoveDistance) { + return -lastDirection; + } + } else { + invert = true; + } + } else { + // Regular + if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) { + return _getInsertDirection(target); + } + } + } + + invert = invert || invertSwap; + + if (invert) { + // Invert of regular + if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) { + return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1; + } + } + + return 0; +} +/** + * Gets the direction dragEl must be swapped relative to target in order to make it + * seem that dragEl has been "inserted" into that element's position + * @param {HTMLElement} target The target whose position dragEl is being inserted at + * @return {Number} Direction dragEl must be swapped + */ + + +function _getInsertDirection(target) { + if (index(dragEl) < index(target)) { + return 1; + } else { + return -1; + } +} +/** + * Generate id + * @param {HTMLElement} el + * @returns {String} + * @private + */ + + +function _generateId(el) { + var str = el.tagName + el.className + el.src + el.href + el.textContent, + i = str.length, + sum = 0; + + while (i--) { + sum += str.charCodeAt(i); + } + + return sum.toString(36); +} + +function _saveInputCheckedState(root) { + savedInputChecked.length = 0; + var inputs = root.getElementsByTagName('input'); + var idx = inputs.length; + + while (idx--) { + var el = inputs[idx]; + el.checked && savedInputChecked.push(el); + } +} + +function _nextTick(fn) { + return setTimeout(fn, 0); +} + +function _cancelNextTick(id) { + return clearTimeout(id); +} // Fixed #973: + + +if (documentExists) { + on(document, 'touchmove', function (evt) { + if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { + evt.preventDefault(); + } + }); +} // Export utils + + +Sortable.utils = { + on: on, + off: off, + css: css, + find: find, + is: function is(el, selector) { + return !!closest(el, selector, el, false); + }, + extend: extend, + throttle: throttle, + closest: closest, + toggleClass: toggleClass, + clone: clone, + index: index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick, + detectDirection: _detectDirection, + getChild: getChild +}; +/** + * Get the Sortable instance of an element + * @param {HTMLElement} element The element + * @return {Sortable|undefined} The instance of Sortable + */ + +Sortable.get = function (element) { + return element[expando]; +}; +/** + * Mount a plugin to Sortable + * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted + */ + + +Sortable.mount = function () { + for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { + plugins[_key] = arguments[_key]; + } + + if (plugins[0].constructor === Array) plugins = plugins[0]; + plugins.forEach(function (plugin) { + if (!plugin.prototype || !plugin.prototype.constructor) { + throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin)); + } + + if (plugin.utils) Sortable.utils = _objectSpread({}, Sortable.utils, plugin.utils); + PluginManager.mount(plugin); + }); +}; +/** + * Create sortable instance + * @param {HTMLElement} el + * @param {Object} [options] + */ + + +Sortable.create = function (el, options) { + return new Sortable(el, options); +}; // Export + + +Sortable.version = version; + +var autoScrolls = [], + scrollEl, + scrollRootEl, + scrolling = false, + lastAutoScrollX, + lastAutoScrollY, + touchEvt$1, + pointerElemChangedInterval; + +function AutoScrollPlugin() { + function AutoScroll() { + this.defaults = { + scroll: true, + scrollSensitivity: 30, + scrollSpeed: 10, + bubbleScroll: true + }; // Bind all private methods + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + } + + AutoScroll.prototype = { + dragStarted: function dragStarted(_ref) { + var originalEvent = _ref.originalEvent; + + if (this.sortable.nativeDraggable) { + on(document, 'dragover', this._handleAutoScroll); + } else { + if (this.options.supportPointer) { + on(document, 'pointermove', this._handleFallbackAutoScroll); + } else if (originalEvent.touches) { + on(document, 'touchmove', this._handleFallbackAutoScroll); + } else { + on(document, 'mousemove', this._handleFallbackAutoScroll); + } + } + }, + dragOverCompleted: function dragOverCompleted(_ref2) { + var originalEvent = _ref2.originalEvent; + + // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) + if (!this.options.dragOverBubble && !originalEvent.rootEl) { + this._handleAutoScroll(originalEvent); + } + }, + drop: function drop() { + if (this.sortable.nativeDraggable) { + off(document, 'dragover', this._handleAutoScroll); + } else { + off(document, 'pointermove', this._handleFallbackAutoScroll); + off(document, 'touchmove', this._handleFallbackAutoScroll); + off(document, 'mousemove', this._handleFallbackAutoScroll); + } + + clearPointerElemChangedInterval(); + clearAutoScrolls(); + cancelThrottle(); + }, + nulling: function nulling() { + touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null; + autoScrolls.length = 0; + }, + _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) { + this._handleAutoScroll(evt, true); + }, + _handleAutoScroll: function _handleAutoScroll(evt, fallback) { + var _this = this; + + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + elem = document.elementFromPoint(x, y); + touchEvt$1 = evt; // IE does not seem to have native autoscroll, + // Edge's autoscroll seems too conditional, + // MACOS Safari does not have autoscroll, + // Firefox and Chrome are good + + if (fallback || Edge || IE11OrLess || Safari) { + autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change + + var ogElemScroller = getParentAutoScrollElement(elem, true); + + if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) { + pointerElemChangedInterval && clearPointerElemChangedInterval(); // Detect for pointer elem change, emulating native DnD behaviour + + pointerElemChangedInterval = setInterval(function () { + var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true); + + if (newElem !== ogElemScroller) { + ogElemScroller = newElem; + clearAutoScrolls(); + } + + autoScroll(evt, _this.options, newElem, fallback); + }, 10); + lastAutoScrollX = x; + lastAutoScrollY = y; + } + } else { + // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll + if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { + clearAutoScrolls(); + return; + } + + autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false); + } + } + }; + return _extends(AutoScroll, { + pluginName: 'scroll', + initializeByDefault: true + }); +} + +function clearAutoScrolls() { + autoScrolls.forEach(function (autoScroll) { + clearInterval(autoScroll.pid); + }); + autoScrolls = []; +} + +function clearPointerElemChangedInterval() { + clearInterval(pointerElemChangedInterval); +} + +var autoScroll = throttle(function (evt, options, rootEl, isFallback) { + // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + if (!options.scroll) return; + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + sens = options.scrollSensitivity, + speed = options.scrollSpeed, + winScroller = getWindowScrollingElement(); + var scrollThisInstance = false, + scrollCustomFn; // New scroll root, set scrollEl + + if (scrollRootEl !== rootEl) { + scrollRootEl = rootEl; + clearAutoScrolls(); + scrollEl = options.scroll; + scrollCustomFn = options.scrollFn; + + if (scrollEl === true) { + scrollEl = getParentAutoScrollElement(rootEl, true); + } + } + + var layersOut = 0; + var currentParent = scrollEl; + + do { + var el = currentParent, + rect = getRect(el), + top = rect.top, + bottom = rect.bottom, + left = rect.left, + right = rect.right, + width = rect.width, + height = rect.height, + canScrollX = void 0, + canScrollY = void 0, + scrollWidth = el.scrollWidth, + scrollHeight = el.scrollHeight, + elCSS = css(el), + scrollPosX = el.scrollLeft, + scrollPosY = el.scrollTop; + + if (el === winScroller) { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible'); + } else { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); + } + + var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX); + var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY); + + if (!autoScrolls[layersOut]) { + for (var i = 0; i <= layersOut; i++) { + if (!autoScrolls[i]) { + autoScrolls[i] = {}; + } + } + } + + if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { + autoScrolls[layersOut].el = el; + autoScrolls[layersOut].vx = vx; + autoScrolls[layersOut].vy = vy; + clearInterval(autoScrolls[layersOut].pid); + + if (vx != 0 || vy != 0) { + scrollThisInstance = true; + /* jshint loopfunc:true */ + + autoScrolls[layersOut].pid = setInterval(function () { + // emulate drag over during autoscroll (fallback), emulating native DnD behaviour + if (isFallback && this.layer === 0) { + Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely + + } + + var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; + var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; + + if (typeof scrollCustomFn === 'function') { + if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') { + return; + } + } + + scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); + }.bind({ + layer: layersOut + }), 24); + } + } + + layersOut++; + } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false))); + + scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not +}, 30); + +var drop = function drop(_ref) { + var originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + dragEl = _ref.dragEl, + activeSortable = _ref.activeSortable, + dispatchSortableEvent = _ref.dispatchSortableEvent, + hideGhostForTarget = _ref.hideGhostForTarget, + unhideGhostForTarget = _ref.unhideGhostForTarget; + if (!originalEvent) return; + var toSortable = putSortable || activeSortable; + hideGhostForTarget(); + var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent; + var target = document.elementFromPoint(touch.clientX, touch.clientY); + unhideGhostForTarget(); + + if (toSortable && !toSortable.el.contains(target)) { + dispatchSortableEvent('spill'); + this.onSpill({ + dragEl: dragEl, + putSortable: putSortable + }); + } +}; + +function Revert() {} + +Revert.prototype = { + startIndex: null, + dragStart: function dragStart(_ref2) { + var oldDraggableIndex = _ref2.oldDraggableIndex; + this.startIndex = oldDraggableIndex; + }, + onSpill: function onSpill(_ref3) { + var dragEl = _ref3.dragEl, + putSortable = _ref3.putSortable; + this.sortable.captureAnimationState(); + + if (putSortable) { + putSortable.captureAnimationState(); + } + + var nextSibling = getChild(this.sortable.el, this.startIndex, this.options); + + if (nextSibling) { + this.sortable.el.insertBefore(dragEl, nextSibling); + } else { + this.sortable.el.appendChild(dragEl); + } + + this.sortable.animateAll(); + + if (putSortable) { + putSortable.animateAll(); + } + }, + drop: drop +}; + +_extends(Revert, { + pluginName: 'revertOnSpill' +}); + +function Remove() {} + +Remove.prototype = { + onSpill: function onSpill(_ref4) { + var dragEl = _ref4.dragEl, + putSortable = _ref4.putSortable; + var parentSortable = putSortable || this.sortable; + parentSortable.captureAnimationState(); + dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); + parentSortable.animateAll(); + }, + drop: drop +}; + +_extends(Remove, { + pluginName: 'removeOnSpill' +}); + +var lastSwapEl; + +function SwapPlugin() { + function Swap() { + this.defaults = { + swapClass: 'sortable-swap-highlight' + }; + } + + Swap.prototype = { + dragStart: function dragStart(_ref) { + var dragEl = _ref.dragEl; + lastSwapEl = dragEl; + }, + dragOverValid: function dragOverValid(_ref2) { + var completed = _ref2.completed, + target = _ref2.target, + onMove = _ref2.onMove, + activeSortable = _ref2.activeSortable, + changed = _ref2.changed, + cancel = _ref2.cancel; + if (!activeSortable.options.swap) return; + var el = this.sortable.el, + options = this.options; + + if (target && target !== el) { + var prevSwapEl = lastSwapEl; + + if (onMove(target) !== false) { + toggleClass(target, options.swapClass, true); + lastSwapEl = target; + } else { + lastSwapEl = null; + } + + if (prevSwapEl && prevSwapEl !== lastSwapEl) { + toggleClass(prevSwapEl, options.swapClass, false); + } + } + + changed(); + completed(true); + cancel(); + }, + drop: function drop(_ref3) { + var activeSortable = _ref3.activeSortable, + putSortable = _ref3.putSortable, + dragEl = _ref3.dragEl; + var toSortable = putSortable || this.sortable; + var options = this.options; + lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); + + if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { + if (dragEl !== lastSwapEl) { + toSortable.captureAnimationState(); + if (toSortable !== activeSortable) activeSortable.captureAnimationState(); + swapNodes(dragEl, lastSwapEl); + toSortable.animateAll(); + if (toSortable !== activeSortable) activeSortable.animateAll(); + } + } + }, + nulling: function nulling() { + lastSwapEl = null; + } + }; + return _extends(Swap, { + pluginName: 'swap', + eventProperties: function eventProperties() { + return { + swapItem: lastSwapEl + }; + } + }); +} + +function swapNodes(n1, n2) { + var p1 = n1.parentNode, + p2 = n2.parentNode, + i1, + i2; + if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; + i1 = index(n1); + i2 = index(n2); + + if (p1.isEqualNode(p2) && i1 < i2) { + i2++; + } + + p1.insertBefore(n2, p1.children[i1]); + p2.insertBefore(n1, p2.children[i2]); +} + +var multiDragElements = [], + multiDragClones = [], + lastMultiDragSelect, + // for selection with modifier key down (SHIFT) +multiDragSortable, + initialFolding = false, + // Initial multi-drag fold when drag started +folding = false, + // Folding any other time +dragStarted = false, + dragEl$1, + clonesFromRect, + clonesHidden; + +function MultiDragPlugin() { + function MultiDrag(sortable) { + // Bind all private methods + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + if (sortable.options.supportPointer) { + on(document, 'pointerup', this._deselectMultiDrag); + } else { + on(document, 'mouseup', this._deselectMultiDrag); + on(document, 'touchend', this._deselectMultiDrag); + } + + on(document, 'keydown', this._checkKeyDown); + on(document, 'keyup', this._checkKeyUp); + this.defaults = { + selectedClass: 'sortable-selected', + multiDragKey: null, + setData: function setData(dataTransfer, dragEl) { + var data = ''; + + if (multiDragElements.length && multiDragSortable === sortable) { + multiDragElements.forEach(function (multiDragElement, i) { + data += (!i ? '' : ', ') + multiDragElement.textContent; + }); + } else { + data = dragEl.textContent; + } + + dataTransfer.setData('Text', data); + } + }; + } + + MultiDrag.prototype = { + multiDragKeyDown: false, + isMultiDrag: false, + delayStartGlobal: function delayStartGlobal(_ref) { + var dragged = _ref.dragEl; + dragEl$1 = dragged; + }, + delayEnded: function delayEnded() { + this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1); + }, + setupClone: function setupClone(_ref2) { + var sortable = _ref2.sortable, + cancel = _ref2.cancel; + if (!this.isMultiDrag) return; + + for (var i = 0; i < multiDragElements.length; i++) { + multiDragClones.push(clone(multiDragElements[i])); + multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; + multiDragClones[i].draggable = false; + multiDragClones[i].style['will-change'] = ''; + toggleClass(multiDragClones[i], this.options.selectedClass, false); + multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false); + } + + sortable._hideClone(); + + cancel(); + }, + clone: function clone(_ref3) { + var sortable = _ref3.sortable, + rootEl = _ref3.rootEl, + dispatchSortableEvent = _ref3.dispatchSortableEvent, + cancel = _ref3.cancel; + if (!this.isMultiDrag) return; + + if (!this.options.removeCloneOnHide) { + if (multiDragElements.length && multiDragSortable === sortable) { + insertMultiDragClones(true, rootEl); + dispatchSortableEvent('clone'); + cancel(); + } + } + }, + showClone: function showClone(_ref4) { + var cloneNowShown = _ref4.cloneNowShown, + rootEl = _ref4.rootEl, + cancel = _ref4.cancel; + if (!this.isMultiDrag) return; + insertMultiDragClones(false, rootEl); + multiDragClones.forEach(function (clone) { + css(clone, 'display', ''); + }); + cloneNowShown(); + clonesHidden = false; + cancel(); + }, + hideClone: function hideClone(_ref5) { + var _this = this; + + var sortable = _ref5.sortable, + cloneNowHidden = _ref5.cloneNowHidden, + cancel = _ref5.cancel; + if (!this.isMultiDrag) return; + multiDragClones.forEach(function (clone) { + css(clone, 'display', 'none'); + + if (_this.options.removeCloneOnHide && clone.parentNode) { + clone.parentNode.removeChild(clone); + } + }); + cloneNowHidden(); + clonesHidden = true; + cancel(); + }, + dragStartGlobal: function dragStartGlobal(_ref6) { + var sortable = _ref6.sortable; + + if (!this.isMultiDrag && multiDragSortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + } + + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.sortableIndex = index(multiDragElement); + }); // Sort multi-drag elements + + multiDragElements = multiDragElements.sort(function (a, b) { + return a.sortableIndex - b.sortableIndex; + }); + dragStarted = true; + }, + dragStarted: function dragStarted(_ref7) { + var _this2 = this; + + var sortable = _ref7.sortable; + if (!this.isMultiDrag) return; + + if (this.options.sort) { + // Capture rects, + // hide multi drag elements (by positioning them absolute), + // set multi drag elements rects to dragRect, + // show multi drag elements, + // animate to rects, + // unset rects & remove from DOM + sortable.captureAnimationState(); + + if (this.options.animation) { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + css(multiDragElement, 'position', 'absolute'); + }); + var dragRect = getRect(dragEl$1, false, true, true); + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRect); + }); + folding = true; + initialFolding = true; + } + } + + sortable.animateAll(function () { + folding = false; + initialFolding = false; + + if (_this2.options.animation) { + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); + } // Remove all auxiliary multidrag items from el, if sorting enabled + + + if (_this2.options.sort) { + removeMultiDragElements(); + } + }); + }, + dragOver: function dragOver(_ref8) { + var target = _ref8.target, + completed = _ref8.completed, + cancel = _ref8.cancel; + + if (folding && ~multiDragElements.indexOf(target)) { + completed(false); + cancel(); + } + }, + revert: function revert(_ref9) { + var fromSortable = _ref9.fromSortable, + rootEl = _ref9.rootEl, + sortable = _ref9.sortable, + dragRect = _ref9.dragRect; + + if (multiDragElements.length > 1) { + // Setup unfold animation + multiDragElements.forEach(function (multiDragElement) { + sortable.addAnimationState({ + target: multiDragElement, + rect: folding ? getRect(multiDragElement) : dragRect + }); + unsetRect(multiDragElement); + multiDragElement.fromRect = dragRect; + fromSortable.removeAnimationState(multiDragElement); + }); + folding = false; + insertMultiDragElements(!this.options.removeCloneOnHide, rootEl); + } + }, + dragOverCompleted: function dragOverCompleted(_ref10) { + var sortable = _ref10.sortable, + isOwner = _ref10.isOwner, + insertion = _ref10.insertion, + activeSortable = _ref10.activeSortable, + parentEl = _ref10.parentEl, + putSortable = _ref10.putSortable; + var options = this.options; + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } + + initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location + + if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { + // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible + var dragRectAbsolute = getRect(dragEl$1, false, true, true); + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted + // while folding, and so that we can capture them again because old sortable will no longer be fromSortable + + parentEl.appendChild(multiDragElement); + }); + folding = true; + } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out + + + if (!isOwner) { + // Only remove if not folding (folding will remove them anyways) + if (!folding) { + removeMultiDragElements(); + } + + if (multiDragElements.length > 1) { + var clonesHiddenBefore = clonesHidden; + + activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden + + + if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { + multiDragClones.forEach(function (clone) { + activeSortable.addAnimationState({ + target: clone, + rect: clonesFromRect + }); + clone.fromRect = clonesFromRect; + clone.thisAnimationDuration = null; + }); + } + } else { + activeSortable._showClone(sortable); + } + } + } + }, + dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) { + var dragRect = _ref11.dragRect, + isOwner = _ref11.isOwner, + activeSortable = _ref11.activeSortable; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + }); + + if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { + clonesFromRect = _extends({}, dragRect); + var dragMatrix = matrix(dragEl$1, true); + clonesFromRect.top -= dragMatrix.f; + clonesFromRect.left -= dragMatrix.e; + } + }, + dragOverAnimationComplete: function dragOverAnimationComplete() { + if (folding) { + folding = false; + removeMultiDragElements(); + } + }, + drop: function drop(_ref12) { + var evt = _ref12.originalEvent, + rootEl = _ref12.rootEl, + parentEl = _ref12.parentEl, + sortable = _ref12.sortable, + dispatchSortableEvent = _ref12.dispatchSortableEvent, + oldIndex = _ref12.oldIndex, + putSortable = _ref12.putSortable; + var toSortable = putSortable || this.sortable; + if (!evt) return; + var options = this.options, + children = parentEl.children; // Multi-drag selection + + if (!dragStarted) { + if (options.multiDragKey && !this.multiDragKeyDown) { + this._deselectMultiDrag(); + } + + toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1)); + + if (!~multiDragElements.indexOf(dragEl$1)) { + multiDragElements.push(dragEl$1); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: dragEl$1, + originalEvt: evt + }); // Modifier activated, select from last to dragEl + + if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { + var lastIndex = index(lastMultiDragSelect), + currentIndex = index(dragEl$1); + + if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { + // Must include lastMultiDragSelect (select it), in case modified selection from no selection + // (but previous selection existed) + var n, i; + + if (currentIndex > lastIndex) { + i = lastIndex; + n = currentIndex; + } else { + i = currentIndex; + n = lastIndex + 1; + } + + for (; i < n; i++) { + if (~multiDragElements.indexOf(children[i])) continue; + toggleClass(children[i], options.selectedClass, true); + multiDragElements.push(children[i]); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: children[i], + originalEvt: evt + }); + } + } + } else { + lastMultiDragSelect = dragEl$1; + } + + multiDragSortable = toSortable; + } else { + multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1); + lastMultiDragSelect = null; + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'deselect', + targetEl: dragEl$1, + originalEvt: evt + }); + } + } // Multi-drag drop + + + if (dragStarted && this.isMultiDrag) { + // Do not "unfold" after around dragEl if reverted + if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { + var dragRect = getRect(dragEl$1), + multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); + if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null; + toSortable.captureAnimationState(); + + if (!initialFolding) { + if (options.animation) { + dragEl$1.fromRect = dragRect; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + + if (multiDragElement !== dragEl$1) { + var rect = folding ? getRect(multiDragElement) : dragRect; + multiDragElement.fromRect = rect; // Prepare unfold animation + + toSortable.addAnimationState({ + target: multiDragElement, + rect: rect + }); + } + }); + } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert + // properly they must all be removed + + + removeMultiDragElements(); + multiDragElements.forEach(function (multiDragElement) { + if (children[multiDragIndex]) { + parentEl.insertBefore(multiDragElement, children[multiDragIndex]); + } else { + parentEl.appendChild(multiDragElement); + } + + multiDragIndex++; + }); // If initial folding is done, the elements may have changed position because they are now + // unfolding around dragEl, even though dragEl may not have his index changed, so update event + // must be fired here as Sortable will not. + + if (oldIndex === index(dragEl$1)) { + var update = false; + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement.sortableIndex !== index(multiDragElement)) { + update = true; + return; + } + }); + + if (update) { + dispatchSortableEvent('update'); + } + } + } // Must be done after capturing individual rects (scroll bar) + + + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); + toSortable.animateAll(); + } + + multiDragSortable = toSortable; + } // Remove clones if necessary + + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + multiDragClones.forEach(function (clone) { + clone.parentNode && clone.parentNode.removeChild(clone); + }); + } + }, + nullingGlobal: function nullingGlobal() { + this.isMultiDrag = dragStarted = false; + multiDragClones.length = 0; + }, + destroyGlobal: function destroyGlobal() { + this._deselectMultiDrag(); + + off(document, 'pointerup', this._deselectMultiDrag); + off(document, 'mouseup', this._deselectMultiDrag); + off(document, 'touchend', this._deselectMultiDrag); + off(document, 'keydown', this._checkKeyDown); + off(document, 'keyup', this._checkKeyUp); + }, + _deselectMultiDrag: function _deselectMultiDrag(evt) { + if (dragStarted) return; // Only deselect if selection is in this sortable + + if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable + + if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click + + if (evt && evt.button !== 0) return; + + while (multiDragElements.length) { + var el = multiDragElements[0]; + toggleClass(el, this.options.selectedClass, false); + multiDragElements.shift(); + dispatchEvent({ + sortable: this.sortable, + rootEl: this.sortable.el, + name: 'deselect', + targetEl: el, + originalEvt: evt + }); + } + }, + _checkKeyDown: function _checkKeyDown(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = true; + } + }, + _checkKeyUp: function _checkKeyUp(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = false; + } + } + }; + return _extends(MultiDrag, { + // Static methods & properties + pluginName: 'multiDrag', + utils: { + /** + * Selects the provided multi-drag item + * @param {HTMLElement} el The element to be selected + */ + select: function select(el) { + var sortable = el.parentNode[expando]; + if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return; + + if (multiDragSortable && multiDragSortable !== sortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + + multiDragSortable = sortable; + } + + toggleClass(el, sortable.options.selectedClass, true); + multiDragElements.push(el); + }, + + /** + * Deselects the provided multi-drag item + * @param {HTMLElement} el The element to be deselected + */ + deselect: function deselect(el) { + var sortable = el.parentNode[expando], + index = multiDragElements.indexOf(el); + if (!sortable || !sortable.options.multiDrag || !~index) return; + toggleClass(el, sortable.options.selectedClass, false); + multiDragElements.splice(index, 1); + } + }, + eventProperties: function eventProperties() { + var _this3 = this; + + var oldIndicies = [], + newIndicies = []; + multiDragElements.forEach(function (multiDragElement) { + oldIndicies.push({ + multiDragElement: multiDragElement, + index: multiDragElement.sortableIndex + }); // multiDragElements will already be sorted if folding + + var newIndex; + + if (folding && multiDragElement !== dragEl$1) { + newIndex = -1; + } else if (folding) { + newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')'); + } else { + newIndex = index(multiDragElement); + } + + newIndicies.push({ + multiDragElement: multiDragElement, + index: newIndex + }); + }); + return { + items: _toConsumableArray(multiDragElements), + clones: [].concat(multiDragClones), + oldIndicies: oldIndicies, + newIndicies: newIndicies + }; + }, + optionListeners: { + multiDragKey: function multiDragKey(key) { + key = key.toLowerCase(); + + if (key === 'ctrl') { + key = 'Control'; + } else if (key.length > 1) { + key = key.charAt(0).toUpperCase() + key.substr(1); + } + + return key; + } + } + }); +} + +function insertMultiDragElements(clonesInserted, rootEl) { + multiDragElements.forEach(function (multiDragElement, i) { + var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(multiDragElement, target); + } else { + rootEl.appendChild(multiDragElement); + } + }); +} +/** + * Insert multi-drag clones + * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted + * @param {HTMLElement} rootEl + */ + + +function insertMultiDragClones(elementsInserted, rootEl) { + multiDragClones.forEach(function (clone, i) { + var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(clone, target); + } else { + rootEl.appendChild(clone); + } + }); +} + +function removeMultiDragElements() { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement); + }); +} + +Sortable.mount(new AutoScrollPlugin()); +Sortable.mount(Remove, Revert); + +export default Sortable; +export { MultiDragPlugin as MultiDrag, Sortable, SwapPlugin as Swap }; diff --git a/public/assets/libs/Sortable/package-lock.json b/public/assets/libs/Sortable/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..e14c8db0feabc512c572e769b7d5611e44c72505 --- /dev/null +++ b/public/assets/libs/Sortable/package-lock.json @@ -0,0 +1,5704 @@ +{ + "name": "sortablejs", + "version": "1.10.0-rc3", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz", + "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helpers": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.5", + "@babel/types": "^7.4.4", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", + "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-define-map": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", + "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.4.4", + "lodash": "^4.17.11" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", + "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", + "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", + "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/types": "^7.4.4", + "lodash": "^4.17.11" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", + "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", + "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "dev": true, + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", + "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "dev": true, + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", + "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", + "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", + "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", + "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", + "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", + "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.11" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", + "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-split-export-declaration": "^7.4.4", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", + "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", + "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", + "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", + "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", + "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", + "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", + "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", + "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", + "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", + "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", + "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", + "dev": true, + "requires": { + "regexp-tree": "^0.1.6" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", + "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-assign": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.2.0.tgz", + "integrity": "sha512-nmE55cZBPFgUktbF2OuoZgPRadfxosLOpSgzEPYotKSls9J4pEPcembi8r78RU37Rph6UApCpNmsQA4QMWK9Ng==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", + "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", + "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.4.4", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", + "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", + "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", + "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", + "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", + "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", + "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/preset-env": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.5.tgz", + "integrity": "sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.4.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.4.4", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.4.4", + "@babel/plugin-transform-classes": "^7.4.4", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.4.4", + "@babel/plugin-transform-function-name": "^7.4.4", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-member-expression-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.2.0", + "@babel/plugin-transform-modules-commonjs": "^7.4.4", + "@babel/plugin-transform-modules-systemjs": "^7.4.4", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", + "@babel/plugin-transform-new-target": "^7.4.4", + "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-parameters": "^7.4.4", + "@babel/plugin-transform-property-literals": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.4.5", + "@babel/plugin-transform-reserved-words": "^7.2.0", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.4.4", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "browserslist": "^4.6.0", + "core-js-compat": "^3.1.1", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.5.0" + } + }, + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/traverse": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", + "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/types": "^7.4.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "@types/error-stack-parser": { + "version": "1.3.18", + "resolved": "https://registry.npmjs.org/@types/error-stack-parser/-/error-stack-parser-1.3.18.tgz", + "integrity": "sha1-4ByfjIXKg7YQMgxiJYsMkCat4Pc=", + "dev": true + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/lodash": { + "version": "4.14.135", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.135.tgz", + "integrity": "sha512-Ed+tSZ9qM1oYpi5kzdsBuOzcAIn1wDW+e8TFJ50IMJMlSopGdJgKAbhHzN6h1E1OfjlGOr2JepzEWtg9NIfoNg==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz", + "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", + "dev": true + }, + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "acorn-hammerhead": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/acorn-hammerhead/-/acorn-hammerhead-0.2.0.tgz", + "integrity": "sha512-kbX1s/0ZikW0WEBY6IrooFgX3AP2D9ycTg0OhxRYLF0Tew/bDK2+8lTxFR4cDdoCZm6Ax8eVf8EV6gbTtr8EYQ==", + "dev": true, + "requires": { + "@types/estree": "^0.0.39" + } + }, + "adm-zip": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz", + "integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==", + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-escapes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", + "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "archiver": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", + "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=", + "dev": true, + "requires": { + "archiver-utils": "^1.3.0", + "async": "^2.0.0", + "buffer-crc32": "^0.2.1", + "glob": "^7.0.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0", + "tar-stream": "^1.5.0", + "zip-stream": "^1.2.0" + }, + "dependencies": { + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + } + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "graceful-fs": "^4.1.0", + "lazystream": "^1.0.0", + "lodash": "^4.8.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz", + "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.6.tgz", + "integrity": "sha1-rT83PZJJrjJIgVZVgryQ4VKrvWg=", + "dev": true + }, + "async-exit-hook": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-1.1.2.tgz", + "integrity": "sha1-gJXXXkiMKazuBVH+hyUhadeJz7o=", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + } + } + }, + "babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true, + "requires": { + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, + "babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true, + "requires": { + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "dev": true, + "requires": { + "babel-plugin-syntax-flow": "^6.18.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-for-of-as-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-for-of-as-array/-/babel-plugin-transform-for-of-as-array-1.1.1.tgz", + "integrity": "sha512-eE4hZJhOUKpX0q/X3adR8B4hLox+t8oe4ZqmhANUmv4cds07AbWt6O0rtFXK7PKFPPnW4nz/5mpbkPMkflyGeg==", + "dev": true + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + }, + "dependencies": { + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + } + } + }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + }, + "dependencies": { + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + } + } + }, + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "^6.22.0" + } + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" + } + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + }, + "dependencies": { + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bin-v8-flags-filter": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bin-v8-flags-filter/-/bin-v8-flags-filter-1.2.0.tgz", + "integrity": "sha512-g8aeYkY7GhyyKRvQMBsJQZjhm2iCX3dKYvfrMpwVR8IxmUGrkpCBFoKbB9Rh0o3sTLCjU/1tFpZ4C7j3f+D+3g==", + "dev": true + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "bowser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.6.0.tgz", + "integrity": "sha1-N/w4e2Fstq7zcNq01r1AK3TFxU0=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brotli": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.2.tgz", + "integrity": "sha1-UlqcrU/LqWR119OI9q7LE+7VL0Y=", + "dev": true, + "requires": { + "base64-js": "^1.1.2" + } + }, + "browserslist": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.0.tgz", + "integrity": "sha512-Jk0YFwXBuMOOol8n6FhgkDzn3mY9PYLYGk29zybF05SbRTsMgPqmTNeQQhOghCxq5oFqAXE3u4sYddr4C0uRhg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000967", + "electron-to-chromium": "^1.3.133", + "node-releases": "^1.1.19" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "callsite-record": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/callsite-record/-/callsite-record-4.1.3.tgz", + "integrity": "sha512-otAcPmu8TiHZ38cIL3NjQa1nGoSQRRe8WDDUgj5ZUwJWn1wzOYBwVSJbpVyzZ0sesQeKlYsPu9DG70fhh6AK9g==", + "dev": true, + "requires": { + "@types/error-stack-parser": "^1.3.18", + "@types/lodash": "^4.14.72", + "callsite": "^1.0.0", + "chalk": "^2.4.0", + "error-stack-parser": "^1.3.3", + "highlight-es": "^1.0.0", + "lodash": "4.6.1 || ^4.16.1", + "pinkie-promise": "^2.0.0" + } + }, + "caniuse-lite": { + "version": "1.0.30000971", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000971.tgz", + "integrity": "sha512-TQFYFhRS0O5rdsmSbF1Wn+16latXYsQJat66f7S7lizXW1PVpWJeZw9wqqVLIjuxDRz7s7xRUj13QCfd8hKn6g==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chrome-emulated-devices-list": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/chrome-emulated-devices-list/-/chrome-emulated-devices-list-0.1.1.tgz", + "integrity": "sha512-wQu6YKNTNGaUXovpkvXLnfeumVK47r2TKpOuCTwOKv/5SmRzfHual+E+oDIwS3KFWAcJPAhoNRAOLvXwzC6/pw==", + "dev": true + }, + "chrome-remote-interface": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.25.7.tgz", + "integrity": "sha512-6zI6LbR2IiGmduFZededaerEr9hHXabxT/L+fRrdq65a0CfyLMzpq0BKuZiqN0Upqcacsb6q2POj7fmobwBsEA==", + "dev": true, + "requires": { + "commander": "2.11.x", + "ws": "3.3.x" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + } + } + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "coffeescript": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.4.1.tgz", + "integrity": "sha512-34GV1aHrsMpTaO3KfMJL40ZNuvKDR/g98THHnE9bQj8HjMaZvSrLik99WWqyMhRtbe8V5hpx5iLgdcSvM/S2wg==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.1", + "crc32-stream": "^2.0.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "dev": true + }, + "core-js-compat": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.2.tgz", + "integrity": "sha512-X0Ch5f6itrHxhg5HSJucX6nNLNAGr+jq+biBh6nPGc3YAWz2a8p/ZIZY8cUkDzSRNG54omAuu3hoEF8qZbu/6Q==", + "dev": true, + "requires": { + "browserslist": "^4.6.0", + "core-js-pure": "3.1.2", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.0.tgz", + "integrity": "sha512-kCqEOOHoBcFs/2Ccuk4Xarm/KiWRSLEX9CAZF8xkJ6ZPlIoTZ8V5f7J16vYLJqDbR7KrxTJpR2lqjIEm2Qx9cQ==", + "dev": true + } + } + }, + "core-js-pure": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.2.tgz", + "integrity": "sha512-5ckIdBF26B3ldK9PM177y2ZcATP2oweam9RskHSoqfZCrJ2As6wVg8zJ1zTriFsZf6clj/N1ThDFRGaomMsh9w==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "requires": { + "buffer": "^5.1.0" + } + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^2.0.0" + } + }, + "crypto-md5": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-md5/-/crypto-md5-1.0.0.tgz", + "integrity": "sha1-zMjadQx1PH7curxUKWdHKjhOhrs=", + "dev": true + }, + "css": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz", + "integrity": "sha512-0W171WccAjQGGTKLhw4m2nnl0zPHUlTO/I8td4XzJgIB8Hg3ZZx71qT4G4eX8OVsSiaAKiUMy73E3nsbPlg2DQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "source-map": "^0.1.38", + "source-map-resolve": "^0.5.1", + "urix": "^0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "dedent": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.4.0.tgz", + "integrity": "sha1-h979BAvUwVldljKC7FfzwqhSVkI=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "desired-capabilities": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/desired-capabilities/-/desired-capabilities-0.1.0.tgz", + "integrity": "sha1-84YNEu3g2sgZpHzJWaaMULqbqD4=", + "dev": true, + "requires": { + "extend": "^3.0.0" + } + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "electron-to-chromium": { + "version": "1.3.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.137.tgz", + "integrity": "sha512-kGi32g42a8vS/WnYE7ELJyejRT7hbr3UeOOu0WeuYuQ29gCpg9Lrf6RdcTQVXSt/v0bjCfnlb/EWOOsiKpTmkw==", + "dev": true + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, + "emittery": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.4.1.tgz", + "integrity": "sha512-r4eRSeStEGf6M5SKdrQhhLK5bOwOBxQhIE3YSTnZE3GpKiLfnnhE+tPtrJE79+eDJgm39BM6LSoI8SCx4HbwlQ==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "endpoint-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/endpoint-utils/-/endpoint-utils-1.0.2.tgz", + "integrity": "sha1-CAjDNppyfNeWejn/NOvJJriBRqg=", + "dev": true, + "requires": { + "ip": "^1.1.3", + "pinkie-promise": "^1.0.0" + }, + "dependencies": { + "pinkie": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", + "integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=", + "dev": true + }, + "pinkie-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", + "integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=", + "dev": true, + "requires": { + "pinkie": "^1.0.0" + } + } + } + }, + "error-stack-parser": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz", + "integrity": "sha1-4Oc7k+QXE40c18C3RrGkoUhUwpI=", + "dev": true, + "requires": { + "stackframe": "^0.3.1" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esotope-hammerhead": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/esotope-hammerhead/-/esotope-hammerhead-0.2.1.tgz", + "integrity": "sha512-IicdvCt1BIFTIM4nbjxGp98whIakOYZ4lA0UaDXnXpJpB11jYBX11Uv3x2f5ncSlFmxyZRdrN5skH5wK4TCWFQ==", + "dev": true, + "requires": { + "@types/estree": "^0.0.39" + } + }, + "estree-walker": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.0.tgz", + "integrity": "sha512-peq1RfVAVzr3PU/jL31RaOjUKLoZJpObQWJJ+LgfcxDUifyLZ1RjPQZTl0pzj2uJ45b7A7XpyppXvxdEqzo4rw==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "dependencies": { + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", + "dev": true + }, + "graphlib": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.7.tgz", + "integrity": "sha512-TyI9jIy2J4j0qgPmOOrHTCtpPqJGN/aurBwc6ZT+bRii+di1I+Wv3obRhVrmBEXet+qkMaEX67dXrwsd3QQM6w==", + "dev": true, + "requires": { + "lodash": "^4.17.5" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "highlight-es": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/highlight-es/-/highlight-es-1.0.3.tgz", + "integrity": "sha512-s/SIX6yp/5S1p8aC/NRDC1fwEb+myGIfp8/TzZz0rtAv8fzsdX7vGl3Q1TrXCsczFq8DI3CBFBCySPClfBSdbg==", + "dev": true, + "requires": { + "chalk": "^2.4.0", + "is-es2016-keyword": "^1.0.0", + "js-tokens": "^3.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + } + } + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "dev": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "iconv-lite": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz", + "integrity": "sha1-LstC/SlHRJIiCaLnxATayHk9it4=", + "dev": true + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-lazy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", + "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", + "dev": true + }, + "indent-string": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz", + "integrity": "sha1-25m8xYPrarux5I3LsZmamGBBy2s=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "minimist": "^1.1.0", + "repeating": "^1.1.0" + }, + "dependencies": { + "repeating": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", + "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-1.1.0.tgz", + "integrity": "sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE=", + "dev": true + }, + "is-es2016-keyword": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-es2016-keyword/-/is-es2016-keyword-1.0.0.tgz", + "integrity": "sha1-9uVOEQxeT40mXmnS7Q6vjPX0dxg=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + } + } + }, + "is-jquery-obj": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-jquery-obj/-/is-jquery-obj-0.1.1.tgz", + "integrity": "sha512-18toSebUVF7y717dgw/Dzn6djOCqrkiDp3MhB8P6TdKyCVkbD1ZwE7Uz8Hwx6hUPTvKjbyYH9ncXT4ts4qLaSA==", + "dev": true + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "linux-platform-info": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/linux-platform-info/-/linux-platform-info-0.0.3.tgz", + "integrity": "sha1-La4yQ4Xmbj11W+yD+Gx77qYc64M=", + "dev": true, + "requires": { + "os-family": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "log-update-async-hook": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/log-update-async-hook/-/log-update-async-hook-2.0.2.tgz", + "integrity": "sha512-HQwkKFTZeUOrDi1Duf2CSUa/pSpcaCHKLdx3D/Z16DsipzByOBffcg5y0JZA1q0n80dYgLXe2hFM9JGNgBsTDw==", + "dev": true, + "requires": { + "ansi-escapes": "^2.0.0", + "async-exit-hook": "^1.1.2", + "onetime": "^2.0.1", + "wrap-ansi": "^2.1.0" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.3.tgz", + "integrity": "sha1-UczQtPwMhDWH16VwnOTTt2Kb7cU=", + "dev": true + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-reverse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-reverse/-/map-reverse-1.0.1.tgz", + "integrity": "sha1-J06fUAphEVMYO1uNhJCpwcI+4xA=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "match-url-wildcard": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/match-url-wildcard/-/match-url-wildcard-0.0.4.tgz", + "integrity": "sha512-R1XhQaamUZPWLOPtp4ig5j+3jctN+skhgRmEQTUamMzmNtRG69QEirQs0NZKLtHMR7tzWpmtnS4Eqv65DcgXUA==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "dev": true + }, + "moment-duration-format-commonjs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/moment-duration-format-commonjs/-/moment-duration-format-commonjs-1.0.0.tgz", + "integrity": "sha512-MVFR4hIh4jfuwSCPBEE5CCwn3refvTsxK/Yv/DpKJ6YcNnCimlVJ6DQeTJG1KVQPw1o8m3tkbHE9gVjivyv9iA==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "mustache": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz", + "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==", + "dev": true + }, + "nanoid": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-1.3.4.tgz", + "integrity": "sha512-4ug4BsuHxiVHoRUe1ud6rUFT3WUMmjXt1W0quL0CviZQANdan7D8kqN5/maw53hmAApY/jfzMRkC57BNNs60ZQ==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "node-releases": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.21.tgz", + "integrity": "sha512-TwnURTCjc8a+ElJUjmDqU6+12jhli1Q61xOQmdZ7ECZVBZuQpN/1UnembiIHDM1wCcfLvh5wrWXUF5H6ufX64Q==", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "node-version": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.2.0.tgz", + "integrity": "sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==", + "dev": true + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "os-family": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/os-family/-/os-family-1.1.0.tgz", + "integrity": "sha512-E3Orl5pvDJXnVmpaAA2TeNNpNhTMl4o5HghuWhOivBjEiTnJSrMYSa5uZMek1lBEvu8kKEsa2YgVcGFVDqX/9w==", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promisify-event": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/promisify-event/-/promisify-event-1.0.0.tgz", + "integrity": "sha1-vXUj6ga3AWLzcJeQFrU6aGxg6Q8=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.33.tgz", + "integrity": "sha512-LTDP2uSrsc7XCb5lO7A8BI1qYxRe/8EqlRvMeEl6rsnYAqDOl8xHR+8lSAIVfrNaSAlTPTNOCgNjWcoUL3AZsw==", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", + "dev": true + }, + "qrcode-terminal": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.10.0.tgz", + "integrity": "sha1-p2pI4mEKGPl/o6K9UytoKs/4bFM=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "read-file-relative": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/read-file-relative/-/read-file-relative-1.2.0.tgz", + "integrity": "sha1-mPfZbqoh0rTHov69Y9L8jPNen5s=", + "dev": true, + "requires": { + "callsite": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz", + "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp-tree": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz", + "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==", + "dev": true + }, + "regexpu-core": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", + "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.0.2", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "replicator": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/replicator/-/replicator-1.0.3.tgz", + "integrity": "sha512-WsKsraaM0x0QHy5CtzdgFXUxyowoBhyNkmPqmZShW6h+rOWnyT6Od3zRdTX9r616rAA6kDC9MKQGnSM/CJKfVQ==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "resolve": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-1.0.0.tgz", + "integrity": "sha1-Tq7qQe0EDRcCRX32SkKysH0kb58=", + "dev": true, + "requires": { + "resolve-from": "^2.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.12.3.tgz", + "integrity": "sha512-ueWhPijWN+GaPgD3l77hXih/gcDXmYph6sWeQegwBYtaqAE834e8u+MC2wT6FKIUsz1DBOyOXAQXUZB+rjWDoQ==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "@types/node": "^12.0.2", + "acorn": "^6.1.1" + } + }, + "rollup-plugin-babel": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.3.2.tgz", + "integrity": "sha512-KfnizE258L/4enADKX61ozfwGHoqYauvoofghFJBhFnpH9Sb9dNPpWg8QHOaAfVASUYV8w0mCx430i9z0LJoJg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "rollup-pluginutils": "^2.3.0" + } + }, + "rollup-plugin-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz", + "integrity": "sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow==", + "dev": true, + "requires": { + "rollup-pluginutils": "^2.5.0" + } + }, + "rollup-plugin-node-resolve": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.0.0.tgz", + "integrity": "sha512-JUFr7DkFps3div9DYwpSg0O+s8zuSSRASUZUVNx6h6zhw2m8vcpToeS68JDPsFbmisMVSMYK0IxftngCRv7M9Q==", + "dev": true, + "requires": { + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.10.1", + "rollup-pluginutils": "^2.7.0" + } + }, + "rollup-pluginutils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.7.1.tgz", + "integrity": "sha512-3nRf3buQGR9qz/IsSzhZAJyoK663kzseps8itkYHr+Z7ESuaffEPfgRinxbCRA0pf0gzLqkNKkSb8aNVTq75NA==", + "dev": true, + "requires": { + "estree-walker": "^0.6.0", + "micromatch": "^3.1.10" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sanitize-filename": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz", + "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=", + "dev": true, + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "sauce-connect-launcher": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.7.tgz", + "integrity": "sha512-v07+QhFrxgz3seMFuRSonu3gW1s6DbcLQlFhjsRrmKUauzPbbudHdnn91WYgEwhoZVdPNzeZpAEJwcQyd9xnTA==", + "dev": true, + "requires": { + "adm-zip": "~0.4.3", + "async": "^2.1.2", + "https-proxy-agent": "^2.2.1", + "lodash": "^4.16.6", + "rimraf": "^2.5.4" + }, + "dependencies": { + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + } + } + }, + "saucelabs-connector": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/saucelabs-connector/-/saucelabs-connector-0.3.0.tgz", + "integrity": "sha512-r0PWFUZeWMoWaKWhvnaHpro5VfpLbg+avKdjb0bs+xSTNh4S6sgjVJMhM8vSjOXog2DjZVe1Agv4Ta5GCMLMog==", + "dev": true, + "requires": { + "babel-runtime": "^5.8.20", + "lodash": "^4.13.1", + "os-family": "^1.0.0", + "pify": "^2.3.0", + "pinkie": "^2.0.4", + "read-file-relative": "^1.2.0", + "request": "^2.67.0", + "sauce-connect-launcher": "^1.2.5", + "wd": "^1.2.0" + }, + "dependencies": { + "babel-runtime": { + "version": "5.8.38", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz", + "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=", + "dev": true, + "requires": { + "core-js": "^1.0.0" + } + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", + "dev": true + } + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stackframe": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", + "integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ=", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "testcafe": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/testcafe/-/testcafe-1.3.1.tgz", + "integrity": "sha512-5IkyFxKBdrUut9JEmGR8lU4qbxL9N9F/3yNJqfLF29bpRfrmJY2FZdAYQ1iHEayfCcSTxQxcqRCEkVsmRTaI4g==", + "dev": true, + "requires": { + "@types/node": "^10.12.19", + "async-exit-hook": "^1.1.2", + "babel-core": "^6.22.1", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-for-of-as-array": "^1.1.1", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-preset-env": "^1.1.8", + "babel-preset-flow": "^6.23.0", + "babel-preset-stage-2": "^6.22.0", + "babel-runtime": "^6.22.0", + "bin-v8-flags-filter": "^1.1.2", + "callsite": "^1.0.0", + "callsite-record": "^4.0.0", + "chai": "^4.1.2", + "chalk": "^1.1.0", + "chrome-emulated-devices-list": "^0.1.0", + "chrome-remote-interface": "^0.25.3", + "coffeescript": "^2.3.1", + "commander": "^2.8.1", + "debug": "^2.2.0", + "dedent": "^0.4.0", + "del": "^3.0.0", + "elegant-spinner": "^1.0.1", + "emittery": "^0.4.1", + "endpoint-utils": "^1.0.2", + "error-stack-parser": "^1.3.6", + "globby": "^9.2.0", + "graceful-fs": "^4.1.11", + "graphlib": "^2.1.5", + "import-lazy": "^3.1.0", + "indent-string": "^1.2.2", + "is-ci": "^1.0.10", + "is-docker": "^1.1.0", + "is-glob": "^2.0.1", + "is-stream": "^1.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "log-update-async-hook": "^2.0.2", + "make-dir": "^1.3.0", + "map-reverse": "^1.0.1", + "moment": "^2.10.3", + "moment-duration-format-commonjs": "^1.0.0", + "mustache": "^2.1.2", + "nanoid": "^1.0.1", + "node-version": "^1.0.0", + "os-family": "^1.0.0", + "parse5": "^1.5.0", + "pify": "^2.3.0", + "pinkie": "^2.0.4", + "pngjs": "^3.3.1", + "promisify-event": "^1.0.0", + "qrcode-terminal": "^0.10.0", + "read-file-relative": "^1.2.0", + "replicator": "^1.0.3", + "resolve-cwd": "^1.0.0", + "resolve-from": "^4.0.0", + "sanitize-filename": "^1.6.0", + "source-map-support": "^0.5.5", + "strip-bom": "^2.0.0", + "testcafe-browser-tools": "1.6.8", + "testcafe-hammerhead": "14.6.10", + "testcafe-legacy-api": "3.1.11", + "testcafe-reporter-json": "^2.1.0", + "testcafe-reporter-list": "^2.1.0", + "testcafe-reporter-minimal": "^2.1.0", + "testcafe-reporter-spec": "^2.1.1", + "testcafe-reporter-xunit": "^2.1.0", + "time-limit-promise": "^1.0.2", + "tmp": "0.0.28", + "tree-kill": "^1.1.0", + "typescript": "^3.3.3", + "useragent": "^2.1.7" + }, + "dependencies": { + "@types/node": { + "version": "10.14.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.12.tgz", + "integrity": "sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg==", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "testcafe-browser-provider-saucelabs": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/testcafe-browser-provider-saucelabs/-/testcafe-browser-provider-saucelabs-1.7.0.tgz", + "integrity": "sha512-M7sRL2MgWuFmnIUJi/sB7w39WP4zSHUl2pDLhTy0mSUwBahM65Berj5t+K5UkAbQFilfLgP4hnkt75c/9RaJ1g==", + "dev": true, + "requires": { + "babel-runtime": "^6.11.6", + "desired-capabilities": "^0.1.0", + "lodash": "^4.14.2", + "pify": "^2.3.0", + "pinkie": "^2.0.4", + "request": "^2.74.0", + "saucelabs-connector": "^0.3.0" + } + }, + "testcafe-browser-tools": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/testcafe-browser-tools/-/testcafe-browser-tools-1.6.8.tgz", + "integrity": "sha512-xFgwmcAOutSJR6goqO8uUFGF5IF2xRC/Ssh4pB5QZ+bTjYsN5amnjgM+813bDBLelC+HmXKqylviz7Dzxbtbcw==", + "dev": true, + "requires": { + "array-find": "^1.0.0", + "babel-runtime": "^5.6.15", + "graceful-fs": "^4.1.11", + "linux-platform-info": "^0.0.3", + "mkdirp": "^0.5.1", + "mustache": "^2.1.2", + "os-family": "^1.0.0", + "pify": "^2.3.0", + "pinkie": "^2.0.1", + "read-file-relative": "^1.2.0", + "which-promise": "^1.0.0" + }, + "dependencies": { + "babel-runtime": { + "version": "5.8.38", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz", + "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=", + "dev": true, + "requires": { + "core-js": "^1.0.0" + } + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", + "dev": true + } + } + }, + "testcafe-hammerhead": { + "version": "14.6.10", + "resolved": "https://registry.npmjs.org/testcafe-hammerhead/-/testcafe-hammerhead-14.6.10.tgz", + "integrity": "sha512-fG/YTz7wKs6Fd0Fl9WlzO4j/ovDSAGxDLvLAz4ydzIKAdnZMZ22QbjYpfahCVpe9nzq/UHCQpSFdThQTmlFEmA==", + "dev": true, + "requires": { + "acorn-hammerhead": "^0.2.0", + "bowser": "1.6.0", + "brotli": "^1.3.1", + "crypto-md5": "^1.0.0", + "css": "2.2.3", + "esotope-hammerhead": "^0.2.1", + "iconv-lite": "0.4.11", + "lodash": "4.17.11", + "lru-cache": "2.6.3", + "match-url-wildcard": "0.0.4", + "merge-stream": "^1.0.1", + "mime": "~1.4.1", + "mustache": "^2.1.1", + "nanoid": "^0.2.2", + "os-family": "^1.0.0", + "parse5": "2.2.3", + "pify": "^2.3.0", + "pinkie": "1.0.0", + "read-file-relative": "^1.2.0", + "semver": "5.5.0", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "webauth": "^1.1.0" + }, + "dependencies": { + "nanoid": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-0.2.2.tgz", + "integrity": "sha512-GHoRrvNEKiwdkwQ/enKL8AhQkkrBC/2KxMZkDvQzp8OtkpX8ZAmoYJWFVl7l8F2+HcEJUfdg21Ab2wXXfrvACQ==", + "dev": true + }, + "parse5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-2.2.3.tgz", + "integrity": "sha1-DE/EHBAAxea5PUiwP4CDg3g06fY=", + "dev": true + }, + "pinkie": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", + "integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "testcafe-legacy-api": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/testcafe-legacy-api/-/testcafe-legacy-api-3.1.11.tgz", + "integrity": "sha512-JWv8Exc9FAEBbKw+IP97Ebd+0FzA3nzgRv9iQCNh/+JlZyUox7NWiojs9BAXqgxIltl54rdo7TxPkNslxb+Ltw==", + "dev": true, + "requires": { + "async": "0.2.6", + "babel-runtime": "^5.8.34", + "dedent": "^0.6.0", + "highlight-es": "^1.0.0", + "is-jquery-obj": "^0.1.0", + "lodash": "^4.14.0", + "moment": "^2.14.1", + "mustache": "^2.2.1", + "os-family": "^1.0.0", + "parse5": "^2.1.5", + "pify": "^2.3.0", + "pinkie": "^2.0.1", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "babel-runtime": { + "version": "5.8.38", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz", + "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=", + "dev": true, + "requires": { + "core-js": "^1.0.0" + } + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", + "dev": true + }, + "dedent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz", + "integrity": "sha1-Dm2o8M5Sg471zsXI+TlrDBtko8s=", + "dev": true + }, + "parse5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-2.2.3.tgz", + "integrity": "sha1-DE/EHBAAxea5PUiwP4CDg3g06fY=", + "dev": true + } + } + }, + "testcafe-reporter-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/testcafe-reporter-json/-/testcafe-reporter-json-2.2.0.tgz", + "integrity": "sha512-wfpNaZgGP2WoqdmnIXOyxcpwSzdH1HvzXSN397lJkXOrQrwhuGUThPDvyzPnZqxZSzXdDUvIPJm55tCMWbfymQ==", + "dev": true + }, + "testcafe-reporter-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/testcafe-reporter-list/-/testcafe-reporter-list-2.1.0.tgz", + "integrity": "sha1-n6ifcbl9Pf5ktDAtXiJ97mmuxrk=", + "dev": true + }, + "testcafe-reporter-minimal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/testcafe-reporter-minimal/-/testcafe-reporter-minimal-2.1.0.tgz", + "integrity": "sha1-Z28DVHY0FDxurzq1KGgnOkvr9CE=", + "dev": true + }, + "testcafe-reporter-spec": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/testcafe-reporter-spec/-/testcafe-reporter-spec-2.1.1.tgz", + "integrity": "sha1-gVb87Q9RMkhlWa1WC8gGdkaSdew=", + "dev": true + }, + "testcafe-reporter-xunit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/testcafe-reporter-xunit/-/testcafe-reporter-xunit-2.1.0.tgz", + "integrity": "sha1-5tZsVyzhWvJmcGrw/WELKoQd1EM=", + "dev": true + }, + "time-limit-promise": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/time-limit-promise/-/time-limit-promise-1.0.4.tgz", + "integrity": "sha512-FLHDDsIDducw7MBcRWlFtW2Tm50DoKOSFf0Nzx17qwXj8REXCte0eUkHrJl9QU3Bl9arG3XNYX0PcHpZ9xyuLw==", + "dev": true + }, + "tmp": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz", + "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, + "requires": { + "punycode": "^1.4.1" + } + }, + "tree-kill": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", + "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "dev": true, + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz", + "integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==", + "dev": true + }, + "uglify-js": { + "version": "3.5.15", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.15.tgz", + "integrity": "sha512-fe7aYFotptIddkwcm6YuA0HmknBZ52ZzOsUxZEdhhkSsz7RfjHDX2QDxwKTiv4JQ5t5NhfmpgAK+J7LiDhKSqg==", + "dev": true, + "requires": { + "commander": "~2.20.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "useragent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", + "dev": true, + "requires": { + "lru-cache": "4.1.x", + "tmp": "0.0.x" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + } + } + }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "vargs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/vargs/-/vargs-0.1.0.tgz", + "integrity": "sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "wd": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/wd/-/wd-1.11.2.tgz", + "integrity": "sha512-zXJY9ARjQQYN2LatLTRcW39EYzIVqKNhGpp4XWJmRgHBioG4FoenIOsoVbaO8lnFGgv31V99kAy5hB4eWGIwzA==", + "dev": true, + "requires": { + "archiver": "2.1.1", + "async": "2.0.1", + "lodash": "4.17.11", + "mkdirp": "^0.5.1", + "q": "1.4.1", + "request": "2.88.0", + "vargs": "0.1.0" + }, + "dependencies": { + "async": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz", + "integrity": "sha1-twnMAoCpw28J9FNr6CPIOKkEniU=", + "dev": true, + "requires": { + "lodash": "^4.8.0" + } + } + } + }, + "webauth": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webauth/-/webauth-1.1.0.tgz", + "integrity": "sha1-ZHBPa4AmmGYFvDymKZUubib90QA=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-promise/-/which-promise-1.0.0.tgz", + "integrity": "sha1-ILch3wWzW3Bhdv+hCwkJq6RgMDU=", + "dev": true, + "requires": { + "pify": "^2.2.0", + "pinkie-promise": "^1.0.0", + "which": "^1.1.2" + }, + "dependencies": { + "pinkie": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", + "integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=", + "dev": true + }, + "pinkie-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", + "integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=", + "dev": true, + "requires": { + "pinkie": "^1.0.0" + } + } + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "dev": true, + "requires": { + "archiver-utils": "^1.3.0", + "compress-commons": "^1.2.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0" + } + } + } +} diff --git a/public/assets/libs/Sortable/package.json b/public/assets/libs/Sortable/package.json new file mode 100644 index 0000000000000000000000000000000000000000..d19fb70033197278dbd99e360dfae52457158011 --- /dev/null +++ b/public/assets/libs/Sortable/package.json @@ -0,0 +1,56 @@ +{ + "name": "sortablejs", + "exportName": "Sortable", + "version": "1.10.1", + "devDependencies": { + "@babel/core": "^7.4.4", + "@babel/plugin-transform-object-assign": "^7.2.0", + "@babel/preset-env": "^7.4.4", + "rollup": "^1.11.3", + "rollup-plugin-babel": "^4.3.2", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-node-resolve": "^5.0.0", + "testcafe": "^1.3.1", + "testcafe-browser-provider-saucelabs": "^1.7.0", + "testcafe-reporter-xunit": "^2.1.0", + "uglify-js": "^3.5.12" + }, + "description": "JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap.", + "main": "./Sortable.js", + "module": "modular/sortable.esm.js", + "scripts": { + "build:umd": "NODE_ENV=umd rollup -c ./scripts/umd-build.js", + "build:umd:watch": "set NODE_ENV=umd&& rollup -w -c ./scripts/umd-build.js", + "build:es": "set NODE_ENV=es&& rollup -c ./scripts/esm-build.js", + "build:es:watch": "set NODE_ENV=es&& rollup -w -c ./scripts/esm-build.js", + "minify": "node ./scripts/minify.js", + "build": "npm run build:es && npm run build:umd && npm run minify", + "test:compat": "node ./scripts/test-compat.js", + "test": "node ./scripts/test.js" + }, + "maintainers": [ + "Konstantin Lebedev ", + "Owen Mills " + ], + "repository": { + "type": "git", + "url": "git://github.com/SortableJS/Sortable.git" + }, + "files": [ + "Sortable.js", + "Sortable.min.js", + "modular/" + ], + "keywords": [ + "sortable", + "reorder", + "drag", + "meteor", + "angular", + "ng-sortable", + "react", + "vue", + "mixin" + ], + "license": "MIT" +} diff --git a/public/assets/libs/Sortable/plugins/AutoScroll/AutoScroll.js b/public/assets/libs/Sortable/plugins/AutoScroll/AutoScroll.js new file mode 100644 index 0000000000000000000000000000000000000000..3027bb3513495da50eb437cd82d3fa13d8a3e600 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/AutoScroll/AutoScroll.js @@ -0,0 +1,270 @@ +import { + on, + off, + css, + throttle, + cancelThrottle, + scrollBy, + getParentAutoScrollElement, + expando, + getRect, + getWindowScrollingElement +} from '../../src/utils.js'; + +import Sortable from '../../src/Sortable.js'; + +import { Edge, IE11OrLess, Safari } from '../../src/BrowserInfo.js'; + +let autoScrolls = [], + scrollEl, + scrollRootEl, + scrolling = false, + lastAutoScrollX, + lastAutoScrollY, + touchEvt, + pointerElemChangedInterval; + +function AutoScrollPlugin() { + + function AutoScroll() { + this.defaults = { + scroll: true, + scrollSensitivity: 30, + scrollSpeed: 10, + bubbleScroll: true + }; + + // Bind all private methods + for (let fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + } + + AutoScroll.prototype = { + dragStarted({ originalEvent }) { + if (this.sortable.nativeDraggable) { + on(document, 'dragover', this._handleAutoScroll); + } else { + if (this.options.supportPointer) { + on(document, 'pointermove', this._handleFallbackAutoScroll); + } else if (originalEvent.touches) { + on(document, 'touchmove', this._handleFallbackAutoScroll); + } else { + on(document, 'mousemove', this._handleFallbackAutoScroll); + } + } + }, + + dragOverCompleted({ originalEvent }) { + // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) + if (!this.options.dragOverBubble && !originalEvent.rootEl) { + this._handleAutoScroll(originalEvent); + } + }, + + drop() { + if (this.sortable.nativeDraggable) { + off(document, 'dragover', this._handleAutoScroll); + } else { + off(document, 'pointermove', this._handleFallbackAutoScroll); + off(document, 'touchmove', this._handleFallbackAutoScroll); + off(document, 'mousemove', this._handleFallbackAutoScroll); + } + + clearPointerElemChangedInterval(); + clearAutoScrolls(); + cancelThrottle(); + }, + + nulling() { + touchEvt = + scrollRootEl = + scrollEl = + scrolling = + pointerElemChangedInterval = + lastAutoScrollX = + lastAutoScrollY = null; + + autoScrolls.length = 0; + }, + + _handleFallbackAutoScroll(evt) { + this._handleAutoScroll(evt, true); + }, + + _handleAutoScroll(evt, fallback) { + const x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + + elem = document.elementFromPoint(x, y); + + touchEvt = evt; + + // IE does not seem to have native autoscroll, + // Edge's autoscroll seems too conditional, + // MACOS Safari does not have autoscroll, + // Firefox and Chrome are good + if (fallback || Edge || IE11OrLess || Safari) { + autoScroll(evt, this.options, elem, fallback); + + // Listener for pointer element change + let ogElemScroller = getParentAutoScrollElement(elem, true); + if ( + scrolling && + ( + !pointerElemChangedInterval || + x !== lastAutoScrollX || + y !== lastAutoScrollY + ) + ) { + pointerElemChangedInterval && clearPointerElemChangedInterval(); + // Detect for pointer elem change, emulating native DnD behaviour + pointerElemChangedInterval = setInterval(() => { + let newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true); + if (newElem !== ogElemScroller) { + ogElemScroller = newElem; + clearAutoScrolls(); + } + autoScroll(evt, this.options, newElem, fallback); + }, 10); + lastAutoScrollX = x; + lastAutoScrollY = y; + } + } else { + // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll + if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { + clearAutoScrolls(); + return; + } + autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false); + } + } + }; + + return Object.assign(AutoScroll, { + pluginName: 'scroll', + initializeByDefault: true + }); +} + +function clearAutoScrolls() { + autoScrolls.forEach(function(autoScroll) { + clearInterval(autoScroll.pid); + }); + autoScrolls = []; +} + +function clearPointerElemChangedInterval() { + clearInterval(pointerElemChangedInterval); +} + + +const autoScroll = throttle(function(evt, options, rootEl, isFallback) { + // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + if (!options.scroll) return; + const x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + sens = options.scrollSensitivity, + speed = options.scrollSpeed, + winScroller = getWindowScrollingElement(); + + let scrollThisInstance = false, + scrollCustomFn; + + // New scroll root, set scrollEl + if (scrollRootEl !== rootEl) { + scrollRootEl = rootEl; + + clearAutoScrolls(); + + scrollEl = options.scroll; + scrollCustomFn = options.scrollFn; + + if (scrollEl === true) { + scrollEl = getParentAutoScrollElement(rootEl, true); + } + } + + + let layersOut = 0; + let currentParent = scrollEl; + do { + let el = currentParent, + rect = getRect(el), + + top = rect.top, + bottom = rect.bottom, + left = rect.left, + right = rect.right, + + width = rect.width, + height = rect.height, + + canScrollX, + canScrollY, + + scrollWidth = el.scrollWidth, + scrollHeight = el.scrollHeight, + + elCSS = css(el), + + scrollPosX = el.scrollLeft, + scrollPosY = el.scrollTop; + + + if (el === winScroller) { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible'); + } else { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); + } + + let vx = canScrollX && (Math.abs(right - x) <= sens && (scrollPosX + width) < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX); + let vy = canScrollY && (Math.abs(bottom - y) <= sens && (scrollPosY + height) < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY); + + + if (!autoScrolls[layersOut]) { + for (let i = 0; i <= layersOut; i++) { + if (!autoScrolls[i]) { + autoScrolls[i] = {}; + } + } + } + + if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { + autoScrolls[layersOut].el = el; + autoScrolls[layersOut].vx = vx; + autoScrolls[layersOut].vy = vy; + + clearInterval(autoScrolls[layersOut].pid); + + if (vx != 0 || vy != 0) { + scrollThisInstance = true; + /* jshint loopfunc:true */ + autoScrolls[layersOut].pid = setInterval((function () { + // emulate drag over during autoscroll (fallback), emulating native DnD behaviour + if (isFallback && this.layer === 0) { + Sortable.active._onTouchMove(touchEvt); // To move ghost if it is positioned absolutely + } + let scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; + let scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; + + if (typeof(scrollCustomFn) === 'function') { + if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt, autoScrolls[this.layer].el) !== 'continue') { + return; + } + } + + scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); + }).bind({layer: layersOut}), 24); + } + } + layersOut++; + } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false))); + scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not +}, 30); + +export default AutoScrollPlugin; diff --git a/public/assets/libs/Sortable/plugins/AutoScroll/README.md b/public/assets/libs/Sortable/plugins/AutoScroll/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1d8bee6a0ccf356481386f1a1586730d0dd7c2a1 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/AutoScroll/README.md @@ -0,0 +1,80 @@ +## AutoScroll +This plugin allows for the page to automatically scroll during dragging near a scrollable element's edge on mobile devices and IE9 (or whenever fallback is enabled), and also enhances most browser's native drag-and-drop autoscrolling. +Demo: + - `window`: https://jsbin.com/dosilir/edit?js,output + - `overflow: hidden`: https://jsbin.com/xecihez/edit?html,js,output + +**This plugin is a default plugin, and is included in the default UMD and ESM builds of Sortable** + + +--- + + +### Mounting +```js +import { Sortable, AutoScroll } from 'sortablejs'; + +Sortable.mount(new AutoScroll()); +``` + + +--- + + +### Options + +```js +new Sortable(el, { + scroll: true, // Enable the plugin. Can be HTMLElement. + scrollFn: function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { ... }, // if you have custom scrollbar scrollFn may be used for autoscrolling + scrollSensitivity: 30, // px, how near the mouse must be to an edge to start scrolling. + scrollSpeed: 10, // px, speed of the scrolling + bubbleScroll: true // apply autoscroll to all parent elements, allowing for easier movement +}); +``` + + +--- + + +#### `scroll` option +Enables the plugin. Defaults to `true`. May also be set to an HTMLElement which will be where autoscrolling is rooted. + +Demo: + - `window`: https://jsbin.com/dosilir/edit?js,output + - `overflow: hidden`: https://jsbin.com/xecihez/edit?html,js,output + + +--- + + +#### `scrollFn` option +Defines function that will be used for autoscrolling. el.scrollTop/el.scrollLeft is used by default. +Useful when you have custom scrollbar with dedicated scroll function. +This function should return `'continue'` if it wishes to allow Sortable's native autoscrolling. + + +--- + + +#### `scrollSensitivity` option +Defines how near the mouse must be to an edge to start scrolling. + + +--- + + +#### `scrollSpeed` option +The speed at which the window should scroll once the mouse pointer gets within the `scrollSensitivity` distance. + + +--- + + +#### `bubbleScroll` option +If set to `true`, the normal `autoscroll` function will also be applied to all parent elements of the element the user is dragging over. + +Demo: https://jsbin.com/kesewor/edit?html,js,output + + +--- diff --git a/public/assets/libs/Sortable/plugins/AutoScroll/index.js b/public/assets/libs/Sortable/plugins/AutoScroll/index.js new file mode 100644 index 0000000000000000000000000000000000000000..cc79f7e2488e13671d75910cac27cff61d08f18f --- /dev/null +++ b/public/assets/libs/Sortable/plugins/AutoScroll/index.js @@ -0,0 +1 @@ +export { default } from './AutoScroll.js'; diff --git a/public/assets/libs/Sortable/plugins/MultiDrag/MultiDrag.js b/public/assets/libs/Sortable/plugins/MultiDrag/MultiDrag.js new file mode 100644 index 0000000000000000000000000000000000000000..7b2c32cda9044115c63a6404a5ee53b3a963d665 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/MultiDrag/MultiDrag.js @@ -0,0 +1,617 @@ +import { + toggleClass, + getRect, + index, + closest, + on, + off, + clone, + css, + setRect, + unsetRect, + matrix, + expando +} from '../../src/utils.js'; + +import dispatchEvent from '../../src/EventDispatcher.js'; + +let multiDragElements = [], + multiDragClones = [], + lastMultiDragSelect, // for selection with modifier key down (SHIFT) + multiDragSortable, + initialFolding = false, // Initial multi-drag fold when drag started + folding = false, // Folding any other time + dragStarted = false, + dragEl, + clonesFromRect, + clonesHidden; + +function MultiDragPlugin() { + function MultiDrag(sortable) { + // Bind all private methods + for (let fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + if (sortable.options.supportPointer) { + on(document, 'pointerup', this._deselectMultiDrag); + } else { + on(document, 'mouseup', this._deselectMultiDrag); + on(document, 'touchend', this._deselectMultiDrag); + } + + on(document, 'keydown', this._checkKeyDown); + on(document, 'keyup', this._checkKeyUp); + + this.defaults = { + selectedClass: 'sortable-selected', + multiDragKey: null, + setData(dataTransfer, dragEl) { + let data = ''; + if (multiDragElements.length && multiDragSortable === sortable) { + multiDragElements.forEach((multiDragElement, i) => { + data += (!i ? '' : ', ') + multiDragElement.textContent; + }); + } else { + data = dragEl.textContent; + } + dataTransfer.setData('Text', data); + } + }; + } + + MultiDrag.prototype = { + multiDragKeyDown: false, + isMultiDrag: false, + + + delayStartGlobal({ dragEl: dragged }) { + dragEl = dragged; + }, + + delayEnded() { + this.isMultiDrag = ~multiDragElements.indexOf(dragEl); + }, + + setupClone({ sortable, cancel }) { + if (!this.isMultiDrag) return; + for (let i = 0; i < multiDragElements.length; i++) { + multiDragClones.push(clone(multiDragElements[i])); + + multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; + + multiDragClones[i].draggable = false; + multiDragClones[i].style['will-change'] = ''; + + toggleClass(multiDragClones[i], this.options.selectedClass, false); + multiDragElements[i] === dragEl && toggleClass(multiDragClones[i], this.options.chosenClass, false); + } + + sortable._hideClone(); + cancel(); + }, + + clone({ sortable, rootEl, dispatchSortableEvent, cancel }) { + if (!this.isMultiDrag) return; + if (!this.options.removeCloneOnHide) { + if (multiDragElements.length && multiDragSortable === sortable) { + insertMultiDragClones(true, rootEl); + dispatchSortableEvent('clone'); + + cancel(); + } + } + }, + + showClone({ cloneNowShown, rootEl, cancel }) { + if (!this.isMultiDrag) return; + insertMultiDragClones(false, rootEl); + multiDragClones.forEach(clone => { + css(clone, 'display', ''); + }); + + cloneNowShown(); + clonesHidden = false; + cancel(); + }, + + hideClone({ sortable, cloneNowHidden, cancel }) { + if (!this.isMultiDrag) return; + multiDragClones.forEach(clone => { + css(clone, 'display', 'none'); + if (this.options.removeCloneOnHide && clone.parentNode) { + clone.parentNode.removeChild(clone); + } + }); + + cloneNowHidden(); + clonesHidden = true; + cancel(); + }, + + dragStartGlobal({ sortable }) { + if (!this.isMultiDrag && multiDragSortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + } + + multiDragElements.forEach(multiDragElement => { + multiDragElement.sortableIndex = index(multiDragElement); + }); + + // Sort multi-drag elements + multiDragElements = multiDragElements.sort(function(a, b) { + return a.sortableIndex - b.sortableIndex; + }); + dragStarted = true; + }, + + dragStarted({ sortable }) { + if (!this.isMultiDrag) return; + if (this.options.sort) { + // Capture rects, + // hide multi drag elements (by positioning them absolute), + // set multi drag elements rects to dragRect, + // show multi drag elements, + // animate to rects, + // unset rects & remove from DOM + + sortable.captureAnimationState(); + + if (this.options.animation) { + multiDragElements.forEach(multiDragElement => { + if (multiDragElement === dragEl) return; + css(multiDragElement, 'position', 'absolute'); + }); + + let dragRect = getRect(dragEl, false, true, true); + + multiDragElements.forEach(multiDragElement => { + if (multiDragElement === dragEl) return; + setRect(multiDragElement, dragRect); + }); + + folding = true; + initialFolding = true; + } + } + + sortable.animateAll(() => { + folding = false; + initialFolding = false; + + if (this.options.animation) { + multiDragElements.forEach(multiDragElement => { + unsetRect(multiDragElement); + }); + } + + // Remove all auxiliary multidrag items from el, if sorting enabled + if (this.options.sort) { + removeMultiDragElements(); + } + }); + }, + + dragOver({ target, completed, cancel }) { + if (folding && ~multiDragElements.indexOf(target)) { + completed(false); + cancel(); + } + }, + + revert({ fromSortable, rootEl, sortable, dragRect }) { + if (multiDragElements.length > 1) { + // Setup unfold animation + multiDragElements.forEach(multiDragElement => { + sortable.addAnimationState({ + target: multiDragElement, + rect: folding ? getRect(multiDragElement) : dragRect + }); + + unsetRect(multiDragElement); + + multiDragElement.fromRect = dragRect; + + fromSortable.removeAnimationState(multiDragElement); + }); + folding = false; + insertMultiDragElements(!this.options.removeCloneOnHide, rootEl); + } + }, + + dragOverCompleted({ sortable, isOwner, insertion, activeSortable, parentEl, putSortable }) { + let options = this.options; + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } + + initialFolding = false; + // If leaving sort:false root, or already folding - Fold to new location + if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { + // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible + let dragRectAbsolute = getRect(dragEl, false, true, true); + + multiDragElements.forEach(multiDragElement => { + if (multiDragElement === dragEl) return; + setRect(multiDragElement, dragRectAbsolute); + + // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted + // while folding, and so that we can capture them again because old sortable will no longer be fromSortable + parentEl.appendChild(multiDragElement); + }); + + folding = true; + } + + // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out + if (!isOwner) { + // Only remove if not folding (folding will remove them anyways) + if (!folding) { + removeMultiDragElements(); + } + + if (multiDragElements.length > 1) { + let clonesHiddenBefore = clonesHidden; + activeSortable._showClone(sortable); + + // Unfold animation for clones if showing from hidden + if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { + multiDragClones.forEach(clone => { + activeSortable.addAnimationState({ + target: clone, + rect: clonesFromRect + }); + + clone.fromRect = clonesFromRect; + clone.thisAnimationDuration = null; + }); + } + } else { + activeSortable._showClone(sortable); + } + } + } + }, + + dragOverAnimationCapture({ dragRect, isOwner, activeSortable }) { + multiDragElements.forEach(multiDragElement => { + multiDragElement.thisAnimationDuration = null; + }); + + if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { + clonesFromRect = Object.assign({}, dragRect); + let dragMatrix = matrix(dragEl, true); + clonesFromRect.top -= dragMatrix.f; + clonesFromRect.left -= dragMatrix.e; + } + }, + + dragOverAnimationComplete() { + if (folding) { + folding = false; + removeMultiDragElements(); + } + }, + + drop({ originalEvent: evt, rootEl, parentEl, sortable, dispatchSortableEvent, oldIndex, putSortable }) { + let toSortable = (putSortable || this.sortable); + + if (!evt) return; + + let options = this.options, + children = parentEl.children; + + // Multi-drag selection + if (!dragStarted) { + if (options.multiDragKey && !this.multiDragKeyDown) { + this._deselectMultiDrag(); + } + toggleClass(dragEl, options.selectedClass, !~multiDragElements.indexOf(dragEl)); + + if (!~multiDragElements.indexOf(dragEl)) { + multiDragElements.push(dragEl); + dispatchEvent({ + sortable, + rootEl, + name: 'select', + targetEl: dragEl, + originalEvt: evt + }); + + // Modifier activated, select from last to dragEl + if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { + let lastIndex = index(lastMultiDragSelect), + currentIndex = index(dragEl); + + if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { + // Must include lastMultiDragSelect (select it), in case modified selection from no selection + // (but previous selection existed) + let n, i; + if (currentIndex > lastIndex) { + i = lastIndex; + n = currentIndex; + } else { + i = currentIndex; + n = lastIndex + 1; + } + + for (; i < n; i++) { + if (~multiDragElements.indexOf(children[i])) continue; + toggleClass(children[i], options.selectedClass, true); + multiDragElements.push(children[i]); + + dispatchEvent({ + sortable, + rootEl, + name: 'select', + targetEl: children[i], + originalEvt: evt + }); + } + } + } else { + lastMultiDragSelect = dragEl; + } + + multiDragSortable = toSortable; + } else { + multiDragElements.splice(multiDragElements.indexOf(dragEl), 1); + lastMultiDragSelect = null; + dispatchEvent({ + sortable, + rootEl, + name: 'deselect', + targetEl: dragEl, + originalEvt: evt + }); + } + } + + // Multi-drag drop + if (dragStarted && this.isMultiDrag) { + // Do not "unfold" after around dragEl if reverted + if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { + let dragRect = getRect(dragEl), + multiDragIndex = index(dragEl, ':not(.' + this.options.selectedClass + ')'); + + if (!initialFolding && options.animation) dragEl.thisAnimationDuration = null; + + toSortable.captureAnimationState(); + + if (!initialFolding) { + if (options.animation) { + dragEl.fromRect = dragRect; + multiDragElements.forEach(multiDragElement => { + multiDragElement.thisAnimationDuration = null; + if (multiDragElement !== dragEl) { + let rect = folding ? getRect(multiDragElement) : dragRect; + multiDragElement.fromRect = rect; + + // Prepare unfold animation + toSortable.addAnimationState({ + target: multiDragElement, + rect: rect + }); + } + }); + } + + // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert + // properly they must all be removed + removeMultiDragElements(); + + multiDragElements.forEach(multiDragElement => { + if (children[multiDragIndex]) { + parentEl.insertBefore(multiDragElement, children[multiDragIndex]); + } else { + parentEl.appendChild(multiDragElement); + } + multiDragIndex++; + }); + + // If initial folding is done, the elements may have changed position because they are now + // unfolding around dragEl, even though dragEl may not have his index changed, so update event + // must be fired here as Sortable will not. + if (oldIndex === index(dragEl)) { + let update = false; + multiDragElements.forEach(multiDragElement => { + if (multiDragElement.sortableIndex !== index(multiDragElement)) { + update = true; + return; + } + }); + + if (update) { + dispatchSortableEvent('update'); + } + } + } + + // Must be done after capturing individual rects (scroll bar) + multiDragElements.forEach(multiDragElement => { + unsetRect(multiDragElement); + }); + + toSortable.animateAll(); + } + + multiDragSortable = toSortable; + } + + // Remove clones if necessary + if (rootEl === parentEl || (putSortable && putSortable.lastPutMode !== 'clone')) { + multiDragClones.forEach(clone => { + clone.parentNode && clone.parentNode.removeChild(clone); + }); + } + }, + + nullingGlobal() { + this.isMultiDrag = + dragStarted = false; + multiDragClones.length = 0; + }, + + destroyGlobal() { + this._deselectMultiDrag(); + off(document, 'pointerup', this._deselectMultiDrag); + off(document, 'mouseup', this._deselectMultiDrag); + off(document, 'touchend', this._deselectMultiDrag); + + off(document, 'keydown', this._checkKeyDown); + off(document, 'keyup', this._checkKeyUp); + }, + + _deselectMultiDrag(evt) { + if (dragStarted) return; + + // Only deselect if selection is in this sortable + if (multiDragSortable !== this.sortable) return; + + // Only deselect if target is not item in this sortable + if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; + + // Only deselect if left click + if (evt && evt.button !== 0) return; + + while (multiDragElements.length) { + let el = multiDragElements[0]; + toggleClass(el, this.options.selectedClass, false); + multiDragElements.shift(); + dispatchEvent({ + sortable: this.sortable, + rootEl: this.sortable.el, + name: 'deselect', + targetEl: el, + originalEvt: evt + }); + } + }, + + _checkKeyDown(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = true; + } + }, + + _checkKeyUp(evt) { + if (evt.key === this.options.multiDragKey) { + this.multiDragKeyDown = false; + } + } + }; + + return Object.assign(MultiDrag, { + // Static methods & properties + pluginName: 'multiDrag', + utils: { + /** + * Selects the provided multi-drag item + * @param {HTMLElement} el The element to be selected + */ + select(el) { + let sortable = el.parentNode[expando]; + if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return; + if (multiDragSortable && multiDragSortable !== sortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + multiDragSortable = sortable; + } + toggleClass(el, sortable.options.selectedClass, true); + multiDragElements.push(el); + }, + /** + * Deselects the provided multi-drag item + * @param {HTMLElement} el The element to be deselected + */ + deselect(el) { + let sortable = el.parentNode[expando], + index = multiDragElements.indexOf(el); + if (!sortable || !sortable.options.multiDrag || !~index) return; + toggleClass(el, sortable.options.selectedClass, false); + multiDragElements.splice(index, 1); + } + }, + eventProperties() { + const oldIndicies = [], + newIndicies = []; + + multiDragElements.forEach(multiDragElement => { + oldIndicies.push({ + multiDragElement, + index: multiDragElement.sortableIndex + }); + + // multiDragElements will already be sorted if folding + let newIndex; + if (folding && multiDragElement !== dragEl) { + newIndex = -1; + } else if (folding) { + newIndex = index(multiDragElement, ':not(.' + this.options.selectedClass + ')'); + } else { + newIndex = index(multiDragElement); + } + newIndicies.push({ + multiDragElement, + index: newIndex + }); + }); + return { + items: [...multiDragElements], + clones: [...multiDragClones], + oldIndicies, + newIndicies + }; + }, + optionListeners: { + multiDragKey(key) { + key = key.toLowerCase(); + if (key === 'ctrl') { + key = 'Control'; + } else if (key.length > 1) { + key = key.charAt(0).toUpperCase() + key.substr(1); + } + return key; + } + } + }); +} + +function insertMultiDragElements(clonesInserted, rootEl) { + multiDragElements.forEach((multiDragElement, i) => { + let target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; + if (target) { + rootEl.insertBefore(multiDragElement, target); + } else { + rootEl.appendChild(multiDragElement); + } + }); +} + +/** + * Insert multi-drag clones + * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted + * @param {HTMLElement} rootEl + */ +function insertMultiDragClones(elementsInserted, rootEl) { + multiDragClones.forEach((clone, i) => { + let target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; + if (target) { + rootEl.insertBefore(clone, target); + } else { + rootEl.appendChild(clone); + } + }); +} + +function removeMultiDragElements() { + multiDragElements.forEach(multiDragElement => { + if (multiDragElement === dragEl) return; + multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement); + }); +} + +export default MultiDragPlugin; diff --git a/public/assets/libs/Sortable/plugins/MultiDrag/README.md b/public/assets/libs/Sortable/plugins/MultiDrag/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a7cb4d596235c3a2b250e5466af422be4473425c --- /dev/null +++ b/public/assets/libs/Sortable/plugins/MultiDrag/README.md @@ -0,0 +1,96 @@ +## MultiDrag Plugin +This plugin allows users to select multiple items within a sortable at once, and drag them as one item. +Once placed, the items will unfold into their original order, but all beside each other at the new position. +[Read More](https://github.com/SortableJS/Sortable/wiki/Dragging-Multiple-Items-in-Sortable) + +Demo: https://jsbin.com/wopavom/edit?js,output + + +--- + + +### Mounting +```js +import { Sortable, MultiDrag } from 'sortablejs'; + +Sortable.mount(new MultiDrag()); +``` + + +--- + + +### Options + +```js +new Sortable(el, { + multiDrag: true, // Enable the plugin + selectedClass: "sortable-selected", // Class name for selected item + multiDragKey: null, // Key that must be down for items to be selected + + // Called when an item is selected + onSelect: function(/**Event*/evt) { + evt.item // The selected item + }, + + // Called when an item is deselected + onDeselect: function(/**Event*/evt) { + evt.item // The deselected item + } +}); +``` + + +--- + + +#### `multiDragKey` option +The key that must be down for multiple items to be selected. The default is `null`, meaning no key must be down. +For special keys, such as the CTRL key, simply specify the option as `'CTRL'` (casing does not matter). + + +--- + + +#### `selectedClass` option +Class name for the selected item(s) if multiDrag is enabled. Defaults to `sortable-selected`. + +```css +.selected { + background-color: #f9c7c8; + border: solid red 1px; +} +``` + +```js +Sortable.create(list, { + multiDrag: true, + selectedClass: "selected" +}); +``` + + +--- + + +### Event Properties + - items:`HTMLElement[]` — Array of selected items, or empty + - clones:`HTMLElement[]` — Array of clones, or empty + - oldIndicies:`Index[]` — Array containing information on the old indicies of the selected elements. + - newIndicies:`Index[]` — Array containing information on the new indicies of the selected elements. + +#### Index Object + - element:`HTMLElement` — The element whose index is being given + - index:`Number` — The index of the element + +#### Note on `newIndicies` +For any event that is fired during sorting, the index of any selected element that is not the main dragged element is given as `-1`. +This is because it has either been removed from the DOM, or because it is in a folding animation (folding to the dragged element) and will be removed after this animation is complete. + + +--- + + +### Sortable.utils +* select(el:`HTMLElement`) — select the given multi-drag item +* deselect(el:`HTMLElement`) — deselect the given multi-drag item diff --git a/public/assets/libs/Sortable/plugins/MultiDrag/index.js b/public/assets/libs/Sortable/plugins/MultiDrag/index.js new file mode 100644 index 0000000000000000000000000000000000000000..2507117e0b76ad9f78fdab46002854c215426a95 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/MultiDrag/index.js @@ -0,0 +1 @@ +export { default } from './MultiDrag.js'; diff --git a/public/assets/libs/Sortable/plugins/OnSpill/OnSpill.js b/public/assets/libs/Sortable/plugins/OnSpill/OnSpill.js new file mode 100644 index 0000000000000000000000000000000000000000..e8c6439d9d0e1f9b8bdbf0e3f2a89497def975b5 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/OnSpill/OnSpill.js @@ -0,0 +1,79 @@ +import { getChild } from '../../src/utils.js'; + + +const drop = function({ + originalEvent, + putSortable, + dragEl, + activeSortable, + dispatchSortableEvent, + hideGhostForTarget, + unhideGhostForTarget +}) { + if (!originalEvent) return; + let toSortable = putSortable || activeSortable; + hideGhostForTarget(); + let touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent; + let target = document.elementFromPoint(touch.clientX, touch.clientY); + unhideGhostForTarget(); + if (toSortable && !toSortable.el.contains(target)) { + dispatchSortableEvent('spill'); + this.onSpill({ dragEl, putSortable }); + } +}; + +function Revert() {} + +Revert.prototype = { + startIndex: null, + dragStart({ oldDraggableIndex }) { + this.startIndex = oldDraggableIndex; + }, + onSpill({ dragEl, putSortable }) { + this.sortable.captureAnimationState(); + if (putSortable) { + putSortable.captureAnimationState(); + } + let nextSibling = getChild(this.sortable.el, this.startIndex, this.options); + + if (nextSibling) { + this.sortable.el.insertBefore(dragEl, nextSibling); + } else { + this.sortable.el.appendChild(dragEl); + } + this.sortable.animateAll(); + if (putSortable) { + putSortable.animateAll(); + } + }, + drop +}; + +Object.assign(Revert, { + pluginName: 'revertOnSpill' +}); + + +function Remove() {} + +Remove.prototype = { + onSpill({ dragEl, putSortable }) { + const parentSortable = putSortable || this.sortable; + parentSortable.captureAnimationState(); + dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); + parentSortable.animateAll(); + }, + drop +}; + +Object.assign(Remove, { + pluginName: 'removeOnSpill' +}); + + +export default [Remove, Revert]; + +export { + Remove as RemoveOnSpill, + Revert as RevertOnSpill +}; diff --git a/public/assets/libs/Sortable/plugins/OnSpill/README.md b/public/assets/libs/Sortable/plugins/OnSpill/README.md new file mode 100644 index 0000000000000000000000000000000000000000..816fd19cc2a6922df513e322db2e4aee122925c9 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/OnSpill/README.md @@ -0,0 +1,60 @@ +# OnSpill Plugins +This file contains two seperate plugins, RemoveOnSpill and RevertOnSpill. They can be imported individually, or the default export (an array of both plugins) can be passed to `Sortable.mount` as well. + +**These plugins are default plugins, and are included in the default UMD and ESM builds of Sortable** + + +--- + + +### Mounting +```js +import { Sortable, OnSpill } from 'sortablejs/modular/sortable.core.esm'; + +Sortable.mount(OnSpill); +``` + + +--- + + +## RevertOnSpill Plugin +This plugin, when enabled, will cause the dragged item to be reverted to it's original position if it is spilled (ie. it is dropped outside of a valid Sortable drop target) + + + + +### Options + +```js +new Sortable(el, { + revertOnSpill: true, // Enable plugin + // Called when item is spilled + onSpill: function(/**Event*/evt) { + evt.item // The spilled item + } +}); +``` + + +--- + + +## RemoveOnSpill Plugin +This plugin, when enabled, will cause the dragged item to be removed from the DOM if it is spilled (ie. it is dropped outside of a valid Sortable drop target) + + +--- + + +### Options + +```js +new Sortable(el, { + removeOnSpill: true, // Enable plugin + // Called when item is spilled + onSpill: function(/**Event*/evt) { + evt.item // The spilled item + } +}); +``` diff --git a/public/assets/libs/Sortable/plugins/OnSpill/index.js b/public/assets/libs/Sortable/plugins/OnSpill/index.js new file mode 100644 index 0000000000000000000000000000000000000000..4023b0f60501cc4e63f46a4c5f0286ab22342217 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/OnSpill/index.js @@ -0,0 +1 @@ +export { default, RemoveOnSpill, RevertOnSpill } from './OnSpill.js'; diff --git a/public/assets/libs/Sortable/plugins/README.md b/public/assets/libs/Sortable/plugins/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c48255a4004eefe8a91a0da416b8e9762fcd2322 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/README.md @@ -0,0 +1,178 @@ +# Creating Sortable Plugins +Sortable plugins are plugins that can be directly mounted to the Sortable class. They are a powerful way of modifying the default behaviour of Sortable beyond what simply using events alone allows. To mount your plugin to Sortable, it must pass a constructor function to the `Sortable.mount` function. This constructor function will be called (with the `new` keyword in front of it) whenever a Sortable instance with your plugin enabled is initialized. The constructor function will be called with the parameters `sortable` and `el`, which is the HTMLElement that the Sortable is being initialized on. This means that there will be a new instance of your plugin each time it is enabled in a Sortable. + + +## Constructor Parameters + +`sortable: Sortable` — The sortable that the plugin is being initialized on + +`el: HTMLElement` — The element that the sortable is being initialized on + +`options: Object` — The options object that the user has passed into Sortable (not merged with defaults yet) + + +## Static Properties +The constructor function passed to `Sortable.mount` may contain several static properties and methods. The following static properties may be defined: + +`pluginName: String` (Required) +The name of the option that the user will use in their sortable's options to enable the plugin. Should start with a lower case and be camel-cased. For example: `'multiDrag'`. This is also the property name that the plugin's instance will be under in a sortable instance (ex. `sortableInstance.multiDrag`). + +`utils: Object` +Object containing functions that will be added to the `Sortable.utils` static object on the Sortable class. + +`eventOptions(eventName: String): Function` +A function that is called whenever Sortable fires an event. This function should return an object to be combined with the event object that Sortable will emit. The function will be called in the context of the instance of the plugin on the Sortable that is firing the event (ie. the `this` keyword will be the plugin instance). + +`initializeByDefault: Boolean` +Determines whether or not the plugin will always be initialized on every new Sortable instance. If this option is enabled, it does not mean that by default the plugin will be enabled on the Sortable - this must still be done in the options via the plugin's `pluginName`, or it can be enabled by default if your plugin specifies it's pluginName as a default option that is truthy. Since the plugin will already be initialized on every Sortable instance, it can also be enabled dynamically via `sortableInstance.option('pluginName', true)`. +It is a good idea to have this option set to `false` if the plugin modifies the behaviour of Sortable in such a way that enabling or disabling the plugin dynamically could cause it to break. Likewise, this option should be disabled if the plugin should only be instantiated on Sortables in which that plugin is enabled. +This option defaults to `true`. + +`optionListeners: Object` +An object that may contain event listeners that are fired when a specific option is updated. +These listeners are useful because the user's provided options are not necessarily unchanging once the plugin is initialized, and could be changed dynamically via the `option()` method. +The listener will be fired in the context of the instance of the plugin that it is being changed in (ie. the `this` keyword will be the instance of your plugin). +The name of the method should match the name of the option it listens for. The new value of the option will be passed in as an argument, and any returned value will be what the option is stored as. If no value is returned, the option will be stored as the value the user provided. + +Example: + +```js +Plugin.name = 'generateTitle'; +Plugin.optionModifiers = { + // Listen for option 'generateTitle' + generateTitle: function(title) { + // Store the option in all caps + return title.toUpperCase(); + + // OR save it to this instance of your plugin as a private field. + // This way it can be accessed in events, but will not modify the user's options. + this.titleAllCaps = title.toUpperCase(); + } +}; + +``` + +## Plugin Options +Plugins may have custom default options or may override the defaults of other options. In order to do this, there must be a `defaults` object on the initialized plugin. This can be set in the plugin's prototype, or during the initialization of the plugin (when the `el` is available). For example: + +```js +function myPlugin(sortable, el, options) { + this.defaults = { + color: el.style.backgroundColor + }; +} + +Sortable.mount(myPlugin); +``` + + +## Plugin Events + +### Context +The events will be fired in the context of their own parent object (ie. context is not changed), however the plugin instance's Sortable instance is available under `this.sortable`. Likewise, the options are available under `this.options`. + +### Event List +The following table contains details on the events that a plugin may handle in the prototype of the plugin's constructor function. + +| Event Name | Description | Cancelable? | Cancel Behaviour | Event Type | Custom Event Object Properties | +|---------------------------|------------------------------------------------------------------------------------------------------------------|-------------|----------------------------------------------------|------------|-------------------------------------------------------------------------| +| filter | Fired when the element is filtered, and dragging is therefore canceled | No | - | Normal | None | +| delayStart | Fired when the delay starts, even if there is no delay | Yes | Cancels sorting | Normal | None | +| delayEnded | Fired when the delay ends, even if there is no delay | Yes | Cancels sorting | Normal | None | +| setupClone | Fired when Sortable clones the dragged element | Yes | Cancels normal clone setup | Normal | None | +| dragStart | Fired when the dragging is first started | Yes | Cancels sorting | Normal | None | +| clone | Fired when the clone is inserted into the DOM (if `removeCloneOnHide: false`). Tick after dragStart. | Yes | Cancels normal clone insertion & hiding | Normal | None | +| dragStarted | Fired tick after dragStart | No | - | Normal | None | +| dragOver | Fired when the user drags over a sortable | Yes | Cancels normal dragover behaviour | DragOver | None | +| dragOverValid | Fired when the user drags over a sortable that the dragged item can be inserted into | Yes | Cancels normal valid dragover behaviour | DragOver | None | +| revert | Fired when the dragged item is reverted to it's original position when entering it's `sort:false` root | Yes | Cancels normal reverting, but is still completed() | DragOver | None | +| dragOverCompleted | Fired when dragOver is completed (ie. bubbling is disabled). To check if inserted, use `inserted` even property. | No | - | DragOver | `insertion: Boolean` — Whether or not the dragged element was inserted | +| dragOverAnimationCapture | Fired right before the animation state is captured in dragOver | No | - | DragOver | None | +| dragOverAnimationComplete | Fired after the animation is completed after a dragOver insertion | No | - | DragOver | None | +| drop | Fired on drop | Yes | Cancels normal drop behavior | Normal | None | +| nulling | Fired when the plugin should preform cleanups, once all drop events have fired | No | - | Normal | None | +| destroy | Fired when Sortable is destroyed | No | - | Normal | None | + +### Global Events +Normally, an event will only be fired in a plugin if the plugin is enabled on the Sortable from which the event is being fired. However, it sometimes may be desirable for a plugin to listen in on an event from Sortables in which it is not enabled on. This is possible with global events. For an event to be global, simply add the suffix 'Global' to the event's name (casing matters) (eg. `dragStartGlobal`). +Please note that your plugin must be initialized on any Sortable from which it expects to recieve events, and that includes global events. In other words, you will want to keep the `initializeByDefault` option as it's default `true` value if your plugin needs to recieve events from Sortables it is not enabled on. +Please also note that if both normal and global event handlers are set, the global event handler will always be fired before the regular one. + +### Event Object +An object with the following properties is passed as an argument to each plugin event when it is fired. + +#### Properties: + +`dragEl: HTMLElement` — The element being dragged + +`parentEl: HTMLElement` — The element that the dragged element is currently in + +`ghostEl: HTMLElement|undefined` — If using fallback, the element dragged under the cursor (undefined until after `dragStarted` plugin event) + +`rootEl: HTMLElement` — The element that the dragged element originated from + +`nextEl: HTMLElement` — The original next sibling of dragEl + +`cloneEl: HTMLElement|undefined` — The clone element (undefined until after `setupClone` plugin event) + +`cloneHidden: Boolean` — Whether or not the clone is hidden + +`dragStarted: Boolean` — Boolean indicating whether or not the dragStart event has fired + +`putSortable: Sortable|undefined` — The element that dragEl is dragged into from it's root, otherwise undefined + +`activeSortable: Sortable` — The active Sortable instance + +`originalEvent: Event` — The original HTML event corresponding to the Sortable event + +`oldIndex: Number` — The old index of dragEl + +`oldDraggableIndex: Number` — The old index of dragEl, only counting draggable elements + +`newIndex: Number` — The new index of dragEl + +`newDraggableIndex: Number` — The new index of dragEl, only counting draggable elements + + +#### Methods: + +`cloneNowHidden()` — Function to be called if the plugin has hidden the clone + +`cloneNowShown()` — Function to be called if the plugin has shown the clone + +`hideGhostForTarget()` — Hides the fallback ghost element if CSS pointer-events are not available. Call this before using document.elementFromPoint at the mouse position. + +`unhideGhostForTarget()` — Unhides the ghost element. To be called after `hideGhostForTarget()`. + +`dispatchSortableEvent(eventName: String)` — Function that can be used to emit an event on the current sortable while sorting, with all usual event properties set (eg. indexes, rootEl, cloneEl, originalEvent, etc.). + + +### DragOverEvent Object +This event is passed to dragover events, and extends the normal event object. + +#### Properties: + +`isOwner: Boolean` — Whether or not the dragged over sortable currently contains the dragged element + +`axis: String` — Direction of the dragged over sortable, `'vertical'` or `'horizontal'` + +`revert: Boolean` — Whether or not the dragged element is being reverted to it's original position from another position + +`dragRect: DOMRect` — DOMRect of the dragged element + +`targetRect: DOMRect` — DOMRect of the target element + +`canSort: Boolean` — Whether or not sorting is enabled in the dragged over sortable + +`fromSortable: Sortable` — The sortable that the dragged element is coming from + +`target: HTMLElement` — The sortable item that is being dragged over + + +#### Methods: + +`onMove(target: HTMLElement, after: Boolean): Boolean|Number` — Calls the `onMove` function the user specified in the options + +`changed()` — Fires the `onChange` event with event properties preconfigured + +`completed(insertion: Boolean)` — Should be called when dragover has "completed", meaning bubbling should be stopped. If `insertion` is `true`, Sortable will treat it as if the dragged element was inserted into the sortable, and hide/show clone, set ghost class, animate, etc. diff --git a/public/assets/libs/Sortable/plugins/Swap/README.md b/public/assets/libs/Sortable/plugins/Swap/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7c6e3994ac764733e98a29e798c02f8d0f5ccf20 --- /dev/null +++ b/public/assets/libs/Sortable/plugins/Swap/README.md @@ -0,0 +1,55 @@ +## Swap Plugin +This plugin modifies the behaviour of Sortable to allow for items to be swapped with eachother rather than sorted. Once dragging starts, the user can drag over other items and there will be no change in the elements. However, the item that the user drops on will be swapped with the originally dragged item. + +Demo: https://jsbin.com/yejehog/edit?html,js,output + + +--- + + +### Mounting +```js +import { Sortable, Swap } from 'sortablejs/modular/sortable.core.esm'; + +Sortable.mount(new Swap()); +``` + + +--- + + +### Options + +```js +new Sortable(el, { + swap: true, // Enable swap mode + swapClass: "sortable-swap-highlight" // Class name for swap item (if swap mode is enabled) +}); +``` + + +--- + + +#### `swapClass` option +Class name for the item to be swapped with, if swap mode is enabled. Defaults to `sortable-swap-highlight`. + +```css +.highlighted { + background-color: #9AB6F1; +} +``` + +```js +Sortable.create(list, { + swap: true, + swapClass: "highlighted" +}); +``` + + +--- + + +### Event Properties + - swapItem:`HTMLElement|undefined` — The element that the dragged element was swapped with diff --git a/public/assets/libs/Sortable/plugins/Swap/Swap.js b/public/assets/libs/Sortable/plugins/Swap/Swap.js new file mode 100644 index 0000000000000000000000000000000000000000..3f0feb7dc76ecd5c7143e6e48af05969c255c6ff --- /dev/null +++ b/public/assets/libs/Sortable/plugins/Swap/Swap.js @@ -0,0 +1,90 @@ +import { + toggleClass, + index +} from '../../src/utils.js'; + +let lastSwapEl; + + +function SwapPlugin() { + function Swap() { + this.defaults = { + swapClass: 'sortable-swap-highlight' + }; + } + + Swap.prototype = { + dragStart({ dragEl }) { + lastSwapEl = dragEl; + }, + dragOverValid({ completed, target, onMove, activeSortable, changed, cancel }) { + if (!activeSortable.options.swap) return; + let el = this.sortable.el, + options = this.options; + if (target && target !== el) { + let prevSwapEl = lastSwapEl; + if (onMove(target) !== false) { + toggleClass(target, options.swapClass, true); + lastSwapEl = target; + } else { + lastSwapEl = null; + } + + if (prevSwapEl && prevSwapEl !== lastSwapEl) { + toggleClass(prevSwapEl, options.swapClass, false); + } + } + changed(); + + completed(true); + cancel(); + }, + drop({ activeSortable, putSortable, dragEl }) { + let toSortable = (putSortable || this.sortable); + let options = this.options; + lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); + if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { + if (dragEl !== lastSwapEl) { + toSortable.captureAnimationState(); + if (toSortable !== activeSortable) activeSortable.captureAnimationState(); + swapNodes(dragEl, lastSwapEl); + + toSortable.animateAll(); + if (toSortable !== activeSortable) activeSortable.animateAll(); + } + } + }, + nulling() { + lastSwapEl = null; + } + }; + + return Object.assign(Swap, { + pluginName: 'swap', + eventProperties() { + return { + swapItem: lastSwapEl + }; + } + }); +} + + +function swapNodes(n1, n2) { + let p1 = n1.parentNode, + p2 = n2.parentNode, + i1, i2; + + if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; + + i1 = index(n1); + i2 = index(n2); + + if (p1.isEqualNode(p2) && i1 < i2) { + i2++; + } + p1.insertBefore(n2, p1.children[i1]); + p2.insertBefore(n1, p2.children[i2]); +} + +export default SwapPlugin; diff --git a/public/assets/libs/Sortable/plugins/Swap/index.js b/public/assets/libs/Sortable/plugins/Swap/index.js new file mode 100644 index 0000000000000000000000000000000000000000..9799bc72c24468e0edd59ea0fa3a22f88b3841bc --- /dev/null +++ b/public/assets/libs/Sortable/plugins/Swap/index.js @@ -0,0 +1 @@ +export { default } from './Swap.js'; diff --git a/public/assets/libs/Sortable/scripts/banner.js b/public/assets/libs/Sortable/scripts/banner.js new file mode 100644 index 0000000000000000000000000000000000000000..337928bff8db0cacead2b06b279b1818e73582dc --- /dev/null +++ b/public/assets/libs/Sortable/scripts/banner.js @@ -0,0 +1,8 @@ +import { version } from '../package.json'; + +export default `/**! + * Sortable ${ version } + * @author RubaXa + * @author owenm + * @license MIT + */`; diff --git a/public/assets/libs/Sortable/scripts/build.js b/public/assets/libs/Sortable/scripts/build.js new file mode 100644 index 0000000000000000000000000000000000000000..11cf99d355459d41216b592efc937c36b771c025 --- /dev/null +++ b/public/assets/libs/Sortable/scripts/build.js @@ -0,0 +1,17 @@ +import babel from 'rollup-plugin-babel'; +import json from 'rollup-plugin-json'; +import resolve from 'rollup-plugin-node-resolve'; +import banner from './banner.js'; + + +export default { + output: { + banner, + name: 'Sortable' + }, + plugins: [ + json(), + babel(), + resolve() + ] +}; diff --git a/public/assets/libs/Sortable/scripts/esm-build.js b/public/assets/libs/Sortable/scripts/esm-build.js new file mode 100644 index 0000000000000000000000000000000000000000..9caff74d0228704d9a91d4d1e943197291ee450d --- /dev/null +++ b/public/assets/libs/Sortable/scripts/esm-build.js @@ -0,0 +1,28 @@ +import build from './build.js'; + +export default ([ + { + input: 'entry/entry-core.js', + output: Object.assign({}, build.output, { + file: 'modular/sortable.core.esm.js', + format: 'esm' + }) + }, + { + input: 'entry/entry-defaults.js', + output: Object.assign({}, build.output, { + file: 'modular/sortable.esm.js', + format: 'esm' + }) + }, + { + input: 'entry/entry-complete.js', + output: Object.assign({}, build.output, { + file: 'modular/sortable.complete.esm.js', + format: 'esm' + }) + } +]).map(config => { + let buildCopy = { ...build }; + return Object.assign(buildCopy, config); +}); diff --git a/public/assets/libs/Sortable/scripts/minify.js b/public/assets/libs/Sortable/scripts/minify.js new file mode 100644 index 0000000000000000000000000000000000000000..e2051a2c28ac71f6117c199ed40199f9c91ecf6a --- /dev/null +++ b/public/assets/libs/Sortable/scripts/minify.js @@ -0,0 +1,11 @@ +const UglifyJS = require('uglify-js'), + fs = require('fs'), + package = require('../package.json'); + +const banner = `/*! Sortable ${ package.version } - ${ package.license } | ${ package.repository.url } */\n`; + +fs.writeFileSync( + `./Sortable.min.js`, + banner + UglifyJS.minify(fs.readFileSync(`./Sortable.js`, 'utf8')).code, + 'utf8' +); diff --git a/public/assets/libs/Sortable/scripts/test-compat.js b/public/assets/libs/Sortable/scripts/test-compat.js new file mode 100644 index 0000000000000000000000000000000000000000..f7408c77fb10134668695b87fb94ccf9eb5604a9 --- /dev/null +++ b/public/assets/libs/Sortable/scripts/test-compat.js @@ -0,0 +1,30 @@ +const createTestCafe = require('testcafe'); +// Testcafe cannot test on IE < 11 +// Testcafe testing on Chrome Android is currently broken (https://github.com/DevExpress/testcafe/issues/3948) +const browsers = [ + 'saucelabs:Internet Explorer@11.285:Windows 10', + 'saucelabs:MicrosoftEdge@16.16299:Windows 10', + 'saucelabs:iPhone XS Simulator@12.2', + 'saucelabs:Safari@12.0:macOS 10.14', + 'chrome:headless', + 'firefox:headless' +]; + +let testcafe; +let runner; +let failedCount; + +createTestCafe(null, 8000, 8001).then((tc) => { + testcafe = tc; + runner = tc.createRunner(); + return runner + .src('./tests/Sortable.compat.test.js') + .browsers(browsers) + .run(); +}).then((actualFailedCount) => { + // https://testcafe-discuss.devexpress.com/t/why-circleci-marked-build-as-green-even-if-this-build-contain-failed-test/726/2 + failedCount = actualFailedCount; + return testcafe.close(); +}).then(() => process.exit(failedCount)); + + diff --git a/public/assets/libs/Sortable/scripts/test.js b/public/assets/libs/Sortable/scripts/test.js new file mode 100644 index 0000000000000000000000000000000000000000..6c62b75adcfc365c884baca65649e7018a2471d2 --- /dev/null +++ b/public/assets/libs/Sortable/scripts/test.js @@ -0,0 +1,21 @@ +const createTestCafe = require('testcafe'); + +let testcafe; +let runner; +let failedCount; + + +createTestCafe().then((tc) => { + testcafe = tc; + runner = tc.createRunner(); + return runner + .src('./tests/Sortable.test.js') + .browsers('chrome:headless') + .concurrency(3) + .run(); +}).then((actualFailedCount) => { + failedCount = actualFailedCount; + console.log('FAILED COUNT', actualFailedCount) + return testcafe.close(); +}).then(() => process.exit(failedCount)); + diff --git a/public/assets/libs/Sortable/scripts/umd-build.js b/public/assets/libs/Sortable/scripts/umd-build.js new file mode 100644 index 0000000000000000000000000000000000000000..ec179fdb9de76c51c9a07d9b2bb988fee810b8ce --- /dev/null +++ b/public/assets/libs/Sortable/scripts/umd-build.js @@ -0,0 +1,15 @@ +import build from './build.js'; + + +export default ([ + { + input: 'entry/entry-complete.js', + output: Object.assign({}, build.output, { + file: './Sortable.js', + format: 'umd' + }) + } +]).map(config => { + let buildCopy = { ...build }; + return Object.assign(buildCopy, config); +}); diff --git a/public/assets/libs/Sortable/src/Animation.js b/public/assets/libs/Sortable/src/Animation.js new file mode 100644 index 0000000000000000000000000000000000000000..194799147f311595ad46f7be6aba7324a90d2d04 --- /dev/null +++ b/public/assets/libs/Sortable/src/Animation.js @@ -0,0 +1,175 @@ +import { getRect, css, matrix, isRectEqual, indexOfObject } from './utils.js'; +import Sortable from './Sortable.js'; + +export default function AnimationStateManager() { + let animationStates = [], + animationCallbackId; + + return { + captureAnimationState() { + animationStates = []; + if (!this.options.animation) return; + let children = [].slice.call(this.el.children); + + children.forEach(child => { + if (css(child, 'display') === 'none' || child === Sortable.ghost) return; + animationStates.push({ + target: child, + rect: getRect(child) + }); + let fromRect = { ...animationStates[animationStates.length - 1].rect }; + + // If animating: compensate for current animation + if (child.thisAnimationDuration) { + let childMatrix = matrix(child, true); + if (childMatrix) { + fromRect.top -= childMatrix.f; + fromRect.left -= childMatrix.e; + } + } + + child.fromRect = fromRect; + }); + }, + + addAnimationState(state) { + animationStates.push(state); + }, + + removeAnimationState(target) { + animationStates.splice(indexOfObject(animationStates, { target }), 1); + }, + + animateAll(callback) { + if (!this.options.animation) { + clearTimeout(animationCallbackId); + if (typeof(callback) === 'function') callback(); + return; + } + + let animating = false, + animationTime = 0; + + animationStates.forEach((state) => { + let time = 0, + animatingThis = false, + target = state.target, + fromRect = target.fromRect, + toRect = getRect(target), + prevFromRect = target.prevFromRect, + prevToRect = target.prevToRect, + animatingRect = state.rect, + targetMatrix = matrix(target, true); + + + if (targetMatrix) { + // Compensate for current animation + toRect.top -= targetMatrix.f; + toRect.left -= targetMatrix.e; + } + + target.toRect = toRect; + + if (target.thisAnimationDuration) { + // Could also check if animatingRect is between fromRect and toRect + if ( + isRectEqual(prevFromRect, toRect) && + !isRectEqual(fromRect, toRect) && + // Make sure animatingRect is on line between toRect & fromRect + (animatingRect.top - toRect.top) / + (animatingRect.left - toRect.left) === + (fromRect.top - toRect.top) / + (fromRect.left - toRect.left) + ) { + // If returning to same place as started from animation and on same axis + time = calculateRealTime(animatingRect, prevFromRect, prevToRect, this.options); + } + } + + // if fromRect != toRect: animate + if (!isRectEqual(toRect, fromRect)) { + target.prevFromRect = fromRect; + target.prevToRect = toRect; + + if (!time) { + time = this.options.animation; + } + this.animate( + target, + animatingRect, + toRect, + time + ); + } + + if (time) { + animating = true; + animationTime = Math.max(animationTime, time); + clearTimeout(target.animationResetTimer); + target.animationResetTimer = setTimeout(function() { + target.animationTime = 0; + target.prevFromRect = null; + target.fromRect = null; + target.prevToRect = null; + target.thisAnimationDuration = null; + }, time); + target.thisAnimationDuration = time; + } + }); + + + clearTimeout(animationCallbackId); + if (!animating) { + if (typeof(callback) === 'function') callback(); + } else { + animationCallbackId = setTimeout(function() { + if (typeof(callback) === 'function') callback(); + }, animationTime); + } + animationStates = []; + }, + + animate(target, currentRect, toRect, duration) { + if (duration) { + css(target, 'transition', ''); + css(target, 'transform', ''); + let elMatrix = matrix(this.el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d, + translateX = (currentRect.left - toRect.left) / (scaleX || 1), + translateY = (currentRect.top - toRect.top) / (scaleY || 1); + + target.animatingX = !!translateX; + target.animatingY = !!translateY; + + css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); + + repaint(target); // repaint + + css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); + css(target, 'transform', 'translate3d(0,0,0)'); + (typeof target.animated === 'number') && clearTimeout(target.animated); + target.animated = setTimeout(function () { + css(target, 'transition', ''); + css(target, 'transform', ''); + target.animated = false; + + target.animatingX = false; + target.animatingY = false; + }, duration); + } + } + }; +} + +function repaint(target) { + return target.offsetWidth; +} + + +function calculateRealTime(animatingRect, fromRect, toRect, options) { + return ( + Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / + Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) + ) * options.animation; +} diff --git a/public/assets/libs/Sortable/src/BrowserInfo.js b/public/assets/libs/Sortable/src/BrowserInfo.js new file mode 100644 index 0000000000000000000000000000000000000000..304a853a2f94cbdb07b8885249f6c513e984975e --- /dev/null +++ b/public/assets/libs/Sortable/src/BrowserInfo.js @@ -0,0 +1,12 @@ +function userAgent(pattern) { + if (typeof window !== 'undefined' && window.navigator) { + return !!/*@__PURE__*/navigator.userAgent.match(pattern); + } +} + +export const IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); +export const Edge = userAgent(/Edge/i); +export const FireFox = userAgent(/firefox/i); +export const Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); +export const IOS = userAgent(/iP(ad|od|hone)/i); +export const ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i); diff --git a/public/assets/libs/Sortable/src/EventDispatcher.js b/public/assets/libs/Sortable/src/EventDispatcher.js new file mode 100644 index 0000000000000000000000000000000000000000..e47cb5809cf8b9e6f186e1a6bb2ea8a7ba5ce5d8 --- /dev/null +++ b/public/assets/libs/Sortable/src/EventDispatcher.js @@ -0,0 +1,57 @@ +import { IE11OrLess, Edge } from './BrowserInfo.js'; +import { expando } from './utils.js'; +import PluginManager from './PluginManager.js'; + +export default function dispatchEvent( + { + sortable, rootEl, name, + targetEl, cloneEl, toEl, fromEl, + oldIndex, newIndex, + oldDraggableIndex, newDraggableIndex, + originalEvent, putSortable, extraEventProperties + } +) { + sortable = (sortable || (rootEl && rootEl[expando])); + if (!sortable) return; + + let evt, + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); + // Support for new CustomEvent feature + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent(name, { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(name, true, true); + } + + evt.to = toEl || rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + + evt.oldIndex = oldIndex; + evt.newIndex = newIndex; + + evt.oldDraggableIndex = oldDraggableIndex; + evt.newDraggableIndex = newDraggableIndex; + + evt.originalEvent = originalEvent; + evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; + + let allEventProperties = { ...extraEventProperties, ...PluginManager.getEventProperties(name, sortable) }; + for (let option in allEventProperties) { + evt[option] = allEventProperties[option]; + } + + if (rootEl) { + rootEl.dispatchEvent(evt); + } + + if (options[onName]) { + options[onName].call(sortable, evt); + } +} diff --git a/public/assets/libs/Sortable/src/PluginManager.js b/public/assets/libs/Sortable/src/PluginManager.js new file mode 100644 index 0000000000000000000000000000000000000000..623c26f6223f46da3e30dcb3d8cc1d8196e4c0e2 --- /dev/null +++ b/public/assets/libs/Sortable/src/PluginManager.js @@ -0,0 +1,87 @@ +let plugins = []; + +const defaults = { + initializeByDefault: true +}; + +export default { + mount(plugin) { + // Set default static properties + for (let option in defaults) { + if (defaults.hasOwnProperty(option) && !(option in plugin)) { + plugin[option] = defaults[option]; + } + } + plugins.push(plugin); + }, + pluginEvent(eventName, sortable, evt) { + this.eventCanceled = false; + evt.cancel = () => { + this.eventCanceled = true; + }; + const eventNameGlobal = eventName + 'Global'; + plugins.forEach(plugin => { + if (!sortable[plugin.pluginName]) return; + // Fire global events if it exists in this sortable + if ( + sortable[plugin.pluginName][eventNameGlobal] + ) { + sortable[plugin.pluginName][eventNameGlobal]({ sortable, ...evt }); + } + + // Only fire plugin event if plugin is enabled in this sortable, + // and plugin has event defined + if ( + sortable.options[plugin.pluginName] && + sortable[plugin.pluginName][eventName] + ) { + sortable[plugin.pluginName][eventName]({ sortable, ...evt }); + } + }); + }, + initializePlugins(sortable, el, defaults, options) { + plugins.forEach(plugin => { + const pluginName = plugin.pluginName; + if (!sortable.options[pluginName] && !plugin.initializeByDefault) return; + + let initialized = new plugin(sortable, el, sortable.options); + initialized.sortable = sortable; + initialized.options = sortable.options; + sortable[pluginName] = initialized; + + // Add default options from plugin + Object.assign(defaults, initialized.defaults); + }); + + for (let option in sortable.options) { + if (!sortable.options.hasOwnProperty(option)) continue; + let modified = this.modifyOption(sortable, option, sortable.options[option]); + if (typeof(modified) !== 'undefined') { + sortable.options[option] = modified; + } + } + }, + getEventProperties(name, sortable) { + let eventProperties = {}; + plugins.forEach(plugin => { + if (typeof(plugin.eventProperties) !== 'function') return; + Object.assign(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name)); + }); + + return eventProperties; + }, + modifyOption(sortable, name, value) { + let modifiedValue; + plugins.forEach(plugin => { + // Plugin must exist on the Sortable + if (!sortable[plugin.pluginName]) return; + + // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin + if (plugin.optionListeners && typeof(plugin.optionListeners[name]) === 'function') { + modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value); + } + }); + + return modifiedValue; + } +}; diff --git a/public/assets/libs/Sortable/src/Sortable.js b/public/assets/libs/Sortable/src/Sortable.js new file mode 100644 index 0000000000000000000000000000000000000000..22d886240895b78f391322b9f765defa3fea3cef --- /dev/null +++ b/public/assets/libs/Sortable/src/Sortable.js @@ -0,0 +1,1963 @@ +/**! + * Sortable + * @author RubaXa + * @author owenm + * @license MIT + */ + +import { version } from '../package.json'; + +import { IE11OrLess, Edge, FireFox, Safari, IOS, ChromeForAndroid } from './BrowserInfo.js'; + +import AnimationStateManager from './Animation.js'; + +import PluginManager from './PluginManager.js'; + +import dispatchEvent from './EventDispatcher.js'; + +import { + on, + off, + closest, + toggleClass, + css, + matrix, + find, + getWindowScrollingElement, + getRect, + isScrolledPast, + getChild, + lastChild, + index, + getRelativeScrollOffset, + extend, + throttle, + scrollBy, + clone, + expando +} from './utils.js'; + + +let pluginEvent = function(eventName, sortable, { evt: originalEvent, ...data } = {}) { + PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, { + dragEl, + parentEl, + ghostEl, + rootEl, + nextEl, + lastDownEl, + cloneEl, + cloneHidden, + dragStarted: moved, + putSortable, + activeSortable: Sortable.active, + originalEvent, + + oldIndex, + oldDraggableIndex, + newIndex, + newDraggableIndex, + + hideGhostForTarget: _hideGhostForTarget, + unhideGhostForTarget: _unhideGhostForTarget, + + + cloneNowHidden() { + cloneHidden = true; + }, + cloneNowShown() { + cloneHidden = false; + }, + + dispatchSortableEvent(name) { + _dispatchEvent({ sortable, name, originalEvent }); + }, + + ...data + }); +}; + +function _dispatchEvent(info) { + dispatchEvent({ + putSortable, + cloneEl, + targetEl: dragEl, + rootEl, + oldIndex, + oldDraggableIndex, + newIndex, + newDraggableIndex, + ...info + }); +} + + +let dragEl, + parentEl, + ghostEl, + rootEl, + nextEl, + lastDownEl, + + cloneEl, + cloneHidden, + + oldIndex, + newIndex, + oldDraggableIndex, + newDraggableIndex, + + activeGroup, + putSortable, + + awaitingDragStarted = false, + ignoreNextClick = false, + sortables = [], + + tapEvt, + touchEvt, + lastDx, + lastDy, + tapDistanceLeft, + tapDistanceTop, + + moved, + + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + + targetMoveDistance, + + // For positioning ghost absolutely + ghostRelativeParent, + ghostRelativeParentInitialScroll = [], // (left, top) + + _silent = false, + savedInputChecked = []; + + /** @const */ + const documentExists = typeof document !== 'undefined', + + PositionGhostAbsolutely = IOS, + + CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', + + // This will not pass for IE9, because IE9 DnD only works on anchors + supportDraggable = documentExists && !ChromeForAndroid && !IOS && ('draggable' in document.createElement('div')), + + supportCssPointerEvents = (function() { + if (!documentExists) return; + // false when <= IE11 + if (IE11OrLess) { + return false; + } + let el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; + })(), + + _detectDirection = function(el, options) { + let elCSS = css(el), + elWidth = parseInt(elCSS.width) + - parseInt(elCSS.paddingLeft) + - parseInt(elCSS.paddingRight) + - parseInt(elCSS.borderLeftWidth) + - parseInt(elCSS.borderRightWidth), + child1 = getChild(el, 0, options), + child2 = getChild(el, 1, options), + firstChildCSS = child1 && css(child1), + secondChildCSS = child2 && css(child2), + firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, + secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; + + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' + ? 'vertical' : 'horizontal'; + } + + if (elCSS.display === 'grid') { + return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; + } + + if (child1 && firstChildCSS.float && firstChildCSS.float !== 'none') { + let touchingSideChild2 = firstChildCSS.float === 'left' ? 'left' : 'right'; + + return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? + 'vertical' : 'horizontal'; + } + + return (child1 && + ( + firstChildCSS.display === 'block' || + firstChildCSS.display === 'flex' || + firstChildCSS.display === 'table' || + firstChildCSS.display === 'grid' || + firstChildWidth >= elWidth && + elCSS[CSSFloatProperty] === 'none' || + child2 && + elCSS[CSSFloatProperty] === 'none' && + firstChildWidth + secondChildWidth > elWidth + ) ? + 'vertical' : 'horizontal' + ); + }, + + _dragElInRowColumn = function(dragRect, targetRect, vertical) { + let dragElS1Opp = vertical ? dragRect.left : dragRect.top, + dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, + dragElOppLength = vertical ? dragRect.width : dragRect.height, + targetS1Opp = vertical ? targetRect.left : targetRect.top, + targetS2Opp = vertical ? targetRect.right : targetRect.bottom, + targetOppLength = vertical ? targetRect.width : targetRect.height; + + return ( + dragElS1Opp === targetS1Opp || + dragElS2Opp === targetS2Opp || + (dragElS1Opp + dragElOppLength / 2) === (targetS1Opp + targetOppLength / 2) + ); + }, + + /** + * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. + * @param {Number} x X position + * @param {Number} y Y position + * @return {HTMLElement} Element of the first found nearest Sortable + */ + _detectNearestEmptySortable = function(x, y) { + let ret; + sortables.some((sortable) => { + if (lastChild(sortable)) return; + + let rect = getRect(sortable), + threshold = sortable[expando].options.emptyInsertThreshold, + insideHorizontally = x >= (rect.left - threshold) && x <= (rect.right + threshold), + insideVertically = y >= (rect.top - threshold) && y <= (rect.bottom + threshold); + + if (threshold && insideHorizontally && insideVertically) { + return (ret = sortable); + } + }); + return ret; + }, + + _prepareGroup = function (options) { + function toFn(value, pull) { + return function(to, from, dragEl, evt) { + let sameGroup = to.options.group.name && + from.options.group.name && + to.options.group.name === from.options.group.name; + + if (value == null && (pull || sameGroup)) { + // Default pull value + // Default pull and put value if same group + return true; + } else if (value == null || value === false) { + return false; + } else if (pull && value === 'clone') { + return value; + } else if (typeof value === 'function') { + return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); + } else { + let otherGroup = (pull ? to : from).options.group.name; + + return (value === true || + (typeof value === 'string' && value === otherGroup) || + (value.join && value.indexOf(otherGroup) > -1)); + } + }; + } + + let group = {}; + let originalGroup = options.group; + + if (!originalGroup || typeof originalGroup != 'object') { + originalGroup = {name: originalGroup}; + } + + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + + options.group = group; + }, + + _hideGhostForTarget = function() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', 'none'); + } + }, + + _unhideGhostForTarget = function() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', ''); + } + }; + + +// #1184 fix - Prevent click event on fallback if dragged but item not changed position +if (documentExists) { + document.addEventListener('click', function(evt) { + if (ignoreNextClick) { + evt.preventDefault(); + evt.stopPropagation && evt.stopPropagation(); + evt.stopImmediatePropagation && evt.stopImmediatePropagation(); + ignoreNextClick = false; + return false; + } + }, true); +} + +let nearestEmptyInsertDetectEvent = function(evt) { + if (dragEl) { + evt = evt.touches ? evt.touches[0] : evt; + let nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); + + if (nearest) { + // Create imitation event + let event = {}; + for (let i in evt) { + if (evt.hasOwnProperty(i)) { + event[i] = evt[i]; + } + } + event.target = event.rootEl = nearest; + event.preventDefault = void 0; + event.stopPropagation = void 0; + nearest[expando]._onDragOver(event); + } + } +}; + + +let _checkOutsideTargetEl = function(evt) { + if (dragEl) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); + } +}; + + +/** + * @class Sortable + * @param {HTMLElement} el + * @param {Object} [options] + */ +function Sortable(el, options) { + if (!(el && el.nodeType && el.nodeType === 1)) { + throw `Sortable: \`el\` must be an HTMLElement, not ${ {}.toString.call(el) }`; + } + + this.el = el; // root element + this.options = options = Object.assign({}, options); + + + // Export instance + el[expando] = this; + + let defaults = { + group: null, + sort: true, + disabled: false, + store: null, + handle: null, + draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*', + swapThreshold: 1, // percentage; 0 <= x <= 1 + invertSwap: false, // invert always + invertedSwapThreshold: null, // will be set to same as swapThreshold if default + removeCloneOnHide: true, + direction: function() { + return _detectDirection(el, this.options); + }, + ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', + dragClass: 'sortable-drag', + ignore: 'a, img', + filter: null, + preventOnFilter: true, + animation: 0, + easing: null, + setData: function (dataTransfer, dragEl) { + dataTransfer.setData('Text', dragEl.textContent); + }, + dropBubble: false, + dragoverBubble: false, + dataIdAttr: 'data-id', + delay: 0, + delayOnTouchOnly: false, + touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false, + fallbackTolerance: 0, + fallbackOffset: {x: 0, y: 0}, + supportPointer: Sortable.supportPointer !== false && ('PointerEvent' in window), + emptyInsertThreshold: 5 + }; + + PluginManager.initializePlugins(this, el, defaults); + + // Set default options + for (let name in defaults) { + !(name in options) && (options[name] = defaults[name]); + } + + _prepareGroup(options); + + // Bind all private methods + for (let fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + // Setup drag mode + this.nativeDraggable = options.forceFallback ? false : supportDraggable; + + if (this.nativeDraggable) { + // Touch start threshold cannot be greater than the native dragstart threshold + this.options.touchStartThreshold = 1; + } + + // Bind events + if (options.supportPointer) { + on(el, 'pointerdown', this._onTapStart); + } else { + on(el, 'mousedown', this._onTapStart); + on(el, 'touchstart', this._onTapStart); + } + + if (this.nativeDraggable) { + on(el, 'dragover', this); + on(el, 'dragenter', this); + } + + sortables.push(this.el); + + // Restore sorting + options.store && options.store.get && this.sort(options.store.get(this) || []); + + // Add animation state manager + Object.assign(this, AnimationStateManager()); +} + +Sortable.prototype = /** @lends Sortable.prototype */ { + constructor: Sortable, + + _isOutsideThisEl: function(target) { + if (!this.el.contains(target) && target !== this.el) { + lastTarget = null; + } + }, + + _getDirection: function(evt, target) { + return (typeof this.options.direction === 'function') ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; + }, + + _onTapStart: function (/** Event|TouchEvent */evt) { + if (!evt.cancelable) return; + let _this = this, + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = (evt.touches && evt.touches[0]) || (evt.pointerType && evt.pointerType === 'touch' && evt), + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && ((evt.path && evt.path[0]) || (evt.composedPath && evt.composedPath()[0])) || target, + filter = options.filter; + + _saveInputCheckedState(el); + + + // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. + if (dragEl) { + return; + } + + if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { + return; // only left button and enabled + } + + // cancel dnd if original target is content editable + if (originalTarget.isContentEditable) { + return; + } + + target = closest(target, options.draggable, el, false); + + + if (target && target.animated) { + return; + } + + if (lastDownEl === target) { + // Ignoring duplicate `down` + return; + } + + // Get the index of the dragged element within its parent + oldIndex = index(target); + oldDraggableIndex = index(target, options.draggable); + + // Check filter + if (typeof filter === 'function') { + if (filter.call(this, evt, target, this)) { + _dispatchEvent({ + sortable: _this, + rootEl: originalTarget, + name: 'filter', + targetEl: target, + toEl: el, + fromEl: el + }); + pluginEvent('filter', _this, { evt }); + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + else if (filter) { + filter = filter.split(',').some(function (criteria) { + criteria = closest(originalTarget, criteria.trim(), el, false); + + if (criteria) { + _dispatchEvent({ + sortable: _this, + rootEl: criteria, + name: 'filter', + targetEl: target, + fromEl: el, + toEl: el + }); + pluginEvent('filter', _this, { evt }); + return true; + } + }); + + if (filter) { + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + + if (options.handle && !closest(originalTarget, options.handle, el, false)) { + return; + } + + // Prepare `dragstart` + this._prepareDragStart(evt, touch, target); + }, + + _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target) { + let _this = this, + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; + + if (target && !dragEl && (target.parentNode === el)) { + let dragRect = getRect(target); + rootEl = el; + dragEl = target; + parentEl = dragEl.parentNode; + nextEl = dragEl.nextSibling; + lastDownEl = target; + activeGroup = options.group; + + Sortable.dragged = dragEl; + + tapEvt = { + target: dragEl, + clientX: (touch || evt).clientX, + clientY: (touch || evt).clientY + }; + + tapDistanceLeft = tapEvt.clientX - dragRect.left; + tapDistanceTop = tapEvt.clientY - dragRect.top; + + this._lastX = (touch || evt).clientX; + this._lastY = (touch || evt).clientY; + + dragEl.style['will-change'] = 'all'; + + dragStartFn = function () { + pluginEvent('delayEnded', _this, { evt }); + if (Sortable.eventCanceled) { + _this._onDrop(); + return; + } + // Delayed drag has been triggered + // we can re-enable the events: touchmove/mousemove + _this._disableDelayedDragEvents(); + + if (!FireFox && _this.nativeDraggable) { + dragEl.draggable = true; + } + + // Bind the events: dragstart/dragend + _this._triggerDragStart(evt, touch); + + // Drag start event + _dispatchEvent({ + sortable: _this, + name: 'choose', + originalEvent: evt + }); + + // Chosen item + toggleClass(dragEl, options.chosenClass, true); + }; + + // Disable "draggable" + options.ignore.split(',').forEach(function (criteria) { + find(dragEl, criteria.trim(), _disableDraggable); + }); + + on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); + + on(ownerDocument, 'mouseup', _this._onDrop); + on(ownerDocument, 'touchend', _this._onDrop); + on(ownerDocument, 'touchcancel', _this._onDrop); + + // Make dragEl draggable (must be before delay for FireFox) + if (FireFox && this.nativeDraggable) { + this.options.touchStartThreshold = 4; + dragEl.draggable = true; + } + + pluginEvent('delayStart', this, { evt }); + + // Delay is impossible for native DnD in Edge or IE + if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { + if (Sortable.eventCanceled) { + this._onDrop(); + return; + } + // If the user moves the pointer or let go the click or touch + // before the delay has been reached: + // disable the delayed drag + on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + on(ownerDocument, 'touchend', _this._disableDelayedDrag); + on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); + on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); + options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); + + _this._dragStartTimer = setTimeout(dragStartFn, options.delay); + } else { + dragStartFn(); + } + } + }, + + _delayedDragTouchMoveHandler: function (/** TouchEvent|PointerEvent **/e) { + let touch = e.touches ? e.touches[0] : e; + if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) + >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1)) + ) { + this._disableDelayedDrag(); + } + }, + + _disableDelayedDrag: function () { + dragEl && _disableDraggable(dragEl); + clearTimeout(this._dragStartTimer); + + this._disableDelayedDragEvents(); + }, + + _disableDelayedDragEvents: function () { + let ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._disableDelayedDrag); + off(ownerDocument, 'touchend', this._disableDelayedDrag); + off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); + }, + + _triggerDragStart: function (/** Event */evt, /** Touch */touch) { + touch = touch || (evt.pointerType == 'touch' && evt); + + if (!this.nativeDraggable || touch) { + if (this.options.supportPointer) { + on(document, 'pointermove', this._onTouchMove); + } else if (touch) { + on(document, 'touchmove', this._onTouchMove); + } else { + on(document, 'mousemove', this._onTouchMove); + } + } else { + on(dragEl, 'dragend', this); + on(rootEl, 'dragstart', this._onDragStart); + } + + try { + if (document.selection) { + // Timeout neccessary for IE9 + _nextTick(function () { + document.selection.empty(); + }); + } else { + window.getSelection().removeAllRanges(); + } + } catch (err) { + } + }, + + _dragStarted: function (fallback, evt) { + let _this = this; + awaitingDragStarted = false; + if (rootEl && dragEl) { + pluginEvent('dragStarted', this, { evt }); + + if (this.nativeDraggable) { + on(document, 'dragover', _checkOutsideTargetEl); + } + let options = this.options; + + // Apply effect + !fallback && toggleClass(dragEl, options.dragClass, false); + toggleClass(dragEl, options.ghostClass, true); + + Sortable.active = this; + + fallback && this._appendGhost(); + + // Drag start event + _dispatchEvent({ + sortable: this, + name: 'start', + originalEvent: evt + }); + } else { + this._nulling(); + } + }, + + _emulateDragOver: function () { + if (touchEvt) { + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + _hideGhostForTarget(); + + let target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + let parent = target; + + while (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + if (target === parent) break; + parent = target; + } + + dragEl.parentNode[expando]._isOutsideThisEl(target); + + if (parent) { + do { + if (parent[expando]) { + let inserted; + + inserted = parent[expando]._onDragOver({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + + if (inserted && !this.options.dragoverBubble) { + break; + } + } + + target = parent; // store last element + } + /* jshint boss:true */ + while (parent = parent.parentNode); + } + + _unhideGhostForTarget(); + } + }, + + + _onTouchMove: function (/**TouchEvent*/evt) { + if (tapEvt) { + let options = this.options, + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + ghostMatrix = ghostEl && matrix(ghostEl), + scaleX = ghostEl && ghostMatrix && ghostMatrix.a, + scaleY = ghostEl && ghostMatrix && ghostMatrix.d, + relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), + dx = ((touch.clientX - tapEvt.clientX) + + fallbackOffset.x) / (scaleX || 1) + + (relativeScrollOffset ? (relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0]) : 0) / (scaleX || 1), + dy = ((touch.clientY - tapEvt.clientY) + + fallbackOffset.y) / (scaleY || 1) + + (relativeScrollOffset ? (relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1]) : 0) / (scaleY || 1); + + // only set the status to dragging, when we are actually dragging + if (!Sortable.active && !awaitingDragStarted) { + if (fallbackTolerance && + Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance + ) { + return; + } + this._onDragStart(evt, true); + } + + if (ghostEl) { + if (ghostMatrix) { + ghostMatrix.e += dx - (lastDx || 0); + ghostMatrix.f += dy - (lastDy || 0); + } else { + ghostMatrix = { + a: 1, + b: 0, + c: 0, + d: 1, + e: dx, + f: dy + }; + } + + let cssMatrix = `matrix(${ghostMatrix.a},${ghostMatrix.b},${ghostMatrix.c},${ghostMatrix.d},${ghostMatrix.e},${ghostMatrix.f})`; + + css(ghostEl, 'webkitTransform', cssMatrix); + css(ghostEl, 'mozTransform', cssMatrix); + css(ghostEl, 'msTransform', cssMatrix); + css(ghostEl, 'transform', cssMatrix); + + lastDx = dx; + lastDy = dy; + + touchEvt = touch; + } + + evt.cancelable && evt.preventDefault(); + } + }, + + _appendGhost: function () { + // Bug if using scale(): https://stackoverflow.com/questions/2637058 + // Not being adjusted for + if (!ghostEl) { + let container = this.options.fallbackOnBody ? document.body : rootEl, + rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), + options = this.options; + + // Position absolutely + if (PositionGhostAbsolutely) { + // Get relatively positioned parent + ghostRelativeParent = container; + + while ( + css(ghostRelativeParent, 'position') === 'static' && + css(ghostRelativeParent, 'transform') === 'none' && + ghostRelativeParent !== document + ) { + ghostRelativeParent = ghostRelativeParent.parentNode; + } + + if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { + if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement(); + + rect.top += ghostRelativeParent.scrollTop; + rect.left += ghostRelativeParent.scrollLeft; + } else { + ghostRelativeParent = getWindowScrollingElement(); + } + ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent); + } + + + ghostEl = dragEl.cloneNode(true); + + toggleClass(ghostEl, options.ghostClass, false); + toggleClass(ghostEl, options.fallbackClass, true); + toggleClass(ghostEl, options.dragClass, true); + + css(ghostEl, 'transition', ''); + css(ghostEl, 'transform', ''); + + css(ghostEl, 'box-sizing', 'border-box'); + css(ghostEl, 'margin', 0); + css(ghostEl, 'top', rect.top); + css(ghostEl, 'left', rect.left); + css(ghostEl, 'width', rect.width); + css(ghostEl, 'height', rect.height); + css(ghostEl, 'opacity', '0.8'); + css(ghostEl, 'position', (PositionGhostAbsolutely ? 'absolute' : 'fixed')); + css(ghostEl, 'zIndex', '100000'); + css(ghostEl, 'pointerEvents', 'none'); + + + Sortable.ghost = ghostEl; + + container.appendChild(ghostEl); + + // Set transform-origin + css(ghostEl, 'transform-origin', (tapDistanceLeft / parseInt(ghostEl.style.width) * 100) + '% ' + (tapDistanceTop / parseInt(ghostEl.style.height) * 100) + '%'); + } + }, + + _onDragStart: function (/**Event*/evt, /**boolean*/fallback) { + let _this = this; + let dataTransfer = evt.dataTransfer; + let options = _this.options; + + pluginEvent('dragStart', this, { evt }); + if (Sortable.eventCanceled) { + this._onDrop(); + return; + } + + pluginEvent('setupClone', this); + if (!Sortable.eventCanceled) { + cloneEl = clone(dragEl); + + cloneEl.draggable = false; + cloneEl.style['will-change'] = ''; + + this._hideClone(); + + toggleClass(cloneEl, this.options.chosenClass, false); + Sortable.clone = cloneEl; + } + + + // #1143: IFrame support workaround + _this.cloneId = _nextTick(function() { + pluginEvent('clone', _this); + if (Sortable.eventCanceled) return; + + if (!_this.options.removeCloneOnHide) { + rootEl.insertBefore(cloneEl, dragEl); + } + _this._hideClone(); + + _dispatchEvent({ + sortable: _this, + name: 'clone' + }); + }); + + + !fallback && toggleClass(dragEl, options.dragClass, true); + + // Set proper drop events + if (fallback) { + ignoreNextClick = true; + _this._loopId = setInterval(_this._emulateDragOver, 50); + } else { + // Undo what was set in _prepareDragStart before drag started + off(document, 'mouseup', _this._onDrop); + off(document, 'touchend', _this._onDrop); + off(document, 'touchcancel', _this._onDrop); + + if (dataTransfer) { + dataTransfer.effectAllowed = 'move'; + options.setData && options.setData.call(_this, dataTransfer, dragEl); + } + + on(document, 'drop', _this); + + // #1276 fix: + css(dragEl, 'transform', 'translateZ(0)'); + } + + awaitingDragStarted = true; + + _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); + on(document, 'selectstart', _this); + + moved = true; + + if (Safari) { + css(document.body, 'user-select', 'none'); + } + }, + + + // Returns true - if no further action is needed (either inserted or another condition) + _onDragOver: function (/**Event*/evt) { + let el = this.el, + target = evt.target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable.active, + isOwner = (activeGroup === group), + canSort = options.sort, + fromSortable = (putSortable || activeSortable), + vertical, + _this = this, + completedFired = false; + + if (_silent) return; + + function dragOverEvent(name, extra) { + pluginEvent(name, _this, { + evt, + isOwner, + axis: vertical ? 'vertical' : 'horizontal', + revert, + dragRect, + targetRect, + canSort, + fromSortable, + target, + completed, + onMove(target, after) { + return onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after); + }, + changed, + ...extra + }); + } + + // Capture animation state + function capture() { + dragOverEvent('dragOverAnimationCapture'); + + _this.captureAnimationState(); + if (_this !== fromSortable) { + fromSortable.captureAnimationState(); + } + } + + // Return invocation when dragEl is inserted (or completed) + function completed(insertion) { + dragOverEvent('dragOverCompleted', { insertion }); + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(_this); + } + + if (_this !== fromSortable) { + // Set ghost class to new sortable's ghost class + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); + toggleClass(dragEl, options.ghostClass, true); + } + + if (putSortable !== _this && _this !== Sortable.active) { + putSortable = _this; + } else if (_this === Sortable.active && putSortable) { + putSortable = null; + } + + // Animation + if (fromSortable === _this) { + _this._ignoreWhileAnimating = target; + } + _this.animateAll(function() { + dragOverEvent('dragOverAnimationComplete'); + _this._ignoreWhileAnimating = null; + }); + if (_this !== fromSortable) { + fromSortable.animateAll(); + fromSortable._ignoreWhileAnimating = null; + } + } + + + // Null lastTarget if it is not inside a previously swapped element + if ((target === dragEl && !dragEl.animated) || (target === el && !target.animated)) { + lastTarget = null; + } + + // no bubbling and not fallback + if (!options.dragoverBubble && !evt.rootEl && target !== document) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); + + // Do not detect for empty insert if already inserted + !insertion && nearestEmptyInsertDetectEvent(evt); + } + + !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); + + return (completedFired = true); + } + + // Call when dragEl has been inserted + function changed() { + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + _dispatchEvent({ + sortable: _this, + name: 'change', + toEl: el, + newIndex, + newDraggableIndex, + originalEvent: evt + }); + } + + + if (evt.preventDefault !== void 0) { + evt.cancelable && evt.preventDefault(); + } + + + target = closest(target, options.draggable, el, true); + + dragOverEvent('dragOver'); + if (Sortable.eventCanceled) return completedFired; + + if ( + dragEl.contains(evt.target) || + target.animated && target.animatingX && target.animatingY || + _this._ignoreWhileAnimating === target + ) { + return completed(false); + } + + ignoreNextClick = false; + + if (activeSortable && !options.disabled && + (isOwner + ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + : ( + putSortable === this || + ( + (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && + group.checkPut(this, activeSortable, dragEl, evt) + ) + ) + ) + ) { + vertical = this._getDirection(evt, target) === 'vertical'; + + dragRect = getRect(dragEl); + + dragOverEvent('dragOverValid'); + if (Sortable.eventCanceled) return completedFired; + + if (revert) { + parentEl = rootEl; // actualization + capture(); + + this._hideClone(); + + dragOverEvent('revert'); + + if (!Sortable.eventCanceled) { + if (nextEl) { + rootEl.insertBefore(dragEl, nextEl); + } else { + rootEl.appendChild(dragEl); + } + } + + return completed(true); + } + + let elLastChild = lastChild(el, options.draggable); + + if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { + // If already at end of list: Do not insert + if (elLastChild === dragEl) { + return completed(false); + } + + // assign target only if condition is true + if (elLastChild && el === evt.target) { + target = elLastChild; + } + + if (target) { + targetRect = getRect(target); + } + + if (onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { + capture(); + el.appendChild(dragEl); + parentEl = el; // actualization + + changed(); + return completed(true); + } + } + else if (target.parentNode === el) { + targetRect = getRect(target); + let direction = 0, + targetBeforeFirstSwap, + differentLevel = dragEl.parentNode !== el, + differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), + side1 = vertical ? 'top' : 'left', + scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), + scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; + + + if (lastTarget !== target) { + targetBeforeFirstSwap = targetRect[side1]; + pastFirstInvertThresh = false; + isCircumstantialInvert = (!differentRowCol && options.invertSwap) || differentLevel; + } + + direction = _getSwapDirection( + evt, target, targetRect, vertical, + differentRowCol ? 1 : options.swapThreshold, + options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, + isCircumstantialInvert, + lastTarget === target + ); + + let sibling; + + if (direction !== 0) { + // Check if target is beside dragEl in respective direction (ignoring hidden elements) + let dragIndex = index(dragEl); + + do { + dragIndex -= direction; + sibling = parentEl.children[dragIndex]; + } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl)); + } + // If dragEl is already beside target: Do not insert + if ( + direction === 0 || + sibling === target + ) { + return completed(false); + } + + lastTarget = target; + + lastDirection = direction; + + let nextSibling = target.nextElementSibling, + after = false; + + after = direction === 1; + + let moveVector = onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); + + if (moveVector !== false) { + if (moveVector === 1 || moveVector === -1) { + after = (moveVector === 1); + } + + _silent = true; + setTimeout(_unsilent, 30); + + capture(); + + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } + + // Undo chrome's scroll adjustment (has no effect on other browsers) + if (scrolledPastTop) { + scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); + } + + parentEl = dragEl.parentNode; // actualization + + // must be done before animation + if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { + targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]); + } + changed(); + + return completed(true); + } + } + + if (el.contains(dragEl)) { + return completed(false); + } + } + + return false; + }, + + _ignoreWhileAnimating: null, + + _offMoveEvents: function() { + off(document, 'mousemove', this._onTouchMove); + off(document, 'touchmove', this._onTouchMove); + off(document, 'pointermove', this._onTouchMove); + off(document, 'dragover', nearestEmptyInsertDetectEvent); + off(document, 'mousemove', nearestEmptyInsertDetectEvent); + off(document, 'touchmove', nearestEmptyInsertDetectEvent); + }, + + _offUpEvents: function () { + let ownerDocument = this.el.ownerDocument; + + off(ownerDocument, 'mouseup', this._onDrop); + off(ownerDocument, 'touchend', this._onDrop); + off(ownerDocument, 'pointerup', this._onDrop); + off(ownerDocument, 'touchcancel', this._onDrop); + off(document, 'selectstart', this); + }, + + _onDrop: function (/**Event*/evt) { + let el = this.el, + options = this.options; + + // Get the index of the dragged element within its parent + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + pluginEvent('drop', this, { + evt + }); + + parentEl = dragEl && dragEl.parentNode; + + // Get again after plugin event + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + if (Sortable.eventCanceled) { + this._nulling(); + return; + } + + awaitingDragStarted = false; + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + + clearInterval(this._loopId); + + clearTimeout(this._dragStartTimer); + + _cancelNextTick(this.cloneId); + _cancelNextTick(this._dragStartId); + + // Unbind events + if (this.nativeDraggable) { + off(document, 'drop', this); + off(el, 'dragstart', this._onDragStart); + } + this._offMoveEvents(); + this._offUpEvents(); + + + if (Safari) { + css(document.body, 'user-select', ''); + } + + + if (evt) { + if (moved) { + evt.cancelable && evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } + + ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); + + if (rootEl === parentEl || (putSortable && putSortable.lastPutMode !== 'clone')) { + // Remove clone(s) + cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); + } + + if (dragEl) { + if (this.nativeDraggable) { + off(dragEl, 'dragend', this); + } + + _disableDraggable(dragEl); + dragEl.style['will-change'] = ''; + + // Remove classes + // ghostClass is added in dragStarted + if (moved && !awaitingDragStarted) { + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); + } + toggleClass(dragEl, this.options.chosenClass, false); + + // Drag stop event + _dispatchEvent({ + sortable: this, + name: 'unchoose', + toEl: parentEl, + newIndex: null, + newDraggableIndex: null, + originalEvent: evt + }); + + + if (rootEl !== parentEl) { + + if (newIndex >= 0) { + // Add event + _dispatchEvent({ + rootEl: parentEl, + name: 'add', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); + + // Remove event + _dispatchEvent({ + sortable: this, + name: 'remove', + toEl: parentEl, + originalEvent: evt + }); + + // drag from one list and drop into another + _dispatchEvent({ + rootEl: parentEl, + name: 'sort', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + + putSortable && putSortable.save(); + } else { + if (newIndex !== oldIndex) { + if (newIndex >= 0) { + // drag & drop within the same list + _dispatchEvent({ + sortable: this, + name: 'update', + toEl: parentEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + } + } + + if (Sortable.active) { + /* jshint eqnull:true */ + if (newIndex == null || newIndex === -1) { + newIndex = oldIndex; + newDraggableIndex = oldDraggableIndex; + } + + _dispatchEvent({ + sortable: this, + name: 'end', + toEl: parentEl, + originalEvent: evt + }); + + // Save sorting + this.save(); + } + } + + } + this._nulling(); + }, + + _nulling: function() { + pluginEvent('nulling', this); + + rootEl = + dragEl = + parentEl = + ghostEl = + nextEl = + cloneEl = + lastDownEl = + cloneHidden = + + tapEvt = + touchEvt = + + moved = + newIndex = + newDraggableIndex = + oldIndex = + oldDraggableIndex = + + lastTarget = + lastDirection = + + putSortable = + activeGroup = + Sortable.dragged = + Sortable.ghost = + Sortable.clone = + Sortable.active = null; + + savedInputChecked.forEach(function (el) { + el.checked = true; + }); + + savedInputChecked.length = + lastDx = + lastDy = 0; + }, + + handleEvent: function (/**Event*/evt) { + switch (evt.type) { + case 'drop': + case 'dragend': + this._onDrop(evt); + break; + + case 'dragenter': + case 'dragover': + if (dragEl) { + this._onDragOver(evt); + _globalDragOver(evt); + } + break; + + case 'selectstart': + evt.preventDefault(); + break; + } + }, + + + /** + * Serializes the item into an array of string. + * @returns {String[]} + */ + toArray: function () { + let order = [], + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; + + for (; i < n; i++) { + el = children[i]; + if (closest(el, options.draggable, this.el, false)) { + order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); + } + } + + return order; + }, + + + /** + * Sorts the elements according to the array. + * @param {String[]} order order of the items + */ + sort: function (order) { + let items = {}, rootEl = this.el; + + this.toArray().forEach(function (id, i) { + let el = rootEl.children[i]; + + if (closest(el, this.options.draggable, rootEl, false)) { + items[id] = el; + } + }, this); + + order.forEach(function (id) { + if (items[id]) { + rootEl.removeChild(items[id]); + rootEl.appendChild(items[id]); + } + }); + }, + + + /** + * Save the current sorting + */ + save: function () { + let store = this.options.store; + store && store.set && store.set(this); + }, + + + /** + * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + * @param {HTMLElement} el + * @param {String} [selector] default: `options.draggable` + * @returns {HTMLElement|null} + */ + closest: function (el, selector) { + return closest(el, selector || this.options.draggable, this.el, false); + }, + + + /** + * Set/get option + * @param {string} name + * @param {*} [value] + * @returns {*} + */ + option: function (name, value) { + let options = this.options; + + if (value === void 0) { + return options[name]; + } else { + let modifiedValue = PluginManager.modifyOption(this, name, value); + if (typeof modifiedValue !== 'undefined') { + options[name] = modifiedValue; + } else { + options[name] = value; + } + + if (name === 'group') { + _prepareGroup(options); + } + } + }, + + + /** + * Destroy + */ + destroy: function () { + pluginEvent('destroy', this); + let el = this.el; + + el[expando] = null; + + off(el, 'mousedown', this._onTapStart); + off(el, 'touchstart', this._onTapStart); + off(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + off(el, 'dragover', this); + off(el, 'dragenter', this); + } + // Remove draggable attributes + Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { + el.removeAttribute('draggable'); + }); + + this._onDrop(); + + sortables.splice(sortables.indexOf(this.el), 1); + + this.el = el = null; + }, + + _hideClone: function() { + if (!cloneHidden) { + pluginEvent('hideClone', this); + if (Sortable.eventCanceled) return; + + + css(cloneEl, 'display', 'none'); + if (this.options.removeCloneOnHide && cloneEl.parentNode) { + cloneEl.parentNode.removeChild(cloneEl); + } + cloneHidden = true; + } + }, + + _showClone: function(putSortable) { + if (putSortable.lastPutMode !== 'clone') { + this._hideClone(); + return; + } + + + if (cloneHidden) { + pluginEvent('showClone', this); + if (Sortable.eventCanceled) return; + + // show clone at dragEl or original position + if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + rootEl.insertBefore(cloneEl, dragEl); + } else if (nextEl) { + rootEl.insertBefore(cloneEl, nextEl); + } else { + rootEl.appendChild(cloneEl); + } + + if (this.options.group.revertClone) { + this.animate(dragEl, cloneEl); + } + + css(cloneEl, 'display', ''); + cloneHidden = false; + } + } +}; + +function _globalDragOver(/**Event*/evt) { + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } + evt.cancelable && evt.preventDefault(); +} + +function onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) { + let evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; + // Support for new CustomEvent feature + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent('move', { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + } + + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || getRect(toEl); + evt.willInsertAfter = willInsertAfter; + + evt.originalEvent = originalEvent; + + fromEl.dispatchEvent(evt); + + if (onMoveFn) { + retVal = onMoveFn.call(sortable, evt, originalEvent); + } + + return retVal; +} + +function _disableDraggable(el) { + el.draggable = false; +} + +function _unsilent() { + _silent = false; +} + + +function _ghostIsLast(evt, vertical, sortable) { + let rect = getRect(lastChild(sortable.el, sortable.options.draggable)); + const spacer = 10; + + return vertical ? + (evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left) : + (evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer); +} + +function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { + let mouseOnAxis = vertical ? evt.clientY : evt.clientX, + targetLength = vertical ? targetRect.height : targetRect.width, + targetS1 = vertical ? targetRect.top : targetRect.left, + targetS2 = vertical ? targetRect.bottom : targetRect.right, + invert = false; + + + if (!invertSwap) { + // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold + if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 + // check if past first invert threshold on side opposite of lastDirection + if (!pastFirstInvertThresh && + (lastDirection === 1 ? + ( + mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 + ) : + ( + mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2 + ) + ) + ) + { + // past first invert threshold, do not restrict inverted threshold to dragEl shadow + pastFirstInvertThresh = true; + } + + if (!pastFirstInvertThresh) { + // dragEl shadow (target move distance shadow) + if ( + lastDirection === 1 ? + ( + mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow + ) : + ( + mouseOnAxis > targetS2 - targetMoveDistance + ) + ) + { + return -lastDirection; + } + } else { + invert = true; + } + } else { + // Regular + if ( + mouseOnAxis > targetS1 + (targetLength * (1 - swapThreshold) / 2) && + mouseOnAxis < targetS2 - (targetLength * (1 - swapThreshold) / 2) + ) { + return _getInsertDirection(target); + } + } + } + + invert = invert || invertSwap; + + if (invert) { + // Invert of regular + if ( + mouseOnAxis < targetS1 + (targetLength * invertedSwapThreshold / 2) || + mouseOnAxis > targetS2 - (targetLength * invertedSwapThreshold / 2) + ) + { + return ((mouseOnAxis > targetS1 + targetLength / 2) ? 1 : -1); + } + } + + return 0; +} + +/** + * Gets the direction dragEl must be swapped relative to target in order to make it + * seem that dragEl has been "inserted" into that element's position + * @param {HTMLElement} target The target whose position dragEl is being inserted at + * @return {Number} Direction dragEl must be swapped + */ +function _getInsertDirection(target) { + if (index(dragEl) < index(target)) { + return 1; + } else { + return -1; + } +} + + +/** + * Generate id + * @param {HTMLElement} el + * @returns {String} + * @private + */ +function _generateId(el) { + let str = el.tagName + el.className + el.src + el.href + el.textContent, + i = str.length, + sum = 0; + + while (i--) { + sum += str.charCodeAt(i); + } + + return sum.toString(36); +} + +function _saveInputCheckedState(root) { + savedInputChecked.length = 0; + + let inputs = root.getElementsByTagName('input'); + let idx = inputs.length; + + while (idx--) { + let el = inputs[idx]; + el.checked && savedInputChecked.push(el); + } +} + +function _nextTick(fn) { + return setTimeout(fn, 0); +} + +function _cancelNextTick(id) { + return clearTimeout(id); +} + +// Fixed #973: +if (documentExists) { + on(document, 'touchmove', function(evt) { + if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { + evt.preventDefault(); + } + }); +} + + +// Export utils +Sortable.utils = { + on: on, + off: off, + css: css, + find: find, + is: function (el, selector) { + return !!closest(el, selector, el, false); + }, + extend: extend, + throttle: throttle, + closest: closest, + toggleClass: toggleClass, + clone: clone, + index: index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick, + detectDirection: _detectDirection, + getChild: getChild +}; + + +/** + * Get the Sortable instance of an element + * @param {HTMLElement} element The element + * @return {Sortable|undefined} The instance of Sortable + */ +Sortable.get = function(element) { + return element[expando]; +}; + +/** + * Mount a plugin to Sortable + * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted + */ +Sortable.mount = function(...plugins) { + if (plugins[0].constructor === Array) plugins = plugins[0]; + + plugins.forEach((plugin) => { + if (!plugin.prototype || !plugin.prototype.constructor) { + throw `Sortable: Mounted plugin must be a constructor function, not ${ {}.toString.call(plugin) }`; + } + if (plugin.utils) Sortable.utils = { ...Sortable.utils, ...plugin.utils }; + + PluginManager.mount(plugin); + }); +}; + + + +/** + * Create sortable instance + * @param {HTMLElement} el + * @param {Object} [options] + */ +Sortable.create = function (el, options) { + return new Sortable(el, options); +}; + + +// Export +Sortable.version = version; + + +export default Sortable; diff --git a/public/assets/libs/Sortable/src/utils.js b/public/assets/libs/Sortable/src/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..7109c973baf6332cbc91dade085b5bcbf2765906 --- /dev/null +++ b/public/assets/libs/Sortable/src/utils.js @@ -0,0 +1,554 @@ +import { IE11OrLess } from './BrowserInfo.js'; +import Sortable from './Sortable.js'; + +const captureMode = { + capture: false, + passive: false +}; + +function on(el, event, fn) { + el.addEventListener(event, fn, !IE11OrLess && captureMode); +} + + +function off(el, event, fn) { + el.removeEventListener(event, fn, !IE11OrLess && captureMode); +} + +function matches(/**HTMLElement*/el, /**String*/selector) { + if (!selector) return; + + selector[0] === '>' && (selector = selector.substring(1)); + + if (el) { + try { + if (el.matches) { + return el.matches(selector); + } else if (el.msMatchesSelector) { + return el.msMatchesSelector(selector); + } else if (el.webkitMatchesSelector) { + return el.webkitMatchesSelector(selector); + } + } catch(_) { + return false; + } + } + + return false; +} + +function getParentOrHost(el) { + return (el.host && el !== document && el.host.nodeType) + ? el.host + : el.parentNode; +} + +function closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) { + if (el) { + ctx = ctx || document; + + do { + if ( + selector != null && + ( + selector[0] === '>' ? + el.parentNode === ctx && matches(el, selector) : + matches(el, selector) + ) || + includeCTX && el === ctx + ) { + return el; + } + + if (el === ctx) break; + /* jshint boss:true */ + } while (el = getParentOrHost(el)); + } + + return null; +} + +const R_SPACE = /\s+/g; + +function toggleClass(el, name, state) { + if (el && name) { + if (el.classList) { + el.classList[state ? 'add' : 'remove'](name); + } + else { + let className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); + el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); + } + } +} + + +function css(el, prop, val) { + let style = el && el.style; + + if (style) { + if (val === void 0) { + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(el, ''); + } + else if (el.currentStyle) { + val = el.currentStyle; + } + + return prop === void 0 ? val : val[prop]; + } + else { + if (!(prop in style) && prop.indexOf('webkit') === -1) { + prop = '-webkit-' + prop; + } + + style[prop] = val + (typeof val === 'string' ? '' : 'px'); + } + } +} + +function matrix(el, selfOnly) { + let appliedTransforms = ''; + if (typeof(el) === 'string') { + appliedTransforms = el; + } else { + do { + let transform = css(el, 'transform'); + + if (transform && transform !== 'none') { + appliedTransforms = transform + ' ' + appliedTransforms; + } + /* jshint boss:true */ + } while (!selfOnly && (el = el.parentNode)); + } + + const matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix; + /*jshint -W056 */ + return matrixFn && (new matrixFn(appliedTransforms)); +} + + +function find(ctx, tagName, iterator) { + if (ctx) { + let list = ctx.getElementsByTagName(tagName), i = 0, n = list.length; + + if (iterator) { + for (; i < n; i++) { + iterator(list[i], i); + } + } + + return list; + } + + return []; +} + + + +function getWindowScrollingElement() { + if (IE11OrLess) { + return document.documentElement; + } else { + return document.scrollingElement; + } +} + + +/** + * Returns the "bounding client rect" of given element + * @param {HTMLElement} el The element whose boundingClientRect is wanted + * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container + * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr + * @param {[Boolean]} undoScale Whether the container's scale() should be undone + * @param {[HTMLElement]} container The parent the element will be placed in + * @return {Object} The boundingClientRect of el, with specified adjustments + */ +function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) { + if (!el.getBoundingClientRect && el !== window) return; + + let elRect, + top, + left, + bottom, + right, + height, + width; + + if (el !== window && el !== getWindowScrollingElement()) { + elRect = el.getBoundingClientRect(); + top = elRect.top; + left = elRect.left; + bottom = elRect.bottom; + right = elRect.right; + height = elRect.height; + width = elRect.width; + } else { + top = 0; + left = 0; + bottom = window.innerHeight; + right = window.innerWidth; + height = window.innerHeight; + width = window.innerWidth; + } + + if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) { + // Adjust for translate() + container = container || el.parentNode; + + // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) + // Not needed on <= IE11 + if (!IE11OrLess) { + do { + if ( + container && + container.getBoundingClientRect && + ( + css(container, 'transform') !== 'none' || + relativeToNonStaticParent && + css(container, 'position') !== 'static' + ) + ) { + let containerRect = container.getBoundingClientRect(); + + // Set relative to edges of padding box of container + top -= containerRect.top + parseInt(css(container, 'border-top-width')); + left -= containerRect.left + parseInt(css(container, 'border-left-width')); + bottom = top + elRect.height; + right = left + elRect.width; + + break; + } + /* jshint boss:true */ + } while (container = container.parentNode); + } + } + + if (undoScale && el !== window) { + // Adjust for scale() + let elMatrix = matrix(container || el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d; + + if (elMatrix) { + top /= scaleY; + left /= scaleX; + + width /= scaleX; + height /= scaleY; + + bottom = top + height; + right = left + width; + } + } + + return { + top: top, + left: left, + bottom: bottom, + right: right, + width: width, + height: height + }; +} + +/** + * Checks if a side of an element is scrolled past a side of its parents + * @param {HTMLElement} el The element who's side being scrolled out of view is in question + * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom') + * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') + * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element + */ +function isScrolledPast(el, elSide, parentSide) { + let parent = getParentAutoScrollElement(el, true), + elSideVal = getRect(el)[elSide]; + + /* jshint boss:true */ + while (parent) { + let parentSideVal = getRect(parent)[parentSide], + visible; + + if (parentSide === 'top' || parentSide === 'left') { + visible = elSideVal >= parentSideVal; + } else { + visible = elSideVal <= parentSideVal; + } + + if (!visible) return parent; + + if (parent === getWindowScrollingElement()) break; + + parent = getParentAutoScrollElement(parent, false); + } + + return false; +} + + + +/** + * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) + * and non-draggable elements + * @param {HTMLElement} el The parent element + * @param {Number} childNum The index of the child + * @param {Object} options Parent Sortable's options + * @return {HTMLElement} The child at index childNum, or null if not found + */ +function getChild(el, childNum, options) { + let currentChild = 0, + i = 0, + children = el.children; + + while (i < children.length) { + if ( + children[i].style.display !== 'none' && + children[i] !== Sortable.ghost && + children[i] !== Sortable.dragged && + closest(children[i], options.draggable, el, false) + ) { + if (currentChild === childNum) { + return children[i]; + } + currentChild++; + } + + i++; + } + return null; +} + +/** + * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) + * @param {HTMLElement} el Parent element + * @param {selector} selector Any other elements that should be ignored + * @return {HTMLElement} The last child, ignoring ghostEl + */ +function lastChild(el, selector) { + let last = el.lastElementChild; + + while ( + last && + ( + last === Sortable.ghost || + css(last, 'display') === 'none' || + selector && !matches(last, selector) + ) + ) { + last = last.previousElementSibling; + } + + return last || null; +} + + +/** + * Returns the index of an element within its parent for a selected set of + * elements + * @param {HTMLElement} el + * @param {selector} selector + * @return {number} + */ +function index(el, selector) { + let index = 0; + + if (!el || !el.parentNode) { + return -1; + } + + /* jshint boss:true */ + while (el = el.previousElementSibling) { + if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && el !== Sortable.clone && (!selector || matches(el, selector))) { + index++; + } + } + + return index; +} + +/** + * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. + * The value is returned in real pixels. + * @param {HTMLElement} el + * @return {Array} Offsets in the format of [left, top] + */ +function getRelativeScrollOffset(el) { + let offsetLeft = 0, + offsetTop = 0, + winScroller = getWindowScrollingElement(); + + if (el) { + do { + let elMatrix = matrix(el), + scaleX = elMatrix.a, + scaleY = elMatrix.d; + + offsetLeft += el.scrollLeft * scaleX; + offsetTop += el.scrollTop * scaleY; + } while (el !== winScroller && (el = el.parentNode)); + } + + return [offsetLeft, offsetTop]; +} + +/** + * Returns the index of the object within the given array + * @param {Array} arr Array that may or may not hold the object + * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find + * @return {Number} The index of the object in the array, or -1 + */ +function indexOfObject(arr, obj) { + for (let i in arr) { + if (!arr.hasOwnProperty(i)) continue; + for (let key in obj) { + if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i); + } + } + return -1; +} + + +function getParentAutoScrollElement(el, includeSelf) { + // skip to window + if (!el || !el.getBoundingClientRect) return getWindowScrollingElement(); + + let elem = el; + let gotSelf = false; + do { + // we don't need to get elem css if it isn't even overflowing in the first place (performance) + if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { + let elemCSS = css(elem); + if ( + elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || + elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll') + ) { + if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement(); + + if (gotSelf || includeSelf) return elem; + gotSelf = true; + } + } + /* jshint boss:true */ + } while (elem = elem.parentNode); + + return getWindowScrollingElement(); +} + +function extend(dst, src) { + if (dst && src) { + for (let key in src) { + if (src.hasOwnProperty(key)) { + dst[key] = src[key]; + } + } + } + + return dst; +} + + +function isRectEqual(rect1, rect2) { + return Math.round(rect1.top) === Math.round(rect2.top) && + Math.round(rect1.left) === Math.round(rect2.left) && + Math.round(rect1.height) === Math.round(rect2.height) && + Math.round(rect1.width) === Math.round(rect2.width); +} + + +let _throttleTimeout; +function throttle(callback, ms) { + return function () { + if (!_throttleTimeout) { + let args = arguments, + _this = this; + + if (args.length === 1) { + callback.call(_this, args[0]); + } else { + callback.apply(_this, args); + } + + _throttleTimeout = setTimeout(function () { + _throttleTimeout = void 0; + }, ms); + } + }; +} + + +function cancelThrottle() { + clearTimeout(_throttleTimeout); + _throttleTimeout = void 0; +} + + +function scrollBy(el, x, y) { + el.scrollLeft += x; + el.scrollTop += y; +} + + +function clone(el) { + let Polymer = window.Polymer; + let $ = window.jQuery || window.Zepto; + + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } + else if ($) { + return $(el).clone(true)[0]; + } + else { + return el.cloneNode(true); + } +} + + +function setRect(el, rect) { + css(el, 'position', 'absolute'); + css(el, 'top', rect.top); + css(el, 'left', rect.left); + css(el, 'width', rect.width); + css(el, 'height', rect.height); +} + +function unsetRect(el) { + css(el, 'position', ''); + css(el, 'top', ''); + css(el, 'left', ''); + css(el, 'width', ''); + css(el, 'height', ''); +} + + +const expando = 'Sortable' + (new Date).getTime(); + + +export { + on, + off, + matches, + getParentOrHost, + closest, + toggleClass, + css, + matrix, + find, + getWindowScrollingElement, + getRect, + isScrolledPast, + getChild, + lastChild, + index, + getRelativeScrollOffset, + indexOfObject, + getParentAutoScrollElement, + extend, + isRectEqual, + throttle, + cancelThrottle, + scrollBy, + clone, + setRect, + unsetRect, + expando +}; diff --git a/public/assets/libs/Sortable/st/app.js b/public/assets/libs/Sortable/st/app.js new file mode 100644 index 0000000000000000000000000000000000000000..3c9e93d0670b23a6d4b4fe2ac056566d1dc046ca --- /dev/null +++ b/public/assets/libs/Sortable/st/app.js @@ -0,0 +1,222 @@ +var example1 = document.getElementById('example1'), + example2Left = document.getElementById('example2-left'), + example2Right = document.getElementById('example2-right'), + example3Left = document.getElementById('example3-left'), + example3Right = document.getElementById('example3-right'), + example4Left = document.getElementById('example4-left'), + example4Right = document.getElementById('example4-right'), + example5 = document.getElementById('example5'), + example6 = document.getElementById('example6'), + example7 = document.getElementById('example7'), + gridDemo = document.getElementById('gridDemo'), + multiDragDemo = document.getElementById('multiDragDemo'), + swapDemo = document.getElementById('swapDemo'); + +// Example 1 - Simple list +new Sortable(example1, { + animation: 150, + ghostClass: 'blue-background-class' +}); + + +// Example 2 - Shared lists +new Sortable(example2Left, { + group: 'shared', // set both lists to same group + animation: 150 +}); + +new Sortable(example2Right, { + group: 'shared', + animation: 150 +}); + +// Example 3 - Cloning +new Sortable(example3Left, { + group: { + name: 'shared', + pull: 'clone' // To clone: set pull to 'clone' + }, + animation: 150 +}); + +new Sortable(example3Right, { + group: { + name: 'shared', + pull: 'clone' + }, + animation: 150 +}); + + +// Example 4 - No Sorting +new Sortable(example4Left, { + group: { + name: 'shared', + pull: 'clone', + put: false // Do not allow items to be put into this list + }, + animation: 150, + sort: false // To disable sorting: set sort to false +}); + +new Sortable(example4Right, { + group: 'shared', + animation: 150 +}); + + +// Example 5 - Handle +new Sortable(example5, { + handle: '.handle', // handle class + animation: 150 +}); + +// Example 6 - Filter +new Sortable(example6, { + filter: '.filtered', + animation: 150 +}); + +// Example 7 - Thresholds +var example7Sortable = new Sortable(example7, { + animation: 150 +}); + + +var example7SwapThreshold = 1; +var example7SwapThresholdInput = document.getElementById('example7SwapThresholdInput'); +var example7SwapThresholdCode = document.getElementById('example7SwapThresholdCode'); +var example7SwapThresholdIndicators = [].slice.call(document.querySelectorAll('.swap-threshold-indicator')); + +var example7InvertSwapInput = document.getElementById('example7InvertSwapInput'); +var example7InvertSwapCode = document.getElementById('example7InvertSwapCode'); +var example7InvertedSwapThresholdIndicators = [].slice.call(document.querySelectorAll('.inverted-swap-threshold-indicator')); + +var example7Squares = [].slice.call(document.querySelectorAll('.square')); + +var activeIndicators = example7SwapThresholdIndicators; + +var example7DirectionInput = document.getElementById('example7DirectionInput'); +var example7SizeProperty = 'width'; + + +function renderThresholdWidth(evt) { + example7SwapThreshold = Number(evt.target.value); + example7SwapThresholdCode.innerHTML = evt.target.value.indexOf('.') > -1 ? evt.target.value.padEnd(4, '0') : evt.target.value; + + for (var i = 0; i < activeIndicators.length; i++) { + activeIndicators[i].style[example7SizeProperty] = (evt.target.value * 100) / + (activeIndicators == example7SwapThresholdIndicators ? 1 : 2) + '%'; + } + + example7Sortable.option('swapThreshold', example7SwapThreshold); +} + +example7SwapThresholdInput.addEventListener('input', renderThresholdWidth); + +example7InvertSwapInput.addEventListener('input', function(evt) { + example7Sortable.option('invertSwap', evt.target.checked); + + + for (var i = 0; i < activeIndicators.length; i++) { + activeIndicators[i].style.display = 'none'; + } + + if (evt.target.checked) { + + example7InvertSwapCode.style.display = ''; + + activeIndicators = example7InvertedSwapThresholdIndicators; + } else { + example7InvertSwapCode.style.display = 'none'; + activeIndicators = example7SwapThresholdIndicators; + } + + renderThresholdWidth({ + target: example7SwapThresholdInput + }); + + for (i = 0; i < activeIndicators.length; i++) { + activeIndicators[i].style.display = ''; + } +}); + +function renderDirection(evt) { + for (var i = 0; i < example7Squares.length; i++) { + example7Squares[i].style.display = evt.target.value === 'h' ? 'inline-block' : 'block'; + } + + for (i = 0; i < example7InvertedSwapThresholdIndicators.length; i++) { + /* jshint expr:true */ + evt.target.value === 'h' && (example7InvertedSwapThresholdIndicators[i].style.height = '100%'); + evt.target.value === 'v' && (example7InvertedSwapThresholdIndicators[i].style.width = '100%'); + } + + for (i = 0; i < example7SwapThresholdIndicators.length; i++) { + if (evt.target.value === 'h') { + example7SwapThresholdIndicators[i].style.height = '100%'; + example7SwapThresholdIndicators[i].style.marginLeft = '50%'; + example7SwapThresholdIndicators[i].style.transform = 'translateX(-50%)'; + + example7SwapThresholdIndicators[i].style.marginTop = '0'; + } else { + example7SwapThresholdIndicators[i].style.width = '100%'; + example7SwapThresholdIndicators[i].style.marginTop = '50%'; + example7SwapThresholdIndicators[i].style.transform = 'translateY(-50%)'; + + example7SwapThresholdIndicators[i].style.marginLeft = '0'; + } + } + + if (evt.target.value === 'h') { + example7SizeProperty = 'width'; + example7Sortable.option('direction', 'horizontal'); + } else { + example7SizeProperty = 'height'; + example7Sortable.option('direction', 'vertical'); + } + + renderThresholdWidth({ + target: example7SwapThresholdInput + }); +} +example7DirectionInput.addEventListener('input', renderDirection); + +renderDirection({ + target: example7DirectionInput +}); + + +// Grid demo +new Sortable(gridDemo, { + animation: 150, + ghostClass: 'blue-background-class' +}); + +// Nested demo +var nestedSortables = [].slice.call(document.querySelectorAll('.nested-sortable')); + +// Loop through each nested sortable element +for (var i = 0; i < nestedSortables.length; i++) { + new Sortable(nestedSortables[i], { + group: 'nested', + animation: 150, + fallbackOnBody: true, + swapThreshold: 0.65 + }); +} + +// MultiDrag demo +new Sortable(multiDragDemo, { + multiDrag: true, + selectedClass: 'selected', + animation: 150 +}); + + +// Swap demo +new Sortable(swapDemo, { + swap: true, + swapClass: 'highlight', + animation: 150 +}); diff --git a/public/assets/libs/Sortable/st/iframe/frame.html b/public/assets/libs/Sortable/st/iframe/frame.html new file mode 100644 index 0000000000000000000000000000000000000000..677eeef642e3f13696d5d02c443d091a082798f3 --- /dev/null +++ b/public/assets/libs/Sortable/st/iframe/frame.html @@ -0,0 +1,32 @@ + + + + + + + + + + + + +
            +
            + 14 + + Drag me by the handle +
            +
            + 2 + + You can also select text +
            +
            + 1 + + Best of both worlds! +
            +
            + + + diff --git a/public/assets/libs/Sortable/st/iframe/index.html b/public/assets/libs/Sortable/st/iframe/index.html new file mode 100644 index 0000000000000000000000000000000000000000..fcd089857c3a61a0f543f58c80e8aae5a1b2b7ba --- /dev/null +++ b/public/assets/libs/Sortable/st/iframe/index.html @@ -0,0 +1,49 @@ + + + + + IFrame playground + + + + + + + + + + + + + +
            +
            This is Sortable
            +
            It works with Bootstrap...
            +
            ...out of the box.
            +
            It has support for touch devices.
            +
            Just drag some elements around.
            +
            + + + + + diff --git a/public/assets/libs/Sortable/st/logo.png b/public/assets/libs/Sortable/st/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..76cc77c3474f3352898bb6a6effe6795c359b1cc Binary files /dev/null and b/public/assets/libs/Sortable/st/logo.png differ diff --git a/public/assets/libs/Sortable/st/og-image.png b/public/assets/libs/Sortable/st/og-image.png new file mode 100644 index 0000000000000000000000000000000000000000..7d7a51da9a6fb573a5df0a4ea189dafa51e7231a Binary files /dev/null and b/public/assets/libs/Sortable/st/og-image.png differ diff --git a/public/assets/libs/Sortable/st/prettify/prettify.css b/public/assets/libs/Sortable/st/prettify/prettify.css new file mode 100644 index 0000000000000000000000000000000000000000..e6fe342f227c005e27ef577a7b0e74ec829dfcfc --- /dev/null +++ b/public/assets/libs/Sortable/st/prettify/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.clo,.opn,.pun{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.kwd,.tag,.typ{font-weight:700}.str{color:#060}.kwd{color:#006}.com{color:#600;font-style:italic}.typ{color:#404}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} \ No newline at end of file diff --git a/public/assets/libs/Sortable/st/prettify/prettify.js b/public/assets/libs/Sortable/st/prettify/prettify.js new file mode 100644 index 0000000000000000000000000000000000000000..477f03d550d5565fa45065362c07b907c02d2d7a --- /dev/null +++ b/public/assets/libs/Sortable/st/prettify/prettify.js @@ -0,0 +1,46 @@ +!function(){/* + + Copyright (C) 2006 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +"undefined"!==typeof window&&(window.PR_SHOULD_USE_CONTINUATION=!0); +(function(){function T(a){function d(e){var a=e.charCodeAt(0);if(92!==a)return a;var c=e.charAt(1);return(a=w[c])?a:"0"<=c&&"7">=c?parseInt(e.substring(1),8):"u"===c||"x"===c?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e}function c(e){var c=e.substring(1,e.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g")); +e=[];var a="^"===c[0],b=["["];a&&b.push("^");for(var a=a?1:0,g=c.length;ak||122k||90k||122h[0]&&(h[1]+1>h[0]&&b.push("-"),b.push(f(h[1])));b.push("]");return b.join("")}function m(e){for(var a=e.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g")),b=a.length,d=[],g=0,h=0;g/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null]));if(c=a.regexLiterals){var m=(c=1|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+ +("/(?=[^/*"+c+"])(?:[^/\\x5B\\x5C"+c+"]|\\x5C"+m+"|\\x5B(?:[^\\x5C\\x5D"+c+"]|\\x5C"+m+")*(?:\\x5D|$))+/")+")")])}(c=a.types)&&f.push(["typ",c]);c=(""+a.keywords).replace(/^ | $/g,"");c.length&&f.push(["kwd",new RegExp("^(?:"+c.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);c="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(c+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i, +null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(c),null]);return G(d,f)}function L(a,d,f){function c(a){var b=a.nodeType;if(1==b&&!t.test(a.className))if("br"===a.nodeName.toLowerCase())m(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)c(a);else if((3==b||4==b)&&f){var e=a.nodeValue,d=e.match(q);d&&(b=e.substring(0,d.index),a.nodeValue=b,(e=e.substring(d.index+ +d[0].length))&&a.parentNode.insertBefore(l.createTextNode(e),a.nextSibling),m(a),b||a.parentNode.removeChild(a))}}function m(a){function c(a,b){var e=b?a.cloneNode(!1):a,k=a.parentNode;if(k){var k=c(k,1),d=a.nextSibling;k.appendChild(e);for(var f=d;f;f=d)d=f.nextSibling,k.appendChild(f)}return e}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=c(a.nextSibling,0);for(var e;(e=a.parentNode)&&1===e.nodeType;)a=e;b.push(a)}for(var t=/(?:^|\s)nocode(?:\s|$)/,q=/\r\n?|\n/,l=a.ownerDocument,n=l.createElement("li");a.firstChild;)n.appendChild(a.firstChild); +for(var b=[n],p=0;p=+m[1],d=/\n/g,t=a.a,q=t.length,f=0,l=a.c,n=l.length,c=0,b=a.g,p=b.length,w=0;b[p]=q;var r,e;for(e=r=0;e=h&&(c+=2);f>=k&&(w+=2)}}finally{g&&(g.style.display=a)}}catch(y){D.console&&console.log(y&&y.stack||y)}}var D="undefined"!==typeof window? +window:{},B=["break,continue,do,else,for,if,return,while"],F=[[B,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],H=[F,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"], +O=[F,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],P=[F,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"], +F=[F,"abstract,async,await,constructor,debugger,enum,eval,export,from,function,get,import,implements,instanceof,interface,let,null,of,set,undefined,var,with,yield,Infinity,NaN"],Q=[B,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],R=[B,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"], +B=[B,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],S=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,W=/\S/,X=x({keywords:[H,P,O,F,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",Q,R,B],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}), +I={};t(X,["default-code"]);t(G([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));t(G([["pln",/^[\s]+/, +null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]); +t(G([],[["atv",/^[\s\S]+/]]),["uq.val"]);t(x({keywords:H,hashComments:!0,cStyleComments:!0,types:S}),"c cc cpp cxx cyc m".split(" "));t(x({keywords:"null,true,false"}),["json"]);t(x({keywords:P,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:S}),["cs"]);t(x({keywords:O,cStyleComments:!0}),["java"]);t(x({keywords:B,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);t(x({keywords:Q,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);t(x({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END", +hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]);t(x({keywords:R,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);t(x({keywords:F,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);t(x({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0, +regexLiterals:!0}),["coffee"]);t(G([],[["str",/^[\s\S]+/]]),["regex"]);var Y=D.PR={createSimpleLexer:G,registerLangHandler:t,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:D.prettyPrintOne=function(a,d,f){f=f||!1;d=d||null;var c=document.createElement("div");c.innerHTML="
            "+a+"
            "; +c=c.firstChild;f&&L(c,f,!0);M({j:d,m:f,h:c,l:1,a:null,i:null,c:null,g:null});return c.innerHTML},prettyPrint:D.prettyPrint=function(a,d){function f(){for(var c=D.PR_SHOULD_USE_CONTINUATION?b.now()+250:Infinity;p=c?parseInt(e.substring(1),8):"u"===c||"x"===c?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e); +return"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e}function c(e){var c=e.substring(1,e.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));e=[];var a="^"===c[0],b=["["];a&&b.push("^");for(var a=a?1:0,h=c.length;ap||122p||90p||122m[0]&&(m[1]+1>m[0]&&b.push("-"),b.push(f(m[1])));b.push("]");return b.join("")}function g(e){for(var a=e.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)", +"g")),b=a.length,d=[],h=0,m=0;h/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/, +null]));if(c=a.regexLiterals){var g=(c=1|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+("/(?=[^/*"+c+"])(?:[^/\\x5B\\x5C"+c+"]|\\x5C"+g+"|\\x5B(?:[^\\x5C\\x5D"+c+"]|\\x5C"+g+")*(?:\\x5D|$))+/")+")")])}(c=a.types)&&f.push(["typ",c]);c=(""+a.keywords).replace(/^ | $/g,"");c.length&&f.push(["kwd", +new RegExp("^(?:"+c.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);c="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(c+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i,null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(c),null]);return E(d,f)}function B(a,d,f){function c(a){var b= +a.nodeType;if(1==b&&!r.test(a.className))if("br"===a.nodeName.toLowerCase())g(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)c(a);else if((3==b||4==b)&&f){var e=a.nodeValue,d=e.match(n);d&&(b=e.substring(0,d.index),a.nodeValue=b,(e=e.substring(d.index+d[0].length))&&a.parentNode.insertBefore(q.createTextNode(e),a.nextSibling),g(a),b||a.parentNode.removeChild(a))}}function g(a){function c(a,b){var e=b?a.cloneNode(!1):a,p=a.parentNode;if(p){var p=c(p,1),d=a.nextSibling; +p.appendChild(e);for(var f=d;f;f=d)d=f.nextSibling,p.appendChild(f)}return e}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=c(a.nextSibling,0);for(var e;(e=a.parentNode)&&1===e.nodeType;)a=e;b.push(a)}for(var r=/(?:^|\s)nocode(?:\s|$)/,n=/\r\n?|\n/,q=a.ownerDocument,k=q.createElement("li");a.firstChild;)k.appendChild(a.firstChild);for(var b=[k],t=0;t=+g[1],d=/\n/g,r=a.a,k=r.length,f=0,q=a.c,n=q.length,c=0,b=a.g,t=b.length,v=0;b[t]=k;var u,e;for(e=u=0;e=m&&(c+=2);f>=p&&(v+=2)}}finally{h&&(h.style.display=a)}}catch(y){Q.console&&console.log(y&&y.stack||y)}}var Q="undefined"!==typeof window?window:{},J=["break,continue,do,else,for,if,return,while"],K=[[J,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],R=[K,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],L=[K,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"], +M=[K,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"],K=[K,"abstract,async,await,constructor,debugger,enum,eval,export,from,function,get,import,implements,instanceof,interface,let,null,of,set,undefined,var,with,yield,Infinity,NaN"], +N=[J,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],O=[J,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],J=[J,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],P=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/, +S=/\S/,T=v({keywords:[R,M,L,K,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",N,O,J],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),V={};n(T,["default-code"]);n(E([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-", +/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));n(E([["pln",/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/], +["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);n(E([],[["atv",/^[\s\S]+/]]),["uq.val"]);n(v({keywords:R,hashComments:!0,cStyleComments:!0,types:P}),"c cc cpp cxx cyc m".split(" "));n(v({keywords:"null,true,false"}),["json"]);n(v({keywords:M,hashComments:!0,cStyleComments:!0, +verbatimStrings:!0,types:P}),["cs"]);n(v({keywords:L,cStyleComments:!0}),["java"]);n(v({keywords:J,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);n(v({keywords:N,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);n(v({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}), +["perl","pl","pm"]);n(v({keywords:O,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);n(v({keywords:K,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);n(v({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);n(E([],[["str",/^[\s\S]+/]]), +["regex"]);var U=Q.PR={createSimpleLexer:E,registerLangHandler:n,sourceDecorator:v,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:function(a,d,f){f=f||!1;d=d||null;var c=document.createElement("div");c.innerHTML="
            "+a+"
            ";c=c.firstChild;f&&B(c,f,!0);H({j:d,m:f,h:c,l:1,a:null,i:null,c:null,g:null}); +return c.innerHTML},prettyPrint:g=function(a,d){function f(){for(var c=Q.PR_SHOULD_USE_CONTINUATION?b.now()+250:Infinity;tPowered by Sauce Labs badges grayvTESTING POWERED BY \ No newline at end of file diff --git a/public/assets/libs/Sortable/st/theme.css b/public/assets/libs/Sortable/st/theme.css new file mode 100644 index 0000000000000000000000000000000000000000..87b24343ad47a77635a596db3a6f750d10b016fa --- /dev/null +++ b/public/assets/libs/Sortable/st/theme.css @@ -0,0 +1,254 @@ +body { + font-family: Helvetica Neue, Helvetica, Arial; + background: rgb(244,215,201); /* Old browsers */ + background: -moz-linear-gradient(top, rgb(244,215,201) 0%, rgb(244,226,201) 100%); /* FF3.6-15 */ + background: -webkit-linear-gradient(top, rgb(244,215,201) 0%,rgb(244,226,201) 100%); /* Chrome10-25,Safari5.1-6 */ + background: linear-gradient(to bottom, rgb(244,215,201) 0%,rgb(244,226,201) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ + margin-bottom: 100px; +} + +.header { + margin-top: 30px; +} + +.header h1 { + margin-top: 10px; +} + +h4 { + padding-bottom: 10px; +} + +.prettyprinted { + margin-top: 5px; + border-top: none !important; + border-bottom: none !important; + border-right: none !important; + border-left: 1px solid rgba(0,0,0,.1) !important; + padding-left: 15px !important; + word-wrap: break-word !important; + overflow: default !important; + text-overflow: default !important; +} + +.tinted { + background-color: #fff6b2; +} + +.handle { + cursor: grab; +} + +code { + color: #606; +} + +.toc { + background-color: rgb(255,255,255,0.5); + border: solid #444 1px; + padding: 20px; + margin-left: auto; + margin-right: auto; + list-style: none; +} + +.toc h5 { + margin-top: 8px; +} + +.list-group-item:hover { + z-index: 0; +} + +.input-section { + background-color: rgb(255,255,255,0.5); + padding: 20px; +} + +.square-section { + background-color: rgb(255,255,255,0.5); +} + + +.square { + width: 20vw; + height: 20vw; + background-color: #00a2ff; + margin-top: 2vw; + margin-left: 2vw; + display: inline-block; + position: relative; +} + +.swap-threshold-indicator { + background-color: #0079bf; + height: 100%; + display: inline-block; +} + +.inverted-swap-threshold-indicator { + background-color: #0079bf; + height: 100%; + position: absolute; +} + +.indicator-left { + left: 0; + top: 0; +} + +.indicator-right { + right: 0; + bottom: 0; +} + +.num-indicator { + position: absolute; + font-size: 50px; + width: 25px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: white; +} + +.grid-square { + width: 100px; + height: 100px; + display: inline-block; + background-color: #fff; + border: solid 1px rgb(0,0,0,0.2); + padding: 10px; + margin: 12px; +} + +.nested-sortable, .nested-1, .nested-2, .nested-3 { + margin-top: 5px; +} + +.nested-1 { + background-color: #e6e6e6; +} + +.nested-2 { + background-color: #cccccc; +} + +.nested-3 { + background-color: #b3b3b3; +} + +.frameworks { + background-color: rgb(255,255,255,0.5); + border: solid rgb(0,0,0,0.3) 1px; + padding: 20px; +} + +.frameworks h3 { + margin-top: 5px; +} + +input[type=range] { + -webkit-appearance: none; + width: 100%; + margin: 3.8px 0; +} +input[type=range]:focus { + outline: none; +} +input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 8.4px; + cursor: pointer; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + background: rgba(48, 113, 169, 0); + border-radius: 1.3px; + border: 0.2px solid #010101; +} +input[type=range]::-webkit-slider-thumb { + box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d; + border: 1.3px solid rgba(0, 0, 0, 0.7); + height: 16px; + width: 16px; + border-radius: 49px; + background: #ffffff; + cursor: pointer; + -webkit-appearance: none; + margin-top: -4px; +} +input[type=range]:focus::-webkit-slider-runnable-track { + background: rgba(54, 126, 189, 0); +} +input[type=range]::-moz-range-track { + width: 100%; + height: 8.4px; + cursor: pointer; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + background: rgba(48, 113, 169, 0); + border-radius: 1.3px; + border: 0.2px solid #010101; +} +input[type=range]::-moz-range-thumb { + box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d; + border: 1.3px solid rgba(0, 0, 0, 0.7); + height: 16px; + width: 16px; + border-radius: 49px; + background: #ffffff; + cursor: pointer; +} +input[type=range]::-ms-track { + width: 100%; + height: 8.4px; + cursor: pointer; + background: transparent; + border-color: transparent; + color: transparent; +} +input[type=range]::-ms-fill-lower { + background: rgba(42, 100, 149, 0); + border: 0.2px solid #010101; + border-radius: 2.6px; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; +} +input[type=range]::-ms-fill-upper { + background: rgba(48, 113, 169, 0); + border: 0.2px solid #010101; + border-radius: 2.6px; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; +} +input[type=range]::-ms-thumb { + box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d; + border: 1.3px solid rgba(0, 0, 0, 0.7); + height: 16px; + width: 16px; + border-radius: 49px; + background: #ffffff; + cursor: pointer; + height: 8.4px; +} +input[type=range]:focus::-ms-fill-lower { + background: rgba(48, 113, 169, 0); +} +input[type=range]:focus::-ms-fill-upper { + background: rgba(54, 126, 189, 0); +} + +.blue-background-class { + background-color: #C8EBFB; +} + +.col { + padding-right: 0; + margin-right: 15px; +} + +.selected { + background-color: #f9c7c8; + border: solid red 1px !important; + z-index: 1 !important; +} + +.highlight { + background-color: #B7F8C7; +} diff --git a/public/assets/libs/art-template/.bower.json b/public/assets/libs/art-template/.bower.json new file mode 100644 index 0000000000000000000000000000000000000000..1f44d9493f1db39a7ab769802a38be13f14cc09b --- /dev/null +++ b/public/assets/libs/art-template/.bower.json @@ -0,0 +1,14 @@ +{ + "name": "art-template", + "homepage": "https://github.com/aui/artTemplate", + "version": "3.1.3", + "_release": "3.1.3", + "_resolution": { + "type": "version", + "tag": "v3.1.3", + "commit": "b1085f546f6d3abbf74d10a5f69d24a63e932e86" + }, + "_source": "https://github.com/aui/artTemplate.git", + "_target": "^3.1.3", + "_originalSource": "art-template" +} \ No newline at end of file diff --git a/public/assets/libs/art-template/.gitignore b/public/assets/libs/art-template/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..10283d8da76a4b17850e8e085c410bea7db60c77 --- /dev/null +++ b/public/assets/libs/art-template/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +node_modules +.vscode +coverage \ No newline at end of file diff --git a/public/assets/libs/art-template/.npmignore b/public/assets/libs/art-template/.npmignore new file mode 100644 index 0000000000000000000000000000000000000000..6db059f34e7f3dc066fe47c7c53c759e372d2089 --- /dev/null +++ b/public/assets/libs/art-template/.npmignore @@ -0,0 +1,3 @@ +test +demo +doc \ No newline at end of file diff --git a/public/assets/libs/art-template/Gruntfile.js b/public/assets/libs/art-template/Gruntfile.js new file mode 100644 index 0000000000000000000000000000000000000000..88c304cf627e6992c289dd69ebc7c2b70c35eedc --- /dev/null +++ b/public/assets/libs/art-template/Gruntfile.js @@ -0,0 +1,99 @@ +module.exports = function (grunt) { + + var sources_native = [ + 'src/intro.js', + 'src/template.js', + 'src/config.js', + 'src/cache.js', + 'src/render.js', + 'src/renderFile.js', + 'src/get.js', + 'src/utils.js', + 'src/helper.js', + 'src/onerror.js', + 'src/compile.js', + //<<<< 'src/syntax.js', + 'src/outro.js' + ]; + + var sources_simple = Array.apply(null, sources_native); + sources_simple.splice(sources_native.length - 1, 0, 'src/syntax.js'); + + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + meta: { + banner: '/*!<%= pkg.name %> - Template Engine | <%= pkg.homepage %>*/\n' + }, + concat: { + options: { + separator: '' + }, + + 'native': { + src: sources_native, + dest: 'dist/template-native-debug.js' + }, + + simple: { + src: sources_simple, + dest: 'dist/template-debug.js' + } + }, + uglify: { + options: { + banner: '<%= meta.banner %>' + }, + 'native': { + src: '<%= concat.native.dest %>', + dest: 'dist/template-native.js' + }, + simple: { + src: '<%= concat.simple.dest %>', + dest: 'dist/template.js' + } + }, + qunit: { + files: ['test/**/*.html'] + }, + jshint: { + files: [ + 'dist/template-native.js', + 'dist/template.js' + ], + options: { + curly: true, + eqeqeq: true, + immed: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + undef: true, + boss: true, + eqnull: true, + browser: true + }, + globals: { + console: true, + define: true, + global: true, + module: true + } + }, + watch: { + files: '', + tasks: 'lint qunit' + } + }); + + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + //grunt.loadNpmTasks('grunt-contrib-qunit'); + //grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-concat'); + + + grunt.registerTask('default', ['concat', /*'jshint',*/ 'uglify']); + +}; \ No newline at end of file diff --git a/public/assets/libs/art-template/README.md b/public/assets/libs/art-template/README.md new file mode 100644 index 0000000000000000000000000000000000000000..953036984ad5d730a4c36d44c4772c6a18e83cb3 --- /dev/null +++ b/public/assets/libs/art-template/README.md @@ -0,0 +1,303 @@ +# artTemplate-3.0 + +新一代 javascript 模板引擎 + +> 后会无期。2016-12-22 + +## 目录 + +* [特性](#特性) +* [快速上手](#快速上手) +* [模板语法](#模板语法) +* [下载](#下载) +* [方法](#方法) +* [NodeJS](#nodejs) +* [使用预编译](#使用预编译) +* [更新日志](#更新日志) +* [授权协议](#授权协议) + +## 特性 + +1. 性能卓越,执行速度通常是 Mustache 与 tmpl 的 20 多倍([性能测试](http://aui.github.com/artTemplate/test/test-speed.html)) +2. 支持运行时调试,可精确定位异常模板所在语句([演示](http://aui.github.io/artTemplate/demo/debug.html)) +3. 对 NodeJS Express 友好支持 +4. 安全,默认对输出进行转义、在沙箱中运行编译后的代码(Node版本可以安全执行用户上传的模板) +5. 支持``include``语句 +6. 可在浏览器端实现按路径加载模板([详情](#使用预编译)) +7. 支持预编译,可将模板转换成为非常精简的 js 文件 +8. 模板语句简洁,无需前缀引用数据,有简洁版本与原生语法版本可选 +9. 支持所有流行的浏览器 + +## 快速上手 + +### 编写模板 + +使用一个``type="text/html"``的``script``标签存放模板: + + + +### 渲染模板 + + var data = { + title: '标签', + list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他'] + }; + var html = template('test', data); + document.getElementById('content').innerHTML = html; + + +[演示](http://aui.github.com/artTemplate/demo/basic.html) + +## 模板语法 + +有两个版本的模板语法可以选择。 + +### 简洁语法 + +推荐使用,语法简单实用,利于读写。 + + {{if admin}} + {{include 'admin_content'}} + + {{each list}} +
            {{$index}}. {{$value.user}}
            + {{/each}} + {{/if}} + +[查看语法与演示](https://github.com/aui/artTemplate/wiki/syntax:simple) + +### 原生语法 + + <%if (admin){%> + <%include('admin_content')%> + + <%for (var i=0;i +
            <%=i%>. <%=list[i].user%>
            + <%}%> + <%}%> + +[查看语法与演示](https://github.com/aui/artTemplate/wiki/syntax:native) + +## 下载 + +* [template.js](https://raw.github.com/aui/artTemplate/master/dist/template.js) *(简洁语法版, 2.7kb)* +* [template-native.js](https://raw.github.com/aui/artTemplate/master/dist/template-native.js) *(原生语法版, 2.3kb)* + +## 方法 + +### template(id, data) + +根据 id 渲染模板。内部会根据``document.getElementById(id)``查找模板。 + +如果没有 data 参数,那么将返回一渲染函数。 + +### template.``compile``(source, options) + +将返回一个渲染函数。[演示](http://aui.github.com/artTemplate/demo/compile.html) + +### template.``render``(source, options) + +将返回渲染结果。 + +### template.``helper``(name, callback) + +添加辅助方法。 + +例如时间格式器:[演示](http://aui.github.com/artTemplate/demo/helper.html) + +### template.``config``(name, value) + +更改引擎的默认配置。 + +字段 | 类型 | 默认值| 说明 +------------ | ------------- | ------------ | ------------ +openTag | String | ``'{{'`` | 逻辑语法开始标签 +closeTag | String | ``"}}"`` | 逻辑语法结束标签 +escape | Boolean | ``true`` | 是否编码输出 HTML 字符 +cache | Boolean | ``true`` | 是否开启缓存(依赖 options 的 filename 字段) +compress | Boolean | ``false`` | 是否压缩 HTML 多余空白字符 + +## 使用预编译 + +可突破浏览器限制,让前端模板拥有后端模板一样的同步“文件”加载能力: + +一、**按文件与目录组织模板** + +``` +template('tpl/home/main', data) +``` + +二、**模板支持引入子模板** + + + {{include '../public/header'}} + +### 基于预编译: + +* 可将模板转换成为非常精简的 js 文件(不依赖引擎) +* 使用同步模板加载接口 +* 支持多种 js 模块输出:AMD、CMD、CommonJS +* 支持作为 GruntJS 插件构建 +* 前端模板可共享给 NodeJS 执行 +* 自动压缩打包模板 + +预编译工具:[TmodJS](http://github.com/aui/tmodjs/) + +## NodeJS + +### 安装 + + npm install art-template + +### 使用 + + var template = require('art-template'); + var data = {list: ["aui", "test"]}; + + var html = template(__dirname + '/index/main', data); + +### 配置 + +NodeJS 版本新增了如下默认配置: + +字段 | 类型 | 默认值| 说明 +------------ | ------------- | ------------ | ------------ +base | String | ``''`` | 指定模板目录 +extname | String | ``'.html'`` | 指定模板后缀名 +encoding | String | ``'utf-8'`` | 指定模板编码 + +配置``base``指定模板目录可以缩短模板的路径,并且能够避免``include``语句越级访问任意路径引发安全隐患,例如: + + template.config('base', __dirname); + var html = template('index/main', data) + +### NodeJS + Express + + var template = require('art-template'); + template.config('base', ''); + template.config('extname', '.html'); + app.engine('.html', template.__express); + app.set('view engine', 'html'); + //app.set('views', __dirname + '/views'); + +运行 demo: + + node demo/node-template-express.js + +> 若使用 js 原生语法作为模板语法,请改用 ``require('art-template/node/template-native.js')`` + +## 升级参考 + +为了适配 NodeJS express,artTemplate v3.0.0 接口有调整。 + +### 接口变更 + +1. 默认使用简洁语法 +2. ``template.render()``方法的第一个参数不再是 id,而是模板字符串 +3. 使用新的配置接口``template.config()``并且字段名有修改 +4. ``template.compile()``方法不支持 id 参数 +5. helper 方法不再强制原文输出,是否编码取决于模板语句 +6. ``template.helpers`` 中的``$string``、``$escape``、``$each``已迁移到``template.utils``中 +7. ``template()``方法不支持传入模板直接编译 + +### 升级方法 + +1. 如果想继续使用 js 原生语法作为模板语言,请使用 [template-native.js](https://raw.github.com/aui/artTemplate/master/dist/template-native.js) +2. 查找项目```template.render```替换为```template``` +3. 使用``template.config(name, value)``来替换以前的配置 +4. ``template()``方法直接传入的模板改用``template.compile()``(v2初期版本) + +## 更新日志 + +### v3.1.0 + +1. 修复``template.runder()``方法与文档表现不一致的问题 +2. 去掉鸡肋的``fs.watch``特性 + +### v3.0.3 + +1. 解决``template.helper()``方法传入的数据被转成字符串的问题 #96 +2. 解决``{{value || value2}}``被识别为管道语句的问题 #105 + +### v3.0.2 + +1. ~~解决管道语法必须使用空格分隔的问题~~ + +### v3.0.1 + +1. 适配 express3.x 与 4.x,修复路径 BUG + +### v3.0.0 + +1. 提供 NodeJS 专属版本,支持使用路径加载模板,并且模板的``include``语句也支持相对路径 +2. 适配 [express](http://expressjs.com) 框架 +3. 内置``print``语句支持传入多个参数 +4. 支持全局缓存配置 +5. 简洁语法版支持管道风格的 helper 调用,例如:``{{time | dateFormat:'yyyy年 MM月 dd日 hh:mm:ss'}}`` + +当前版本接口有调整,请阅读 [升级参考](#升级参考) + +> artTemplate 预编译工具 [TmodJS](https://github.com/aui/tmodjs) 已更新 + +### v2.0.4 + +1. 修复低版本安卓浏览器编译后可能产生语法错误的问题(因为此版本浏览器 js 引擎存在 BUG) + +### v2.0.3 + +1. 优化辅助方法性能 +2. NodeJS 用户可以通过 npm 获取 artTemplate:``$ npm install art-template -g`` +3. 不转义输出语句推荐使用``<%=#value%>``(兼容 v2.0.3 版本之前使用的``<%==value%>``),而简版语法则可以使用``{{#value}}`` +4. 提供简版语法的合并版本 dist/[template-simple.js](https://raw.github.com/aui/artTemplate/master/dist/template-simple.js) + +### v2.0.2 + +1. 优化自定义语法扩展,减少体积 +2. [重要]为了最大化兼容第三方库,自定义语法扩展默认界定符修改为``{{``与``}}``。 +3. 修复合并工具的BUG [#25](https://github.com/aui/artTemplate/issues/25) +4. 公开了内部缓存,可以通过``template.cache``访问到编译后的函数 +5. 公开了辅助方法缓存,可以通过``template.helpers``访问到 +6. 优化了调试信息 + +### v2.0.1 + +1. 修复模板变量静态分析的[BUG](https://github.com/aui/artTemplate/pull/22) + +### v2.0 release + +1. ~~编译工具更名为 atc,成为 artTemplate 的子项目单独维护:~~ + +### v2.0 beta5 + +1. 修复编译工具可能存在重复依赖的问题。感谢 @warmhug +2. 修复预编译``include``内部实现可能产生上下文不一致的问题。感谢 @warmhug +3. 编译工具支持使用拖拽文件进行单独编译 + +### v2.0 beta4 + +1. 修复编译工具在压缩模板可能导致 HTML 意外截断的问题。感谢 @warmhug +2. 完善编译工具对``include``支持支持,可以支持不同目录之间模板嵌套 +3. 修复编译工具没能正确处理自定义语法插件的辅助方法 + +### v2.0 beta1 + +1. 对非 String、Number 类型的数据不输出,而 Function 类型求值后输出。 +2. 默认对 html 进行转义输出,原文输出可使用``<%==value%>``(备注:v2.0.3 推荐使用``<%=#value%>``),也可以关闭默认的转义功能``template.defaults.escape = false``。 +3. 增加批处理工具支持把模板编译成不依赖模板引擎的 js 文件,可通过 RequireJS、SeaJS 等模块加载器进行异步加载。 + +## 授权协议 + +Released under the MIT, BSD, and GPL Licenses + +============ + +[所有演示例子](http://aui.github.com/artTemplate/demo/index.html) | [引擎原理](http://cdc.tencent.com/?p=5723) + +© tencent.com diff --git a/public/assets/libs/art-template/demo/basic.html b/public/assets/libs/art-template/demo/basic.html new file mode 100644 index 0000000000000000000000000000000000000000..8340311233c7e8e0e2de0709e9206fab10e18389 --- /dev/null +++ b/public/assets/libs/art-template/demo/basic.html @@ -0,0 +1,34 @@ + + + + +basic-demo + + + + +
            + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/compile.html b/public/assets/libs/art-template/demo/compile.html new file mode 100644 index 0000000000000000000000000000000000000000..35c682ae8a26794f167dff7e46329b759f008d57 --- /dev/null +++ b/public/assets/libs/art-template/demo/compile.html @@ -0,0 +1,27 @@ + + + + +compile-demo + + + + +

            在javascript中存放模板

            +
            + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/debug-syntax.html b/public/assets/libs/art-template/demo/debug-syntax.html new file mode 100644 index 0000000000000000000000000000000000000000..4dc733ae207459af65ec9d0d3e6b8d04ba50ac02 --- /dev/null +++ b/public/assets/libs/art-template/demo/debug-syntax.html @@ -0,0 +1,24 @@ + + + + +debug-demo + + + + +

            错误捕获(请打开控制台)

            + + + + + + + + diff --git a/public/assets/libs/art-template/demo/debug.html b/public/assets/libs/art-template/demo/debug.html new file mode 100644 index 0000000000000000000000000000000000000000..23c1882e396e81cf99326436158ac29d5c81a5ce --- /dev/null +++ b/public/assets/libs/art-template/demo/debug.html @@ -0,0 +1,29 @@ + + + + +debug-demo + + + + +

            错误捕获(请打开控制台)

            + + + + + + + + diff --git a/public/assets/libs/art-template/demo/helper.html b/public/assets/libs/art-template/demo/helper.html new file mode 100755 index 0000000000000000000000000000000000000000..45530f8b2ffc9342dc977b61229c84078095ce51 --- /dev/null +++ b/public/assets/libs/art-template/demo/helper.html @@ -0,0 +1,87 @@ + + + + +helper-demo + + + + +

            辅助方法

            +
            + + + + + + + + diff --git a/public/assets/libs/art-template/demo/include.html b/public/assets/libs/art-template/demo/include.html new file mode 100644 index 0000000000000000000000000000000000000000..d3dcbb2baf9d0eb29545c39340bac233315a6574 --- /dev/null +++ b/public/assets/libs/art-template/demo/include.html @@ -0,0 +1,32 @@ + + + + +include-demo + + + + +
            + + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/index.html b/public/assets/libs/art-template/demo/index.html new file mode 100644 index 0000000000000000000000000000000000000000..20d9e94ec76a6d2c7809ec23c1047f8aba8f1d22 --- /dev/null +++ b/public/assets/libs/art-template/demo/index.html @@ -0,0 +1,21 @@ + + + + +demo + + + +

            演示

            + + + + diff --git a/public/assets/libs/art-template/demo/no-escape.html b/public/assets/libs/art-template/demo/no-escape.html new file mode 100644 index 0000000000000000000000000000000000000000..b245b0fa83e5cbe15e4e2a40f48c6b49216f1429 --- /dev/null +++ b/public/assets/libs/art-template/demo/no-escape.html @@ -0,0 +1,25 @@ + + + + +no escape-demo + + + + +

            不转义HTML

            +
            + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/node-template-express.js b/public/assets/libs/art-template/demo/node-template-express.js new file mode 100644 index 0000000000000000000000000000000000000000..0be91db9c2e499805fae63db659d8beb0b99fadc --- /dev/null +++ b/public/assets/libs/art-template/demo/node-template-express.js @@ -0,0 +1,48 @@ +var express = require('express'); +var template = require('../node/template.js'); + + +var app = module.exports = express(); + +template.config('extname', '.html'); +app.engine('.html', template.__express); +app.set('view engine', 'html'); +app.set('views', __dirname + '/node-template'); + + +var demoData = { + title: '国内要闻', + time: (new Date).toString(), + list: [ + { + title: '<油价>调整周期缩至10个工作日 无4%幅度限制', + url: 'http://finance.qq.com/zt2013/2013yj/index.htm' + }, + { + title: '明起汽油价格每吨下调310元 单价回归7元时代', + url: 'http://finance.qq.com/a/20130326/007060.htm' + }, + { + title: '广东副县长疑因抛弃情妇遭6女子围殴 纪检调查', + url: 'http://news.qq.com/a/20130326/001254.htm' + }, + { + title: '湖南27岁副县长回应质疑:父亲已不是领导', + url: 'http://news.qq.com/a/20130326/000959.htm' + }, + { + title: '朝军进入战斗工作状态 称随时准备导弹攻击美国', + url: 'http://news.qq.com/a/20130326/001307.htm' + } + ] +}; + +app.get('/', function(req, res){ + res.render('./index', demoData); +}); + +/* istanbul ignore next */ +if (!module.parent) { + app.listen(3000); + console.log('Express started on port 3000'); +} \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/node-template.js b/public/assets/libs/art-template/demo/node-template.js new file mode 100644 index 0000000000000000000000000000000000000000..6ca505a1e6ca804941a8221f5835187968adb3ab --- /dev/null +++ b/public/assets/libs/art-template/demo/node-template.js @@ -0,0 +1,35 @@ +var template = require('../node/template.js'); +//console.log(template); +template.config('base', __dirname);// 设置模板根目录,默认为引擎所在目录 +template.config('compress', true);// 压缩输出 + +var html = template('node-template/index', { + title: '国内要闻', + time: (new Date).toString(), + list: [ + { + title: '<油价>调整周期缩至10个工作日 无4%幅度限制', + url: 'http://finance.qq.com/zt2013/2013yj/index.htm' + }, + { + title: '明起汽油价格每吨下调310元 单价回归7元时代', + url: 'http://finance.qq.com/a/20130326/007060.htm' + }, + { + title: '广东副县长疑因抛弃情妇遭6女子围殴 纪检调查', + url: 'http://news.qq.com/a/20130326/001254.htm' + }, + { + title: '湖南27岁副县长回应质疑:父亲已不是领导', + url: 'http://news.qq.com/a/20130326/000959.htm' + }, + { + title: '朝军进入战斗工作状态 称随时准备导弹攻击美国', + url: 'http://news.qq.com/a/20130326/001307.htm' + } + ] +}); + + +console.log(html); +//console.log(template.cache) \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/node-template/copyright.html b/public/assets/libs/art-template/demo/node-template/copyright.html new file mode 100644 index 0000000000000000000000000000000000000000..4c65dfafcaf4e081a659666616c0d1daa6c75a4d --- /dev/null +++ b/public/assets/libs/art-template/demo/node-template/copyright.html @@ -0,0 +1 @@ +(c) 2013 \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/node-template/index.html b/public/assets/libs/art-template/demo/node-template/index.html new file mode 100644 index 0000000000000000000000000000000000000000..c2592138ebe696cc37202760b8c5ba300c1041a8 --- /dev/null +++ b/public/assets/libs/art-template/demo/node-template/index.html @@ -0,0 +1,12 @@ +{{include './public/header'}} + +
            +

            {{title}}

            + +
            + +{{include './public/footer'}} \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/node-template/public/footer.html b/public/assets/libs/art-template/demo/node-template/public/footer.html new file mode 100644 index 0000000000000000000000000000000000000000..956c23ea775c406817f5e4b2d2faf58e89746d64 --- /dev/null +++ b/public/assets/libs/art-template/demo/node-template/public/footer.html @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/node-template/public/header.html b/public/assets/libs/art-template/demo/node-template/public/header.html new file mode 100644 index 0000000000000000000000000000000000000000..d93e780a07bbc6088a53e5dd0b25d2f7835d12e6 --- /dev/null +++ b/public/assets/libs/art-template/demo/node-template/public/header.html @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/node-template/public/logo.html b/public/assets/libs/art-template/demo/node-template/public/logo.html new file mode 100644 index 0000000000000000000000000000000000000000..b02f7cbf63ee2442f15dd40b1822b1465dca102b --- /dev/null +++ b/public/assets/libs/art-template/demo/node-template/public/logo.html @@ -0,0 +1,7 @@ + +

            + + 腾讯网 + +

            + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/print.html b/public/assets/libs/art-template/demo/print.html new file mode 100644 index 0000000000000000000000000000000000000000..65f5b2c526d11c876ef79f97fa625d3574f43c28 --- /dev/null +++ b/public/assets/libs/art-template/demo/print.html @@ -0,0 +1,29 @@ + + + + +print-demo + + + + +

            print

            + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/template-native/basic.html b/public/assets/libs/art-template/demo/template-native/basic.html new file mode 100644 index 0000000000000000000000000000000000000000..ddf8fdec7faa1b42b62803a9be4f8bc8fb02ab21 --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/basic.html @@ -0,0 +1,34 @@ + + + + +basic-demo + + + + +
            + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/template-native/compile.html b/public/assets/libs/art-template/demo/template-native/compile.html new file mode 100644 index 0000000000000000000000000000000000000000..c6fe29623a2d145dfb6b940456a3b5afa3a9a146 --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/compile.html @@ -0,0 +1,27 @@ + + + + +compile-demo + + + + +

            在javascript中存放模板

            +
            + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/template-native/debug-syntax.html b/public/assets/libs/art-template/demo/template-native/debug-syntax.html new file mode 100644 index 0000000000000000000000000000000000000000..66847d0b95c8c0aaaae9dde8c0a96011ed0b0e4a --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/debug-syntax.html @@ -0,0 +1,35 @@ + + + + +debug-demo + + + + +

            错误捕获(请打开控制台)

            + + + + + + + + diff --git a/public/assets/libs/art-template/demo/template-native/debug.html b/public/assets/libs/art-template/demo/template-native/debug.html new file mode 100644 index 0000000000000000000000000000000000000000..d4b46758378738fbedd138957eab03457eceb502 --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/debug.html @@ -0,0 +1,35 @@ + + + + +debug-demo + + + + +

            错误捕获(请打开控制台)

            + + + + + + + + diff --git a/public/assets/libs/art-template/demo/template-native/helper.html b/public/assets/libs/art-template/demo/template-native/helper.html new file mode 100644 index 0000000000000000000000000000000000000000..05e3b7a82c600dae7d0588a3ada4e774f7683afd --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/helper.html @@ -0,0 +1,76 @@ + + + + +helper-demo + + + + +

            辅助方法

            +
            + + + + + + + + diff --git a/public/assets/libs/art-template/demo/template-native/include.html b/public/assets/libs/art-template/demo/template-native/include.html new file mode 100644 index 0000000000000000000000000000000000000000..ded2f8e1a583b3ab79698a6a9d8d640632e58858 --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/include.html @@ -0,0 +1,32 @@ + + + + +include-demo + + + + +
            + + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/template-native/index.html b/public/assets/libs/art-template/demo/template-native/index.html new file mode 100644 index 0000000000000000000000000000000000000000..9ad7294854fb9db3f6d0fe881e0747158100b934 --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/index.html @@ -0,0 +1,22 @@ + + + + +demo + + + +

            演示

            + + + + diff --git a/public/assets/libs/art-template/demo/template-native/no-escape.html b/public/assets/libs/art-template/demo/template-native/no-escape.html new file mode 100644 index 0000000000000000000000000000000000000000..810ee6f77908b6b75e37a680eb9ca1de0fb9d2af --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/no-escape.html @@ -0,0 +1,25 @@ + + + + +no escape-demo + + + + +

            不转义HTML

            +
            + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/template-native/print.html b/public/assets/libs/art-template/demo/template-native/print.html new file mode 100644 index 0000000000000000000000000000000000000000..75047eb723a97bbd42bc41842d49250b0f07f567 --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/print.html @@ -0,0 +1,30 @@ + + + + +print-demo + + + + +

            print

            + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/demo/template-native/tag.html b/public/assets/libs/art-template/demo/template-native/tag.html new file mode 100644 index 0000000000000000000000000000000000000000..afd06019089700a1b7237d56f568a2a3bd61a6ab --- /dev/null +++ b/public/assets/libs/art-template/demo/template-native/tag.html @@ -0,0 +1,42 @@ + + + + +tag-demo + + + + +

            自定义界定符

            + + + + + \ No newline at end of file diff --git a/public/assets/libs/art-template/dist/template-debug.js b/public/assets/libs/art-template/dist/template-debug.js new file mode 100644 index 0000000000000000000000000000000000000000..9403bef0f6d675dbccc657996049ca4870769dee --- /dev/null +++ b/public/assets/libs/art-template/dist/template-debug.js @@ -0,0 +1,739 @@ +/*! + * artTemplate - Template Engine + * https://github.com/aui/artTemplate + * Released under the MIT, BSD, and GPL Licenses + */ + +!(function () { + + +/** + * 模板引擎 + * @name template + * @param {String} 模板名 + * @param {Object, String} 数据。如果为字符串则编译并缓存编译结果 + * @return {String, Function} 渲染好的HTML字符串或者渲染方法 + */ +var template = function (filename, content) { + return typeof content === 'string' + ? compile(content, { + filename: filename + }) + : renderFile(filename, content); +}; + + +template.version = '3.0.0'; + + +/** + * 设置全局配置 + * @name template.config + * @param {String} 名称 + * @param {Any} 值 + */ +template.config = function (name, value) { + defaults[name] = value; +}; + + + +var defaults = template.defaults = { + openTag: '<%', // 逻辑语法开始标签 + closeTag: '%>', // 逻辑语法结束标签 + escape: true, // 是否编码输出变量的 HTML 字符 + cache: true, // 是否开启缓存(依赖 options 的 filename 字段) + compress: false, // 是否压缩输出 + parser: null // 自定义语法格式器 @see: template-syntax.js +}; + + +var cacheStore = template.cache = {}; + + +/** + * 渲染模板 + * @name template.render + * @param {String} 模板 + * @param {Object} 数据 + * @return {String} 渲染好的字符串 + */ +template.render = function (source, options) { + return compile(source)(options); +}; + + +/** + * 渲染模板(根据模板名) + * @name template.render + * @param {String} 模板名 + * @param {Object} 数据 + * @return {String} 渲染好的字符串 + */ +var renderFile = template.renderFile = function (filename, data) { + var fn = template.get(filename) || showDebugInfo({ + filename: filename, + name: 'Render Error', + message: 'Template not found' + }); + return data ? fn(data) : fn; +}; + + +/** + * 获取编译缓存(可由外部重写此方法) + * @param {String} 模板名 + * @param {Function} 编译好的函数 + */ +template.get = function (filename) { + + var cache; + + if (cacheStore[filename]) { + // 使用内存缓存 + cache = cacheStore[filename]; + } else if (typeof document === 'object') { + // 加载模板并编译 + var elem = document.getElementById(filename); + + if (elem) { + var source = (elem.value || elem.innerHTML) + .replace(/^\s*|\s*$/g, ''); + cache = compile(source, { + filename: filename + }); + } + } + + return cache; +}; + + +var toString = function (value, type) { + + if (typeof value !== 'string') { + + type = typeof value; + if (type === 'number') { + value += ''; + } else if (type === 'function') { + value = toString(value.call(value)); + } else { + value = ''; + } + } + + return value; + +}; + + +var escapeMap = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "&": "&" +}; + + +var escapeFn = function (s) { + return escapeMap[s]; +}; + +var escapeHTML = function (content) { + return toString(content) + .replace(/&(?![\w#]+;)|[<>"']/g, escapeFn); +}; + + +var isArray = Array.isArray || function (obj) { + return ({}).toString.call(obj) === '[object Array]'; +}; + + +var each = function (data, callback) { + var i, len; + if (isArray(data)) { + for (i = 0, len = data.length; i < len; i++) { + callback.call(data, data[i], i, data); + } + } else { + for (i in data) { + callback.call(data, data[i], i); + } + } +}; + + +var utils = template.utils = { + + $helpers: {}, + + $include: renderFile, + + $string: toString, + + $escape: escapeHTML, + + $each: each + +};/** + * 添加模板辅助方法 + * @name template.helper + * @param {String} 名称 + * @param {Function} 方法 + */ +template.helper = function (name, helper) { + helpers[name] = helper; +}; + +var helpers = template.helpers = utils.$helpers; + + + + +/** + * 模板错误事件(可由外部重写此方法) + * @name template.onerror + * @event + */ +template.onerror = function (e) { + var message = 'Template Error\n\n'; + for (var name in e) { + message += '<' + name + '>\n' + e[name] + '\n\n'; + } + + if (typeof console === 'object') { + console.error(message); + } +}; + + +// 模板调试器 +var showDebugInfo = function (e) { + + template.onerror(e); + + return function () { + return '{Template Error}'; + }; +}; + + +/** + * 编译模板 + * 2012-6-6 @TooBug: define 方法名改为 compile,与 Node Express 保持一致 + * @name template.compile + * @param {String} 模板字符串 + * @param {Object} 编译选项 + * + * - openTag {String} + * - closeTag {String} + * - filename {String} + * - escape {Boolean} + * - compress {Boolean} + * - debug {Boolean} + * - cache {Boolean} + * - parser {Function} + * + * @return {Function} 渲染方法 + */ +var compile = template.compile = function (source, options) { + + // 合并默认配置 + options = options || {}; + for (var name in defaults) { + if (options[name] === undefined) { + options[name] = defaults[name]; + } + } + + + var filename = options.filename; + + + try { + + var Render = compiler(source, options); + + } catch (e) { + + e.filename = filename || 'anonymous'; + e.name = 'Syntax Error'; + + return showDebugInfo(e); + + } + + + // 对编译结果进行一次包装 + + function render (data) { + + try { + + return new Render(data, filename) + ''; + + } catch (e) { + + // 运行时出错后自动开启调试模式重新编译 + if (!options.debug) { + options.debug = true; + return compile(source, options)(data); + } + + return showDebugInfo(e)(); + + } + + } + + + render.prototype = Render.prototype; + render.toString = function () { + return Render.toString(); + }; + + + if (filename && options.cache) { + cacheStore[filename] = render; + } + + + return render; + +}; + + + + +// 数组迭代 +var forEach = utils.$each; + + +// 静态分析模板变量 +var KEYWORDS = + // 关键字 + 'break,case,catch,continue,debugger,default,delete,do,else,false' + + ',finally,for,function,if,in,instanceof,new,null,return,switch,this' + + ',throw,true,try,typeof,var,void,while,with' + + // 保留字 + + ',abstract,boolean,byte,char,class,const,double,enum,export,extends' + + ',final,float,goto,implements,import,int,interface,long,native' + + ',package,private,protected,public,short,static,super,synchronized' + + ',throws,transient,volatile' + + // ECMA 5 - use strict + + ',arguments,let,yield' + + + ',undefined'; + +var REMOVE_RE = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g; +var SPLIT_RE = /[^\w$]+/g; +var KEYWORDS_RE = new RegExp(["\\b" + KEYWORDS.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g'); +var NUMBER_RE = /^\d[^,]*|,\d[^,]*/g; +var BOUNDARY_RE = /^,+|,+$/g; +var SPLIT2_RE = /^$|,+/; + + +// 获取变量 +function getVariable (code) { + return code + .replace(REMOVE_RE, '') + .replace(SPLIT_RE, ',') + .replace(KEYWORDS_RE, '') + .replace(NUMBER_RE, '') + .replace(BOUNDARY_RE, '') + .split(SPLIT2_RE); +}; + + +// 字符串转义 +function stringify (code) { + return "'" + code + // 单引号与反斜杠转义 + .replace(/('|\\)/g, '\\$1') + // 换行符转义(windows + linux) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + "'"; +} + + +function compiler (source, options) { + + var debug = options.debug; + var openTag = options.openTag; + var closeTag = options.closeTag; + var parser = options.parser; + var compress = options.compress; + var escape = options.escape; + + + + var line = 1; + var uniq = {$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1}; + + + + var isNewEngine = ''.trim;// '__proto__' in {} + var replaces = isNewEngine + ? ["$out='';", "$out+=", ";", "$out"] + : ["$out=[];", "$out.push(", ");", "$out.join('')"]; + + var concat = isNewEngine + ? "$out+=text;return $out;" + : "$out.push(text);"; + + var print = "function(){" + + "var text=''.concat.apply('',arguments);" + + concat + + "}"; + + var include = "function(filename,data){" + + "data=data||$data;" + + "var text=$utils.$include(filename,data,$filename);" + + concat + + "}"; + + var headerCode = "'use strict';" + + "var $utils=this,$helpers=$utils.$helpers," + + (debug ? "$line=0," : ""); + + var mainCode = replaces[0]; + + var footerCode = "return new String(" + replaces[3] + ");" + + // html与逻辑语法分离 + forEach(source.split(openTag), function (code) { + code = code.split(closeTag); + + var $0 = code[0]; + var $1 = code[1]; + + // code: [html] + if (code.length === 1) { + + mainCode += html($0); + + // code: [logic, html] + } else { + + mainCode += logic($0); + + if ($1) { + mainCode += html($1); + } + } + + + }); + + var code = headerCode + mainCode + footerCode; + + // 调试语句 + if (debug) { + code = "try{" + code + "}catch(e){" + + "throw {" + + "filename:$filename," + + "name:'Render Error'," + + "message:e.message," + + "line:$line," + + "source:" + stringify(source) + + ".split(/\\n/)[$line-1].replace(/^\\s+/,'')" + + "};" + + "}"; + } + + + + try { + + + var Render = new Function("$data", "$filename", code); + Render.prototype = utils; + + return Render; + + } catch (e) { + e.temp = "function anonymous($data,$filename) {" + code + "}"; + throw e; + } + + + + + // 处理 HTML 语句 + function html (code) { + + // 记录行号 + line += code.split(/\n/).length - 1; + + // 压缩多余空白与注释 + if (compress) { + code = code + .replace(/\s+/g, ' ') + .replace(//g, ''); + } + + if (code) { + code = replaces[1] + stringify(code) + replaces[2] + "\n"; + } + + return code; + } + + + // 处理逻辑语句 + function logic (code) { + + var thisLine = line; + + if (parser) { + + // 语法转换插件钩子 + code = parser(code, options); + + } else if (debug) { + + // 记录行号 + code = code.replace(/\n/g, function () { + line ++; + return "$line=" + line + ";"; + }); + + } + + + // 输出语句. 编码: <%=value%> 不编码:<%=#value%> + // <%=#value%> 等同 v2.0.3 之前的 <%==value%> + if (code.indexOf('=') === 0) { + + var escapeSyntax = escape && !/^=[=#]/.test(code); + + code = code.replace(/^=[=#]?|[\s;]*$/g, ''); + + // 对内容编码 + if (escapeSyntax) { + + var name = code.replace(/\s*\([^\)]+\)/, ''); + + // 排除 utils.* | include | print + + if (!utils[name] && !/^(include|print)$/.test(name)) { + code = "$escape(" + code + ")"; + } + + // 不编码 + } else { + code = "$string(" + code + ")"; + } + + + code = replaces[1] + code + replaces[2]; + + } + + if (debug) { + code = "$line=" + thisLine + ";" + code; + } + + // 提取模板中的变量名 + forEach(getVariable(code), function (name) { + + // name 值可能为空,在安卓低版本浏览器下 + if (!name || uniq[name]) { + return; + } + + var value; + + // 声明模板变量 + // 赋值优先级: + // [include, print] > utils > helpers > data + if (name === 'print') { + + value = print; + + } else if (name === 'include') { + + value = include; + + } else if (utils[name]) { + + value = "$utils." + name; + + } else if (helpers[name]) { + + value = "$helpers." + name; + + } else { + + value = "$data." + name; + } + + headerCode += name + "=" + value + ","; + uniq[name] = true; + + + }); + + return code + "\n"; + } + + +}; + + + +// 定义模板引擎的语法 + + +defaults.openTag = '{{'; +defaults.closeTag = '}}'; + + +var filtered = function (js, filter) { + var parts = filter.split(':'); + var name = parts.shift(); + var args = parts.join(':') || ''; + + if (args) { + args = ', ' + args; + } + + return '$helpers.' + name + '(' + js + args + ')'; +} + + +defaults.parser = function (code, options) { + + // var match = code.match(/([\w\$]*)(\b.*)/); + // var key = match[1]; + // var args = match[2]; + // var split = args.split(' '); + // split.shift(); + + code = code.replace(/^\s/, ''); + + var split = code.split(' '); + var key = split.shift(); + var args = split.join(' '); + + + + switch (key) { + + case 'if': + + code = 'if(' + args + '){'; + break; + + case 'else': + + if (split.shift() === 'if') { + split = ' if(' + split.join(' ') + ')'; + } else { + split = ''; + } + + code = '}else' + split + '{'; + break; + + case '/if': + + code = '}'; + break; + + case 'each': + + var object = split[0] || '$data'; + var as = split[1] || 'as'; + var value = split[2] || '$value'; + var index = split[3] || '$index'; + + var param = value + ',' + index; + + if (as !== 'as') { + object = '[]'; + } + + code = '$each(' + object + ',function(' + param + '){'; + break; + + case '/each': + + code = '});'; + break; + + case 'echo': + + code = 'print(' + args + ');'; + break; + + case 'print': + case 'include': + + code = key + '(' + split.join(',') + ');'; + break; + + default: + + // 过滤器(辅助方法) + // {{value | filterA:'abcd' | filterB}} + // >>> $helpers.filterB($helpers.filterA(value, 'abcd')) + // TODO: {{ddd||aaa}} 不包含空格 + if (/^\s*\|\s*[\w\$]/.test(args)) { + + var escape = true; + + // {{#value | link}} + if (code.indexOf('#') === 0) { + code = code.substr(1); + escape = false; + } + + var i = 0; + var array = code.split('|'); + var len = array.length; + var val = array[i++]; + + for (; i < len; i ++) { + val = filtered(val, array[i]); + } + + code = (escape ? '=' : '=#') + val; + + // 即将弃用 {{helperName value}} + } else if (template.helpers[key]) { + + code = '=#' + key + '(' + split.join(',') + ');'; + + // 内容直接输出 {{value}} + } else { + + code = '=' + code; + } + + break; + } + + + return code; +}; + + +// CommonJs +if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = template; +// RequireJS && SeaJS +} else if (typeof define === 'function') { + define(function() { + return template; + }); +} else { + this.template = template; +} + +})(); diff --git a/public/assets/libs/art-template/dist/template-native-debug.js b/public/assets/libs/art-template/dist/template-native-debug.js new file mode 100644 index 0000000000000000000000000000000000000000..cfdf124a193706f36eeb1f36ccd97cb2ae5a52ba --- /dev/null +++ b/public/assets/libs/art-template/dist/template-native-debug.js @@ -0,0 +1,602 @@ +/*! + * artTemplate - Template Engine + * https://github.com/aui/artTemplate + * Released under the MIT, BSD, and GPL Licenses + */ + +!(function () { + + +/** + * 模板引擎 + * @name template + * @param {String} 模板名 + * @param {Object, String} 数据。如果为字符串则编译并缓存编译结果 + * @return {String, Function} 渲染好的HTML字符串或者渲染方法 + */ +var template = function (filename, content) { + return typeof content === 'string' + ? compile(content, { + filename: filename + }) + : renderFile(filename, content); +}; + + +template.version = '3.0.0'; + + +/** + * 设置全局配置 + * @name template.config + * @param {String} 名称 + * @param {Any} 值 + */ +template.config = function (name, value) { + defaults[name] = value; +}; + + + +var defaults = template.defaults = { + openTag: '<%', // 逻辑语法开始标签 + closeTag: '%>', // 逻辑语法结束标签 + escape: true, // 是否编码输出变量的 HTML 字符 + cache: true, // 是否开启缓存(依赖 options 的 filename 字段) + compress: false, // 是否压缩输出 + parser: null // 自定义语法格式器 @see: template-syntax.js +}; + + +var cacheStore = template.cache = {}; + + +/** + * 渲染模板 + * @name template.render + * @param {String} 模板 + * @param {Object} 数据 + * @return {String} 渲染好的字符串 + */ +template.render = function (source, options) { + return compile(source)(options); +}; + + +/** + * 渲染模板(根据模板名) + * @name template.render + * @param {String} 模板名 + * @param {Object} 数据 + * @return {String} 渲染好的字符串 + */ +var renderFile = template.renderFile = function (filename, data) { + var fn = template.get(filename) || showDebugInfo({ + filename: filename, + name: 'Render Error', + message: 'Template not found' + }); + return data ? fn(data) : fn; +}; + + +/** + * 获取编译缓存(可由外部重写此方法) + * @param {String} 模板名 + * @param {Function} 编译好的函数 + */ +template.get = function (filename) { + + var cache; + + if (cacheStore[filename]) { + // 使用内存缓存 + cache = cacheStore[filename]; + } else if (typeof document === 'object') { + // 加载模板并编译 + var elem = document.getElementById(filename); + + if (elem) { + var source = (elem.value || elem.innerHTML) + .replace(/^\s*|\s*$/g, ''); + cache = compile(source, { + filename: filename + }); + } + } + + return cache; +}; + + +var toString = function (value, type) { + + if (typeof value !== 'string') { + + type = typeof value; + if (type === 'number') { + value += ''; + } else if (type === 'function') { + value = toString(value.call(value)); + } else { + value = ''; + } + } + + return value; + +}; + + +var escapeMap = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "&": "&" +}; + + +var escapeFn = function (s) { + return escapeMap[s]; +}; + +var escapeHTML = function (content) { + return toString(content) + .replace(/&(?![\w#]+;)|[<>"']/g, escapeFn); +}; + + +var isArray = Array.isArray || function (obj) { + return ({}).toString.call(obj) === '[object Array]'; +}; + + +var each = function (data, callback) { + var i, len; + if (isArray(data)) { + for (i = 0, len = data.length; i < len; i++) { + callback.call(data, data[i], i, data); + } + } else { + for (i in data) { + callback.call(data, data[i], i); + } + } +}; + + +var utils = template.utils = { + + $helpers: {}, + + $include: renderFile, + + $string: toString, + + $escape: escapeHTML, + + $each: each + +};/** + * 添加模板辅助方法 + * @name template.helper + * @param {String} 名称 + * @param {Function} 方法 + */ +template.helper = function (name, helper) { + helpers[name] = helper; +}; + +var helpers = template.helpers = utils.$helpers; + + + + +/** + * 模板错误事件(可由外部重写此方法) + * @name template.onerror + * @event + */ +template.onerror = function (e) { + var message = 'Template Error\n\n'; + for (var name in e) { + message += '<' + name + '>\n' + e[name] + '\n\n'; + } + + if (typeof console === 'object') { + console.error(message); + } +}; + + +// 模板调试器 +var showDebugInfo = function (e) { + + template.onerror(e); + + return function () { + return '{Template Error}'; + }; +}; + + +/** + * 编译模板 + * 2012-6-6 @TooBug: define 方法名改为 compile,与 Node Express 保持一致 + * @name template.compile + * @param {String} 模板字符串 + * @param {Object} 编译选项 + * + * - openTag {String} + * - closeTag {String} + * - filename {String} + * - escape {Boolean} + * - compress {Boolean} + * - debug {Boolean} + * - cache {Boolean} + * - parser {Function} + * + * @return {Function} 渲染方法 + */ +var compile = template.compile = function (source, options) { + + // 合并默认配置 + options = options || {}; + for (var name in defaults) { + if (options[name] === undefined) { + options[name] = defaults[name]; + } + } + + + var filename = options.filename; + + + try { + + var Render = compiler(source, options); + + } catch (e) { + + e.filename = filename || 'anonymous'; + e.name = 'Syntax Error'; + + return showDebugInfo(e); + + } + + + // 对编译结果进行一次包装 + + function render (data) { + + try { + + return new Render(data, filename) + ''; + + } catch (e) { + + // 运行时出错后自动开启调试模式重新编译 + if (!options.debug) { + options.debug = true; + return compile(source, options)(data); + } + + return showDebugInfo(e)(); + + } + + } + + + render.prototype = Render.prototype; + render.toString = function () { + return Render.toString(); + }; + + + if (filename && options.cache) { + cacheStore[filename] = render; + } + + + return render; + +}; + + + + +// 数组迭代 +var forEach = utils.$each; + + +// 静态分析模板变量 +var KEYWORDS = + // 关键字 + 'break,case,catch,continue,debugger,default,delete,do,else,false' + + ',finally,for,function,if,in,instanceof,new,null,return,switch,this' + + ',throw,true,try,typeof,var,void,while,with' + + // 保留字 + + ',abstract,boolean,byte,char,class,const,double,enum,export,extends' + + ',final,float,goto,implements,import,int,interface,long,native' + + ',package,private,protected,public,short,static,super,synchronized' + + ',throws,transient,volatile' + + // ECMA 5 - use strict + + ',arguments,let,yield' + + + ',undefined'; + +var REMOVE_RE = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g; +var SPLIT_RE = /[^\w$]+/g; +var KEYWORDS_RE = new RegExp(["\\b" + KEYWORDS.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g'); +var NUMBER_RE = /^\d[^,]*|,\d[^,]*/g; +var BOUNDARY_RE = /^,+|,+$/g; +var SPLIT2_RE = /^$|,+/; + + +// 获取变量 +function getVariable (code) { + return code + .replace(REMOVE_RE, '') + .replace(SPLIT_RE, ',') + .replace(KEYWORDS_RE, '') + .replace(NUMBER_RE, '') + .replace(BOUNDARY_RE, '') + .split(SPLIT2_RE); +}; + + +// 字符串转义 +function stringify (code) { + return "'" + code + // 单引号与反斜杠转义 + .replace(/('|\\)/g, '\\$1') + // 换行符转义(windows + linux) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + "'"; +} + + +function compiler (source, options) { + + var debug = options.debug; + var openTag = options.openTag; + var closeTag = options.closeTag; + var parser = options.parser; + var compress = options.compress; + var escape = options.escape; + + + + var line = 1; + var uniq = {$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1}; + + + + var isNewEngine = ''.trim;// '__proto__' in {} + var replaces = isNewEngine + ? ["$out='';", "$out+=", ";", "$out"] + : ["$out=[];", "$out.push(", ");", "$out.join('')"]; + + var concat = isNewEngine + ? "$out+=text;return $out;" + : "$out.push(text);"; + + var print = "function(){" + + "var text=''.concat.apply('',arguments);" + + concat + + "}"; + + var include = "function(filename,data){" + + "data=data||$data;" + + "var text=$utils.$include(filename,data,$filename);" + + concat + + "}"; + + var headerCode = "'use strict';" + + "var $utils=this,$helpers=$utils.$helpers," + + (debug ? "$line=0," : ""); + + var mainCode = replaces[0]; + + var footerCode = "return new String(" + replaces[3] + ");" + + // html与逻辑语法分离 + forEach(source.split(openTag), function (code) { + code = code.split(closeTag); + + var $0 = code[0]; + var $1 = code[1]; + + // code: [html] + if (code.length === 1) { + + mainCode += html($0); + + // code: [logic, html] + } else { + + mainCode += logic($0); + + if ($1) { + mainCode += html($1); + } + } + + + }); + + var code = headerCode + mainCode + footerCode; + + // 调试语句 + if (debug) { + code = "try{" + code + "}catch(e){" + + "throw {" + + "filename:$filename," + + "name:'Render Error'," + + "message:e.message," + + "line:$line," + + "source:" + stringify(source) + + ".split(/\\n/)[$line-1].replace(/^\\s+/,'')" + + "};" + + "}"; + } + + + + try { + + + var Render = new Function("$data", "$filename", code); + Render.prototype = utils; + + return Render; + + } catch (e) { + e.temp = "function anonymous($data,$filename) {" + code + "}"; + throw e; + } + + + + + // 处理 HTML 语句 + function html (code) { + + // 记录行号 + line += code.split(/\n/).length - 1; + + // 压缩多余空白与注释 + if (compress) { + code = code + .replace(/\s+/g, ' ') + .replace(//g, ''); + } + + if (code) { + code = replaces[1] + stringify(code) + replaces[2] + "\n"; + } + + return code; + } + + + // 处理逻辑语句 + function logic (code) { + + var thisLine = line; + + if (parser) { + + // 语法转换插件钩子 + code = parser(code, options); + + } else if (debug) { + + // 记录行号 + code = code.replace(/\n/g, function () { + line ++; + return "$line=" + line + ";"; + }); + + } + + + // 输出语句. 编码: <%=value%> 不编码:<%=#value%> + // <%=#value%> 等同 v2.0.3 之前的 <%==value%> + if (code.indexOf('=') === 0) { + + var escapeSyntax = escape && !/^=[=#]/.test(code); + + code = code.replace(/^=[=#]?|[\s;]*$/g, ''); + + // 对内容编码 + if (escapeSyntax) { + + var name = code.replace(/\s*\([^\)]+\)/, ''); + + // 排除 utils.* | include | print + + if (!utils[name] && !/^(include|print)$/.test(name)) { + code = "$escape(" + code + ")"; + } + + // 不编码 + } else { + code = "$string(" + code + ")"; + } + + + code = replaces[1] + code + replaces[2]; + + } + + if (debug) { + code = "$line=" + thisLine + ";" + code; + } + + // 提取模板中的变量名 + forEach(getVariable(code), function (name) { + + // name 值可能为空,在安卓低版本浏览器下 + if (!name || uniq[name]) { + return; + } + + var value; + + // 声明模板变量 + // 赋值优先级: + // [include, print] > utils > helpers > data + if (name === 'print') { + + value = print; + + } else if (name === 'include') { + + value = include; + + } else if (utils[name]) { + + value = "$utils." + name; + + } else if (helpers[name]) { + + value = "$helpers." + name; + + } else { + + value = "$data." + name; + } + + headerCode += name + "=" + value + ","; + uniq[name] = true; + + + }); + + return code + "\n"; + } + + +}; + + + +// CommonJs +if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = template; +// RequireJS && SeaJS +} else if (typeof define === 'function') { + define(function() { + return template; + }); +} else { + this.template = template; +} + +})(); diff --git a/public/assets/libs/art-template/dist/template-native.js b/public/assets/libs/art-template/dist/template-native.js new file mode 100644 index 0000000000000000000000000000000000000000..1944fdca5affd8e877ec532bb524ee82ea12e90e --- /dev/null +++ b/public/assets/libs/art-template/dist/template-native.js @@ -0,0 +1,2 @@ +/*!art-template - Template Engine | http://aui.github.com/artTemplate/*/ +!function(){function a(a){return a.replace(t,"").replace(u,",").replace(v,"").replace(w,"").replace(x,"").split(y)}function b(a){return"'"+a.replace(/('|\\)/g,"\\$1").replace(/\r/g,"\\r").replace(/\n/g,"\\n")+"'"}function c(c,d){function e(a){return m+=a.split(/\n/).length-1,k&&(a=a.replace(/\s+/g," ").replace(//g,"")),a&&(a=s[1]+b(a)+s[2]+"\n"),a}function f(b){var c=m;if(j?b=j(b,d):g&&(b=b.replace(/\n/g,function(){return m++,"$line="+m+";"})),0===b.indexOf("=")){var e=l&&!/^=[=#]/.test(b);if(b=b.replace(/^=[=#]?|[\s;]*$/g,""),e){var f=b.replace(/\s*\([^\)]+\)/,"");n[f]||/^(include|print)$/.test(f)||(b="$escape("+b+")")}else b="$string("+b+")";b=s[1]+b+s[2]}return g&&(b="$line="+c+";"+b),r(a(b),function(a){if(a&&!p[a]){var b;b="print"===a?u:"include"===a?v:n[a]?"$utils."+a:o[a]?"$helpers."+a:"$data."+a,w+=a+"="+b+",",p[a]=!0}}),b+"\n"}var g=d.debug,h=d.openTag,i=d.closeTag,j=d.parser,k=d.compress,l=d.escape,m=1,p={$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1},q="".trim,s=q?["$out='';","$out+=",";","$out"]:["$out=[];","$out.push(",");","$out.join('')"],t=q?"$out+=text;return $out;":"$out.push(text);",u="function(){var text=''.concat.apply('',arguments);"+t+"}",v="function(filename,data){data=data||$data;var text=$utils.$include(filename,data,$filename);"+t+"}",w="'use strict';var $utils=this,$helpers=$utils.$helpers,"+(g?"$line=0,":""),x=s[0],y="return new String("+s[3]+");";r(c.split(h),function(a){a=a.split(i);var b=a[0],c=a[1];1===a.length?x+=e(b):(x+=f(b),c&&(x+=e(c)))});var z=w+x+y;g&&(z="try{"+z+"}catch(e){throw {filename:$filename,name:'Render Error',message:e.message,line:$line,source:"+b(c)+".split(/\\n/)[$line-1].replace(/^\\s+/,'')};}");try{var A=new Function("$data","$filename",z);return A.prototype=n,A}catch(a){throw a.temp="function anonymous($data,$filename) {"+z+"}",a}}var d=function(a,b){return"string"==typeof b?q(b,{filename:a}):g(a,b)};d.version="3.0.0",d.config=function(a,b){e[a]=b};var e=d.defaults={openTag:"<%",closeTag:"%>",escape:!0,cache:!0,compress:!1,parser:null},f=d.cache={};d.render=function(a,b){return q(a)(b)};var g=d.renderFile=function(a,b){var c=d.get(a)||p({filename:a,name:"Render Error",message:"Template not found"});return b?c(b):c};d.get=function(a){var b;if(f[a])b=f[a];else if("object"==typeof document){var c=document.getElementById(a);if(c){var d=(c.value||c.innerHTML).replace(/^\s*|\s*$/g,"");b=q(d,{filename:a})}}return b};var h=function(a,b){return"string"!=typeof a&&(b=typeof a,"number"===b?a+="":a="function"===b?h(a.call(a)):""),a},i={"<":"<",">":">",'"':""","'":"'","&":"&"},j=function(a){return i[a]},k=function(a){return h(a).replace(/&(?![\w#]+;)|[<>"']/g,j)},l=Array.isArray||function(a){return"[object Array]"==={}.toString.call(a)},m=function(a,b){var c,d;if(l(a))for(c=0,d=a.length;c\n"+a[c]+"\n\n";"object"==typeof console&&console.error(b)};var p=function(a){return d.onerror(a),function(){return"{Template Error}"}},q=d.compile=function(a,b){function d(c){try{return new i(c,h)+""}catch(d){return b.debug?p(d)():(b.debug=!0,q(a,b)(c))}}b=b||{};for(var g in e)void 0===b[g]&&(b[g]=e[g]);var h=b.filename;try{var i=c(a,b)}catch(a){return a.filename=h||"anonymous",a.name="Syntax Error",p(a)}return d.prototype=i.prototype,d.toString=function(){return i.toString()},h&&b.cache&&(f[h]=d),d},r=n.$each,s="break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto,implements,import,int,interface,long,native,package,private,protected,public,short,static,super,synchronized,throws,transient,volatile,arguments,let,yield,undefined",t=/\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g,u=/[^\w$]+/g,v=new RegExp(["\\b"+s.replace(/,/g,"\\b|\\b")+"\\b"].join("|"),"g"),w=/^\d[^,]*|,\d[^,]*/g,x=/^,+|,+$/g,y=/^$|,+/;"object"==typeof exports&&"undefined"!=typeof module?module.exports=d:"function"==typeof define?define(function(){return d}):this.template=d}(); \ No newline at end of file diff --git a/public/assets/libs/art-template/dist/template.js b/public/assets/libs/art-template/dist/template.js new file mode 100644 index 0000000000000000000000000000000000000000..9e3ab2705d7b899dd2ee934cf086940dff2ba529 --- /dev/null +++ b/public/assets/libs/art-template/dist/template.js @@ -0,0 +1,2 @@ +/*!art-template - Template Engine | http://aui.github.com/artTemplate/*/ +!function(){function a(a){return a.replace(t,"").replace(u,",").replace(v,"").replace(w,"").replace(x,"").split(y)}function b(a){return"'"+a.replace(/('|\\)/g,"\\$1").replace(/\r/g,"\\r").replace(/\n/g,"\\n")+"'"}function c(c,d){function e(a){return m+=a.split(/\n/).length-1,k&&(a=a.replace(/\s+/g," ").replace(//g,"")),a&&(a=s[1]+b(a)+s[2]+"\n"),a}function f(b){var c=m;if(j?b=j(b,d):g&&(b=b.replace(/\n/g,function(){return m++,"$line="+m+";"})),0===b.indexOf("=")){var e=l&&!/^=[=#]/.test(b);if(b=b.replace(/^=[=#]?|[\s;]*$/g,""),e){var f=b.replace(/\s*\([^\)]+\)/,"");n[f]||/^(include|print)$/.test(f)||(b="$escape("+b+")")}else b="$string("+b+")";b=s[1]+b+s[2]}return g&&(b="$line="+c+";"+b),r(a(b),function(a){if(a&&!p[a]){var b;b="print"===a?u:"include"===a?v:n[a]?"$utils."+a:o[a]?"$helpers."+a:"$data."+a,w+=a+"="+b+",",p[a]=!0}}),b+"\n"}var g=d.debug,h=d.openTag,i=d.closeTag,j=d.parser,k=d.compress,l=d.escape,m=1,p={$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1},q="".trim,s=q?["$out='';","$out+=",";","$out"]:["$out=[];","$out.push(",");","$out.join('')"],t=q?"$out+=text;return $out;":"$out.push(text);",u="function(){var text=''.concat.apply('',arguments);"+t+"}",v="function(filename,data){data=data||$data;var text=$utils.$include(filename,data,$filename);"+t+"}",w="'use strict';var $utils=this,$helpers=$utils.$helpers,"+(g?"$line=0,":""),x=s[0],y="return new String("+s[3]+");";r(c.split(h),function(a){a=a.split(i);var b=a[0],c=a[1];1===a.length?x+=e(b):(x+=f(b),c&&(x+=e(c)))});var z=w+x+y;g&&(z="try{"+z+"}catch(e){throw {filename:$filename,name:'Render Error',message:e.message,line:$line,source:"+b(c)+".split(/\\n/)[$line-1].replace(/^\\s+/,'')};}");try{var A=new Function("$data","$filename",z);return A.prototype=n,A}catch(a){throw a.temp="function anonymous($data,$filename) {"+z+"}",a}}var d=function(a,b){return"string"==typeof b?q(b,{filename:a}):g(a,b)};d.version="3.0.0",d.config=function(a,b){e[a]=b};var e=d.defaults={openTag:"<%",closeTag:"%>",escape:!0,cache:!0,compress:!1,parser:null},f=d.cache={};d.render=function(a,b){return q(a)(b)};var g=d.renderFile=function(a,b){var c=d.get(a)||p({filename:a,name:"Render Error",message:"Template not found"});return b?c(b):c};d.get=function(a){var b;if(f[a])b=f[a];else if("object"==typeof document){var c=document.getElementById(a);if(c){var d=(c.value||c.innerHTML).replace(/^\s*|\s*$/g,"");b=q(d,{filename:a})}}return b};var h=function(a,b){return"string"!=typeof a&&(b=typeof a,"number"===b?a+="":a="function"===b?h(a.call(a)):""),a},i={"<":"<",">":">",'"':""","'":"'","&":"&"},j=function(a){return i[a]},k=function(a){return h(a).replace(/&(?![\w#]+;)|[<>"']/g,j)},l=Array.isArray||function(a){return"[object Array]"==={}.toString.call(a)},m=function(a,b){var c,d;if(l(a))for(c=0,d=a.length;c\n"+a[c]+"\n\n";"object"==typeof console&&console.error(b)};var p=function(a){return d.onerror(a),function(){return"{Template Error}"}},q=d.compile=function(a,b){function d(c){try{return new i(c,h)+""}catch(d){return b.debug?p(d)():(b.debug=!0,q(a,b)(c))}}b=b||{};for(var g in e)void 0===b[g]&&(b[g]=e[g]);var h=b.filename;try{var i=c(a,b)}catch(a){return a.filename=h||"anonymous",a.name="Syntax Error",p(a)}return d.prototype=i.prototype,d.toString=function(){return i.toString()},h&&b.cache&&(f[h]=d),d},r=n.$each,s="break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto,implements,import,int,interface,long,native,package,private,protected,public,short,static,super,synchronized,throws,transient,volatile,arguments,let,yield,undefined",t=/\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g,u=/[^\w$]+/g,v=new RegExp(["\\b"+s.replace(/,/g,"\\b|\\b")+"\\b"].join("|"),"g"),w=/^\d[^,]*|,\d[^,]*/g,x=/^,+|,+$/g,y=/^$|,+/;e.openTag="{{",e.closeTag="}}";var z=function(a,b){var c=b.split(":"),d=c.shift(),e=c.join(":")||"";return e&&(e=", "+e),"$helpers."+d+"("+a+e+")"};e.parser=function(a,b){a=a.replace(/^\s/,"");var c=a.split(" "),e=c.shift(),f=c.join(" ");switch(e){case"if":a="if("+f+"){";break;case"else":c="if"===c.shift()?" if("+c.join(" ")+")":"",a="}else"+c+"{";break;case"/if":a="}";break;case"each":var g=c[0]||"$data",h=c[1]||"as",i=c[2]||"$value",j=c[3]||"$index",k=i+","+j;"as"!==h&&(g="[]"),a="$each("+g+",function("+k+"){";break;case"/each":a="});";break;case"echo":a="print("+f+");";break;case"print":case"include":a=e+"("+c.join(",")+");";break;default:if(/^\s*\|\s*[\w\$]/.test(f)){var l=!0;0===a.indexOf("#")&&(a=a.substr(1),l=!1);for(var m=0,n=a.split("|"),o=n.length,p=n[m++];m + +[下载](https://raw.github.com/aui/artTemplate/master/dist/template-native.js) + +## 表达式 + +``<%`` 与 ``%>`` 符号包裹起来的语句则为模板的逻辑表达式。 + +### 输出表达式 + +对内容编码输出: + + <%=content%> + +不编码输出: + + <%=#content%> + +编码可以防止数据中含有 HTML 字符串,避免引起 XSS 攻击。 + +### 逻辑 + +支持使用 js 原生语法 + +

            <%=title%>

            +
              + <%for(i = 0; i < list.length; i ++) {%> +
            • 条目内容 <%=i + 1%> :<%=list[i]%>
            • + <%}%> +
            + +> 模板不能访问全局对象,公用的方法请参见文档[辅助方法](#辅助方法)章节 + +### 模板包含表达式 + +用于嵌入子模板。 + + <% include('template_name') %> + +子模板默认共享当前数据,亦可以指定数据: + + <% include('template_name', news_list) %> + +## 辅助方法 + +使用``template.helper(name, callback)``注册公用辅助方法: + + template.helper('dateFormat', function (date, format) { + // .. + return value; + }); + +模板中使用的方式: + + <%=dateFormat(content) %> + +## 演示例子 + +* [基本例子](http://aui.github.io/artTemplate/demo/template-native/basic.html) +* [不转义HTML](http://aui.github.io/artTemplate/demo/template-native/no-escape.html) +* [在javascript中存放模板](http://aui.github.io/artTemplate/demo/template-native/compile.html) +* [嵌入子模板(include)](http://aui.github.io/artTemplate/demo/template-native/include.html) +* [访问外部公用函数(辅助方法)](http://aui.github.io/artTemplate/demo/template-native/helper.html) + +---------------------------------------------- + +本文档针对 artTemplate v3.0.0 编写 \ No newline at end of file diff --git a/public/assets/libs/art-template/doc/syntax-simple.md b/public/assets/libs/art-template/doc/syntax-simple.md new file mode 100644 index 0000000000000000000000000000000000000000..cd3ac40b07f4aff3a3b24ce9fdb6dd008d5c9826 --- /dev/null +++ b/public/assets/libs/art-template/doc/syntax-simple.md @@ -0,0 +1,90 @@ +# artTemplate 简洁语法版 + +## 使用 + +引用简洁语法的引擎版本,例如: + + + + [下载](https://raw.github.com/aui/artTemplate/master/dist/template.js) + +## 表达式 + +``{{`` 与 ``}}`` 符号包裹起来的语句则为模板的逻辑表达式。 + +### 输出表达式 + +对内容编码输出: + + {{content}} + +不编码输出: + + {{#content}} + +编码可以防止数据中含有 HTML 字符串,避免引起 XSS 攻击。 + +### 条件表达式 + + {{if admin}} +

            admin

            + {{else if code > 0}} +

            master

            + {{else}} +

            error!

            + {{/if}} + +### 遍历表达式 + +无论数组或者对象都可以用 each 进行遍历。 + + {{each list as value index}} +
          • {{index}} - {{value.user}}
          • + {{/each}} + +亦可以被简写: + + {{each list}} +
          • {{$index}} - {{$value.user}}
          • + {{/each}} + +### 模板包含表达式 + +用于嵌入子模板。 + + {{include 'template_name'}} + +子模板默认共享当前数据,亦可以指定数据: + + {{include 'template_name' news_list}} + +## 辅助方法 + +使用``template.helper(name, callback)``注册公用辅助方法: + +``` +template.helper('dateFormat', function (date, format) { + // .. + return value; +}); +``` + +模板中使用的方式: + + {{time | dateFormat:'yyyy-MM-dd hh:mm:ss'}} + +支持传入参数与嵌套使用: + + {{time | say:'cd' | ubb | link}} + +## 演示例子 + +* [基本例子](http://aui.github.io/artTemplate/demo/basic.html) +* [不转义HTML](http://aui.github.io/artTemplate/demo/no-escape.html) +* [在javascript中存放模板](http://aui.github.io/artTemplate/demo/compile.html) +* [嵌入子模板(include)](http://aui.github.io/artTemplate/demo/include.html) +* [访问外部公用函数(辅助方法)](http://aui.github.io/artTemplate/demo/helper.html) + +---------------------------------------------- + +本文档针对 artTemplate v3.0.0+ 编写 \ No newline at end of file diff --git a/public/assets/libs/art-template/loader/index.js b/public/assets/libs/art-template/loader/index.js new file mode 100644 index 0000000000000000000000000000000000000000..cf8a1cfb7d24aa099f22d4046638313a315696fb --- /dev/null +++ b/public/assets/libs/art-template/loader/index.js @@ -0,0 +1,18 @@ +var template = require('art-template/dist/template'); + +module.exports = function(source) { + this.cacheable && this.cacheable() + + var ANONYMOUS_RE = /^function\s+anonymous/ + + template.onerror = function(e) { + var message = 'Template Error\n\n'; + for (var name in e) { + message += '<' + name + '>\n' + e[name] + '\n\n'; + } + throw new SyntaxError(message) + } + + var render = template.compile(source, {}).toString().replace(ANONYMOUS_RE, 'function'); + return 'module.exports = require("art-template/loader/runtime")(' + render + ');'; +} \ No newline at end of file diff --git a/public/assets/libs/art-template/loader/package.json b/public/assets/libs/art-template/loader/package.json new file mode 100644 index 0000000000000000000000000000000000000000..9b093c12ae07ab768535b2244cd41d40728ff1df --- /dev/null +++ b/public/assets/libs/art-template/loader/package.json @@ -0,0 +1,14 @@ +{ + "name": "t-loader", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "art-template": "^3.1.3" + } +} diff --git a/public/assets/libs/art-template/loader/runtime.js b/public/assets/libs/art-template/loader/runtime.js new file mode 100644 index 0000000000000000000000000000000000000000..53a9d1d5067731a001f364157a6f6ac23053b8b8 --- /dev/null +++ b/public/assets/libs/art-template/loader/runtime.js @@ -0,0 +1,129 @@ +function template(content) { + return compile(content); +}; + +var String = this.String; + +function toString(value, type) { + + if (typeof value !== 'string') { + + type = typeof value; + if (type === 'number') { + value += ''; + } else if (type === 'function') { + value = toString(value.call(value)); + } else { + value = ''; + } + } + + return value; + +}; + + +var escapeMap = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "&": "&" +}; + + +function escapeFn(s) { + return escapeMap[s]; +} + + +function escapeHTML(content) { + return toString(content) + .replace(/&(?![\w#]+;)|[<>"']/g, escapeFn); +}; + + +var isArray = Array.isArray || function (obj) { + return ({}).toString.call(obj) === '[object Array]'; +}; + + +function each(data, callback) { + if (isArray(data)) { + for (var i = 0, len = data.length; i < len; i++) { + callback.call(data, data[i], i, data); + } + } else { + for (i in data) { + callback.call(data, data[i], i); + } + } +}; + + +var utils = template.utils = { + + $helpers: {}, + + $include: function () { + throw new Error('art-template/loader: not support `include`.'); + }, + + $string: toString, + + $escape: escapeHTML, + + $each: each + +}; + + +var helpers = template.helpers = utils.$helpers; + + +function compile(fn) { + var render = function (data) { + try { + return new fn(data) + ''; + } catch (e) { + return showDebugInfo(e)(); + } + }; + + render.prototype = fn.prototype = utils; + render.toString = function () { + return fn + ''; + }; + + return render; +}; + + +function showDebugInfo(e) { + + var type = "{Template Error}"; + var message = e.stack || ''; + + if (message) { + // 利用报错堆栈信息 + message = message.split('\n').slice(0, 2).join('\n'); + } else { + // 调试版本,直接给出模板语句行 + for (var name in e) { + message += "<" + name + ">\n" + e[name] + "\n\n"; + } + } + + return function () { + if (typeof console === "object") { + console.error(type + "\n\n" + message); + } + return type; + }; +}; + +template.helper = function (name, helper) { + helpers[name] = helper; +}; + +module.exports = template; \ No newline at end of file diff --git a/public/assets/libs/art-template/node/_node.js b/public/assets/libs/art-template/node/_node.js new file mode 100644 index 0000000000000000000000000000000000000000..673a2cea7a4b970f1713478546757b6de2b9e929 --- /dev/null +++ b/public/assets/libs/art-template/node/_node.js @@ -0,0 +1,90 @@ +var fs = require('fs'); +var path = require('path'); + +module.exports = function (template) { + + var cacheStore = template.cache; + var defaults = template.defaults; + var rExtname; + + // 提供新的配置字段 + defaults.base = ''; + defaults.extname = '.html'; + defaults.encoding = 'utf-8'; + + function compileFromFS(filename) { + // 加载模板并编译 + var source = readTemplate(filename); + + if (typeof source === 'string') { + return template.compile(source, { + filename: filename + }); + } + } + + // 重写引擎编译结果获取方法 + template.get = function (filename) { + + var fn; + + + if (cacheStore.hasOwnProperty(filename)) { + // 使用内存缓存 + fn = cacheStore[filename]; + } else { + fn = compileFromFS(filename); + } + + return fn; + }; + + + function readTemplate (id) { + id = path.join(defaults.base, id + defaults.extname); + + if (id.indexOf(defaults.base) !== 0) { + // 安全限制:禁止超出模板目录之外调用文件 + throw new Error('"' + id + '" is not in the template directory'); + } else { + try { + return fs.readFileSync(id, defaults.encoding); + } catch (e) {} + } + } + + + // 重写模板`include``语句实现方法,转换模板为绝对路径 + template.utils.$include = function (filename, data, from) { + + from = path.dirname(from); + filename = path.join(from, filename); + + return template.renderFile(filename, data); + } + + + // express support + template.__express = function (file, options, fn) { + + if (typeof options === 'function') { + fn = options; + options = {}; + } + + + if (!rExtname) { + // 去掉 express 传入的路径 + rExtname = new RegExp((defaults.extname + '$').replace(/\./g, '\\.')); + } + + + file = file.replace(rExtname, ''); + + options.filename = file; + fn(null, template.renderFile(file, options)); + }; + + + return template; +} \ No newline at end of file diff --git a/public/assets/libs/art-template/node/template-native.js b/public/assets/libs/art-template/node/template-native.js new file mode 100644 index 0000000000000000000000000000000000000000..046e37fd37a855a77dbb390e503a13b4c6e39ed6 --- /dev/null +++ b/public/assets/libs/art-template/node/template-native.js @@ -0,0 +1,9 @@ +/*! + * artTemplate[NodeJS] + * https://github.com/aui/artTemplate + * Released under the MIT, BSD, and GPL Licenses + */ + +var node = require('./_node.js'); +var template = require('../dist/template-native-debug.js'); +module.exports = node(template); \ No newline at end of file diff --git a/public/assets/libs/art-template/node/template.js b/public/assets/libs/art-template/node/template.js new file mode 100644 index 0000000000000000000000000000000000000000..ce46a0a0f4034395f1c155507903e6239b7cfe01 --- /dev/null +++ b/public/assets/libs/art-template/node/template.js @@ -0,0 +1,9 @@ +/*! + * artTemplate[NodeJS] + * https://github.com/aui/artTemplate + * Released under the MIT, BSD, and GPL Licenses + */ + +var node = require('./_node.js'); +var template = require('../dist/template-debug.js'); +module.exports = node(template); \ No newline at end of file diff --git a/public/assets/libs/art-template/package.json b/public/assets/libs/art-template/package.json new file mode 100644 index 0000000000000000000000000000000000000000..9c771fe8f7dae03efb7fb39e49768d67f9a1f9be --- /dev/null +++ b/public/assets/libs/art-template/package.json @@ -0,0 +1,29 @@ +{ + "name": "art-template", + "description": "JavaScript Template Engine", + "version": "3.1.3", + "homepage": "http://aui.github.com/artTemplate/", + "keywords": [ + "util", + "functional", + "template" + ], + "author": "tangbin ", + "repository": { + "type": "git", + "url": "git://github.com/aui/artTemplate.git" + }, + "main": "./node/template.js", + "devDependencies": { + "express": "~4.4.3", + "grunt-cli": "*", + "grunt": "*", + "grunt-contrib-jshint": "*", + "grunt-contrib-concat": "*", + "grunt-contrib-uglify": "*" + }, + "scripts": { + "build": "grunt" + }, + "license": "BSD" +} diff --git a/public/assets/libs/art-template/src/cache.js b/public/assets/libs/art-template/src/cache.js new file mode 100644 index 0000000000000000000000000000000000000000..c663e1a7712dc802c615d9dcf671af7f72864656 --- /dev/null +++ b/public/assets/libs/art-template/src/cache.js @@ -0,0 +1,3 @@ +var cacheStore = template.cache = {}; + + diff --git a/public/assets/libs/art-template/src/compile.js b/public/assets/libs/art-template/src/compile.js new file mode 100644 index 0000000000000000000000000000000000000000..7873f19225f7634d11f3aea8a5328f93bddc8d60 --- /dev/null +++ b/public/assets/libs/art-template/src/compile.js @@ -0,0 +1,366 @@ +/** + * 编译模板 + * 2012-6-6 @TooBug: define 方法名改为 compile,与 Node Express 保持一致 + * @name template.compile + * @param {String} 模板字符串 + * @param {Object} 编译选项 + * + * - openTag {String} + * - closeTag {String} + * - filename {String} + * - escape {Boolean} + * - compress {Boolean} + * - debug {Boolean} + * - cache {Boolean} + * - parser {Function} + * + * @return {Function} 渲染方法 + */ +var compile = template.compile = function (source, options) { + + // 合并默认配置 + options = options || {}; + for (var name in defaults) { + if (options[name] === undefined) { + options[name] = defaults[name]; + } + } + + + var filename = options.filename; + + + try { + + var Render = compiler(source, options); + + } catch (e) { + + e.filename = filename || 'anonymous'; + e.name = 'Syntax Error'; + + return showDebugInfo(e); + + } + + + // 对编译结果进行一次包装 + + function render (data) { + + try { + + return new Render(data, filename) + ''; + + } catch (e) { + + // 运行时出错后自动开启调试模式重新编译 + if (!options.debug) { + options.debug = true; + return compile(source, options)(data); + } + + return showDebugInfo(e)(); + + } + + } + + + render.prototype = Render.prototype; + render.toString = function () { + return Render.toString(); + }; + + + if (filename && options.cache) { + cacheStore[filename] = render; + } + + + return render; + +}; + + + + +// 数组迭代 +var forEach = utils.$each; + + +// 静态分析模板变量 +var KEYWORDS = + // 关键字 + 'break,case,catch,continue,debugger,default,delete,do,else,false' + + ',finally,for,function,if,in,instanceof,new,null,return,switch,this' + + ',throw,true,try,typeof,var,void,while,with' + + // 保留字 + + ',abstract,boolean,byte,char,class,const,double,enum,export,extends' + + ',final,float,goto,implements,import,int,interface,long,native' + + ',package,private,protected,public,short,static,super,synchronized' + + ',throws,transient,volatile' + + // ECMA 5 - use strict + + ',arguments,let,yield' + + + ',undefined'; + +var REMOVE_RE = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g; +var SPLIT_RE = /[^\w$]+/g; +var KEYWORDS_RE = new RegExp(["\\b" + KEYWORDS.replace(/,/g, '\\b|\\b') + "\\b"].join('|'), 'g'); +var NUMBER_RE = /^\d[^,]*|,\d[^,]*/g; +var BOUNDARY_RE = /^,+|,+$/g; +var SPLIT2_RE = /^$|,+/; + + +// 获取变量 +function getVariable (code) { + return code + .replace(REMOVE_RE, '') + .replace(SPLIT_RE, ',') + .replace(KEYWORDS_RE, '') + .replace(NUMBER_RE, '') + .replace(BOUNDARY_RE, '') + .split(SPLIT2_RE); +}; + + +// 字符串转义 +function stringify (code) { + return "'" + code + // 单引号与反斜杠转义 + .replace(/('|\\)/g, '\\$1') + // 换行符转义(windows + linux) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + "'"; +} + + +function compiler (source, options) { + + var debug = options.debug; + var openTag = options.openTag; + var closeTag = options.closeTag; + var parser = options.parser; + var compress = options.compress; + var escape = options.escape; + + + + var line = 1; + var uniq = {$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1}; + + + + var isNewEngine = ''.trim;// '__proto__' in {} + var replaces = isNewEngine + ? ["$out='';", "$out+=", ";", "$out"] + : ["$out=[];", "$out.push(", ");", "$out.join('')"]; + + var concat = isNewEngine + ? "$out+=text;return $out;" + : "$out.push(text);"; + + var print = "function(){" + + "var text=''.concat.apply('',arguments);" + + concat + + "}"; + + var include = "function(filename,data){" + + "data=data||$data;" + + "var text=$utils.$include(filename,data,$filename);" + + concat + + "}"; + + var headerCode = "'use strict';" + + "var $utils=this,$helpers=$utils.$helpers," + + (debug ? "$line=0," : ""); + + var mainCode = replaces[0]; + + var footerCode = "return new String(" + replaces[3] + ");" + + // html与逻辑语法分离 + forEach(source.split(openTag), function (code) { + code = code.split(closeTag); + + var $0 = code[0]; + var $1 = code[1]; + + // code: [html] + if (code.length === 1) { + + mainCode += html($0); + + // code: [logic, html] + } else { + + mainCode += logic($0); + + if ($1) { + mainCode += html($1); + } + } + + + }); + + var code = headerCode + mainCode + footerCode; + + // 调试语句 + if (debug) { + code = "try{" + code + "}catch(e){" + + "throw {" + + "filename:$filename," + + "name:'Render Error'," + + "message:e.message," + + "line:$line," + + "source:" + stringify(source) + + ".split(/\\n/)[$line-1].replace(/^\\s+/,'')" + + "};" + + "}"; + } + + + + try { + + + var Render = new Function("$data", "$filename", code); + Render.prototype = utils; + + return Render; + + } catch (e) { + e.temp = "function anonymous($data,$filename) {" + code + "}"; + throw e; + } + + + + + // 处理 HTML 语句 + function html (code) { + + // 记录行号 + line += code.split(/\n/).length - 1; + + // 压缩多余空白与注释 + if (compress) { + code = code + .replace(/\s+/g, ' ') + .replace(//g, ''); + } + + if (code) { + code = replaces[1] + stringify(code) + replaces[2] + "\n"; + } + + return code; + } + + + // 处理逻辑语句 + function logic (code) { + + var thisLine = line; + + if (parser) { + + // 语法转换插件钩子 + code = parser(code, options); + + } else if (debug) { + + // 记录行号 + code = code.replace(/\n/g, function () { + line ++; + return "$line=" + line + ";"; + }); + + } + + + // 输出语句. 编码: <%=value%> 不编码:<%=#value%> + // <%=#value%> 等同 v2.0.3 之前的 <%==value%> + if (code.indexOf('=') === 0) { + + var escapeSyntax = escape && !/^=[=#]/.test(code); + + code = code.replace(/^=[=#]?|[\s;]*$/g, ''); + + // 对内容编码 + if (escapeSyntax) { + + var name = code.replace(/\s*\([^\)]+\)/, ''); + + // 排除 utils.* | include | print + + if (!utils[name] && !/^(include|print)$/.test(name)) { + code = "$escape(" + code + ")"; + } + + // 不编码 + } else { + code = "$string(" + code + ")"; + } + + + code = replaces[1] + code + replaces[2]; + + } + + if (debug) { + code = "$line=" + thisLine + ";" + code; + } + + // 提取模板中的变量名 + forEach(getVariable(code), function (name) { + + // name 值可能为空,在安卓低版本浏览器下 + if (!name || uniq[name]) { + return; + } + + var value; + + // 声明模板变量 + // 赋值优先级: + // [include, print] > utils > helpers > data + if (name === 'print') { + + value = print; + + } else if (name === 'include') { + + value = include; + + } else if (utils[name]) { + + value = "$utils." + name; + + } else if (helpers[name]) { + + value = "$helpers." + name; + + } else { + + value = "$data." + name; + } + + headerCode += name + "=" + value + ","; + uniq[name] = true; + + + }); + + return code + "\n"; + } + + +}; + + + diff --git a/public/assets/libs/art-template/src/config.js b/public/assets/libs/art-template/src/config.js new file mode 100644 index 0000000000000000000000000000000000000000..c978311430c09c86ceb9423f071e02ac7b2a2f3e --- /dev/null +++ b/public/assets/libs/art-template/src/config.js @@ -0,0 +1,22 @@ +/** + * 设置全局配置 + * @name template.config + * @param {String} 名称 + * @param {Any} 值 + */ +template.config = function (name, value) { + defaults[name] = value; +}; + + + +var defaults = template.defaults = { + openTag: '<%', // 逻辑语法开始标签 + closeTag: '%>', // 逻辑语法结束标签 + escape: true, // 是否编码输出变量的 HTML 字符 + cache: true, // 是否开启缓存(依赖 options 的 filename 字段) + compress: false, // 是否压缩输出 + parser: null // 自定义语法格式器 @see: template-syntax.js +}; + + diff --git a/public/assets/libs/art-template/src/get.js b/public/assets/libs/art-template/src/get.js new file mode 100644 index 0000000000000000000000000000000000000000..d91deb19d8df9e29e4cea686235c2dbf3bacc1cd --- /dev/null +++ b/public/assets/libs/art-template/src/get.js @@ -0,0 +1,29 @@ +/** + * 获取编译缓存(可由外部重写此方法) + * @param {String} 模板名 + * @param {Function} 编译好的函数 + */ +template.get = function (filename) { + + var cache; + + if (cacheStore[filename]) { + // 使用内存缓存 + cache = cacheStore[filename]; + } else if (typeof document === 'object') { + // 加载模板并编译 + var elem = document.getElementById(filename); + + if (elem) { + var source = (elem.value || elem.innerHTML) + .replace(/^\s*|\s*$/g, ''); + cache = compile(source, { + filename: filename + }); + } + } + + return cache; +}; + + diff --git a/public/assets/libs/art-template/src/helper.js b/public/assets/libs/art-template/src/helper.js new file mode 100644 index 0000000000000000000000000000000000000000..dd99afd58c9b7f2a09f24e10bc6e1a62e159680f --- /dev/null +++ b/public/assets/libs/art-template/src/helper.js @@ -0,0 +1,15 @@ +/** + * 添加模板辅助方法 + * @name template.helper + * @param {String} 名称 + * @param {Function} 方法 + */ +template.helper = function (name, helper) { + helpers[name] = helper; +}; + +var helpers = template.helpers = utils.$helpers; + + + + diff --git a/public/assets/libs/art-template/src/intro.js b/public/assets/libs/art-template/src/intro.js new file mode 100644 index 0000000000000000000000000000000000000000..f5afc937a885ea600fba50fd7fa00bfdd35fbcf1 --- /dev/null +++ b/public/assets/libs/art-template/src/intro.js @@ -0,0 +1,9 @@ +/*! + * artTemplate - Template Engine + * https://github.com/aui/artTemplate + * Released under the MIT, BSD, and GPL Licenses + */ + +!(function () { + + diff --git a/public/assets/libs/art-template/src/onerror.js b/public/assets/libs/art-template/src/onerror.js new file mode 100644 index 0000000000000000000000000000000000000000..c08e37c4337396bce79b0c73ff32a8191e90848d --- /dev/null +++ b/public/assets/libs/art-template/src/onerror.js @@ -0,0 +1,28 @@ +/** + * 模板错误事件(可由外部重写此方法) + * @name template.onerror + * @event + */ +template.onerror = function (e) { + var message = 'Template Error\n\n'; + for (var name in e) { + message += '<' + name + '>\n' + e[name] + '\n\n'; + } + + if (typeof console === 'object') { + console.error(message); + } +}; + + +// 模板调试器 +var showDebugInfo = function (e) { + + template.onerror(e); + + return function () { + return '{Template Error}'; + }; +}; + + diff --git a/public/assets/libs/art-template/src/outro.js b/public/assets/libs/art-template/src/outro.js new file mode 100644 index 0000000000000000000000000000000000000000..4ee8e47f4ac60a0de7a5fba8f207283b03e8b828 --- /dev/null +++ b/public/assets/libs/art-template/src/outro.js @@ -0,0 +1,13 @@ +// CommonJs +if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = template; +// RequireJS && SeaJS +} else if (typeof define === 'function') { + define(function() { + return template; + }); +} else { + this.template = template; +} + +})(); diff --git a/public/assets/libs/art-template/src/render.js b/public/assets/libs/art-template/src/render.js new file mode 100644 index 0000000000000000000000000000000000000000..b90b01a1f324c928fa77edf9466f15d6627b9b6e --- /dev/null +++ b/public/assets/libs/art-template/src/render.js @@ -0,0 +1,12 @@ +/** + * 渲染模板 + * @name template.render + * @param {String} 模板 + * @param {Object} 数据 + * @return {String} 渲染好的字符串 + */ +template.render = function (source, options) { + return compile(source)(options); +}; + + diff --git a/public/assets/libs/art-template/src/renderFile.js b/public/assets/libs/art-template/src/renderFile.js new file mode 100644 index 0000000000000000000000000000000000000000..ae9faacfbb2591e7ea6e25404c38c70d5e7fe14c --- /dev/null +++ b/public/assets/libs/art-template/src/renderFile.js @@ -0,0 +1,17 @@ +/** + * 渲染模板(根据模板名) + * @name template.render + * @param {String} 模板名 + * @param {Object} 数据 + * @return {String} 渲染好的字符串 + */ +var renderFile = template.renderFile = function (filename, data) { + var fn = template.get(filename) || showDebugInfo({ + filename: filename, + name: 'Render Error', + message: 'Template not found' + }); + return data ? fn(data) : fn; +}; + + diff --git a/public/assets/libs/art-template/src/syntax.js b/public/assets/libs/art-template/src/syntax.js new file mode 100644 index 0000000000000000000000000000000000000000..7aff672d25e3f9cd916cace105944d0e4cd59f17 --- /dev/null +++ b/public/assets/libs/art-template/src/syntax.js @@ -0,0 +1,137 @@ +// 定义模板引擎的语法 + + +defaults.openTag = '{{'; +defaults.closeTag = '}}'; + + +var filtered = function (js, filter) { + var parts = filter.split(':'); + var name = parts.shift(); + var args = parts.join(':') || ''; + + if (args) { + args = ', ' + args; + } + + return '$helpers.' + name + '(' + js + args + ')'; +} + + +defaults.parser = function (code, options) { + + // var match = code.match(/([\w\$]*)(\b.*)/); + // var key = match[1]; + // var args = match[2]; + // var split = args.split(' '); + // split.shift(); + + code = code.replace(/^\s/, ''); + + var split = code.split(' '); + var key = split.shift(); + var args = split.join(' '); + + + + switch (key) { + + case 'if': + + code = 'if(' + args + '){'; + break; + + case 'else': + + if (split.shift() === 'if') { + split = ' if(' + split.join(' ') + ')'; + } else { + split = ''; + } + + code = '}else' + split + '{'; + break; + + case '/if': + + code = '}'; + break; + + case 'each': + + var object = split[0] || '$data'; + var as = split[1] || 'as'; + var value = split[2] || '$value'; + var index = split[3] || '$index'; + + var param = value + ',' + index; + + if (as !== 'as') { + object = '[]'; + } + + code = '$each(' + object + ',function(' + param + '){'; + break; + + case '/each': + + code = '});'; + break; + + case 'echo': + + code = 'print(' + args + ');'; + break; + + case 'print': + case 'include': + + code = key + '(' + split.join(',') + ');'; + break; + + default: + + // 过滤器(辅助方法) + // {{value | filterA:'abcd' | filterB}} + // >>> $helpers.filterB($helpers.filterA(value, 'abcd')) + // TODO: {{ddd||aaa}} 不包含空格 + if (/^\s*\|\s*[\w\$]/.test(args)) { + + var escape = true; + + // {{#value | link}} + if (code.indexOf('#') === 0) { + code = code.substr(1); + escape = false; + } + + var i = 0; + var array = code.split('|'); + var len = array.length; + var val = array[i++]; + + for (; i < len; i ++) { + val = filtered(val, array[i]); + } + + code = (escape ? '=' : '=#') + val; + + // 即将弃用 {{helperName value}} + } else if (template.helpers[key]) { + + code = '=#' + key + '(' + split.join(',') + ');'; + + // 内容直接输出 {{value}} + } else { + + code = '=' + code; + } + + break; + } + + + return code; +}; + + diff --git a/public/assets/libs/art-template/src/template.js b/public/assets/libs/art-template/src/template.js new file mode 100644 index 0000000000000000000000000000000000000000..52e46c424b6c24b04fc6c5c1963b1545077b5c6c --- /dev/null +++ b/public/assets/libs/art-template/src/template.js @@ -0,0 +1,19 @@ +/** + * 模板引擎 + * @name template + * @param {String} 模板名 + * @param {Object, String} 数据。如果为字符串则编译并缓存编译结果 + * @return {String, Function} 渲染好的HTML字符串或者渲染方法 + */ +var template = function (filename, content) { + return typeof content === 'string' + ? compile(content, { + filename: filename + }) + : renderFile(filename, content); +}; + + +template.version = '3.0.0'; + + diff --git a/public/assets/libs/art-template/src/utils.js b/public/assets/libs/art-template/src/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..bf48b4c5544a09b40fc3f8f330d4ceeb4e8445b0 --- /dev/null +++ b/public/assets/libs/art-template/src/utils.js @@ -0,0 +1,70 @@ +var toString = function (value, type) { + + if (typeof value !== 'string') { + + type = typeof value; + if (type === 'number') { + value += ''; + } else if (type === 'function') { + value = toString(value.call(value)); + } else { + value = ''; + } + } + + return value; + +}; + + +var escapeMap = { + "<": "<", + ">": ">", + '"': """, + "'": "'", + "&": "&" +}; + + +var escapeFn = function (s) { + return escapeMap[s]; +}; + +var escapeHTML = function (content) { + return toString(content) + .replace(/&(?![\w#]+;)|[<>"']/g, escapeFn); +}; + + +var isArray = Array.isArray || function (obj) { + return ({}).toString.call(obj) === '[object Array]'; +}; + + +var each = function (data, callback) { + var i, len; + if (isArray(data)) { + for (i = 0, len = data.length; i < len; i++) { + callback.call(data, data[i], i, data); + } + } else { + for (i in data) { + callback.call(data, data[i], i); + } + } +}; + + +var utils = template.utils = { + + $helpers: {}, + + $include: renderFile, + + $string: toString, + + $escape: escapeHTML, + + $each: each + +}; \ No newline at end of file diff --git a/public/assets/libs/art-template/test/js/baiduTemplate.js b/public/assets/libs/art-template/test/js/baiduTemplate.js new file mode 100644 index 0000000000000000000000000000000000000000..2f05969e36b5385476a08e75c6dbebe71a8f032f --- /dev/null +++ b/public/assets/libs/art-template/test/js/baiduTemplate.js @@ -0,0 +1,216 @@ +/** + * baiduTemplate简单好用的Javascript模板引擎 1.0.6 版本 + * http://baidufe.github.com/BaiduTemplate + * 开源协议:BSD License + * 浏览器环境占用命名空间 baidu.template ,nodejs环境直接安装 npm install baidutemplate + * @param str{String} dom结点ID,或者模板string + * @param data{Object} 需要渲染的json对象,可以为空。当data为{}时,仍然返回html。 + * @return 如果无data,直接返回编译后的函数;如果有data,返回html。 + * @author wangxiao + * @email 1988wangxiao@gmail.com +*/ + +;(function(window){ + + //取得浏览器环境的baidu命名空间,非浏览器环境符合commonjs规范exports出去 + //修正在nodejs环境下,采用baidu.template变量名 + var baidu = typeof module === 'undefined' ? (window.baidu = window.baidu || {}) : module.exports; + + //模板函数(放置于baidu.template命名空间下) + baidu.template = function(str, data){ + + //检查是否有该id的元素存在,如果有元素则获取元素的innerHTML/value,否则认为字符串为模板 + var fn = (function(){ + + //判断如果没有document,则为非浏览器环境 + if(!window.document){ + return bt._compile(str); + }; + + //HTML5规定ID可以由任何不包含空格字符的字符串组成 + var element = document.getElementById(str); + if (element) { + + //取到对应id的dom,缓存其编译后的HTML模板函数 + if (bt.cache[str]) { + return bt.cache[str]; + }; + + //textarea或input则取value,其它情况取innerHTML + var html = /^(textarea|input)$/i.test(element.nodeName) ? element.value : element.innerHTML; + return bt._compile(html); + + }else{ + + //是模板字符串,则生成一个函数 + //如果直接传入字符串作为模板,则可能变化过多,因此不考虑缓存 + return bt._compile(str); + }; + + })(); + + //有数据则返回HTML字符串,没有数据则返回函数 支持data={}的情况 + var result = bt._isObject(data) ? fn( data ) : fn; + fn = null; + + return result; + }; + + //取得命名空间 baidu.template + var bt = baidu.template; + + //标记当前版本 + bt.versions = bt.versions || []; + bt.versions.push('1.0.6'); + + //缓存 将对应id模板生成的函数缓存下来。 + bt.cache = {}; + + //自定义分隔符,可以含有正则中的字符,可以是HTML注释开头 + bt.LEFT_DELIMITER = bt.LEFT_DELIMITER||'<%'; + bt.RIGHT_DELIMITER = bt.RIGHT_DELIMITER||'%>'; + + //自定义默认是否转义,默认为默认自动转义 + bt.ESCAPE = true; + + //HTML转义 + bt._encodeHTML = function (source) { + return String(source) + .replace(/&/g,'&') + .replace(//g,'>') + .replace(/\\/g,'\') + .replace(/"/g,'"') + .replace(/'/g,'''); + }; + + //转义影响正则的字符 + bt._encodeReg = function (source) { + return String(source).replace(/([.*+?^=!:${}()|[\]/\\])/g,'\\$1'); + }; + + //转义UI UI变量使用在HTML页面标签onclick等事件函数参数中 + bt._encodeEventHTML = function (source) { + return String(source) + .replace(/&/g,'&') + .replace(//g,'>') + .replace(/"/g,'"') + .replace(/'/g,''') + .replace(/\\\\/g,'\\') + .replace(/\\\//g,'\/') + .replace(/\\n/g,'\n') + .replace(/\\r/g,'\r'); + }; + + //将字符串拼接生成函数,即编译过程(compile) + bt._compile = function(str){ + var funBody = "var _template_fun_array=[];\nvar fn=(function(__data__){\nvar _template_varName='';\nfor(name in __data__){\n_template_varName+=('var '+name+'=__data__[\"'+name+'\"];');\n};\neval(_template_varName);\n_template_fun_array.push('"+bt._analysisStr(str)+"');\n_template_varName=null;\n})(_template_object);\nfn = null;\nreturn _template_fun_array.join('');\n"; + return new Function("_template_object",funBody); + }; + + //判断是否是Object类型 + bt._isObject = function (source) { + return 'function' === typeof source || !!(source && 'object' === typeof source); + }; + + //解析模板字符串 + bt._analysisStr = function(str){ + + //取得分隔符 + var _left_ = bt.LEFT_DELIMITER; + var _right_ = bt.RIGHT_DELIMITER; + + //对分隔符进行转义,支持正则中的元字符,可以是HTML注释 + var _left = bt._encodeReg(_left_); + var _right = bt._encodeReg(_right_); + + str = String(str) + + //去掉分隔符中js注释 + .replace(new RegExp("("+_left+"[^"+_right+"]*)//.*\n","g"), "$1") + + //去掉注释内容 <%* 这里可以任意的注释 *%> + //默认支持HTML注释,将HTML注释匹配掉的原因是用户有可能用 来做分割符 + .replace(new RegExp("", "g"),"") + .replace(new RegExp(_left+"\\*.*?\\*"+_right, "g"),"") + + //把所有换行去掉 \r回车符 \t制表符 \n换行符 + .replace(new RegExp("[\\r\\t\\n]","g"), "") + + //用来处理非分隔符内部的内容中含有 斜杠 \ 单引号 ‘ ,处理办法为HTML转义 + .replace(new RegExp(_left+"(?:(?!"+_right+")[\\s\\S])*"+_right+"|((?:(?!"+_left+")[\\s\\S])+)","g"),function (item, $1) { + var str = ''; + if($1){ + + //将 斜杠 单引 HTML转义 + str = $1.replace(/\\/g,"\").replace(/'/g,'''); + while(/<[^<]*?'[^<]*?>/g.test(str)){ + + //将标签内的单引号转义为\r 结合最后一步,替换为\' + str = str.replace(/(<[^<]*?)'([^<]*?>)/g,'$1\r$2') + }; + }else{ + str = item; + } + return str ; + }); + + + str = str + //定义变量,如果没有分号,需要容错 <%var val='test'%> + .replace(new RegExp("("+_left+"[\\s]*?var[\\s]*?.*?[\\s]*?[^;])[\\s]*?"+_right,"g"),"$1;"+_right_) + + //对变量后面的分号做容错(包括转义模式 如<%:h=value%>) <%=value;%> 排除掉函数的情况 <%fun1();%> 排除定义变量情况 <%var val='test';%> + .replace(new RegExp("("+_left+":?[hvu]?[\\s]*?=[\\s]*?[^;|"+_right+"]*?);[\\s]*?"+_right,"g"),"$1"+_right_) + + //按照 <% 分割为一个个数组,再用 \t 和在一起,相当于将 <% 替换为 \t + //将模板按照<%分为一段一段的,再在每段的结尾加入 \t,即用 \t 将每个模板片段前面分隔开 + .split(_left_).join("\t"); + + //支持用户配置默认是否自动转义 + if(bt.ESCAPE){ + str = str + + //找到 \t=任意一个字符%> 替换为 ‘,任意字符,' + //即替换简单变量 \t=data%> 替换为 ',data,' + //默认HTML转义 也支持HTML转义写法<%:h=value%> + .replace(new RegExp("\\t=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':baidu.template._encodeHTML($1),'"); + }else{ + str = str + + //默认不转义HTML转义 + .replace(new RegExp("\\t=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':$1,'"); + }; + + str = str + + //支持HTML转义写法<%:h=value%> + .replace(new RegExp("\\t:h=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':baidu.template._encodeHTML($1),'") + + //支持不转义写法 <%:=value%>和<%-value%> + .replace(new RegExp("\\t(?::=|-)(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':$1,'") + + //支持url转义 <%:u=value%> + .replace(new RegExp("\\t:u=(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':encodeURIComponent($1),'") + + //支持UI 变量使用在HTML页面标签onclick等事件函数参数中 <%:v=value%> + .replace(new RegExp("\\t:v=(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':baidu.template._encodeEventHTML($1),'") + + //将字符串按照 \t 分成为数组,在用'); 将其合并,即替换掉结尾的 \t 为 '); + //在if,for等语句前面加上 '); ,形成 ');if ');for 的形式 + .split("\t").join("');") + + //将 %> 替换为_template_fun_array.push(' + //即去掉结尾符,生成函数中的push方法 + //如:if(list.length=5){%>

            ',list[4],'

            ');} + //会被替换为 if(list.length=5){_template_fun_array.push('

            ',list[4],'

            ');} + .split(_right_).join("_template_fun_array.push('") + + //将 \r 替换为 \ + .split("\r").join("\\'"); + + return str; + }; + +})(window); diff --git a/public/assets/libs/art-template/test/js/doT.js b/public/assets/libs/art-template/test/js/doT.js new file mode 100644 index 0000000000000000000000000000000000000000..12ecd42e413739439c7c8c4cec555ee7fb74769f --- /dev/null +++ b/public/assets/libs/art-template/test/js/doT.js @@ -0,0 +1,101 @@ +// doT.js +// 2011, Laura Doktorova +// https://github.com/olado/doT +// +// doT.js is an open source component of http://bebedo.com +// +// doT is a custom blend of templating functions from jQote2.js +// (jQuery plugin) by aefxx (http://aefxx.com/jquery-plugins/jqote2/) +// and underscore.js (http://documentcloud.github.com/underscore/) +// plus extensions. +// +// Licensed under the MIT license. +// +(function() { + var doT = { version : '0.1.7' }; + + if (typeof module !== 'undefined' && module.exports) { + module.exports = doT; + } else { + this.doT = doT; + } + + doT.templateSettings = { + evaluate: /\{\{([\s\S]+?)\}\}/g, + interpolate: /\{\{=([\s\S]+?)\}\}/g, + encode: /\{\{!([\s\S]+?)\}\}/g, + use: /\{\{#([\s\S]+?)\}\}/g, //compile time evaluation + define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g, //compile time defs + conditionalStart: /\{\{\?([\s\S]+?)\}\}/g, + conditionalEnd: /\{\{\?\}\}/g, + varname: 'it', + strip : true, + append: true + }; + + function resolveDefs(c, block, def) { + return ((typeof block === 'string') ? block : block.toString()) + .replace(c.define, function (match, code, assign, value) { + if (code.indexOf('def.') === 0) { + code = code.substring(4); + } + if (!(code in def)) { + if (assign === ':') { + def[code]= value; + } else { + eval("def[code]=" + value); + } + } + return ''; + }) + .replace(c.use, function(match, code) { + var v = eval(code); + return v ? resolveDefs(c, v, def) : v; + }); + } + + doT.template = function(tmpl, c, def) { + c = c || doT.templateSettings; + var cstart = c.append ? "'+(" : "';out+=(", // optimal choice depends on platform/size of templates + cend = c.append ? ")+'" : ");out+='"; + var str = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl; + + str = ("var out='" + + ((c.strip) ? str.replace(/\s*\s*|[\r\n\t]|(\/\*[\s\S]*?\*\/)/g, ''): str) + .replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(c.interpolate, function(match, code) { + return cstart + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + cend; + }) + .replace(c.encode, function(match, code) { + return cstart + code.replace(/\\'/g, "'").replace(/\\\\/g, "\\").replace(/[\r\t\n]/g, ' ') + ").toString().replace(/&(?!\\w+;)/g, '&').split('<').join('<').split('>').join('>').split('" + '"' + "').join('"').split(" + '"' + "'" + '"' + ").join(''').split('/').join('/'" + cend; + }) + .replace(c.conditionalEnd, function(match, expression) { + return "';}out+='"; + }) + .replace(c.conditionalStart, function(match, expression) { + var code = "if(" + expression + "){"; + return "';" + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + "out+='"; + }) + .replace(c.evaluate, function(match, code) { + return "';" + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + "out+='"; + }) + + "';return out;") + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + .replace(/\r/g, '\\r') + .split("out+='';").join('') + .split("var out='';out+=").join('var out='); + + try { + return new Function(c.varname, str); + } catch (e) { + if (typeof console !== 'undefined') console.log("Could not create a template function: " + str); + throw e; + } + }; + + doT.compile = function(tmpl, def) { + return doT.template(tmpl, null, def); + }; +}()); \ No newline at end of file diff --git a/public/assets/libs/art-template/test/js/easytemplate.js b/public/assets/libs/art-template/test/js/easytemplate.js new file mode 100644 index 0000000000000000000000000000000000000000..2bfdd94d957ad104a1abeb45be23da96294506f8 --- /dev/null +++ b/public/assets/libs/art-template/test/js/easytemplate.js @@ -0,0 +1,55 @@ +var easyTemplate = function(s,d){ + if(!s){return '';} + if(s!==easyTemplate.template){ + easyTemplate.template = s; + easyTemplate.aStatement = easyTemplate.parsing(easyTemplate.separate(s)); + } + var aST = easyTemplate.aStatement; + var process = function(d2){ + if(d2){d = d2;} + return arguments.callee; + }; + process.toString = function(){ + return (new Function(aST[0],aST[1]))(d); + }; + return process; +}; +easyTemplate.separate = function(s){ + var r = /\\'/g; + var sRet = s.replace(/(<(\/?)#(.*?(?:\(.*?\))*)>)|(')|([\r\n\t])|(\$\{([^\}]*?)\})/g,function(a,b,c,d,e,f,g,h){ + if(b){return '{|}'+(c?'-':'+')+d+'{|}';} + if(e){return '\\\'';} + if(f){return '';} + if(g){return '\'+('+h.replace(r,'\'')+')+\'';} + }); + return sRet; +}; +easyTemplate.parsing = function(s){ + var mName,vName,sTmp,aTmp,sFL,sEl,aList,aStm = ['var aRet = [];']; + aList = s.split(/\{\|\}/); + var r = /\s/; + while(aList.length){ + sTmp = aList.shift(); + if(!sTmp){continue;} + sFL = sTmp.charAt(0); + if(sFL!=='+'&&sFL!=='-'){ + sTmp = '\''+sTmp+'\'';aStm.push('aRet.push('+sTmp+');'); + continue; + } + aTmp = sTmp.split(r); + switch(aTmp[0]){ + case '+macro':mName = aTmp[1];vName = aTmp[2];aStm.push('aRet.push(" 和 变量替换串:${...} 的解析 + * + * @inner + * @param {string} source 要解析的文本 + * @param {string} open 包含块开头 + * @param {string} close 包含块结束 + * @param {boolean} greedy 是否贪婪匹配 + * @param {function({string})} onInBlock 包含块内文本的处理函数 + * @param {function({string})} onOutBlock 非包含块内文本的处理函数 + */ + function parseTextBlock( source, open, close, greedy, onInBlock, onOutBlock ) { + var closeLen = close.length; + var texts = source.split( open ); + var level = 0; + var buf = []; + + for ( var i = 0, len = texts.length; i < len; i++ ) { + var text = texts[ i ]; + + if ( i ) { + var openBegin = 1; + level++; + while ( 1 ) { + var closeIndex = text.indexOf( close ); + if ( closeIndex < 0 ) { + buf.push( level > 1 && openBegin ? open : '', text ); + break; + } + + level = greedy ? level - 1 : 0; + buf.push( + level > 0 && openBegin ? open : '', + text.slice( 0, closeIndex ), + level > 0 ? close : '' + ); + text = text.slice( closeIndex + closeLen ); + openBegin = 0; + + if ( level === 0 ) { + break; + } + } + + if ( level === 0 ) { + onInBlock( buf.join( '' ) ); + onOutBlock( text ); + buf = []; + } + } + else { + text && onOutBlock( text ); + } + } + + if ( level > 0 && buf.length > 0 ) { + onOutBlock( open ); + onOutBlock( buf.join( '' ) ); + } + } + + /** + * 编译变量访问和变量替换的代码 + * 用于普通文本或if、var、filter等命令生成编译代码 + * + * @inner + * @param {string} source 源代码 + * @param {Engine} engine 引擎实例 + * @param {boolean} forText 是否为输出文本的变量替换 + * @return {string} + */ + function compileVariable( source, engine, forText ) { + var code = []; + var options = engine.options; + + var toStringHead = ''; + var toStringFoot = ''; + var wrapHead = ''; + var wrapFoot = ''; + + // 默认的filter,当forText模式时有效 + var defaultFilter; + + if ( forText ) { + toStringHead = 'ts('; + toStringFoot = ')'; + wrapHead = RENDER_STRING_ADD_START; + wrapFoot = RENDER_STRING_ADD_END; + defaultFilter = options.defaultFilter + } + + parseTextBlock( + source, options.variableOpen, options.variableClose, 1, + + function ( text ) { + // 加入默认filter + // 只有当处理forText时,需要加入默认filter + // 处理if/var/use等command时,不需要加入默认filter + if ( forText && text.indexOf( '|' ) < 0 && defaultFilter ) { + text += '|' + defaultFilter; + } + + // variableCode是一个gv调用,然后通过循环,在外面包filter的调用 + // 形成filter["b"](filter["a"](gv(...))) + // + // 当forText模式,处理的是文本中的变量替换时 + // 传递给filter的需要是字符串形式,所以gv外需要包一层ts调用 + // 形成filter["b"](filter["a"](ts(gv(...)))) + // + // 当variableName以*起始时,忽略ts调用,直接传递原值给filter + var filterCharIndex = text.indexOf( '|' ); + var variableName = (filterCharIndex > 0 + ? text.slice( 0, filterCharIndex ) + : text).replace( /^\s+/, '' ).replace( /\s+$/, '' ); + var filterSource = filterCharIndex > 0 + ? text.slice( filterCharIndex + 1 ) + : ''; + + var variableRawValue = variableName.indexOf( '*' ) === 0; + var variableCode = [ + variableRawValue ? '' : toStringHead, + toGetVariableLiteral( variableName ), + variableRawValue ? '' : toStringFoot + ]; + + if ( filterSource ) { + filterSource = compileVariable( filterSource, engine ); + var filterSegs = filterSource.split( '|' ); + for ( var i = 0, len = filterSegs.length; i < len; i++ ) { + var seg = filterSegs[ i ]; + + if ( /^\s*([a-z0-9_-]+)(\((.*)\))?\s*$/i.test( seg ) ) { + variableCode.unshift( 'fs["' + RegExp.$1 + '"](' ); + + if ( RegExp.$3 ) { + variableCode.push( + ',', + RegExp.$3 + ); + } + + variableCode.push( ')' ); + } + } + } + + code.push( + wrapHead, + variableCode.join( '' ), + wrapFoot + ); + }, + + function ( text ) { + code.push( + wrapHead, + forText ? stringLiteralize( text ) : text, + wrapFoot + ); + } + ); + + return code.join( '' ); + } + + /** + * 文本节点类 + * + * @inner + * @constructor + * @param {string} value 文本节点的内容文本 + * @param {Engine} engine 引擎实例 + */ + function TextNode( value, engine ) { + this.value = value; + this.engine = engine; + } + + TextNode.prototype = { + /** + * 获取renderer body的生成代码 + * + * @return {string} + */ + getRendererBody: function () { + var value = this.value; + var options = this.engine.options; + + if ( !value || ( options.strip && /^\s*$/.test( value ) ) ) { + return ''; + } + + return compileVariable( value, this.engine, 1 ); + }, + + /** + * 获取内容 + * + * @return {string} + */ + getContent: function () { + return this.value; + } + }; + + /** + * 命令节点类 + * + * @inner + * @constructor + * @param {string} value 命令节点的value + * @param {Engine} engine 引擎实例 + */ + function Command( value, engine ) { + this.value = value; + this.engine = engine; + this.children = []; + } + + Command.prototype = { + /** + * 添加子节点 + * + * @param {TextNode|Command} node 子节点 + */ + addChild: function ( node ) { + this.children.push( node ); + }, + + /** + * 节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + open: function ( context ) { + var parent = context.stack.top(); + this.parent = parent; + parent && parent.addChild( this ); + context.stack.push( this ); + }, + + /** + * 节点闭合,解析结束 + * + * @param {Object} context 语法分析环境对象 + */ + close: function ( context ) { + while (context.stack.pop().constructor !== this.constructor) {} + }, + + /** + * 添加文本节点 + * + * @param {TextNode} node 节点 + */ + addTextNode: function ( node ) { + this.addChild( node ); + }, + + /** + * 获取renderer body的生成代码 + * + * @return {string} + */ + getRendererBody: function () { + var buf = []; + var children = this.children; + for ( var i = 0; i < children.length; i++ ) { + buf.push( children[ i ].getRendererBody() ); + } + + return buf.join( '' ); + } + }; + + /** + * 命令自动闭合 + * + * @inner + * @param {Object} context 语法分析环境对象 + * @param {Function=} CommandType 自闭合的节点类型 + */ + function autoCloseCommand( context, CommandType ) { + var stack = context.stack; + var closeEnd = CommandType + ? stack.find( function ( item ) { + return item instanceof CommandType; + } ) + : stack.bottom(); + + if ( closeEnd ) { + var node; + + do { + node = stack.top(); + + // 如果节点对象不包含autoClose方法 + // 则认为该节点不支持自动闭合,需要抛出错误 + // for等节点不支持自动闭合 + if ( !node.autoClose ) { + throw new Error( node.type + ' must be closed manually: ' + node.value ); + } + node.autoClose( context ); + } while ( node !== closeEnd ); + } + + return closeEnd; + } + + /** + * renderer body起始代码段 + * + * @inner + * @const + * @type {string} + */ + var RENDERER_BODY_START = '' + + 'data=data||{};' + + 'var v={},fs=engine.filters,hg=typeof data.get=="function",' + + 'gv=function(n,ps){' + + 'var p=ps[0],d=v[p];' + + 'if(d==null){' + + 'if(hg){return data.get(n);}' + + 'd=data[p];' + + '}' + + 'for(var i=1,l=ps.length;i= TMNodeState.APPLIED ) { + return 1; + } + + var masterNode = this.engine.masters[ this.master ]; + if ( masterNode && masterNode.applyMaster() ) { + this.children = []; + + for ( var i = 0, len = masterNode.children.length; i < len; i++ ) { + var child = masterNode.children[ i ]; + + if ( child instanceof ContentPlaceHolderCommand ) { + this.children.push.apply( + this.children, + (this.contents[ child.name ] || child).children + ); + } + else { + this.children.push( child ); + } + } + + this.state = TMNodeState.APPLIED; + return 1; + } + }; + + /** + * 判断target是否ready + * 包括是否成功应用母版,以及import和use语句依赖的target是否ready + * + * @return {boolean} + */ + TargetCommand.prototype.isReady = function () { + if ( this.state >= TMNodeState.READY ) { + return 1; + } + + var engine = this.engine; + var readyState = 1; + + /** + * 递归检查节点的ready状态 + * + * @inner + * @param {Command|TextNode} node 目标节点 + */ + function checkReadyState( node ) { + for ( var i = 0, len = node.children.length; i < len; i++ ) { + var child = node.children[ i ]; + if ( child instanceof ImportCommand ) { + var target = engine.targets[ child.name ]; + readyState = readyState + && target && target.isReady( engine ); + } + else if ( child instanceof Command ) { + checkReadyState( child ); + } + } + } + + if ( this.applyMaster() ) { + checkReadyState( this ); + readyState && (this.state = TMNodeState.READY); + return readyState; + } + }; + + /** + * 获取target的renderer函数 + * + * @return {function(Object):string} + */ + TargetCommand.prototype.getRenderer = function () { + if ( this.renderer ) { + return this.renderer; + } + + if ( this.isReady() ) { + // console.log( this.name + ' ------------------' ); + // console.log(RENDERER_BODY_START +RENDER_STRING_DECLATION + // + this.getRendererBody() + // + RENDER_STRING_RETURN); + + var realRenderer = new Function( + 'data', 'engine', + [ + RENDERER_BODY_START, + RENDER_STRING_DECLATION, + this.getRendererBody(), + RENDER_STRING_RETURN + ].join( '\n' ) + ); + + var engine = this.engine; + this.renderer = function ( data ) { + return realRenderer( data, engine ); + }; + + return this.renderer; + } + + return null; + }; + + /** + * 获取内容 + * + * @return {string} + */ + TargetCommand.prototype.getContent = function () { + if ( this.isReady() ) { + var buf = []; + var children = this.children; + for ( var i = 0; i < children.length; i++ ) { + buf.push( children[ i ].getContent() ); + } + + return buf.join( '' ); + } + + return ''; + }; + + /** + * 将target或master节点对象添加到语法分析环境中 + * + * @inner + * @param {TargetCommand|MasterCommand} targetOrMaster target或master节点对象 + * @param {Object} context 语法分析环境对象 + */ + function addTargetOrMasterToContext( targetOrMaster, context ) { + context.targetOrMaster = targetOrMaster; + + var engine = context.engine; + var name = targetOrMaster.name; + var isTarget = targetOrMaster instanceof TargetCommand; + var prop = isTarget ? 'targets' : 'masters'; + + if ( engine[ prop ][ name ] ) { + switch ( engine.options.namingConflict ) { + case 'override': + engine[ prop ][ name ] = targetOrMaster; + isTarget && context.targets.push( name ); + case 'ignore': + break; + default: + throw new Error( ( isTarget ? 'Target' :'Master' ) + + ' is exists: ' + name ); + } + } + else { + engine[ prop ][ name ] = targetOrMaster; + isTarget && context.targets.push( name ); + } + } + + /** + * target节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + TargetCommand.prototype.open = + + /** + * master节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + MasterCommand.prototype.open = function ( context ) { + autoCloseCommand( context ); + Command.prototype.open.call( this, context ); + this.state = TMNodeState.READING; + addTargetOrMasterToContext( this, context ); + }; + + /** + * Import节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + ImportCommand.prototype.open = + + /** + * Var节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + VarCommand.prototype.open = + + /** + * Use节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + UseCommand.prototype.open = function ( context ) { + var parent = context.stack.top(); + this.parent = parent; + parent.addChild( this ); + }; + + + /** + * 节点open前的处理动作:节点不在target中时,自动创建匿名target + * + * @param {Object} context 语法分析环境对象 + */ + UseCommand.prototype.beforeOpen = + + /** + * 节点open前的处理动作:节点不在target中时,自动创建匿名target + * + * @param {Object} context 语法分析环境对象 + */ + ImportCommand.prototype.beforeOpen = + + /** + * 节点open前的处理动作:节点不在target中时,自动创建匿名target + * + * @param {Object} context 语法分析环境对象 + */ + VarCommand.prototype.beforeOpen = + + /** + * 节点open前的处理动作:节点不在target中时,自动创建匿名target + * + * @param {Object} context 语法分析环境对象 + */ + ForCommand.prototype.beforeOpen = + + /** + * 节点open前的处理动作:节点不在target中时,自动创建匿名target + * + * @param {Object} context 语法分析环境对象 + */ + FilterCommand.prototype.beforeOpen = + + /** + * 节点open前的处理动作:节点不在target中时,自动创建匿名target + * + * @param {Object} context 语法分析环境对象 + */ + IfCommand.prototype.beforeOpen = + + /** + * 文本节点被添加到分析环境前的处理动作:节点不在target中时,自动创建匿名target + * + * @param {Object} context 语法分析环境对象 + */ + TextNode.prototype.beforeAdd = function ( context ) { + if ( context.stack.bottom() ) { + return; + } + + var target = new TargetCommand( generateGUID(), context.engine ); + target.open( context ); + }; + + /** + * 节点解析结束 + * 由于use节点无需闭合,处理时不会入栈,所以将close置为空函数 + * + * @param {Object} context 语法分析环境对象 + */ + UseCommand.prototype.close = + + /** + * 节点解析结束 + * 由于import节点无需闭合,处理时不会入栈,所以将close置为空函数 + * + * @param {Object} context 语法分析环境对象 + */ + ImportCommand.prototype.close = + + /** + * 节点解析结束 + * 由于else节点无需闭合,处理时不会入栈,闭合由if负责。所以将close置为空函数 + * + * @param {Object} context 语法分析环境对象 + */ + ElseCommand.prototype.close = + + /** + * 节点解析结束 + * 由于var节点无需闭合,处理时不会入栈,所以将close置为空函数 + * + * @param {Object} context 语法分析环境对象 + */ + VarCommand.prototype.close = function () {}; + + /** + * 获取内容 + * + * @return {string} + */ + ImportCommand.prototype.getContent = function () { + var target = this.engine.targets[ this.name ]; + return target.getContent(); + }; + + /** + * 获取renderer body的生成代码 + * + * @return {string} + */ + ImportCommand.prototype.getRendererBody = function () { + var target = this.engine.targets[ this.name ]; + return target.getRendererBody(); + }; + + /** + * 获取renderer body的生成代码 + * + * @return {string} + */ + UseCommand.prototype.getRendererBody = function () { + return stringFormat( + '{0}engine.render({2},{{3}}){1}', + RENDER_STRING_ADD_START, + RENDER_STRING_ADD_END, + stringLiteralize( this.name ), + compileVariable( this.args, this.engine ).replace( + /(^|,)\s*([a-z0-9_]+)\s*=/ig, + function ( match, start, argName ) { + return (start || '') + stringLiteralize( argName ) + ':'; + } + ) + ); + }; + + /** + * 获取renderer body的生成代码 + * + * @return {string} + */ + VarCommand.prototype.getRendererBody = function () { + if ( this.expr ) { + return stringFormat( + 'v[{0}]={1};', + stringLiteralize( this.name ), + compileVariable( this.expr, this.engine ) + ); + } + + return ''; + }; + + /** + * 获取renderer body的生成代码 + * + * @return {string} + */ + IfCommand.prototype.getRendererBody = function () { + var rendererBody = stringFormat( + 'if({0}){{1}}', + compileVariable( this.value, this.engine ), + Command.prototype.getRendererBody.call( this ) + ); + + var elseCommand = this[ 'else' ]; + if ( elseCommand ) { + return [ + rendererBody, + stringFormat( + 'else{{0}}', + elseCommand.getRendererBody() + ) + ].join( '' ); + } + + return rendererBody; + }; + + /** + * 获取renderer body的生成代码 + * + * @return {string} + */ + ForCommand.prototype.getRendererBody = function () { + return stringFormat( + '' + + 'var {0}={1};' + + 'if({0} instanceof Array)' + + 'for (var {4}=0,{5}={0}.length;{4}<{5};{4}++){v[{2}]={4};v[{3}]={0}[{4}];{6}}' + + 'else if(typeof {0}==="object")' + + 'for(var {4} in {0}){v[{2}]={4};v[{3}]={0}[{4}];{6}}', + generateGUID(), + compileVariable( this.list, this.engine ), + stringLiteralize( this.index || generateGUID() ), + stringLiteralize( this.item ), + generateGUID(), + generateGUID(), + Command.prototype.getRendererBody.call( this ) + ); + }; + + /** + * 获取renderer body的生成代码 + * + * @return {string} + */ + FilterCommand.prototype.getRendererBody = function () { + var args = this.args; + return stringFormat( + '{2}fs[{5}]((function(){{0}{4}{1}})(){6}){3}', + RENDER_STRING_DECLATION, + RENDER_STRING_RETURN, + RENDER_STRING_ADD_START, + RENDER_STRING_ADD_END, + Command.prototype.getRendererBody.call( this ), + stringLiteralize( this.name ), + args ? ',' + compileVariable( args, this.engine ) : '' + ); + }; + + /** + * content节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + ContentCommand.prototype.open = function ( context ) { + autoCloseCommand( context, ContentCommand ); + Command.prototype.open.call( this, context ); + context.targetOrMaster.contents[ this.name ] = this; + }; + + /** + * content节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + ContentPlaceHolderCommand.prototype.open = function ( context ) { + autoCloseCommand( context, ContentPlaceHolderCommand ); + Command.prototype.open.call( this, context ); + }; + + /** + * 节点自动闭合,解析结束 + * + * @param {Object} context 语法分析环境对象 + */ + ContentCommand.prototype.autoClose = + + /** + * 节点自动闭合,解析结束 + * + * @param {Object} context 语法分析环境对象 + */ + IfCommand.prototype.autoClose = Command.prototype.close; + + /** + * 节点自动闭合,解析结束 + * contentplaceholder的自动结束逻辑为,在其开始位置后马上结束 + * 所以,其自动结束时children应赋予其所属的parent,也就是master + * + * @param {Object} context 语法分析环境对象 + */ + ContentPlaceHolderCommand.prototype.autoClose = function ( context ) { + var parentChildren = this.parent.children; + parentChildren.push.apply( parentChildren, this.children ); + this.children.length = 0; + this.close( context ); + }; + + /** + * 添加子节点 + * + * @param {TextNode|Command} node 子节点 + */ + IfCommand.prototype.addChild = function ( node ) { + var elseCommand = this[ 'else' ]; + ( elseCommand + ? elseCommand.children + : this.children + ).push( node ); + }; + + /** + * elif节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + ElifCommand.prototype.open = function ( context ) { + var elseCommand = new ElseCommand(); + elseCommand.open( context ); + + var ifCommand = autoCloseCommand( context, IfCommand ); + ifCommand.addChild( this ); + context.stack.push( this ); + }; + + /** + * else节点open,解析开始 + * + * @param {Object} context 语法分析环境对象 + */ + ElseCommand.prototype.open = function ( context ) { + var ifCommand = autoCloseCommand( context, IfCommand ); + + ifCommand[ 'else' ] = this; + context.stack.push( ifCommand ); + }; + + /** + * 命令类型集合 + * + * @type {Object} + */ + var commandTypes = {}; + + /** + * 添加命令类型 + * + * @inner + * @param {string} name 命令名称 + * @param {Function} Type 处理命令用到的类 + */ + function addCommandType( name, Type ) { + commandTypes[ name ] = Type; + Type.prototype.type = name; + } + + addCommandType( 'target', TargetCommand ); + addCommandType( 'master', MasterCommand ); + addCommandType( 'content', ContentCommand ); + addCommandType( 'contentplaceholder', ContentPlaceHolderCommand ); + addCommandType( 'import', ImportCommand ); + addCommandType( 'use', UseCommand ); + addCommandType( 'var', VarCommand ); + addCommandType( 'for', ForCommand ); + addCommandType( 'if', IfCommand ); + addCommandType( 'elif', ElifCommand ); + addCommandType( 'else', ElseCommand ); + addCommandType( 'filter', FilterCommand ); + + + /** + * etpl引擎类 + * + * @constructor + * @param {Object=} options 引擎参数 + * @param {string=} options.commandOpen 命令语法起始串 + * @param {string=} options.commandClose 命令语法结束串 + * @param {string=} options.defaultFilter 默认变量替换的filter + * @param {boolean=} options.strip 是否清除命令标签前后的空白字符 + * @param {string=} options.namingConflict target或master名字冲突时的处理策略 + */ + function Engine( options ) { + this.options = { + commandOpen: '', + variableOpen: '${', + variableClose: '}', + defaultFilter: 'html' + }; + + this.config( options ); + this.masters = {}; + this.targets = {}; + this.filters = extend({}, DEFAULT_FILTERS); + } + + /** + * 配置引擎参数,设置的参数将被合并到现有参数中 + * + * @param {Object} options 参数对象 + * @param {string=} options.commandOpen 命令语法起始串 + * @param {string=} options.commandClose 命令语法结束串 + * @param {string=} options.defaultFilter 默认变量替换的filter + * @param {boolean=} options.strip 是否清除命令标签前后的空白字符 + * @param {string=} options.namingConflict target或master名字冲突时的处理策略 + */ + Engine.prototype.config = function ( options ) { + extend( this.options, options ); + }; + + /** + * 解析模板并编译,返回第一个target编译后的renderer函数。 + * + * @param {string} source 模板源代码 + * @return {function(Object):string} + */ + Engine.prototype.compile = + + /** + * 解析模板并编译,返回第一个target编译后的renderer函数。 + * 该方法的存在为了兼容老模板引擎 + * + * @param {string} source 模板源代码 + * @return {function(Object):string} + */ + Engine.prototype.parse = function ( source ) { + if ( source ) { + var targetNames = parseSource( source, this ); + if ( targetNames.length ) { + return this.targets[ targetNames[ 0 ] ].getRenderer(); + } + } + + return new Function('return ""'); + }; + + /** + * 根据target名称获取编译后的renderer函数 + * + * @param {string} name target名称 + * @return {function(Object):string} + */ + Engine.prototype.getRenderer = function ( name ) { + var target = this.targets[ name ]; + if ( target ) { + return target.getRenderer(); + } + }; + + /** + * 根据target名称获取模板内容 + * + * @param {string} name target名称 + * @return {string} + */ + Engine.prototype.get = function ( name ) { + var target = this.targets[ name ]; + if ( target ) { + return target.getContent(); + } + + return ''; + }; + + /** + * 执行模板渲染,返回渲染后的字符串。 + * + * @param {string} name target名称 + * @param {Object=} data 模板数据。 + * 可以是plain object, + * 也可以是带有 {string}get({string}name) 方法的对象 + * @return {string} + */ + Engine.prototype.render = function ( name, data ) { + var renderer = this.getRenderer( name ); + if ( renderer ) { + return renderer( data ); + } + + return ''; + }; + + /** + * 增加过滤器 + * + * @param {string} name 过滤器名称 + * @param {Function} filter 过滤函数 + */ + Engine.prototype.addFilter = function ( name, filter ) { + if ( typeof filter == 'function' ) { + this.filters[ name ] = filter; + } + }; + + /** + * 解析源代码 + * + * @inner + * @param {string} source 模板源代码 + * @param {Engine} engine 引擎实例 + * @return {Array} target名称列表 + */ + function parseSource( source, engine ) { + var commandOpen = engine.options.commandOpen; + var commandClose = engine.options.commandClose; + + var stack = new Stack(); + var analyseContext = { + engine: engine, + targets: [], + stack: stack + }; + + // text节点内容缓冲区,用于合并多text + var textBuf = []; + + /** + * 将缓冲区中的text节点内容写入 + * + * @inner + */ + function flushTextBuf() { + if ( textBuf.length > 0 ) { + var text = textBuf.join( '' ); + var textNode = new TextNode( text, engine ); + textNode.beforeAdd( analyseContext ); + + stack.top().addTextNode( textNode ); + textBuf = []; + + if ( engine.options.strip + && analyseContext.current instanceof Command + ) { + textNode.value = text.replace( /^[\x20\t\r]*\n/, '' ); + } + analyseContext.current = textNode; + } + } + + var NodeType; + + /** + * 判断节点是否是NodeType类型的实例 + * 用于在stack中find提供filter + * + * @inner + * @param {Command} node 目标节点 + * @return {boolean} + */ + function isInstanceofNodeType( node ) { + return node instanceof NodeType; + } + + parseTextBlock( + source, commandOpen, commandClose, 0, + + function ( text ) { // 内文本的处理函数 + var match = /^\s*(\/)?([a-z]+)\s*(:([\s\S]*))?$/.exec( text ); + + // 符合command规则,并且存在相应的Command类,说明是合法有含义的Command + // 否则,为不具有command含义的普通文本 + if ( match + && ( NodeType = commandTypes[ match[2].toLowerCase() ] ) + && typeof NodeType == 'function' + ) { + // 先将缓冲区中的text节点内容写入 + flushTextBuf(); + + var currentNode = analyseContext.current; + if ( engine.options.strip && currentNode instanceof TextNode ) { + currentNode.value = currentNode.value + .replace( /\r?\n[\x20\t]*$/, '\n' ); + } + + if ( match[1] ) { + currentNode = stack.find( isInstanceofNodeType ); + currentNode && currentNode.close( analyseContext ); + } + else { + currentNode = new NodeType( match[4], engine ); + if ( typeof currentNode.beforeOpen == 'function' ) { + currentNode.beforeOpen( analyseContext ); + } + currentNode.open( analyseContext ); + } + + analyseContext.current = currentNode; + } + else if ( !/^\s*\/\//.test( text ) ) { + // 如果不是模板注释,则作为普通文本,写入缓冲区 + textBuf.push( commandOpen, text, commandClose ); + } + + NodeType = null; + }, + + function ( text ) { // 外,普通文本的处理函数 + // 普通文本直接写入缓冲区 + textBuf.push( text ); + } + ); + + + flushTextBuf(); // 将缓冲区中的text节点内容写入 + autoCloseCommand( analyseContext ); + + return analyseContext.targets; + } + + var etpl = new Engine(); + etpl.Engine = Engine; + + if ( typeof exports == 'object' && typeof module == 'object' ) { + // For CommonJS + exports = module.exports = etpl; + } + else if ( typeof define == 'function' && define.amd ) { + // For AMD + define( etpl ); + } + else { + // For + */ + // notice: timestamp + var baseReg = /^(.*)(seed|kissy)(-aio)?(-min)?\.js[^/]*/i, + baseTestReg = /(seed|kissy)(-aio)?(-min)?\.js/i; + + function getBaseUrl(script) { + var src = utils.absoluteFilePath(script.src), + prefix = script.getAttribute('data-combo-prefix') || '??', + sep = script.getAttribute('data-combo-sep') || ',', + parts = src.split(sep), + base, + part0 = parts[0], + index = part0.indexOf(prefix); + // no combo + if (index == -1) { + base = src.replace(baseReg, '$1'); + } else { + base = part0.substring(0, index); + var part01 = part0.substring(index + 2, part0.length); + // combo first + // notice use match better than test + if (part01.match(baseTestReg)) { + base += part01.replace(baseReg, '$1'); + } + // combo after first + else { + S.each(parts, function (part) { + if (part.match(baseTestReg)) { + base += part.replace(baseReg, '$1'); + return false; + } + }); + } + } + return base; + } + + /** + * Initializes loader. + */ + S.__initLoader = function () { + var self = this; + self.Env.mods = self.Env.mods || {}; // all added mods + }; + + S.Env._loadQueue = {}; // information for loading and loaded mods + S.__initLoader(); + + (function () { + // get base from current script file path + var scripts = document.getElementsByTagName('script'), + currentScript = scripts[scripts.length - 1], + base = getBaseUrl(currentScript); + S.Config.base = utils.normalBasePath(base); + // the default timeout for getScript + S.Config.timeout = 10; + })(); + + S.mix(S.configs, { + base:function (base) { + S.Config.base = utils.normalBasePath(base); + }, + timeout:function (v) { + S.Config.timeout = v; + }, + debug:function (v) { + S.Config.debug = v; + } + }); + + // for S.app working properly + S.each(loader, function (v, k) { + S.__APP_MEMBERS.push(k); + }); + + S.__APP_INIT_METHODS.push('__initLoader'); + +})(KISSY, KISSY.__loader, KISSY.__loaderUtils);/** + * @module web.js + * @author lifesinger@gmail.com,yiminghe@gmail.com + * @description this code can only run at browser environment + */ +(function(S, undefined) { + + var win = S.__HOST, + doc = win['document'], + + docElem = doc.documentElement, + + EMPTY = '', + + // Is the DOM ready to be used? Set to true once it occurs. + isReady = false, + + // The functions to execute on DOM ready. + readyList = [], + + // The number of poll times. + POLL_RETRYS = 500, + + // The poll interval in milliseconds. + POLL_INTERVAL = 40, + + // #id or id + RE_IDSTR = /^#?([\w-]+)$/, + + RE_NOT_WHITE = /\S/; + S.mix(S, { + + + /** + * A crude way of determining if an object is a window + */ + isWindow: function(o) { + return S.type(o) === 'object' + && 'setInterval' in o + && 'document' in o + && o.document.nodeType == 9; + }, + + + parseXML: function(data) { + var xml; + try { + // Standard + if (window.DOMParser) { + xml = new DOMParser().parseFromString(data, "text/xml"); + } else { // IE + xml = new ActiveXObject("Microsoft.XMLDOM"); + xml.async = "false"; + xml.loadXML(data); + } + } catch(e) { + S.log("parseXML error : "); + S.log(e); + xml = undefined; + } + if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) { + S.error("Invalid XML: " + data); + } + return xml; + }, + + /** + * Evalulates a script in a global context. + */ + globalEval: function(data) { + if (data && RE_NOT_WHITE.test(data)) { + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + ( window.execScript || function(data) { + window[ "eval" ].call(window, data); + } )(data); + } + }, + + /** + * Specify a function to execute when the DOM is fully loaded. + * @param fn {Function} A function to execute after the DOM is ready + * + * KISSY.ready(function(S){ }); + * + * @return {KISSY} + */ + ready: function(fn) { + + // If the DOM is already ready + if (isReady) { + // Execute the function immediately + fn.call(win, this); + } else { + // Remember the function for later + readyList.push(fn); + } + + return this; + }, + + /** + * Executes the supplied callback when the item with the supplied id is found. + * @param id The id of the element, or an array of ids to look for. + * @param fn What to execute when the element is found. + */ + available: function(id, fn) { + id = (id + EMPTY).match(RE_IDSTR)[1]; + if (!id || !S.isFunction(fn)) { + return; + } + + var retryCount = 1, + node, + timer = S.later(function() { + if ((node = doc.getElementById(id)) && (fn(node) || 1) || + ++retryCount > POLL_RETRYS) { + timer.cancel(); + } + }, POLL_INTERVAL, true); + } + }); + + + /** + * Binds ready events. + */ + function _bindReady() { + var doScroll = docElem.doScroll, + eventType = doScroll ? 'onreadystatechange' : 'DOMContentLoaded', + COMPLETE = 'complete', + fire = function() { + _fireReady(); + }; + + // Catch cases where ready() is called after the + // browser event has already occurred. + if (doc.readyState === COMPLETE) { + return fire(); + } + + // w3c mode + if (doc.addEventListener) { + function domReady() { + doc.removeEventListener(eventType, domReady, false); + fire(); + } + + doc.addEventListener(eventType, domReady, false); + + // A fallback to window.onload, that will always work + win.addEventListener('load', fire, false); + } + // IE event model is used + else { + function stateChange() { + if (doc.readyState === COMPLETE) { + doc.detachEvent(eventType, stateChange); + fire(); + } + } + + // ensure firing before onload, maybe late but safe also for iframes + doc.attachEvent(eventType, stateChange); + + // A fallback to window.onload, that will always work. + win.attachEvent('onload', fire); + + // If IE and not a frame + // continually check to see if the document is ready + var notframe = false; + + try { + notframe = (win['frameElement'] === null); + } catch(e) { + S.log("frameElement error : "); + S.log(e); + } + + if (doScroll && notframe) { + function readyScroll() { + try { + // Ref: http://javascript.nwbox.com/IEContentLoaded/ + doScroll('left'); + fire(); + } catch(ex) { + //S.log("detect document ready : " + ex); + setTimeout(readyScroll, POLL_INTERVAL); + } + } + + readyScroll(); + } + } + return 0; + } + + /** + * Executes functions bound to ready event. + */ + function _fireReady() { + if (isReady) { + return; + } + + // Remember that the DOM is ready + isReady = true; + + // If there are functions bound, to execute + if (readyList) { + // Execute all of them + var fn, i = 0; + while (fn = readyList[i++]) { + fn.call(win, S); + } + + // Reset the list of functions + readyList = null; + } + } + + // If url contains '?ks-debug', debug mode will turn on automatically. + if (location && (location.search || EMPTY).indexOf('ks-debug') !== -1) { + S.Config.debug = true; + } + + /** + * bind on start + * in case when you bind but the DOMContentLoaded has triggered + * then you has to wait onload + * worst case no callback at all + */ + _bindReady(); + +})(KISSY, undefined); +/** + * 声明 kissy 核心中所包含的模块,动态加载时将直接从 core.js 中加载核心模块 + * @description: 为了和 1.1.7 及以前版本保持兼容,务实与创新,兼容与革新 ! + * @author yiminghe@gmail.com + */ +(function (S) { + S.config({ + 'combines':{ + 'core':['dom', 'ua', 'event', 'node', 'json', 'ajax', 'anim', 'base', 'cookie'] + } + }); +})(KISSY); +/** + combined files : + +D:\code\kissy_git\kissy1.2\src\ua\base.js +D:\code\kissy_git\kissy1.2\src\ua\extra.js +D:\code\kissy_git\kissy1.2\src\ua.js +D:\code\kissy_git\kissy1.2\src\dom\base.js +D:\code\kissy_git\kissy1.2\src\dom\attr.js +D:\code\kissy_git\kissy1.2\src\dom\class.js +D:\code\kissy_git\kissy1.2\src\dom\create.js +D:\code\kissy_git\kissy1.2\src\dom\data.js +D:\code\kissy_git\kissy1.2\src\dom\insertion.js +D:\code\kissy_git\kissy1.2\src\dom\offset.js +D:\code\kissy_git\kissy1.2\src\dom\style.js +D:\code\kissy_git\kissy1.2\src\dom\selector.js +D:\code\kissy_git\kissy1.2\src\dom\style-ie.js +D:\code\kissy_git\kissy1.2\src\dom\traversal.js +D:\code\kissy_git\kissy1.2\src\dom.js +D:\code\kissy_git\kissy1.2\src\event\keycodes.js +D:\code\kissy_git\kissy1.2\src\event\object.js +D:\code\kissy_git\kissy1.2\src\event\utils.js +D:\code\kissy_git\kissy1.2\src\event\base.js +D:\code\kissy_git\kissy1.2\src\event\target.js +D:\code\kissy_git\kissy1.2\src\event\focusin.js +D:\code\kissy_git\kissy1.2\src\event\hashchange.js +D:\code\kissy_git\kissy1.2\src\event\valuechange.js +D:\code\kissy_git\kissy1.2\src\event\delegate.js +D:\code\kissy_git\kissy1.2\src\event\mouseenter.js +D:\code\kissy_git\kissy1.2\src\event\submit.js +D:\code\kissy_git\kissy1.2\src\event\change.js +D:\code\kissy_git\kissy1.2\src\event\mousewheel.js +D:\code\kissy_git\kissy1.2\src\event.js +D:\code\kissy_git\kissy1.2\src\node\base.js +D:\code\kissy_git\kissy1.2\src\node\attach.js +D:\code\kissy_git\kissy1.2\src\node\override.js +D:\code\kissy_git\kissy1.2\src\anim\easing.js +D:\code\kissy_git\kissy1.2\src\anim\manager.js +D:\code\kissy_git\kissy1.2\src\anim\fx.js +D:\code\kissy_git\kissy1.2\src\anim\queue.js +D:\code\kissy_git\kissy1.2\src\anim\base.js +D:\code\kissy_git\kissy1.2\src\anim\color.js +D:\code\kissy_git\kissy1.2\src\anim.js +D:\code\kissy_git\kissy1.2\src\node\anim.js +D:\code\kissy_git\kissy1.2\src\node.js +D:\code\kissy_git\kissy1.2\src\json\json2.js +D:\code\kissy_git\kissy1.2\src\json.js +D:\code\kissy_git\kissy1.2\src\ajax\form-serializer.js +D:\code\kissy_git\kissy1.2\src\ajax\xhrobject.js +D:\code\kissy_git\kissy1.2\src\ajax\base.js +D:\code\kissy_git\kissy1.2\src\ajax\xhrbase.js +D:\code\kissy_git\kissy1.2\src\ajax\subdomain.js +D:\code\kissy_git\kissy1.2\src\ajax\xdr.js +D:\code\kissy_git\kissy1.2\src\ajax\xhr.js +D:\code\kissy_git\kissy1.2\src\ajax\script.js +D:\code\kissy_git\kissy1.2\src\ajax\jsonp.js +D:\code\kissy_git\kissy1.2\src\ajax\form.js +D:\code\kissy_git\kissy1.2\src\ajax\iframe-upload.js +D:\code\kissy_git\kissy1.2\src\ajax.js +D:\code\kissy_git\kissy1.2\src\base\attribute.js +D:\code\kissy_git\kissy1.2\src\base\base.js +D:\code\kissy_git\kissy1.2\src\base.js +D:\code\kissy_git\kissy1.2\src\cookie\base.js +D:\code\kissy_git\kissy1.2\src\cookie.js +D:\code\kissy_git\kissy1.2\src\core.js +**/ + +/** + * @module ua + * @author lifesinger@gmail.com + */ +KISSY.add('ua/base', function() { + + var ua = navigator.userAgent, + EMPTY = '', MOBILE = 'mobile', + core = EMPTY, shell = EMPTY, m, + IE_DETECT_RANGE = [6, 9], v, end, + VERSION_PLACEHOLDER = '{{version}}', + IE_DETECT_TPL = '', + div = document.createElement('div'), s, + o = { + // browser core type + //webkit: 0, + //trident: 0, + //gecko: 0, + //presto: 0, + + // browser type + //chrome: 0, + //safari: 0, + //firefox: 0, + //ie: 0, + //opera: 0 + + //mobile: '', + //core: '', + //shell: '' + }, + numberify = function(s) { + var c = 0; + // convert '1.2.3.4' to 1.234 + return parseFloat(s.replace(/\./g, function() { + return (c++ === 0) ? '.' : ''; + })); + }; + + // try to use IE-Conditional-Comment detect IE more accurately + // IE10 doesn't support this method, @ref: http://blogs.msdn.com/b/ie/archive/2011/07/06/html5-parsing-in-ie10.aspx + div.innerHTML = IE_DETECT_TPL.replace(VERSION_PLACEHOLDER, ''); + s = div.getElementsByTagName('s'); + + if (s.length > 0) { + + shell = 'ie'; + o[core = 'trident'] = 0.1; // Trident detected, look for revision + + // Get the Trident's accurate version + if ((m = ua.match(/Trident\/([\d.]*)/)) && m[1]) { + o[core] = numberify(m[1]); + } + + // Detect the accurate version + // 注意: + // o.shell = ie, 表示外壳是 ie + // 但 o.ie = 7, 并不代表外壳是 ie7, 还有可能是 ie8 的兼容模式 + // 对于 ie8 的兼容模式,还要通过 documentMode 去判断。但此处不能让 o.ie = 8, 否则 + // 很多脚本判断会失误。因为 ie8 的兼容模式表现行为和 ie7 相同,而不是和 ie8 相同 + for (v = IE_DETECT_RANGE[0],end = IE_DETECT_RANGE[1]; v <= end; v++) { + div.innerHTML = IE_DETECT_TPL.replace(VERSION_PLACEHOLDER, v); + if (s.length > 0) { + o[shell] = v; + break; + } + } + + } else { + + // WebKit + if ((m = ua.match(/AppleWebKit\/([\d.]*)/)) && m[1]) { + o[core = 'webkit'] = numberify(m[1]); + + // Chrome + if ((m = ua.match(/Chrome\/([\d.]*)/)) && m[1]) { + o[shell = 'chrome'] = numberify(m[1]); + } + // Safari + else if ((m = ua.match(/\/([\d.]*) Safari/)) && m[1]) { + o[shell = 'safari'] = numberify(m[1]); + } + + // Apple Mobile + if (/ Mobile\//.test(ua)) { + o[MOBILE] = 'apple'; // iPad, iPhone or iPod Touch + } + // Other WebKit Mobile Browsers + else if ((m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/))) { + o[MOBILE] = m[0].toLowerCase(); // Nokia N-series, Android, webOS, ex: NokiaN95 + } + } + // NOT WebKit + else { + // Presto + // ref: http://www.useragentstring.com/pages/useragentstring.php + if ((m = ua.match(/Presto\/([\d.]*)/)) && m[1]) { + o[core = 'presto'] = numberify(m[1]); + + // Opera + if ((m = ua.match(/Opera\/([\d.]*)/)) && m[1]) { + o[shell = 'opera'] = numberify(m[1]); // Opera detected, look for revision + + if ((m = ua.match(/Opera\/.* Version\/([\d.]*)/)) && m[1]) { + o[shell] = numberify(m[1]); + } + + // Opera Mini + if ((m = ua.match(/Opera Mini[^;]*/)) && m) { + o[MOBILE] = m[0].toLowerCase(); // ex: Opera Mini/2.0.4509/1316 + } + // Opera Mobile + // ex: Opera/9.80 (Windows NT 6.1; Opera Mobi/49; U; en) Presto/2.4.18 Version/10.00 + // issue: 由于 Opera Mobile 有 Version/ 字段,可能会与 Opera 混淆,同时对于 Opera Mobile 的版本号也比较混乱 + else if ((m = ua.match(/Opera Mobi[^;]*/)) && m) { + o[MOBILE] = m[0]; + } + } + + // NOT WebKit or Presto + } else { + // MSIE + // 由于最开始已经使用了 IE 条件注释判断,因此落到这里的唯一可能性只有 IE10+ + if ((m = ua.match(/MSIE\s([^;]*)/)) && m[1]) { + o[core = 'trident'] = 0.1; // Trident detected, look for revision + o[shell = 'ie'] = numberify(m[1]); + + // Get the Trident's accurate version + if ((m = ua.match(/Trident\/([\d.]*)/)) && m[1]) { + o[core] = numberify(m[1]); + } + + // NOT WebKit, Presto or IE + } else { + // Gecko + if ((m = ua.match(/Gecko/))) { + o[core = 'gecko'] = 0.1; // Gecko detected, look for revision + if ((m = ua.match(/rv:([\d.]*)/)) && m[1]) { + o[core] = numberify(m[1]); + } + + // Firefox + if ((m = ua.match(/Firefox\/([\d.]*)/)) && m[1]) { + o[shell = 'firefox'] = numberify(m[1]); + } + } + } + } + } + } + + o.core = core; + o.shell = shell; + o._numberify = numberify; + return o; +}); + +/** + * NOTES: + * + * 2011.11.08 + * - ie < 10 使用条件注释判断内核,更精确 by gonghaocn@gmail.com + * + * 2010.03 + * - jQuery, YUI 等类库都推荐用特性探测替代浏览器嗅探。特性探测的好处是能自动适应未来设备和未知设备,比如 + * if(document.addEventListener) 假设 IE9 支持标准事件,则代码不用修改,就自适应了“未来浏览器”。 + * 对于未知浏览器也是如此。但是,这并不意味着浏览器嗅探就得彻底抛弃。当代码很明确就是针对已知特定浏览器的, + * 同时并非是某个特性探测可以解决时,用浏览器嗅探反而能带来代码的简洁,同时也也不会有什么后患。总之,一切 + * 皆权衡。 + * - UA.ie && UA.ie < 8 并不意味着浏览器就不是 IE8, 有可能是 IE8 的兼容模式。进一步的判断需要使用 documentMode. + * + * TODO: + * - test mobile + * - 3Q 大战后,360 去掉了 UA 信息中的 360 信息,需采用 res 方法去判断 + * + */ + +/** + * @module ua-extra + * @author gonghao + */ +KISSY.add('ua/extra', function(S, UA) { + var ua = navigator.userAgent, + m, external, shell, + o = { }, + numberify = UA._numberify; + + /** + * 说明: + * @子涯总结的各国产浏览器的判断依据: http://spreadsheets0.google.com/ccc?key=tluod2VGe60_ceDrAaMrfMw&hl=zh_CN#gid=0 + * 根据 CNZZ 2009 年度浏览器占用率报告,优化了判断顺序:http://www.tanmi360.com/post/230.htm + * 如果检测出浏览器,但是具体版本号未知用 0.1 作为标识 + * 世界之窗 & 360 浏览器,在 3.x 以下的版本都无法通过 UA 或者特性检测进行判断,所以目前只要检测到 UA 关键字就认为起版本号为 3 + */ + + // 360Browser + if (m = ua.match(/360SE/)) { + o[shell = 'se360'] = 3; // issue: 360Browser 2.x cannot be recognised, so if recognised default set verstion number to 3 + } + // Maxthon + else if ((m = ua.match(/Maxthon/)) && (external = window.external)) { + // issue: Maxthon 3.x in IE-Core cannot be recognised and it doesn't have exact version number + // but other maxthon versions all have exact version number + shell = 'maxthon'; + try { + o[shell] = numberify(external['max_version']); + } catch(ex) { + o[shell] = 0.1; + } + } + // TT + else if (m = ua.match(/TencentTraveler\s([\d.]*)/)) { + o[shell = 'tt'] = m[1] ? numberify(m[1]) : 0.1; + } + // TheWorld + else if (m = ua.match(/TheWorld/)) { + o[shell = 'theworld'] = 3; // issue: TheWorld 2.x cannot be recognised, so if recognised default set verstion number to 3 + } + // Sougou + else if (m = ua.match(/SE\s([\d.]*)/)) { + o[shell = 'sougou'] = m[1] ? numberify(m[1]) : 0.1; + } + + // If the browser has shell(no matter IE-core or Webkit-core or others), set the shell key + shell && (o.shell = shell); + + S.mix(UA, o); + return UA; +}, { + requires:["ua/base"] +}); + +KISSY.add("ua", function(S,UA) { + return UA; +}, { + requires:["ua/extra"] +}); + +/** + * @module dom + * @author yiminghe@gmail.com,lifesinger@gmail.com + */ +KISSY.add('dom/base', function(S, UA, undefined) { + + function nodeTypeIs(node, val) { + return node && node.nodeType === val; + } + + + var NODE_TYPE = { + /** + * enumeration of dom node type + * @type Number + */ + ELEMENT_NODE : 1, + "ATTRIBUTE_NODE" : 2, + TEXT_NODE:3, + "CDATA_SECTION_NODE" : 4, + "ENTITY_REFERENCE_NODE": 5, + "ENTITY_NODE" : 6, + "PROCESSING_INSTRUCTION_NODE" :7, + COMMENT_NODE : 8, + DOCUMENT_NODE : 9, + "DOCUMENT_TYPE_NODE" : 10, + DOCUMENT_FRAGMENT_NODE : 11, + "NOTATION_NODE" : 12 + }; + var DOM = { + + _isCustomDomain :function (win) { + win = win || window; + var domain = win.document.domain, + hostname = win.location.hostname; + return domain != hostname && + domain != ( '[' + hostname + ']' ); // IPv6 IP support + }, + + _genEmptyIframeSrc:function(win) { + win = win || window; + if (UA['ie'] && DOM._isCustomDomain(win)) { + return 'javascript:void(function(){' + encodeURIComponent("" + + "document.open();" + + "document.domain='" + + win.document.domain + + "';" + + "document.close();") + "}())"; + } + }, + + _NODE_TYPE:NODE_TYPE, + + + /** + * 是不是 element node + */ + _isElementNode: function(elem) { + return nodeTypeIs(elem, DOM.ELEMENT_NODE); + }, + + /** + * elem 为 window 时,直接返回 + * elem 为 document 时,返回关联的 window + * elem 为 undefined 时,返回当前 window + * 其它值,返回 false + */ + _getWin: function(elem) { + return (elem && ('scrollTo' in elem) && elem['document']) ? + elem : + nodeTypeIs(elem, DOM.DOCUMENT_NODE) ? + elem.defaultView || elem.parentWindow : + (elem === undefined || elem === null) ? + window : false; + }, + + _nodeTypeIs: nodeTypeIs, + + // Ref: http://lifesinger.github.com/lab/2010/nodelist.html + _isNodeList:function(o) { + // 注1:ie 下,有 window.item, typeof node.item 在 ie 不同版本下,返回值不同 + // 注2:select 等元素也有 item, 要用 !node.nodeType 排除掉 + // 注3:通过 namedItem 来判断不可靠 + // 注4:getElementsByTagName 和 querySelectorAll 返回的集合不同 + // 注5: 考虑 iframe.contentWindow + return o && !o.nodeType && o.item && !o.setTimeout; + }, + + _nodeName:function(e, name) { + return e && e.nodeName.toLowerCase() === name.toLowerCase(); + } + }; + + S.mix(DOM, NODE_TYPE); + + return DOM; + +}, { + requires:['ua'] +}); + +/** + * 2011-08 + * - 添加键盘枚举值,方便依赖程序清晰 + */ + +/** + * @module dom-attr + * @author yiminghe@gmail.com,lifesinger@gmail.com + */ +KISSY.add('dom/attr', function(S, DOM, UA, undefined) { + + var doc = document, + docElement = doc.documentElement, + oldIE = !docElement.hasAttribute, + TEXT = docElement.textContent === undefined ? + 'innerText' : 'textContent', + EMPTY = '', + nodeName = DOM._nodeName, + isElementNode = DOM._isElementNode, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rinvalidChar = /:|^on/, + rreturn = /\r/g, + attrFix = { + }, + attrFn = { + val: 1, + css: 1, + html: 1, + text: 1, + data: 1, + width: 1, + height: 1, + offset: 1, + scrollTop:1, + scrollLeft:1 + }, + attrHooks = { + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + tabindex:{ + get:function(el) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + var attributeNode = el.getAttributeNode("tabindex"); + return attributeNode && attributeNode.specified ? + parseInt(attributeNode.value, 10) : + rfocusable.test(el.nodeName) || rclickable.test(el.nodeName) && el.href ? + 0 : + undefined; + } + }, + // 在标准浏览器下,用 getAttribute 获取 style 值 + // IE7- 下,需要用 cssText 来获取 + // 统一使用 cssText + style:{ + get:function(el) { + return el.style.cssText; + }, + set:function(el, val) { + el.style.cssText = val; + } + } + }, + propFix = { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + "cellpadding": "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + "contenteditable": "contentEditable" + }, + // Hook for boolean attributes + // if bool is false + // - standard browser returns null + // - ie<8 return false + // - so norm to undefined + boolHook = { + get: function(elem, name) { + // 转发到 prop 方法 + return DOM.prop(elem, name) ? + // 根据 w3c attribute , true 时返回属性名字符串 + name.toLowerCase() : + undefined; + }, + set: function(elem, value, name) { + var propName; + if (value === false) { + // Remove boolean attributes when set to false + DOM.removeAttr(elem, name); + } else { + // 直接设置 true,因为这是 bool 类属性 + propName = propFix[ name ] || name; + if (propName in elem) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + elem.setAttribute(name, name.toLowerCase()); + } + return name; + } + }, + propHooks = {}, + // get attribute value from attribute node , only for ie + attrNodeHook = { + }, + valHooks = { + option: { + get: function(elem) { + // 当没有设定 value 时,标准浏览器 option.value === option.text + // ie7- 下,没有设定 value 时,option.value === '', 需要用 el.attributes.value 来判断是否有设定 value + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + // 对于 select, 特别是 multiple type, 存在很严重的兼容性问题 + get: function(elem) { + var index = elem.selectedIndex, + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if (index < 0) { + return null; + } else if (one) { + return DOM.val(options[index]); + } + + // Loop through all the selected options + var ret = [], i = 0, len = options.length; + for (; i < len; ++i) { + if (options[i].selected) { + ret.push(DOM.val(options[i])); + } + } + // Multi-Selects return an array + return ret; + }, + + set: function(elem, value) { + var values = S.makeArray(value), + opts = elem.options; + S.each(opts, function(opt) { + opt.selected = S.inArray(DOM.val(opt), values); + }); + + if (!values.length) { + elem.selectedIndex = -1; + } + return values; + } + }}; + + function isTextNode(elem) { + return DOM._nodeTypeIs(elem, DOM.TEXT_NODE); + } + + if (oldIE) { + + // get attribute value from attribute node for ie + attrNodeHook = { + get: function(elem, name) { + var ret; + ret = elem.getAttributeNode(name); + // Return undefined if nodeValue is empty string + return ret && ret.nodeValue !== "" ? + ret.nodeValue : + undefined; + }, + set: function(elem, value, name) { + // Check form objects in IE (multiple bugs related) + // Only use nodeValue if the attribute node exists on the form + var ret = elem.getAttributeNode(name); + if (ret) { + ret.nodeValue = value; + } else { + try { + var attr = elem.ownerDocument.createAttribute(name); + attr.value = value; + elem.setAttributeNode(attr); + } + catch (e) { + // It's a real failure only if setAttribute also fails. + return elem.setAttribute(name, value, 0); + } + } + } + }; + + + // ie6,7 不区分 attribute 与 property + attrFix = propFix; + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + attrHooks.tabIndex = attrHooks.tabindex; + // fix ie bugs + // 不光是 href, src, 还有 rowspan 等非 mapping 属性,也需要用第 2 个参数来获取原始值 + // 注意 colSpan rowSpan 已经由 propFix 转为大写 + S.each([ "href", "src", "width", "height","colSpan","rowSpan" ], function(name) { + attrHooks[ name ] = { + get: function(elem) { + var ret = elem.getAttribute(name, 2); + return ret === null ? undefined : ret; + } + }; + }); + // button 元素的 value 属性和其内容冲突 + // + valHooks.button = attrHooks.value = attrNodeHook; + } + + // Radios and checkboxes getter/setter + + S.each([ "radio", "checkbox" ], function(r) { + valHooks[ r ] = { + get: function(elem) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }, + set: function(elem, value) { + if (S.isArray(value)) { + return elem.checked = S.inArray(DOM.val(elem), value); + } + } + + }; + }); + + function getProp(elem, name) { + name = propFix[ name ] || name; + var hook = propHooks[ name ]; + if (hook && hook.get) { + return hook.get(elem, name); + + } else { + return elem[ name ]; + } + } + + S.mix(DOM, { + + /** + * 自定义属性不推荐使用,使用 .data + * @param selector + * @param name + * @param value + */ + prop: function(selector, name, value) { + // suports hash + if (S.isPlainObject(name)) { + for (var k in name) { + DOM.prop(selector, k, name[k]); + } + return; + } + var elems = DOM.query(selector); + // Try to normalize/fix the name + name = propFix[ name ] || name; + var hook = propHooks[ name ]; + if (value !== undefined) { + elems.each(function(elem) { + if (hook && hook.set) { + hook.set(elem, value, name); + } else { + elem[ name ] = value; + } + }); + } else { + if (elems.length) { + return getProp(elems[0], name); + } + } + }, + + /** + * 是否其中一个元素包含指定 property + * @param selector + * @param name + */ + hasProp:function(selector, name) { + var elems = DOM.query(selector); + for (var i = 0; i < elems.length; i++) { + var el = elems[i]; + if (getProp(el, name) !== undefined) { + return true; + } + } + return false; + }, + + /** + * 不推荐使用,使用 .data .removeData + * @param selector + * @param name + */ + removeProp:function(selector, name) { + name = propFix[ name ] || name; + DOM.query(selector).each(function(el) { + try { + el[ name ] = undefined; + delete el[ name ]; + } catch(e) { + S.log("delete el property error : "); + S.log(e); + } + }); + }, + + /** + * Gets the value of an attribute for the first element in the set of matched elements or + * Sets an attribute for the set of matched elements. + */ + attr:function(selector, name, val, pass) { + /* + Hazards From Caja Note: + + - In IE[67], el.setAttribute doesn't work for attributes like + 'class' or 'for'. IE[67] expects you to set 'className' or + 'htmlFor'. Caja use setAttributeNode solves this problem. + + - In IE[67], elements can shadow attributes. If el is a + form that contains an named x, then el.setAttribute(x, y) + will set x's value rather than setting el's attribute. Using + setAttributeNode solves this problem. + + - In IE[67], the style attribute can only be modified by setting + el.style.cssText. Neither setAttribute nor setAttributeNode will + work. el.style.cssText isn't bullet-proof, since it can be + shadowed by elements. + + - In IE[67], you can never change the type of an ' + this.options.header + '' : ''; + var searchbox = this.options.liveSearch ? + '' + : ''; + var actionsbox = this.multiple && this.options.actionsBox ? + '
            ' + + '
            ' + + '' + + '' + + '
            ' + + '
            ' + : ''; + var donebutton = this.multiple && this.options.doneButton ? + '
            ' + + '
            ' + + '' + + '
            ' + + '
            ' + : ''; + var drop = + '
            ' + + '' + + '' + + '
            '; + + return $(drop); + }, + + createView: function () { + var $drop = this.createDropdown(), + li = this.createLi(); + + $drop.find('ul')[0].innerHTML = li; + return $drop; + }, + + reloadLi: function () { + //Remove all children. + this.destroyLi(); + //Re build + var li = this.createLi(); + this.$menuInner[0].innerHTML = li; + }, + + destroyLi: function () { + this.$menu.find('li').remove(); + }, + + createLi: function () { + var that = this, + _li = [], + optID = 0, + titleOption = document.createElement('option'), + liIndex = -1; // increment liIndex whenever a new
          • element is created to ensure liObj is correct + + // Helper functions + /** + * @param content + * @param [index] + * @param [classes] + * @param [optgroup] + * @returns {string} + */ + var generateLI = function (content, index, classes, optgroup) { + return '' + content + '
          • '; + }; + + /** + * @param text + * @param [classes] + * @param [inline] + * @param [tokens] + * @returns {string} + */ + var generateA = function (text, classes, inline, tokens) { + return '' + text + + '' + + ''; + }; + + if (this.options.title && !this.multiple) { + // this option doesn't create a new
          • element, but does add a new option, so liIndex is decreased + // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended + liIndex--; + + if (!this.$element.find('.bs-title-option').length) { + // Use native JS to prepend option (faster) + var element = this.$element[0]; + titleOption.className = 'bs-title-option'; + titleOption.appendChild(document.createTextNode(this.options.title)); + titleOption.value = ''; + element.insertBefore(titleOption, element.firstChild); + // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option. + // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs, + // if so, the select will have the data-selected attribute + var $opt = $(element.options[element.selectedIndex]); + if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) { + titleOption.selected = true; + } + } + } + + this.$element.find('option').each(function (index) { + var $this = $(this); + + liIndex++; + + if ($this.hasClass('bs-title-option')) return; + + // Get the class and text for the option + var optionClass = this.className || '', + inline = this.style.cssText, + text = $this.data('content') ? $this.data('content') : $this.html(), + tokens = $this.data('tokens') ? $this.data('tokens') : null, + subtext = typeof $this.data('subtext') !== 'undefined' ? '' + $this.data('subtext') + '' : '', + icon = typeof $this.data('icon') !== 'undefined' ? ' ' : '', + $parent = $this.parent(), + isOptgroup = $parent[0].tagName === 'OPTGROUP', + isOptgroupDisabled = isOptgroup && $parent[0].disabled, + isDisabled = this.disabled || isOptgroupDisabled; + + if (icon !== '' && isDisabled) { + icon = '' + icon + ''; + } + + if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) { + liIndex--; + return; + } + + if (!$this.data('content')) { + // Prepend any icon and append any subtext to the main text. + text = icon + '' + text + subtext + ''; + } + + if (isOptgroup && $this.data('divider') !== true) { + if (that.options.hideDisabled && isDisabled) { + if ($parent.data('allOptionsDisabled') === undefined) { + var $options = $parent.children(); + $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length); + } + + if ($parent.data('allOptionsDisabled')) { + liIndex--; + return; + } + } + + var optGroupClass = ' ' + $parent[0].className || ''; + + if ($this.index() === 0) { // Is it the first option of the optgroup? + optID += 1; + + // Get the opt group label + var label = $parent[0].label, + labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '' + $parent.data('subtext') + '' : '', + labelIcon = $parent.data('icon') ? ' ' : ''; + + label = labelIcon + '' + label + labelSubtext + ''; + + if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown? + liIndex++; + _li.push(generateLI('', null, 'divider', optID + 'div')); + } + liIndex++; + _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID)); + } + + if (that.options.hideDisabled && isDisabled) { + liIndex--; + return; + } + + _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID)); + } else if ($this.data('divider') === true) { + _li.push(generateLI('', index, 'divider')); + } else if ($this.data('hidden') === true) { + _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden')); + } else { + var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP'; + + // if previous element is not an optgroup and hideDisabled is true + if (!showDivider && that.options.hideDisabled) { + // get previous elements + var $prev = $(this).prevAll(); + + for (var i = 0; i < $prev.length; i++) { + // find the first element in the previous elements that is an optgroup + if ($prev[i].tagName === 'OPTGROUP') { + var optGroupDistance = 0; + + // loop through the options in between the current option and the optgroup + // and check if they are hidden or disabled + for (var d = 0; d < i; d++) { + var prevOption = $prev[d]; + if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++; + } + + // if all of the options between the current option and the optgroup are hidden or disabled, show the divider + if (optGroupDistance === i) showDivider = true; + + break; + } + } + } + + if (showDivider) { + liIndex++; + _li.push(generateLI('', null, 'divider', optID + 'div')); + } + _li.push(generateLI(generateA(text, optionClass, inline, tokens), index)); + } + + that.liObj[index] = liIndex; + }); + + //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button + if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) { + this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected'); + } + + return _li.join(''); + }, + + findLis: function () { + if (this.$lis == null) this.$lis = this.$menu.find('li'); + return this.$lis; + }, + + /** + * @param [updateLi] defaults to true + */ + render: function (updateLi) { + var that = this, + notDisabled; + + //Update the LI to match the SELECT + if (updateLi !== false) { + this.$element.find('option').each(function (index) { + var $lis = that.findLis().eq(that.liObj[index]); + + that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis); + that.setSelected(index, this.selected, $lis); + }); + } + + this.togglePlaceholder(); + + this.tabIndex(); + + var selectedItems = this.$element.find('option').map(function () { + if (this.selected) { + if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return; + + var $this = $(this), + icon = $this.data('icon') && that.options.showIcon ? ' ' : '', + subtext; + + if (that.options.showSubtext && $this.data('subtext') && !that.multiple) { + subtext = ' ' + $this.data('subtext') + ''; + } else { + subtext = ''; + } + if (typeof $this.attr('title') !== 'undefined') { + return $this.attr('title'); + } else if ($this.data('content') && that.options.showContent) { + return $this.data('content'); + } else { + return icon + $this.html() + subtext; + } + } + }).toArray(); + + //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled + //Convert all the values into a comma delimited string + var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator); + + //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc.. + if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) { + var max = this.options.selectedTextFormat.split('>'); + if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) { + notDisabled = this.options.hideDisabled ? ', [disabled]' : ''; + var totalCount = this.$element.find('option').not('[data-divider="true"], [data-hidden="true"]' + notDisabled).length, + tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText; + title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString()); + } + } + + if (this.options.title == undefined) { + this.options.title = this.$element.attr('title'); + } + + if (this.options.selectedTextFormat == 'static') { + title = this.options.title; + } + + //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text + if (!title) { + title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText; + } + + //strip all html-tags and trim the result + this.$button.attr('title', $.trim(title.replace(/<[^>]*>?/g, ''))); + this.$button.children('.filter-option').html(title); + + this.$element.trigger('rendered.bs.select'); + }, + + /** + * @param [style] + * @param [status] + */ + setStyle: function (style, status) { + if (this.$element.attr('class')) { + this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, '')); + } + + var buttonClass = style ? style : this.options.style; + + if (status == 'add') { + this.$button.addClass(buttonClass); + } else if (status == 'remove') { + this.$button.removeClass(buttonClass); + } else { + this.$button.removeClass(this.options.style); + this.$button.addClass(buttonClass); + } + }, + + liHeight: function (refresh) { + if (!refresh && (this.options.size === false || this.sizeInfo)) return; + + var newElement = document.createElement('div'), + menu = document.createElement('div'), + menuInner = document.createElement('ul'), + divider = document.createElement('li'), + li = document.createElement('li'), + a = document.createElement('a'), + text = document.createElement('span'), + header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null, + search = this.options.liveSearch ? document.createElement('div') : null, + actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null, + doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null; + + text.className = 'text'; + newElement.className = this.$menu[0].parentNode.className + ' open'; + menu.className = 'dropdown-menu open'; + menuInner.className = 'dropdown-menu inner'; + divider.className = 'divider'; + + text.appendChild(document.createTextNode('Inner text')); + a.appendChild(text); + li.appendChild(a); + menuInner.appendChild(li); + menuInner.appendChild(divider); + if (header) menu.appendChild(header); + if (search) { + // create a span instead of input as creating an input element is slower + var input = document.createElement('span'); + search.className = 'bs-searchbox'; + input.className = 'form-control'; + search.appendChild(input); + menu.appendChild(search); + } + if (actions) menu.appendChild(actions); + menu.appendChild(menuInner); + if (doneButton) menu.appendChild(doneButton); + newElement.appendChild(menu); + + document.body.appendChild(newElement); + + var liHeight = a.offsetHeight, + headerHeight = header ? header.offsetHeight : 0, + searchHeight = search ? search.offsetHeight : 0, + actionsHeight = actions ? actions.offsetHeight : 0, + doneButtonHeight = doneButton ? doneButton.offsetHeight : 0, + dividerHeight = $(divider).outerHeight(true), + // fall back to jQuery if getComputedStyle is not supported + menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false, + $menu = menuStyle ? null : $(menu), + menuPadding = { + vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) + + parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) + + parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) + + parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')), + horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) + + parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) + + parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) + + parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth')) + }, + menuExtras = { + vert: menuPadding.vert + + parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) + + parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2, + horiz: menuPadding.horiz + + parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) + + parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2 + } + + document.body.removeChild(newElement); + + this.sizeInfo = { + liHeight: liHeight, + headerHeight: headerHeight, + searchHeight: searchHeight, + actionsHeight: actionsHeight, + doneButtonHeight: doneButtonHeight, + dividerHeight: dividerHeight, + menuPadding: menuPadding, + menuExtras: menuExtras + }; + }, + + setSize: function () { + this.findLis(); + this.liHeight(); + + if (this.options.header) this.$menu.css('padding-top', 0); + if (this.options.size === false) return; + + var that = this, + $menu = this.$menu, + $menuInner = this.$menuInner, + $window = $(window), + selectHeight = this.$newElement[0].offsetHeight, + selectWidth = this.$newElement[0].offsetWidth, + liHeight = this.sizeInfo['liHeight'], + headerHeight = this.sizeInfo['headerHeight'], + searchHeight = this.sizeInfo['searchHeight'], + actionsHeight = this.sizeInfo['actionsHeight'], + doneButtonHeight = this.sizeInfo['doneButtonHeight'], + divHeight = this.sizeInfo['dividerHeight'], + menuPadding = this.sizeInfo['menuPadding'], + menuExtras = this.sizeInfo['menuExtras'], + notDisabled = this.options.hideDisabled ? '.disabled' : '', + menuHeight, + menuWidth, + getHeight, + getWidth, + selectOffsetTop, + selectOffsetBot, + selectOffsetLeft, + selectOffsetRight, + getPos = function() { + var pos = that.$newElement.offset(), + $container = $(that.options.container), + containerPos; + + if (that.options.container && !$container.is('body')) { + containerPos = $container.offset(); + containerPos.top += parseInt($container.css('borderTopWidth')); + containerPos.left += parseInt($container.css('borderLeftWidth')); + } else { + containerPos = { top: 0, left: 0 }; + } + + selectOffsetTop = pos.top - containerPos.top - $window.scrollTop(); + selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top; + selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft(); + selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left; + }; + + getPos(); + + if (this.options.size === 'auto') { + var getSize = function () { + var minHeight, + hasClass = function (className, include) { + return function (element) { + if (include) { + return (element.classList ? element.classList.contains(className) : $(element).hasClass(className)); + } else { + return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className)); + } + }; + }, + lis = that.$menuInner[0].getElementsByTagName('li'), + lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'), + optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header'); + + getPos(); + menuHeight = selectOffsetBot - menuExtras.vert; + menuWidth = selectOffsetRight - menuExtras.horiz; + + if (that.options.container) { + if (!$menu.data('height')) $menu.data('height', $menu.height()); + getHeight = $menu.data('height'); + + if (!$menu.data('width')) $menu.data('width', $menu.width()); + getWidth = $menu.data('width'); + } else { + getHeight = $menu.height(); + getWidth = $menu.width(); + } + + if (that.options.dropupAuto) { + that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight); + } + + if (that.$newElement.hasClass('dropup')) { + menuHeight = selectOffsetTop - menuExtras.vert; + } + + if (that.options.dropdownAlignRight === 'auto') { + $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth)); + } + + if ((lisVisible.length + optGroup.length) > 3) { + minHeight = liHeight * 3 + menuExtras.vert - 2; + } else { + minHeight = 0; + } + + $menu.css({ + 'max-height': menuHeight + 'px', + 'overflow': 'hidden', + 'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px' + }); + $menuInner.css({ + 'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px', + 'overflow-y': 'auto', + 'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px' + }); + }; + getSize(); + this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize); + $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize); + } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) { + var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(), + divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length; + menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert; + + if (that.options.container) { + if (!$menu.data('height')) $menu.data('height', $menu.height()); + getHeight = $menu.data('height'); + } else { + getHeight = $menu.height(); + } + + if (that.options.dropupAuto) { + //noinspection JSUnusedAssignment + this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight); + } + $menu.css({ + 'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px', + 'overflow': 'hidden', + 'min-height': '' + }); + $menuInner.css({ + 'max-height': menuHeight - menuPadding.vert + 'px', + 'overflow-y': 'auto', + 'min-height': '' + }); + } + }, + + setWidth: function () { + if (this.options.width === 'auto') { + this.$menu.css('min-width', '0'); + + // Get correct width if element is hidden + var $selectClone = this.$menu.parent().clone().appendTo('body'), + $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone, + ulWidth = $selectClone.children('.dropdown-menu').outerWidth(), + btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth(); + + $selectClone.remove(); + $selectClone2.remove(); + + // Set width to whatever's larger, button title or longest option + this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px'); + } else if (this.options.width === 'fit') { + // Remove inline min-width so width can be changed from 'auto' + this.$menu.css('min-width', ''); + this.$newElement.css('width', '').addClass('fit-width'); + } else if (this.options.width) { + // Remove inline min-width so width can be changed from 'auto' + this.$menu.css('min-width', ''); + this.$newElement.css('width', this.options.width); + } else { + // Remove inline min-width/width so width can be changed + this.$menu.css('min-width', ''); + this.$newElement.css('width', ''); + } + // Remove fit-width class if width is changed programmatically + if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') { + this.$newElement.removeClass('fit-width'); + } + }, + + selectPosition: function () { + this.$bsContainer = $('
            '); + + var that = this, + $container = $(this.options.container), + pos, + containerPos, + actualHeight, + getPlacement = function ($element) { + that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup')); + pos = $element.offset(); + + if (!$container.is('body')) { + containerPos = $container.offset(); + containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop(); + containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft(); + } else { + containerPos = { top: 0, left: 0 }; + } + + actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight; + + that.$bsContainer.css({ + 'top': pos.top - containerPos.top + actualHeight, + 'left': pos.left - containerPos.left, + 'width': $element[0].offsetWidth + }); + }; + + this.$button.on('click', function () { + var $this = $(this); + + if (that.isDisabled()) { + return; + } + + getPlacement(that.$newElement); + + that.$bsContainer + .appendTo(that.options.container) + .toggleClass('open', !$this.hasClass('open')) + .append(that.$menu); + }); + + $(window).on('resize scroll', function () { + getPlacement(that.$newElement); + }); + + this.$element.on('hide.bs.select', function () { + that.$menu.data('height', that.$menu.height()); + that.$bsContainer.detach(); + }); + }, + + /** + * @param {number} index - the index of the option that is being changed + * @param {boolean} selected - true if the option is being selected, false if being deselected + * @param {JQuery} $lis - the 'li' element that is being modified + */ + setSelected: function (index, selected, $lis) { + if (!$lis) { + this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select + $lis = this.findLis().eq(this.liObj[index]); + } + + $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected); + }, + + /** + * @param {number} index - the index of the option that is being disabled + * @param {boolean} disabled - true if the option is being disabled, false if being enabled + * @param {JQuery} $lis - the 'li' element that is being modified + */ + setDisabled: function (index, disabled, $lis) { + if (!$lis) { + $lis = this.findLis().eq(this.liObj[index]); + } + + if (disabled) { + $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true); + } else { + $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false); + } + }, + + isDisabled: function () { + return this.$element[0].disabled; + }, + + checkDisabled: function () { + var that = this; + + if (this.isDisabled()) { + this.$newElement.addClass('disabled'); + this.$button.addClass('disabled').attr('tabindex', -1); + } else { + if (this.$button.hasClass('disabled')) { + this.$newElement.removeClass('disabled'); + this.$button.removeClass('disabled'); + } + + if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) { + this.$button.removeAttr('tabindex'); + } + } + + this.$button.click(function () { + return !that.isDisabled(); + }); + }, + + togglePlaceholder: function () { + var value = this.$element.val(); + this.$button.toggleClass('bs-placeholder', value === null || value === ''); + }, + + tabIndex: function () { + if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && + (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) { + this.$element.data('tabindex', this.$element.attr('tabindex')); + this.$button.attr('tabindex', this.$element.data('tabindex')); + } + + this.$element.attr('tabindex', -98); + }, + + clickListener: function () { + var that = this, + $document = $(document); + + this.$newElement.on('touchstart.dropdown', '.dropdown-menu', function (e) { + e.stopPropagation(); + }); + + $document.data('spaceSelect', false); + + this.$button.on('keyup', function (e) { + if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) { + e.preventDefault(); + $document.data('spaceSelect', false); + } + }); + + this.$button.on('click', function () { + that.setSize(); + }); + + this.$element.on('shown.bs.select', function () { + if (!that.options.liveSearch && !that.multiple) { + that.$menuInner.find('.selected a').focus(); + } else if (!that.multiple) { + var selectedIndex = that.liObj[that.$element[0].selectedIndex]; + + if (typeof selectedIndex !== 'number' || that.options.size === false) return; + + // scroll to selected option + var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop; + offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2; + that.$menuInner[0].scrollTop = offset; + } + }); + + this.$menuInner.on('click', 'li a', function (e) { + var $this = $(this), + clickedIndex = $this.parent().data('originalIndex'), + prevValue = that.$element.val(), + prevIndex = that.$element.prop('selectedIndex'), + triggerChange = true; + + // Don't close on multi choice menu + if (that.multiple && that.options.maxOptions !== 1) { + e.stopPropagation(); + } + + e.preventDefault(); + + //Don't run if we have been disabled + if (!that.isDisabled() && !$this.parent().hasClass('disabled')) { + var $options = that.$element.find('option'), + $option = $options.eq(clickedIndex), + state = $option.prop('selected'), + $optgroup = $option.parent('optgroup'), + maxOptions = that.options.maxOptions, + maxOptionsGrp = $optgroup.data('maxOptions') || false; + + if (!that.multiple) { // Deselect all others if not multi select box + $options.prop('selected', false); + $option.prop('selected', true); + that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false); + that.setSelected(clickedIndex, true); + } else { // Toggle the one we have chosen if we are multi select. + $option.prop('selected', !state); + that.setSelected(clickedIndex, !state); + $this.blur(); + + if (maxOptions !== false || maxOptionsGrp !== false) { + var maxReached = maxOptions < $options.filter(':selected').length, + maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length; + + if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) { + if (maxOptions && maxOptions == 1) { + $options.prop('selected', false); + $option.prop('selected', true); + that.$menuInner.find('.selected').removeClass('selected'); + that.setSelected(clickedIndex, true); + } else if (maxOptionsGrp && maxOptionsGrp == 1) { + $optgroup.find('option:selected').prop('selected', false); + $option.prop('selected', true); + var optgroupID = $this.parent().data('optgroup'); + that.$menuInner.find('[data-optgroup="' + optgroupID + '"]').removeClass('selected'); + that.setSelected(clickedIndex, true); + } else { + var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText, + maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText, + maxTxt = maxOptionsArr[0].replace('{n}', maxOptions), + maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp), + $notify = $('
            '); + // If {var} is set in array, replace it + /** @deprecated */ + if (maxOptionsArr[2]) { + maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]); + maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]); + } + + $option.prop('selected', false); + + that.$menu.append($notify); + + if (maxOptions && maxReached) { + $notify.append($('
            ' + maxTxt + '
            ')); + triggerChange = false; + that.$element.trigger('maxReached.bs.select'); + } + + if (maxOptionsGrp && maxReachedGrp) { + $notify.append($('
            ' + maxTxtGrp + '
            ')); + triggerChange = false; + that.$element.trigger('maxReachedGrp.bs.select'); + } + + setTimeout(function () { + that.setSelected(clickedIndex, false); + }, 10); + + $notify.delay(750).fadeOut(300, function () { + $(this).remove(); + }); + } + } + } + } + + if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) { + that.$button.focus(); + } else if (that.options.liveSearch) { + that.$searchbox.focus(); + } + + // Trigger select 'change' + if (triggerChange) { + if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) { + // $option.prop('selected') is current option state (selected/unselected). state is previous option state. + changed_arguments = [clickedIndex, $option.prop('selected'), state]; + that.$element + .triggerNative('change'); + } + } + } + }); + + this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) { + if (e.currentTarget == this) { + e.preventDefault(); + e.stopPropagation(); + if (that.options.liveSearch && !$(e.target).hasClass('close')) { + that.$searchbox.focus(); + } else { + that.$button.focus(); + } + } + }); + + this.$menuInner.on('click', '.divider, .dropdown-header', function (e) { + e.preventDefault(); + e.stopPropagation(); + if (that.options.liveSearch) { + that.$searchbox.focus(); + } else { + that.$button.focus(); + } + }); + + this.$menu.on('click', '.popover-title .close', function () { + that.$button.click(); + }); + + this.$searchbox.on('click', function (e) { + e.stopPropagation(); + }); + + this.$menu.on('click', '.actions-btn', function (e) { + if (that.options.liveSearch) { + that.$searchbox.focus(); + } else { + that.$button.focus(); + } + + e.preventDefault(); + e.stopPropagation(); + + if ($(this).hasClass('bs-select-all')) { + that.selectAll(); + } else { + that.deselectAll(); + } + }); + + this.$element.change(function () { + that.render(false); + that.$element.trigger('changed.bs.select', changed_arguments); + changed_arguments = null; + }); + }, + + liveSearchListener: function () { + var that = this, + $no_results = $('
          • '); + + this.$button.on('click.dropdown.data-api touchstart.dropdown.data-api', function () { + that.$menuInner.find('.active').removeClass('active'); + if (!!that.$searchbox.val()) { + that.$searchbox.val(''); + that.$lis.not('.is-hidden').removeClass('hidden'); + if (!!$no_results.parent().length) $no_results.remove(); + } + if (!that.multiple) that.$menuInner.find('.selected').addClass('active'); + setTimeout(function () { + that.$searchbox.focus(); + }, 10); + }); + + this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) { + e.stopPropagation(); + }); + + this.$searchbox.on('input propertychange', function () { + if (that.$searchbox.val()) { + var $searchBase = that.$lis.not('.is-hidden').removeClass('hidden').children('a'); + if (that.options.liveSearchNormalize) { + $searchBase = $searchBase.not(':a' + that._searchStyle() + '("' + normalizeToBase(that.$searchbox.val()) + '")'); + } else { + $searchBase = $searchBase.not(':' + that._searchStyle() + '("' + that.$searchbox.val() + '")'); + } + $searchBase.parent().addClass('hidden'); + + that.$lis.filter('.dropdown-header').each(function () { + var $this = $(this), + optgroup = $this.data('optgroup'); + + if (that.$lis.filter('[data-optgroup=' + optgroup + ']').not($this).not('.hidden').length === 0) { + $this.addClass('hidden'); + that.$lis.filter('[data-optgroup=' + optgroup + 'div]').addClass('hidden'); + } + }); + + var $lisVisible = that.$lis.not('.hidden'); + + // hide divider if first or last visible, or if followed by another divider + $lisVisible.each(function (index) { + var $this = $(this); + + if ($this.hasClass('divider') && ( + $this.index() === $lisVisible.first().index() || + $this.index() === $lisVisible.last().index() || + $lisVisible.eq(index + 1).hasClass('divider'))) { + $this.addClass('hidden'); + } + }); + + if (!that.$lis.not('.hidden, .no-results').length) { + if (!!$no_results.parent().length) { + $no_results.remove(); + } + $no_results.html(that.options.noneResultsText.replace('{0}', '"' + htmlEscape(that.$searchbox.val()) + '"')).show(); + that.$menuInner.append($no_results); + } else if (!!$no_results.parent().length) { + $no_results.remove(); + } + } else { + that.$lis.not('.is-hidden').removeClass('hidden'); + if (!!$no_results.parent().length) { + $no_results.remove(); + } + } + + that.$lis.filter('.active').removeClass('active'); + if (that.$searchbox.val()) that.$lis.not('.hidden, .divider, .dropdown-header').eq(0).addClass('active').children('a').focus(); + $(this).focus(); + }); + }, + + _searchStyle: function () { + var styles = { + begins: 'ibegins', + startsWith: 'ibegins' + }; + + return styles[this.options.liveSearchStyle] || 'icontains'; + }, + + val: function (value) { + if (typeof value !== 'undefined') { + this.$element.val(value); + this.render(); + + return this.$element; + } else { + return this.$element.val(); + } + }, + + changeAll: function (status) { + if (!this.multiple) return; + if (typeof status === 'undefined') status = true; + + this.findLis(); + + var $options = this.$element.find('option'), + $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'), + lisVisLen = $lisVisible.length, + selectedOptions = []; + + if (status) { + if ($lisVisible.filter('.selected').length === $lisVisible.length) return; + } else { + if ($lisVisible.filter('.selected').length === 0) return; + } + + $lisVisible.toggleClass('selected', status); + + for (var i = 0; i < lisVisLen; i++) { + var origIndex = $lisVisible[i].getAttribute('data-original-index'); + selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0]; + } + + $(selectedOptions).prop('selected', status); + + this.render(false); + + this.togglePlaceholder(); + + this.$element + .triggerNative('change'); + }, + + selectAll: function () { + return this.changeAll(true); + }, + + deselectAll: function () { + return this.changeAll(false); + }, + + toggle: function (e) { + e = e || window.event; + + if (e) e.stopPropagation(); + + this.$button.trigger('click'); + }, + + keydown: function (e) { + var $this = $(this), + $parent = $this.is('input') ? $this.parent().parent() : $this.parent(), + $items, + that = $parent.data('this'), + index, + next, + first, + last, + prev, + nextPrev, + prevIndex, + isActive, + selector = ':not(.disabled, .hidden, .dropdown-header, .divider)', + keyCodeMap = { + 32: ' ', + 48: '0', + 49: '1', + 50: '2', + 51: '3', + 52: '4', + 53: '5', + 54: '6', + 55: '7', + 56: '8', + 57: '9', + 59: ';', + 65: 'a', + 66: 'b', + 67: 'c', + 68: 'd', + 69: 'e', + 70: 'f', + 71: 'g', + 72: 'h', + 73: 'i', + 74: 'j', + 75: 'k', + 76: 'l', + 77: 'm', + 78: 'n', + 79: 'o', + 80: 'p', + 81: 'q', + 82: 'r', + 83: 's', + 84: 't', + 85: 'u', + 86: 'v', + 87: 'w', + 88: 'x', + 89: 'y', + 90: 'z', + 96: '0', + 97: '1', + 98: '2', + 99: '3', + 100: '4', + 101: '5', + 102: '6', + 103: '7', + 104: '8', + 105: '9' + }; + + if (that.options.liveSearch) $parent = $this.parent().parent(); + + if (that.options.container) $parent = that.$menu; + + $items = $('[role="listbox"] li', $parent); + + isActive = that.$newElement.hasClass('open'); + + if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) { + if (!that.options.container) { + that.setSize(); + that.$menu.parent().addClass('open'); + isActive = true; + } else { + that.$button.trigger('click'); + } + that.$searchbox.focus(); + return; + } + + if (that.options.liveSearch) { + if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) { + e.preventDefault(); + e.stopPropagation(); + that.$button.click().focus(); + } + // $items contains li elements when liveSearch is enabled + $items = $('[role="listbox"] li' + selector, $parent); + if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) { + if ($items.filter('.active').length === 0) { + $items = that.$menuInner.find('li'); + if (that.options.liveSearchNormalize) { + $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')'); + } else { + $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')'); + } + } + } + } + + if (!$items.length) return; + + if (/(38|40)/.test(e.keyCode.toString(10))) { + index = $items.index($items.find('a').filter(':focus').parent()); + first = $items.filter(selector).first().index(); + last = $items.filter(selector).last().index(); + next = $items.eq(index).nextAll(selector).eq(0).index(); + prev = $items.eq(index).prevAll(selector).eq(0).index(); + nextPrev = $items.eq(next).prevAll(selector).eq(0).index(); + + if (that.options.liveSearch) { + $items.each(function (i) { + if (!$(this).hasClass('disabled')) { + $(this).data('index', i); + } + }); + index = $items.index($items.filter('.active')); + first = $items.first().data('index'); + last = $items.last().data('index'); + next = $items.eq(index).nextAll().eq(0).data('index'); + prev = $items.eq(index).prevAll().eq(0).data('index'); + nextPrev = $items.eq(next).prevAll().eq(0).data('index'); + } + + prevIndex = $this.data('prevIndex'); + + if (e.keyCode == 38) { + if (that.options.liveSearch) index--; + if (index != nextPrev && index > prev) index = prev; + if (index < first) index = first; + if (index == prevIndex) index = last; + } else if (e.keyCode == 40) { + if (that.options.liveSearch) index++; + if (index == -1) index = 0; + if (index != nextPrev && index < next) index = next; + if (index > last) index = last; + if (index == prevIndex) index = first; + } + + $this.data('prevIndex', index); + + if (!that.options.liveSearch) { + $items.eq(index).children('a').focus(); + } else { + e.preventDefault(); + if (!$this.hasClass('dropdown-toggle')) { + $items.removeClass('active').eq(index).addClass('active').children('a').focus(); + $this.focus(); + } + } + + } else if (!$this.is('input')) { + var keyIndex = [], + count, + prevKey; + + $items.each(function () { + if (!$(this).hasClass('disabled')) { + if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) { + keyIndex.push($(this).index()); + } + } + }); + + count = $(document).data('keycount'); + count++; + $(document).data('keycount', count); + + prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1); + + if (prevKey != keyCodeMap[e.keyCode]) { + count = 1; + $(document).data('keycount', count); + } else if (count >= keyIndex.length) { + $(document).data('keycount', 0); + if (count > keyIndex.length) count = 1; + } + + $items.eq(keyIndex[count - 1]).children('a').focus(); + } + + // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu. + if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) { + if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault(); + if (!that.options.liveSearch) { + var elem = $(':focus'); + elem.click(); + // Bring back focus for multiselects + elem.focus(); + // Prevent screen from scrolling if the user hit the spacebar + e.preventDefault(); + // Fixes spacebar selection of dropdown items in FF & IE + $(document).data('spaceSelect', true); + } else if (!/(32)/.test(e.keyCode.toString(10))) { + that.$menuInner.find('.active a').click(); + $this.focus(); + } + $(document).data('keycount', 0); + } + + if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) { + that.$menu.parent().removeClass('open'); + if (that.options.container) that.$newElement.removeClass('open'); + that.$button.focus(); + } + }, + + mobile: function () { + this.$element.addClass('mobile-device'); + }, + + refresh: function () { + this.$lis = null; + this.liObj = {}; + this.reloadLi(); + this.render(); + this.checkDisabled(); + this.liHeight(true); + this.setStyle(); + this.setWidth(); + if (this.$lis) this.$searchbox.trigger('propertychange'); + + this.$element.trigger('refreshed.bs.select'); + }, + + hide: function () { + this.$newElement.hide(); + }, + + show: function () { + this.$newElement.show(); + }, + + remove: function () { + this.$newElement.remove(); + this.$element.remove(); + }, + + destroy: function () { + this.$newElement.before(this.$element).remove(); + + if (this.$bsContainer) { + this.$bsContainer.remove(); + } else { + this.$menu.remove(); + } + + this.$element + .off('.bs.select') + .removeData('selectpicker') + .removeClass('bs-select-hidden selectpicker'); + } + }; + + // SELECTPICKER PLUGIN DEFINITION + // ============================== + function Plugin(option, event) { + // get the args of the outer function.. + var args = arguments; + // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them + // to get lost/corrupted in android 2.3 and IE9 #715 #775 + var _option = option, + _event = event; + [].shift.apply(args); + + var value; + var chain = this.each(function () { + var $this = $(this); + if ($this.is('select')) { + var data = $this.data('selectpicker'), + options = typeof _option == 'object' && _option; + + if (!data) { + var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options); + config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template); + $this.data('selectpicker', (data = new Selectpicker(this, config, _event))); + } else if (options) { + for (var i in options) { + if (options.hasOwnProperty(i)) { + data.options[i] = options[i]; + } + } + } + + if (typeof _option == 'string') { + if (data[_option] instanceof Function) { + value = data[_option].apply(data, args); + } else { + value = data.options[_option]; + } + } + } + }); + + if (typeof value !== 'undefined') { + //noinspection JSUnusedAssignment + return value; + } else { + return chain; + } + } + + var old = $.fn.selectpicker; + $.fn.selectpicker = Plugin; + $.fn.selectpicker.Constructor = Selectpicker; + + // SELECTPICKER NO CONFLICT + // ======================== + $.fn.selectpicker.noConflict = function () { + $.fn.selectpicker = old; + return this; + }; + + $(document) + .data('keycount', 0) + .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="listbox"], .bs-searchbox input', Selectpicker.prototype.keydown) + .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="listbox"], .bs-searchbox input', function (e) { + e.stopPropagation(); + }); + + // SELECTPICKER DATA-API + // ===================== + $(window).on('load.bs.select.data-api', function () { + $('.selectpicker').each(function () { + var $selectpicker = $(this); + Plugin.call($selectpicker, $selectpicker.data()); + }) + }); +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-ar_AR.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-ar_AR.js new file mode 100644 index 0000000000000000000000000000000000000000..07f14dc5b6b0f62c2627ef46d29ee858c0c5aa36 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-ar_AR.js @@ -0,0 +1,23 @@ +/*! + * Translated default messages for bootstrap-select. + * Locale: AR (Arabic) + * Author: Yasser Lotfy + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'لم يتم إختيار شئ', + noneResultsText: 'لا توجد نتائج مطابقة لـ {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} خيار تم إختياره" : "{0} خيارات تمت إختيارها"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)', + (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)' + ]; + }, + selectAllText: 'إختيار الجميع', + deselectAllText: 'إلغاء إختيار الجميع', + multipleSeparator: '، ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-bg_BG.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-bg_BG.js new file mode 100644 index 0000000000000000000000000000000000000000..4d99b60b32a2261634c557dc3f707c2a377de06a --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-bg_BG.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: BG (Bulgaria) + * Region: BG (Bulgaria) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Нищо избрано', + noneResultsText: 'Няма резултат за {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} избран елемент" : "{0} избрани елемента"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)', + (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)' + ]; + }, + selectAllText: 'Избери всички', + deselectAllText: 'Размаркирай всички', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-cro_CRO.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-cro_CRO.js new file mode 100644 index 0000000000000000000000000000000000000000..57198956849db123fd4e5b9602ecbe129601c1d9 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-cro_CRO.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: CRO (Croatia) + * Region: CRO (Croatia) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Odaberite stavku', + noneResultsText: 'Nema rezultata pretrage {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} stavka selektirana" : "{0} stavke selektirane"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)', + (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)' + ]; + }, + selectAllText: 'Selektiraj sve', + deselectAllText: 'Deselektiraj sve', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-cs_CZ.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-cs_CZ.js new file mode 100644 index 0000000000000000000000000000000000000000..d4572795498f07770e93095d2eb5041ff80a3ea1 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-cs_CZ.js @@ -0,0 +1,14 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: CS + * Region: CZ (Czech Republic) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Nic není vybráno', + noneResultsText: 'Žádné výsledky {0}', + countSelectedText: 'Označeno {0} z {1}', + maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-da_DK.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-da_DK.js new file mode 100644 index 0000000000000000000000000000000000000000..5376021ab1cef622a25a714a617eb12dcdf88b0f --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-da_DK.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: DA (Danish) + * Region: DK (Denmark) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Intet valgt', + noneResultsText: 'Ingen resultater fundet {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} valgt" : "{0} valgt"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)', + (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)' + ]; + }, + selectAllText: 'Markér alle', + deselectAllText: 'Afmarkér alle', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-de_DE.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-de_DE.js new file mode 100644 index 0000000000000000000000000000000000000000..d5f5729aa7ce013c9e363c22f0b1292e89ae3d27 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-de_DE.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: DE (German, deutsch) + * Region: DE (Germany, Deutschland) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Bitte wählen...', + noneResultsText: 'Keine Ergebnisse für {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} Element ausgewählt" : "{0} Elemente ausgewählt"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)', + (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)' + ]; + }, + selectAllText: 'Alles auswählen', + deselectAllText: 'Nichts auswählen', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-en_US.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-en_US.js new file mode 100644 index 0000000000000000000000000000000000000000..acb90352d4cb55959a2f62695f8adef90258509f --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-en_US.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: EN (English) + * Region: US (United States) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Nothing selected', + noneResultsText: 'No results match {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} item selected" : "{0} items selected"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)', + (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)' + ]; + }, + selectAllText: 'Select All', + deselectAllText: 'Deselect All', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-es_CL.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-es_CL.js new file mode 100644 index 0000000000000000000000000000000000000000..ed17a5f4a8d2b8d968bd5fafc82fc41eb51f6135 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-es_CL.js @@ -0,0 +1,14 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: ES (Spanish) + * Region: CL (Chile) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'No hay selección', + noneResultsText: 'No hay resultados {0}', + countSelectedText: 'Seleccionados {0} de {1}', + maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-eu.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-eu.js new file mode 100644 index 0000000000000000000000000000000000000000..037c7d7c0d72d4a89ab83fe1b51c7e47c50db776 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-eu.js @@ -0,0 +1,14 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: EU (Basque) + * Region: + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Hautapenik ez', + noneResultsText: 'Emaitzarik ez {0}', + countSelectedText: '{1}(e)tik {0} hautatuta', + maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-fa_IR.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-fa_IR.js new file mode 100644 index 0000000000000000000000000000000000000000..00b179868f8d7b3a8bb34930030b2ba0335bb1f1 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-fa_IR.js @@ -0,0 +1,16 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: FA (Farsi) + * Region: IR (Iran) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'چیزی انتخاب نشده است', + noneResultsText: 'هیج مشابهی برای {0} پیدا نشد', + countSelectedText: "{0} از {1} مورد انتخاب شده", + maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'], + selectAllText: 'انتخاب همه', + deselectAllText: 'انتخاب هیچ کدام', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-fi_FI.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-fi_FI.js new file mode 100644 index 0000000000000000000000000000000000000000..c526cd79b221ccc890565a8fb249350a8d9cef82 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-fi_FI.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: FI (Finnish) + * Region: FI (Finland) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Ei valintoja', + noneResultsText: 'Ei hakutuloksia {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} valittu" : "{0} valitut"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)', + (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)' + ]; + }, + selectAllText: 'Valitse kaikki', + deselectAllText: 'Poista kaikki', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-fr_FR.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-fr_FR.js new file mode 100644 index 0000000000000000000000000000000000000000..30d8c403ac3b1a33c8f37bc5c177e267ad9bb788 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-fr_FR.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: FR (French; Français) + * Region: FR (France) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Aucune sélection', + noneResultsText: 'Aucun résultat pour {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected > 1) ? "{0} éléments sélectionnés" : "{0} élément sélectionné"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)', + (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)' + ]; + }, + multipleSeparator: ', ', + selectAllText: 'Tout Sélectionner', + deselectAllText: 'Tout Dé-selectionner', + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-hu_HU.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-hu_HU.js new file mode 100644 index 0000000000000000000000000000000000000000..99bc64406c1afbb383ed8b71df2dbfc93ed9c6da --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-hu_HU.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: HU (Hungarian) + * Region: HU (Hungary) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Válasszon!', + noneResultsText: 'Nincs találat {0}', + countSelectedText: function (numSelected, numTotal) { + return '{0} elem kiválasztva'; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + 'Legfeljebb {n} elem választható', + 'A csoportban legfeljebb {n} elem választható' + ]; + }, + selectAllText: 'Mind', + deselectAllText: 'Egyik sem', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-id_ID.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-id_ID.js new file mode 100644 index 0000000000000000000000000000000000000000..e7018b695cc09dbe2ec979c0c39795b6f669e77e --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-id_ID.js @@ -0,0 +1,16 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: ID (Indonesian; Bahasa Indonesia) + * Region: ID (Indonesia) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Tidak ada yang dipilih', + noneResultsText: 'Tidak ada yang cocok {0}', + countSelectedText: '{0} terpilih', + maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'], + selectAllText: 'Pilih Semua', + deselectAllText: 'Hapus Semua', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-it_IT.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-it_IT.js new file mode 100644 index 0000000000000000000000000000000000000000..3cf2e13f6c862589225932771d52b9f1f44b9ceb --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-it_IT.js @@ -0,0 +1,15 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: IT (Italian; italiano) + * Region: IT (Italy; Italia) + * Author: Michele Beltrame + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Nessuna selezione', + noneResultsText: 'Nessun risultato per {0}', + countSelectedText: 'Selezionati {0} di {1}', + maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-ko_KR.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-ko_KR.js new file mode 100644 index 0000000000000000000000000000000000000000..9583cc5612c08761add18d7235e5da90f0429f61 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-ko_KR.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: KO (Korean) + * Region: KR (South Korea) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: '항목을 선택해주세요', + noneResultsText: '{0} 검색 결과가 없습니다', + countSelectedText: function (numSelected, numTotal) { + return "{0}개를 선택하였습니다"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + '{n}개까지 선택 가능합니다', + '해당 그룹은 {n}개까지 선택 가능합니다' + ]; + }, + selectAllText: '전체선택', + deselectAllText: '전체해제', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-lt_LT.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-lt_LT.js new file mode 100644 index 0000000000000000000000000000000000000000..1a299a9f90b367edf55b569ccad97a4e9f650fa8 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-lt_LT.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: LT (Lithuanian) + * Region: LT (Lithuania) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Niekas nepasirinkta', + noneResultsText: 'Niekas nesutapo su {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} elementas pasirinktas" : "{0} elementai(-ų) pasirinkta"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)', + (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)' + ]; + }, + selectAllText: 'Pasirinkti visus', + deselectAllText: 'Atmesti visus', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-nb_NO.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-nb_NO.js new file mode 100644 index 0000000000000000000000000000000000000000..e5bb914f1a99864e7782c4d0d356fbaa55bbbad1 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-nb_NO.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: NB (Norwegian; Bokmål) + * Region: NO (Norway) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Ingen valgt', + noneResultsText: 'Søket gir ingen treff {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} alternativ valgt" : "{0} alternativer valgt"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)', + (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)' + ]; + }, + selectAllText: 'Merk alle', + deselectAllText: 'Fjern alle', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-nl_NL.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-nl_NL.js new file mode 100644 index 0000000000000000000000000000000000000000..96b857a43821630fea180f136fd0f80fed233b76 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-nl_NL.js @@ -0,0 +1,15 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: NL (Dutch; Nederlands) + * Region: NL (Europe) + * Author: Daan Rosbergen (Badmuts) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Niets geselecteerd', + noneResultsText: 'Geen resultaten gevonden voor {0}', + countSelectedText: '{0} van {1} geselecteerd', + maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-pl_PL.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-pl_PL.js new file mode 100644 index 0000000000000000000000000000000000000000..e7eccaf9a4e725dd6b5ce84976565b96716d6dd1 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-pl_PL.js @@ -0,0 +1,16 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: PL (Polish) + * Region: EU (Europe) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Nic nie zaznaczono', + noneResultsText: 'Brak wyników wyszukiwania {0}', + countSelectedText: 'Zaznaczono {0} z {1}', + maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']], + selectAll: 'Zaznacz wszystkie', + deselectAll: 'Odznacz wszystkie', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-pt_BR.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-pt_BR.js new file mode 100644 index 0000000000000000000000000000000000000000..610871b1e5bdcc49bf1b2fc1d4bf1b51d1539d9a --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-pt_BR.js @@ -0,0 +1,15 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: PT (Portuguese; português) + * Region: BR (Brazil; Brasil) + * Author: Rodrigo de Avila + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Nada selecionado', + noneResultsText: 'Nada encontrado contendo {0}', + countSelectedText: 'Selecionado {0} de {1}', + maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-pt_PT.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-pt_PT.js new file mode 100644 index 0000000000000000000000000000000000000000..2d07e87c287b829f3e9f58e93c68287ee06ed759 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-pt_PT.js @@ -0,0 +1,15 @@ +/* +* Translated default messages for bootstrap-select. +* Locale: PT (Portuguese; português) +* Region: PT (Portugal; Portugal) +* Author: Burnspirit +*/ +(function ($) { +$.fn.selectpicker.defaults = { +noneSelectedText: 'Nenhum seleccionado', +noneResultsText: 'Sem resultados contendo {0}', +countSelectedText: 'Selecionado {0} de {1}', +maxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']], +multipleSeparator: ', ' +}; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-ro_RO.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-ro_RO.js new file mode 100644 index 0000000000000000000000000000000000000000..c6ddf6f6a5c175dbf844f24941f40605c32bb06a --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-ro_RO.js @@ -0,0 +1,15 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: RO (Romanian) + * Region: RO (Romania) + * Alex Florea + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Nu a fost selectat nimic', + noneResultsText: 'Nu exista niciun rezultat {0}', + countSelectedText: '{0} din {1} selectat(e)', + maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-ru_RU.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-ru_RU.js new file mode 100644 index 0000000000000000000000000000000000000000..c354f8c9813e71f1fe2a89fdaa117b849c75b8fe --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-ru_RU.js @@ -0,0 +1,15 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: RU (Russian; Русский) + * Region: RU (Russian Federation) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Ничего не выбрано', + noneResultsText: 'Совпадений не найдено {0}', + countSelectedText: 'Выбрано {0} из {1}', + maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['items', 'item']], + doneButtonText: 'Закрыть', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-sk_SK.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-sk_SK.js new file mode 100644 index 0000000000000000000000000000000000000000..e96762d7bd89a65434ebf04ef00093abc02504a0 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-sk_SK.js @@ -0,0 +1,16 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: SK + * Region: SK (Slovak Republic) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Vyberte zo zoznamu', + noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky', + countSelectedText: 'Vybrané {0} z {1}', + maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']], + selectAllText: 'Vybrať všetky', + deselectAllText: 'Zrušiť výber', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-sl_SI.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-sl_SI.js new file mode 100644 index 0000000000000000000000000000000000000000..a328c8c17030f51338387f0e0b8bec0d914cdbbe --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-sl_SI.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: SL (Slovenian) + * Region: SI (Slovenia) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Nič izbranega', + noneResultsText: 'Ni zadetkov za {0}', + countSelectedText: function (numSelected, numTotal) { + "Število izbranih: {0}"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + 'Omejitev dosežena (max. izbranih: {n})', + 'Omejitev skupine dosežena (max. izbranih: {n})' + ]; + }, + selectAllText: 'Izberi vse', + deselectAllText: 'Počisti izbor', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-sv_SE.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-sv_SE.js new file mode 100644 index 0000000000000000000000000000000000000000..89128e947b8ff70d49d9bf05c84156ef7f77ef40 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-sv_SE.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: SV (Swedish) + * Region: SE (Sweden) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Inget valt', + noneResultsText: 'Inget sökresultat matchar {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected === 1) ? "{0} alternativ valt" : "{0} alternativ valda"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + 'Gräns uppnåd (max {n} alternativ)', + 'Gräns uppnåd (max {n} gruppalternativ)' + ]; + }, + selectAllText: 'Markera alla', + deselectAllText: 'Avmarkera alla', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-tr_TR.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-tr_TR.js new file mode 100644 index 0000000000000000000000000000000000000000..fe43937d13ae4490f9a4ee3884969d776dca134d --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-tr_TR.js @@ -0,0 +1,24 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: TR (Turkey) + * Region: TR (Europe) + * Author: Serhan Güney + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Hiçbiri seçilmedi', + noneResultsText: 'Hiçbir sonuç bulunamadı {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? "{0} öğe seçildi" : "{0} öğe seçildi"; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)', + (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' + ]; + }, + selectAllText: 'Tümünü Seç', + deselectAllText: 'Seçiniz', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-ua_UA.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-ua_UA.js new file mode 100644 index 0000000000000000000000000000000000000000..e1d3958669887c1c970d06aad238ec32cd66d3b6 --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-ua_UA.js @@ -0,0 +1,14 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: UA (Ukrainian; Українська) + * Region: UA (Ukraine) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: 'Нічого не вибрано', + noneResultsText: 'Збігів не знайдено {0}', + countSelectedText: 'Вибрано {0} із {1}', + maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-zh_CN.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-zh_CN.js new file mode 100644 index 0000000000000000000000000000000000000000..ad1c13293d9fcb94bd351c561f6a1af1ad6551ef --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-zh_CN.js @@ -0,0 +1,14 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: ZH (Chinese) + * Region: CN (China) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: '没有选中任何项', + noneResultsText: '没有找到匹配项', + countSelectedText: '选中{1}中的{0}项', + maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'], + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/js/i18n/defaults-zh_TW.js b/public/assets/libs/bootstrap-select/js/i18n/defaults-zh_TW.js new file mode 100644 index 0000000000000000000000000000000000000000..c05add33451e35804c09594891db2edc96ec008c --- /dev/null +++ b/public/assets/libs/bootstrap-select/js/i18n/defaults-zh_TW.js @@ -0,0 +1,16 @@ +/* + * Translated default messages for bootstrap-select. + * Locale: ZH (Chinese) + * Region: TW (Taiwan) + */ +(function ($) { + $.fn.selectpicker.defaults = { + noneSelectedText: '沒有選取任何項目', + noneResultsText: '沒有找到符合的結果', + countSelectedText: '已經選取{0}個項目', + maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'], + selectAllText: '選取全部', + deselectAllText: '全部取消', + multipleSeparator: ', ' + }; +})(jQuery); diff --git a/public/assets/libs/bootstrap-select/less/bootstrap-select.less b/public/assets/libs/bootstrap-select/less/bootstrap-select.less new file mode 100644 index 0000000000000000000000000000000000000000..7be681f5cbfaed61c9372b392e3d3c2d4fc16f54 --- /dev/null +++ b/public/assets/libs/bootstrap-select/less/bootstrap-select.less @@ -0,0 +1,367 @@ +@import "variables"; + +// Mixins +.cursor-disabled() { + cursor: not-allowed; +} + +// Rules +select.bs-select-hidden, +select.selectpicker { + display: none !important; +} + +.bootstrap-select { + width: 220px \0; /*IE9 and below*/ + + // The selectpicker button + > .dropdown-toggle { + width: 100%; + padding-right: 25px; + z-index: 1; + + &.bs-placeholder, + &.bs-placeholder:hover, + &.bs-placeholder:focus, + &.bs-placeholder:active { color: @input-color-placeholder; } + } + + > select { + position: absolute !important; + bottom: 0; + left: 50%; + display: block !important; + width: 0.5px !important; + height: 100% !important; + padding: 0 !important; + opacity: 0 !important; + border: none; + + &.mobile-device { + top: 0; + left: 0; + display: block !important; + width: 100% !important; + z-index: 2; + } + } + + // Error display + .has-error & .dropdown-toggle, + .error & .dropdown-toggle { + border-color: @color-red-error; + } + + &.fit-width { + width: auto !important; + } + + &:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { + width: @width-default; + } + + .dropdown-toggle:focus { + outline: thin dotted #333333 !important; + outline: 5px auto -webkit-focus-ring-color !important; + outline-offset: -2px; + } +} + +.bootstrap-select.form-control { + margin-bottom: 0; + padding: 0; + border: none; + + &:not([class*="col-"]) { + width: 100%; + } + + &.input-group-btn { + z-index: auto; + + &:not(:first-child):not(:last-child) { + > .btn { + border-radius: 0; + } + } + } +} + +// The selectpicker components +.bootstrap-select.btn-group { + &:not(.input-group-btn), + &[class*="col-"] { + float: none; + display: inline-block; + margin-left: 0; + } + + // Forces the pull to the right, if necessary + &, + &[class*="col-"], + .row &[class*="col-"] { + &.dropdown-menu-right { + float: right; + } + } + + .form-inline &, + .form-horizontal &, + .form-group & { + margin-bottom: 0; + } + + .form-group-lg &.form-control, + .form-group-sm &.form-control { + padding: 0; + } + + // Set the width of the live search (and any other form control within an inline form) + // see https://github.com/silviomoreto/bootstrap-select/issues/685 + .form-inline & .form-control { + width: 100%; + } + + &.disabled, + > .disabled { + .cursor-disabled(); + + &:focus { + outline: none !important; + } + } + + &.bs-container { + position: absolute; + height: 0 !important; + padding: 0 !important; + + .dropdown-menu { + z-index: @zindex-select-dropdown; + } + } + + // The selectpicker button + .dropdown-toggle { + .filter-option { + display: inline-block; + overflow: hidden; + width: 100%; + text-align: left; + } + + .caret { + position: absolute; + top: 50%; + right: 12px; + margin-top: -2px; + vertical-align: middle; + } + } + + &[class*="col-"] .dropdown-toggle { + width: 100%; + } + + // The selectpicker dropdown + .dropdown-menu { + min-width: 100%; + box-sizing: border-box; + + &.inner { + position: static; + float: none; + border: 0; + padding: 0; + margin: 0; + border-radius: 0; + box-shadow: none; + } + + li { + position: relative; + + &.active small { + color: #fff; + } + + &.disabled a { + .cursor-disabled(); + } + + a { + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + &.opt { + position: relative; + padding-left: 2.25em; + } + + span.check-mark { + display: none; + } + + span.text { + display: inline-block; + } + } + + small { + padding-left: 0.5em; + } + } + + .notify { + position: absolute; + bottom: 5px; + width: 96%; + margin: 0 2%; + min-height: 26px; + padding: 3px 5px; + background: rgb(245, 245, 245); + border: 1px solid rgb(227, 227, 227); + box-shadow: inset 0 1px 1px fade(rgb(0, 0, 0), 5%); + pointer-events: none; + opacity: 0.9; + box-sizing: border-box; + } + } + + .no-results { + padding: 3px; + background: #f5f5f5; + margin: 0 5px; + white-space: nowrap; + } + + &.fit-width .dropdown-toggle { + .filter-option { + position: static; + } + + .caret { + position: static; + top: auto; + margin-top: -1px; + } + } + + &.show-tick .dropdown-menu li { + &.selected a span.check-mark { + position: absolute; + display: inline-block; + right: 15px; + margin-top: 5px; + } + + a span.text { + margin-right: 34px; + } + } +} + +.bootstrap-select.show-menu-arrow { + &.open > .dropdown-toggle { + z-index: (@zindex-select-dropdown + 1); + } + + .dropdown-toggle { + &:before { + content: ''; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid @color-grey-arrow; + position: absolute; + bottom: -4px; + left: 9px; + display: none; + } + + &:after { + content: ''; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + bottom: -4px; + left: 10px; + display: none; + } + } + + &.dropup .dropdown-toggle { + &:before { + bottom: auto; + top: -3px; + border-top: 7px solid @color-grey-arrow; + border-bottom: 0; + } + + &:after { + bottom: auto; + top: -3px; + border-top: 6px solid white; + border-bottom: 0; + } + } + + &.pull-right .dropdown-toggle { + &:before { + right: 12px; + left: auto; + } + + &:after { + right: 13px; + left: auto; + } + } + + &.open > .dropdown-toggle { + &:before, + &:after { + display: block; + } + } +} + +.bs-searchbox, +.bs-actionsbox, +.bs-donebutton { + padding: 4px 8px; +} + +.bs-actionsbox { + width: 100%; + box-sizing: border-box; + + & .btn-group button { + width: 50%; + } +} + +.bs-donebutton { + float: left; + width: 100%; + box-sizing: border-box; + + & .btn-group button { + width: 100%; + } +} + +.bs-searchbox { + & + .bs-actionsbox { + padding: 0 8px 4px; + } + + & .form-control { + margin-bottom: 0; + width: 100%; + float: none; + } +} diff --git a/public/assets/libs/bootstrap-select/less/variables.less b/public/assets/libs/bootstrap-select/less/variables.less new file mode 100644 index 0000000000000000000000000000000000000000..2514a85b791ba924b3d6aa9493906822582f3fd2 --- /dev/null +++ b/public/assets/libs/bootstrap-select/less/variables.less @@ -0,0 +1,9 @@ +@color-red-error: rgb(185, 74, 72); +@color-grey-arrow: rgba(204, 204, 204, 0.2); + +@width-default: 220px; // 3 960px-grid columns + +@zindex-select-dropdown: 1060; // must be higher than a modal background (1050) + +//** Placeholder text color +@input-color-placeholder: #999; \ No newline at end of file diff --git a/public/assets/libs/bootstrap-select/nuget/MyGet.ps1 b/public/assets/libs/bootstrap-select/nuget/MyGet.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..aba127f74015c623bbfb008726344b3400461190 --- /dev/null +++ b/public/assets/libs/bootstrap-select/nuget/MyGet.ps1 @@ -0,0 +1,20 @@ +# set env vars usually set by MyGet (enable for local testing) +#$env:SourcesPath = '..' +#$env:NuGet = "./nuget.exe" #https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + +$nuget = $env:NuGet + +# parse the version number out of package.json +$bsversionParts = ((Get-Content $env:SourcesPath\package.json) -join "`n" | ConvertFrom-Json).version.split('-', 2) # split the version on the '-' +$bsversion = $bsversionParts[0] + +if ($bsversionParts.Length -gt 1) +{ + $bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_') # strip out invalid chars from the PreRelease part +} + +# update sourceMappingURL in bootstrap-select.min.js +(Get-Content $env:SourcesPath\dist\js\bootstrap-select.min.js).replace("sourceMappingURL=", "sourceMappingURL=Scripts/") | Set-Content $env:SourcesPath\dist\js\bootstrap-select.min.js + +# create packages +& $nuget pack "$env:SourcesPath\nuget\bootstrap-select.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion \ No newline at end of file diff --git a/public/assets/libs/bootstrap-select/nuget/bootstrap-select.nuspec b/public/assets/libs/bootstrap-select/nuget/bootstrap-select.nuspec new file mode 100644 index 0000000000000000000000000000000000000000..049462008fe32d8538ef8dfd3278138368080f97 --- /dev/null +++ b/public/assets/libs/bootstrap-select/nuget/bootstrap-select.nuspec @@ -0,0 +1,22 @@ + + + + bootstrap-select + 1.11.2 + bootstrap-select + Silvio Moreto,Ana Carolina,caseyjhol,Matt Bryson,and t0xicCode. + Silvio Moreto + https://github.com/silviomoreto/bootstrap-select + Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements. + bootstrap dropdown select + false + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/libs/bootstrap-select/sass/bootstrap-select.scss b/public/assets/libs/bootstrap-select/sass/bootstrap-select.scss new file mode 100644 index 0000000000000000000000000000000000000000..7f54f71e0327f621acd63397391b5bb9d7334ad4 --- /dev/null +++ b/public/assets/libs/bootstrap-select/sass/bootstrap-select.scss @@ -0,0 +1,385 @@ +@import "variables"; + +// Mixins +@mixin cursor-disabled() { + cursor: not-allowed; +} + +@mixin box-sizing($fmt) { + -webkit-box-sizing: $fmt; + -moz-box-sizing: $fmt; + box-sizing: $fmt; +} + +@mixin box-shadow($fmt) { + -webkit-box-shadow: $fmt; + box-shadow: $fmt; +} + +@function fade($color, $amnt) { + @if $amnt > 1 { + $amnt: $amnt / 100; // convert to percentage if int + } + @return rgba($color, $amnt); +} + +// Rules +select.bs-select-hidden, +select.selectpicker { + display: none !important; +} + +.bootstrap-select { + width: 220px \0; /*IE9 and below*/ + + // The selectpicker button + > .dropdown-toggle { + width: 100%; + padding-right: 25px; + z-index: 1; + + &.bs-placeholder, + &.bs-placeholder:hover, + &.bs-placeholder:focus, + &.bs-placeholder:active { color: $input-color-placeholder; } + } + + > select { + position: absolute !important; + bottom: 0; + left: 50%; + display: block !important; + width: 0.5px !important; + height: 100% !important; + padding: 0 !important; + opacity: 0 !important; + border: none; + + &.mobile-device { + top: 0; + left: 0; + display: block !important; + width: 100% !important; + z-index: 2; + } + } + + // Error display + .has-error & .dropdown-toggle, + .error & .dropdown-toggle { + border-color: $color-red-error; + } + + &.fit-width { + width: auto !important; + } + + &:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { + width: $width-default; + } + + .dropdown-toggle:focus { + outline: thin dotted #333333 !important; + outline: 5px auto -webkit-focus-ring-color !important; + outline-offset: -2px; + } +} + +.bootstrap-select.form-control { + margin-bottom: 0; + padding: 0; + border: none; + + &:not([class*="col-"]) { + width: 100%; + } + + &.input-group-btn { + z-index: auto; + + &:not(:first-child):not(:last-child) { + > .btn { + border-radius: 0; + } + } + } +} + +// The selectpicker components +.bootstrap-select.btn-group { + &:not(.input-group-btn), + &[class*="col-"] { + float: none; + display: inline-block; + margin-left: 0; + } + + // Forces the pull to the right, if necessary + &, + &[class*="col-"], + .row &[class*="col-"] { + &.dropdown-menu-right { + float: right; + } + } + + .form-inline &, + .form-horizontal &, + .form-group & { + margin-bottom: 0; + } + + .form-group-lg &.form-control, + .form-group-sm &.form-control { + padding: 0; + } + + // Set the width of the live search (and any other form control within an inline form) + // see https://github.com/silviomoreto/bootstrap-select/issues/685 + .form-inline & .form-control { + width: 100%; + } + + &.disabled, + > .disabled { + @include cursor-disabled(); + + &:focus { + outline: none !important; + } + } + + &.bs-container { + position: absolute; + height: 0 !important; + padding: 0 !important; + + .dropdown-menu { + z-index: $zindex-select-dropdown; + } + } + + // The selectpicker button + .dropdown-toggle { + .filter-option { + display: inline-block; + overflow: hidden; + width: 100%; + text-align: left; + } + + .caret { + position: absolute; + top: 50%; + right: 12px; + margin-top: -2px; + vertical-align: middle; + } + } + + &[class*="col-"] .dropdown-toggle { + width: 100%; + } + + // The selectpicker dropdown + .dropdown-menu { + min-width: 100%; + @include box-sizing(border-box); + + &.inner { + position: static; + float: none; + border: 0; + padding: 0; + margin: 0; + border-radius: 0; + box-shadow: none; + } + + li { + position: relative; + + &.active small { + color: #fff; + } + + &.disabled a { + @include cursor-disabled(); + } + + a { + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + &.opt { + position: relative; + padding-left: 2.25em; + } + + span.check-mark { + display: none; + } + + span.text { + display: inline-block; + } + } + + small { + padding-left: 0.5em; + } + } + + .notify { + position: absolute; + bottom: 5px; + width: 96%; + margin: 0 2%; + min-height: 26px; + padding: 3px 5px; + background: rgb(245, 245, 245); + border: 1px solid rgb(227, 227, 227); + @include box-shadow(inset 0 1px 1px fade(rgb(0, 0, 0), 5)); + pointer-events: none; + opacity: 0.9; + @include box-sizing(border-box); + } + } + + .no-results { + padding: 3px; + background: #f5f5f5; + margin: 0 5px; + white-space: nowrap; + } + + &.fit-width .dropdown-toggle { + .filter-option { + position: static; + } + + .caret { + position: static; + top: auto; + margin-top: -1px; + } + } + + &.show-tick .dropdown-menu li { + &.selected a span.check-mark { + position: absolute; + display: inline-block; + right: 15px; + margin-top: 5px; + } + + a span.text { + margin-right: 34px; + } + } +} + +.bootstrap-select.show-menu-arrow { + &.open > .dropdown-toggle { + z-index: ($zindex-select-dropdown + 1); + } + + .dropdown-toggle { + &:before { + content: ''; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid $color-grey-arrow; + position: absolute; + bottom: -4px; + left: 9px; + display: none; + } + + &:after { + content: ''; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + bottom: -4px; + left: 10px; + display: none; + } + } + + &.dropup .dropdown-toggle { + &:before { + bottom: auto; + top: -3px; + border-top: 7px solid $color-grey-arrow; + border-bottom: 0; + } + + &:after { + bottom: auto; + top: -3px; + border-top: 6px solid white; + border-bottom: 0; + } + } + + &.pull-right .dropdown-toggle { + &:before { + right: 12px; + left: auto; + } + + &:after { + right: 13px; + left: auto; + } + } + + &.open > .dropdown-toggle { + &:before, + &:after { + display: block; + } + } +} + +.bs-searchbox, +.bs-actionsbox, +.bs-donebutton { + padding: 4px 8px; +} + +.bs-actionsbox { + width: 100%; + @include box-sizing(border-box); + + & .btn-group button { + width: 50%; + } +} + +.bs-donebutton { + float: left; + width: 100%; + @include box-sizing(border-box); + + & .btn-group button { + width: 100%; + } +} + +.bs-searchbox { + & + .bs-actionsbox { + padding: 0 8px 4px; + } + + & .form-control { + margin-bottom: 0; + width: 100%; + float: none; + } +} diff --git a/public/assets/libs/bootstrap-select/sass/variables.scss b/public/assets/libs/bootstrap-select/sass/variables.scss new file mode 100644 index 0000000000000000000000000000000000000000..8ba1fc0f15b88ccd222b2f19e1b79601dfd9f87b --- /dev/null +++ b/public/assets/libs/bootstrap-select/sass/variables.scss @@ -0,0 +1,9 @@ +$color-red-error: rgb(185, 74, 72); +$color-grey-arrow: rgba(204, 204, 204, 0.2); + +$width-default: 220px; // 3 960px-grid columns + +$zindex-select-dropdown: 1060; // must be higher than a modal background (1050) + +//** Placeholder text color +$input-color-placeholder: #999; \ No newline at end of file diff --git a/public/assets/libs/bootstrap-slider/.bower.json b/public/assets/libs/bootstrap-slider/.bower.json new file mode 100644 index 0000000000000000000000000000000000000000..c3bd2087fb805c34cb9e7cd5e9931d52c24e512e --- /dev/null +++ b/public/assets/libs/bootstrap-slider/.bower.json @@ -0,0 +1,33 @@ +{ + "name": "bootstrap-slider", + "main": [ + "bootstrap-slider.js", + "slider.css" + ], + "homepage": "https://github.com/pammacdotnet/bootstrap-slider", + "authors": [ + "pammacdotnet" + ], + "description": "Eyecon Slider for Bootstrap", + "keywords": [ + "slider", + "bootstrap" + ], + "license": "Apache", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "_release": "879a98dcd0", + "_resolution": { + "type": "branch", + "branch": "master", + "commit": "879a98dcd0923107363861e56423f3cc1c2472e7" + }, + "_source": "https://github.com/pammacdotnet/bootstrap-slider.git", + "_target": "*", + "_originalSource": "bootstrap-slider" +} \ No newline at end of file diff --git a/public/assets/libs/bootstrap-slider/README.md b/public/assets/libs/bootstrap-slider/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2a073efef8cd6e21875ae6b6df9a688b7eb46640 --- /dev/null +++ b/public/assets/libs/bootstrap-slider/README.md @@ -0,0 +1,26 @@ +Bootstrap Slider +============= + +Fork of eyecon's [bootstrap-slider](http://www.eyecon.ro/bootstrap-slider/). + +Specially remastered for iLIME Project @ UNIR Research. More info: +[http://blogs.unir.net/elearning/telsock-research-group/](http://) + +![ScreenShot](https://raw.github.com/pammacdotnet/bootstrap-slider/master/locks.png) + +Changes +---------- +Current changes include: + ++ Better responsive support ++ Updated look and feel ++ Minor layout tweaks ++ Removed built-in handle types ++ Bower install ++ Limits and locks + + + + + + diff --git a/public/assets/libs/bootstrap-slider/bootstrap-slider.js b/public/assets/libs/bootstrap-slider/bootstrap-slider.js new file mode 100644 index 0000000000000000000000000000000000000000..2191faf363573ec72e0822b1464b44a728cc21be --- /dev/null +++ b/public/assets/libs/bootstrap-slider/bootstrap-slider.js @@ -0,0 +1,427 @@ +/* ========================================================= + * bootstrap-slider.js v2.0.0 + * http://www.eyecon.ro/bootstrap-slider + * ========================================================= + * Copyright 2012 Stefan Petre + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + +!function( $ ) { + + var Slider = function(element, options) { + this.dragLocked = false; + this.limit = 100000; + this.element = $(element).hide(); + this.picker = $('
            '+ + '
            '+ + '
            '+ + '
            '+ + '
            '+ + '
            '+ + '
            '+ + '
            ') + .insertBefore(this.element) + .append(this.element); + this.id = this.element.data('slider-id')||options.id; + if (this.id) { + this.picker[0].id = this.id; + } + + if (typeof Modernizr !== 'undefined' && Modernizr.touch) { + this.touchCapable = true; + } + + var tooltip = this.element.data('slider-tooltip')||options.tooltip; + + this.tooltip = this.picker.find('.tooltip'); + this.tooltipInner = this.tooltip.find('div.tooltip-inner'); + + this.orientation = this.element.data('slider-orientation')||options.orientation; + switch(this.orientation) { + case 'vertical': + this.picker.addClass('slider-vertical'); + this.stylePos = 'top'; + this.mousePos = 'pageY'; + this.sizePos = 'offsetHeight'; + this.tooltip.addClass('right')[0].style.left = '100%'; + break; + default: + this.picker + .addClass('slider-horizontal') + .css('width', this.element.outerWidth()); + this.orientation = 'horizontal'; + this.stylePos = 'left'; + this.mousePos = 'pageX'; + this.sizePos = 'offsetWidth'; + this.tooltip.addClass('top')[0].style.top = -this.tooltip.outerHeight() - 14 + 'px'; + break; + } + + this.min = this.element.data('slider-min')||options.min; + this.max = this.element.data('slider-max')||options.max; + this.step = this.element.data('slider-step')||options.step; + this.value = this.element.data('slider-value')||options.value; + if (this.value[1]) { + this.range = true; + } + + this.selection = this.element.data('slider-selection')||options.selection; + this.selectionEl = this.picker.find('.slider-selection'); + if (this.selection === 'none') { + this.selectionEl.addClass('hide'); + } + this.selectionElStyle = this.selectionEl[0].style; + + + this.handle1 = this.picker.find('.slider-handle:first'); + this.handle1Stype = this.handle1[0].style; + this.handle2 = this.picker.find('.slider-handle:last'); + this.handle2Stype = this.handle2[0].style; + + var handle = this.element.data('slider-handle')||options.handle; + switch(handle) { + case 'round': + this.handle1.addClass('round'); + this.handle2.addClass('round'); + break + case 'triangle': + this.handle1.addClass('triangle'); + this.handle2.addClass('triangle'); + break + } + + if (this.range) { + this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); + this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); + } else { + this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; + this.handle2.addClass('hide'); + if (this.selection == 'after') { + this.value[1] = this.max; + } else { + this.value[1] = this.min; + } + } + this.diff = this.max - this.min; + this.percentage = [ + (this.value[0]-this.min)*100/this.diff, + (this.value[1]-this.min)*100/this.diff, + this.step*100/this.diff + ]; + + this.offset = this.picker.offset(); + this.size = this.picker[0][this.sizePos]; + + this.formater = options.formater; + this.reversed = this.element.data('slider-reversed')||options.reversed; + + this.layout(); + + if (this.touchCapable) { + // Touch: Bind touch events: + this.picker.on({ + touchstart: $.proxy(this.mousedown, this) + }); + } else { + this.picker.on({ + mousedown: $.proxy(this.mousedown, this) + }); + } + + if (tooltip === 'show') { + this.picker.on({ + mouseenter: $.proxy(this.showTooltip, this), + mouseleave: $.proxy(this.hideTooltip, this) + }); + } else { + this.tooltip.addClass('hide'); + } + }; + + Slider.prototype = { + constructor: Slider, + + over: false, + inDrag: false, + + showTooltip: function(){ + this.tooltip.addClass('in'); + //var left = Math.round(this.percent*this.width); + //this.tooltip.css('left', left - this.tooltip.outerWidth()/2); + this.over = true; + }, + + hideTooltip: function(){ + if (this.inDrag === false) { + this.tooltip.removeClass('in'); + } + this.over = false; + }, + + layout: function(){ + var positionPercentages; + + if(this.reversed) { + positionPercentages = [ this.percentage[1] - this.percentage[0], this.percentage[1] ]; + } else { + positionPercentages = [ this.percentage[0], this.percentage[1] ]; + } + + this.handle1Stype[this.stylePos] = positionPercentages[0]+'%'; + this.handle2Stype[this.stylePos] = positionPercentages[1]+'%'; + if (this.orientation == 'vertical') { + this.selectionElStyle.top = Math.min(positionPercentages[0], positionPercentages[1]) +'%'; + this.selectionElStyle.height = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%'; + } else { + this.selectionElStyle.left = Math.min(positionPercentages[0], positionPercentages[1]) +'%'; + this.selectionElStyle.width = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%'; + } + + if (this.range) { + this.tooltipInner.text( + this.formater(this.value[0]) + + ' : ' + + this.formater(this.value[1]) + ); + this.tooltip[0].style[this.stylePos] = this.size * (positionPercentages[0] + (positionPercentages[1] - positionPercentages[0])/2)/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; + } else { + this.tooltipInner.text( + this.formater(this.value[0]) + ); + this.tooltip[0].style[this.stylePos] = this.size * positionPercentages[0]/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px'; + } + }, + + mousedown: function(ev) { + + if (!this.dragLocked){ + // Touch: Get the original event: + if (this.touchCapable && ev.type === 'touchstart') { + ev = ev.originalEvent; + } + + this.offset = this.picker.offset(); + this.size = this.picker[0][this.sizePos]; + + var percentage = this.getPercentage(ev); + + if (this.range) { + var diff1 = Math.abs(this.percentage[0] - percentage); + var diff2 = Math.abs(this.percentage[1] - percentage); + this.dragged = (diff1 < diff2) ? 0 : 1; + } else { + this.dragged = 0; + } + + this.percentage[this.dragged] = this.reversed ? this.percentage[1] - percentage : percentage; + this.layout(); + + if (this.touchCapable) { + // Touch: Bind touch events: + $(document).on({ + touchmove: $.proxy(this.mousemove, this), + touchend: $.proxy(this.mouseup, this) + }); + } else { + $(document).on({ + mousemove: $.proxy(this.mousemove, this), + mouseup: $.proxy(this.mouseup, this) + }); + } + + this.inDrag = true; + var val = this.calculateValue(); + + this.setValue(val); + this.element.trigger({ + type: 'slideStart', + value: val + }).trigger({ + type: 'slide', + value: val + }); + return false; + } + }, + + mousemove: function(ev) { + // Touch: Get the original event: + if (!this.dragLocked){ + if (this.touchCapable && ev.type === 'touchmove') { + ev = ev.originalEvent; + } + + var percentage = this.getPercentage(ev); + if (this.range) { + if (this.dragged === 0 && this.percentage[1] < percentage) { + this.percentage[0] = this.percentage[1]; + this.dragged = 1; + } else if (this.dragged === 1 && this.percentage[0] > percentage) { + this.percentage[1] = this.percentage[0]; + this.dragged = 0; + } + } + x = this.reversed ? this.percentage[1] - percentage : percentage; + if (x > this.limit) { + return ; + } + this.percentage[this.dragged] = x; + this.layout(); + var val = this.calculateValue(); + this.setValue(val); + + this.element + .trigger({ + type: 'slide', + value: val + }) + .data('value', val) + .prop('value', val); + return false; + } + }, + + mouseup: function(ev) { + if (this.touchCapable) { + // Touch: Bind touch events: + $(document).off({ + touchmove: this.mousemove, + touchend: this.mouseup + }); + } else { + $(document).off({ + mousemove: this.mousemove, + mouseup: this.mouseup + }); + } + + this.inDrag = false; + if (this.over == false) { + this.hideTooltip(); + } + this.element; + var val = this.calculateValue(); + this.layout(); + this.element + .trigger({ + type: 'slideStop', + value: val + }) + .data('value', val) + .prop('value', val); + return false; + }, + + calculateValue: function() { + var val; + if (this.range) { + val = [ + (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step), + (this.min + Math.round((this.diff * this.percentage[1]/100)/this.step)*this.step) + ]; + this.value = val; + } else { + val = (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step); + this.value = [val, this.value[1]]; + } + return val; + }, + + getPercentage: function(ev) { + if (this.touchCapable) { + ev = ev.touches[0]; + } + var percentage = (ev[this.mousePos] - this.offset[this.stylePos])*100/this.size; + percentage = Math.round(percentage/this.percentage[2])*this.percentage[2]; + return Math.max(0, Math.min(100, percentage)); + }, + + getValue: function() { + if (this.range) { + return this.value; + } + return this.value[0]; + }, + setLimit: function(val) { + this.limit = val; + }, + setDragLocked: function(val) { + this.dragLocked = val; + }, + getDragLocked: function(val) { + return this.dragLocked; + }, + setValue: function(val) { + this.value = val; + + if (this.range) { + this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0])); + this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1])); + } else { + this.value = [ Math.max(this.min, Math.min(this.max, this.value))]; + this.handle2.addClass('hide'); + if (this.selection == 'after') { + this.value[1] = this.max; + } else { + this.value[1] = this.min; + } + } + this.diff = this.max - this.min; + this.percentage = [ + (this.value[0]-this.min)*100/this.diff, + (this.value[1]-this.min)*100/this.diff, + this.step*100/this.diff + ]; + this.layout(); + }, + destroy: function(){ + this.element.show().insertBefore(this.picker); + this.picker.remove(); + }, + }; + + $.fn.slider = function ( option, val ) { + return this.each(function () { + var $this = $(this), + data = $this.data('slider'), + options = typeof option === 'object' && option; + if (!data) { + $this.data('slider', (data = new Slider(this, $.extend({}, $.fn.slider.defaults,options)))); + } + if (typeof option == 'string') { + data[option](val); + } + }) + }; + + $.fn.slider.defaults = { + min: 0, + max: 10, + step: 1, + orientation: 'horizontal', + value: 5, + selection: 'before', + tooltip: 'show', + handle: 'round', + reversed : false, + limit: 100000, + dragLocked: false, + formater: function(value) { + return value; + } + }; + + $.fn.slider.Constructor = Slider; + +}( window.jQuery ); diff --git a/public/assets/libs/bootstrap-slider/bower.json b/public/assets/libs/bootstrap-slider/bower.json new file mode 100644 index 0000000000000000000000000000000000000000..4f0242c4f7e4a3ce06428d0691d9639e3e729e13 --- /dev/null +++ b/public/assets/libs/bootstrap-slider/bower.json @@ -0,0 +1,22 @@ +{ + "name": "bootstrap-slider", + "main": ["bootstrap-slider.js", "slider.css"], + "version": "2.0.0", + "homepage": "https://github.com/pammacdotnet/bootstrap-slider", + "authors": [ + "pammacdotnet" + ], + "description": "Eyecon Slider for Bootstrap", + "keywords": [ + "slider", + "bootstrap" + ], + "license": "Apache", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/public/assets/libs/bootstrap-slider/locks.png b/public/assets/libs/bootstrap-slider/locks.png new file mode 100644 index 0000000000000000000000000000000000000000..b29baf4e271e3abcf8210575c656684fdf11ae52 Binary files /dev/null and b/public/assets/libs/bootstrap-slider/locks.png differ diff --git a/public/assets/libs/bootstrap-slider/slider.css b/public/assets/libs/bootstrap-slider/slider.css new file mode 100644 index 0000000000000000000000000000000000000000..1447d089db1eaec2ff3c45d4be70860319afecf5 --- /dev/null +++ b/public/assets/libs/bootstrap-slider/slider.css @@ -0,0 +1,178 @@ +/*! + * Slider for Bootstrap + * + * Copyright 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ +.slider { + display: inline-block; + vertical-align: middle; + position: relative; + margin-bottom: 10px +} + +.slider[class*="span"] { + float: none; + margin-left: 0; +} + +.slider-horizontal { + width: 210px; + height: 20px; +} + +.slider-horizontal .slider-handle-container, +.slider-horizontal .slider-track { + height: 10px; + margin-top: -5px; + top: 50%; +} + +.slider-horizontal .slider-track { + left: 0; + right: 0; +} + +.slider-horizontal .slider-handle-container { + left: 10px; + right: 10px; +} + +.slider-horizontal .slider-selection { + height: 100%; + top: 0; + bottom: 0; +} + +.slider-horizontal .slider-handle { + margin-left: -10px; + margin-top: -5px; +} + +.slider-vertical { + height: 210px; + width: 20px; +} + +.slider-vertical .slider-handle-container, +.slider-vertical .slider-track { + width: 10px; + margin-left: -5px; + left: 50%; +} + +.slider-vertical .slider-track { + top: 0; + bottom: 0; +} + +.slider-vertical .slider-handle-container { + top: 10px; + bottom: 10px; +} +.slider-vertical .slider-selection { + width: 100%; + left: 0; + top: 0; + bottom: 0; +} + +.slider-vertical .slider-handle { + margin-left: -5px; + margin-top: -10px; +} + +.slider input, +.slider input[class*="span"] { + display: none; +} + +.slider .tooltip-inner { + white-space: nowrap; +} + +.slider-handle-container { + position: absolute; +} + +.slider-track { + position: absolute; + cursor: pointer; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.slider-selection { + position: absolute; + background-color: #e6e6e6; + background-image: -moz-linear-gradient(top, #f0f0f0, #e0e0e0); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f0f0f0), to(#e0e0e0)); + background-image: -webkit-linear-gradient(top, #f0f0f0, #e0e0e0); + background-image: -o-linear-gradient(top, #f0f0f0, #e0e0e0); + background-image: linear-gradient(to bottom, #f0f0f0, #e0e0e0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-border-radius: 20px; + -moz-border-radius: 20px; + border-radius: 20px; +} + +.slider-handle { + position: absolute; + width: 20px; + height: 20px; + cursor: pointer; +} + +.slider-knob { + width: 20px; + height: 20px; + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #e6e6e6, #ffffff); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#ffffff)); + background-image: -webkit-linear-gradient(top, #e6e6e6, #ffffff); + background-image: -o-linear-gradient(top, #e6e6e6, #ffffff); + background-image: linear-gradient(to bottom, #e6e6e6, #ffffff); + background-repeat: repeat-x; + border: 1px solid #bbbbbb; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border-bottom-color: #a2a2a2; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -webkit-border-radius: 20px; + -moz-border-radius: 20px; + border-radius: 20px; +} + +.slider-handle:active .slider-knob, +.slider-handle:hover .slider-knob { + background-color: #e6e6e6; + background-position: 0 5px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} \ No newline at end of file diff --git a/public/assets/libs/bootstrap-table/.bower.json b/public/assets/libs/bootstrap-table/.bower.json new file mode 100644 index 0000000000000000000000000000000000000000..20a0aa3aff888a4cb756923569db8ae45e12c095 --- /dev/null +++ b/public/assets/libs/bootstrap-table/.bower.json @@ -0,0 +1,37 @@ +{ + "name": "bootstrap-table", + "homepage": "https://github.com/wenzhixin/bootstrap-table", + "authors": [ + "zhixin " + ], + "description": "An extended Bootstrap table with radio, checkbox, sort, pagination, and other added features.", + "main": [ + "src/bootstrap-table.js", + "src/bootstrap-table.css" + ], + "keywords": [ + "bootstrap", + "table", + "bootstrap table" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "docs", + "assets" + ], + "version": "1.11.3", + "_release": "1.11.3", + "_resolution": { + "type": "version", + "tag": "1.11.3", + "commit": "8aa6944b83b1267a9ef4c84bd4f9982a2975ddc9" + }, + "_source": "https://github.com/karsonzhang/fastadmin-bootstraptable.git", + "_target": "~1.11.3", + "_originalSource": "fastadmin-bootstraptable" +} \ No newline at end of file diff --git a/public/assets/libs/bootstrap-table/Gruntfile.js b/public/assets/libs/bootstrap-table/Gruntfile.js new file mode 100644 index 0000000000000000000000000000000000000000..21242491785c9eded631af05c1b201526fd25a12 --- /dev/null +++ b/public/assets/libs/bootstrap-table/Gruntfile.js @@ -0,0 +1,132 @@ +'use strict'; + +var fs = require('fs'); + +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + // Metadata. + pkg: grunt.file.readJSON('bootstrap-table.jquery.json'), + banner: '/*\n' + + '* <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' + + '<%= pkg.homepage ? "* " + pkg.homepage : "" %>\n' + + '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>\n' + + '* Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n' + + '*/\n', + // Task configuration. + clean: ['dist', 'docs/dist'], + concat: { + //basic_target: { + // src: ['src/<%= pkg.name %>.js', 'src/extensions/**/*.js'], + // dest: 'dist/<%= pkg.name %>-all.js' + //}, + locale_target: { + src: ['src/locale/**/*.js'], + dest: 'dist/<%= pkg.name %>-locale-all.js' + } + }, + uglify: { + options: { + banner: '<%= banner %>' + }, + basic_target: { + files: { + 'dist/<%= pkg.name %>.min.js': ['src/<%=pkg.name %>.js'], + //'dist/<%= pkg.name %>-all.min.js': ['dist/<%=pkg.name %>-all.js'], + 'dist/<%= pkg.name %>-locale-all.min.js': ['dist/<%=pkg.name %>-locale-all.js'] + } + }, + locale_target: { + files: [{ + expand: true, + cwd: 'src/locale', + src: '**/*.js', + dest: 'dist/locale', + ext: '.min.js' // replace .js to .min.js + }] + }, + extensions_target: { + files: [{ + expand: true, + cwd: 'src/extensions', + src: '**/*.js', + dest: 'dist/extensions', + ext: '.min.js' // replace .js to .min.js + }] + } + }, + cssmin: { + add_banner: { + options: { + banner: '<%= banner %>' + }, + files: { + 'dist/<%= pkg.name %>.min.css': ['src/<%=pkg.name %>.css'] + } + } + }, + copy: { + source: { + cwd: 'src', // set working folder / root to copy + src: ['**/*.js', '**/*.css'], // copy all files and subfolders + dest: 'dist', // destination folder + expand: true // required when using cwd + }, + files: { + cwd: 'dist', // set working folder / root to copy + src: '**/*', // copy all files and subfolders + dest: 'docs/dist', // destination folder + expand: true // required when using cwd + } + }, + release: { + options: { + additionalFiles: ['bootstrap-table.jquery.json'], + beforeRelease: ['docs', 'default'] + } + } + }); + + var bumpVersion = function (path, version, startWith) { + var lines = fs.readFileSync(path, 'utf8').split('\n'); + lines.forEach(function (line, i) { + if (line.indexOf(startWith) === 0) { + lines[i] = startWith + version; + } + }); + fs.writeFileSync(path, lines.join('\n'), 'utf8'); + + grunt.log.ok('bumped version of ' + path + ' to ' + version); + }; + + grunt.registerTask('docs', 'build the docs', function () { + var version = require('./package.json').version; + bumpVersion('./_config.yml', version, 'current_version: '); + bumpVersion('./src/bootstrap-table.js', version, ' * version: '); + bumpVersion('./src/bootstrap-table.css', version, ' * version: '); + + var changeLog = fs.readFileSync('./CHANGELOG.md', 'utf8'); + var latestLogs = changeLog.split('### ')[1]; + var date = new Date(); + + var lines = [ + '### Latest release (' + + [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-') + ')', + '', + '#### v' + latestLogs + ]; + fs.writeFileSync('./docs/_includes/latest-release.md', lines.join('\n'), 'utf8'); + + grunt.log.ok('updated the latest-release.md to ' + version); + }); + + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-release'); + + grunt.registerTask('default', ['clean', 'concat', 'uglify', 'cssmin', 'copy']); +}; diff --git a/public/assets/libs/bootstrap-table/LICENSE b/public/assets/libs/bootstrap-table/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..58a155e2e77cd191463cf63bb1134550b8ee2b44 --- /dev/null +++ b/public/assets/libs/bootstrap-table/LICENSE @@ -0,0 +1,21 @@ +(The MIT License) + +Copyright (c) 2012-2017 Zhixin Wen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/public/assets/libs/bootstrap-table/README.md b/public/assets/libs/bootstrap-table/README.md new file mode 100644 index 0000000000000000000000000000000000000000..35250e54023a0971016bed136da4ae214272558c --- /dev/null +++ b/public/assets/libs/bootstrap-table/README.md @@ -0,0 +1,8 @@ +# fastamin-bootstraptable +FastAdmin Bootstrap-table表格组件 + +## 使用方法 +https://f4nniu.gitee.io/bootstrap-table-home/zh-cn/home/ + +## 特别感谢 +https://github.com/wenzhixin/bootstrap-table \ No newline at end of file diff --git a/public/assets/libs/bootstrap-table/bower.json b/public/assets/libs/bootstrap-table/bower.json new file mode 100644 index 0000000000000000000000000000000000000000..6d1e164fd8544fa76042dc84c0a1a14308d75cc8 --- /dev/null +++ b/public/assets/libs/bootstrap-table/bower.json @@ -0,0 +1,27 @@ +{ + "name": "bootstrap-table", + "homepage": "https://github.com/wenzhixin/bootstrap-table", + "authors": [ + "zhixin " + ], + "description": "An extended Bootstrap table with radio, checkbox, sort, pagination, and other added features.", + "main": [ + "src/bootstrap-table.js", + "src/bootstrap-table.css" + ], + "keywords": [ + "bootstrap", + "table", + "bootstrap table" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "docs", + "assets" + ] +} diff --git a/public/assets/libs/bootstrap-table/composer.json b/public/assets/libs/bootstrap-table/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..d494d73518bdec929cdb4b39b8713308d9bb1e27 --- /dev/null +++ b/public/assets/libs/bootstrap-table/composer.json @@ -0,0 +1,17 @@ +{ + "name": "karsonzhang/fastadmin-bootstraptable", + "description": "An extended Bootstrap table with radio, checkbox, sort, pagination and other features.", + "keywords": ["bootstrap","table","tablesort","pagination"], + "type": "component", + "homepage": "https://github.com/karsonzhang/fastadmin-bootstraptable", + "license": "MIT", + "require": { + "twitter/bootstrap": ">=3.3.0" + }, + "authors": [ + { + "name": "wenzhixin2010", + "email": "wenzhixin2010@gmail.com" + } + ] +} diff --git a/public/assets/libs/bootstrap-table/dist/bootstrap-table-locale-all.js b/public/assets/libs/bootstrap-table/dist/bootstrap-table-locale-all.js new file mode 100644 index 0000000000000000000000000000000000000000..bfa5780a45090de2689616291253495ad219b464 --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/bootstrap-table-locale-all.js @@ -0,0 +1,1928 @@ +/** + * Bootstrap Table Afrikaans translation + * Author: Phillip Kruger + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['af-ZA'] = { + formatLoadingMessage: function () { + return 'Besig om te laai, wag asseblief ...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' rekords per bladsy'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Resultate ' + pageFrom + ' tot ' + pageTo + ' van ' + totalRows + ' rye'; + }, + formatSearch: function () { + return 'Soek'; + }, + formatNoMatches: function () { + return 'Geen rekords gevind nie'; + }, + formatPaginationSwitch: function () { + return 'Wys/verberg bladsy nummering'; + }, + formatRefresh: function () { + return 'Herlaai'; + }, + formatToggle: function () { + return 'Wissel'; + }, + formatColumns: function () { + return 'Kolomme'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['af-ZA']); + +})(jQuery); + +/** + * Bootstrap Table English translation + * Author: Zhixin Wen + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['ar-SA'] = { + formatLoadingMessage: function () { + return 'جاري التحميل, يرجى الإنتظار...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' سجل لكل صفحة'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'الظاهر ' + pageFrom + ' إلى ' + pageTo + ' من ' + totalRows + ' سجل'; + }, + formatSearch: function () { + return 'بحث'; + }, + formatNoMatches: function () { + return 'لا توجد نتائج مطابقة للبحث'; + }, + formatPaginationSwitch: function () { + return 'إخفاء\إظهار ترقيم الصفحات'; + }, + formatRefresh: function () { + return 'تحديث'; + }, + formatToggle: function () { + return 'تغيير'; + }, + formatColumns: function () { + return 'أعمدة'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ar-SA']); + +})(jQuery); + +/** + * Bootstrap Table Catalan translation + * Authors: Marc Pina + * Claudi Martinez + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['ca-ES'] = { + formatLoadingMessage: function () { + return 'Espereu, si us plau...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' resultats per pàgina'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Mostrant de ' + pageFrom + ' fins ' + pageTo + ' - total ' + totalRows + ' resultats'; + }, + formatSearch: function () { + return 'Cerca'; + }, + formatNoMatches: function () { + return 'No s\'han trobat resultats'; + }, + formatPaginationSwitch: function () { + return 'Amaga/Mostra paginació'; + }, + formatRefresh: function () { + return 'Refresca'; + }, + formatToggle: function () { + return 'Alterna formatació'; + }, + formatColumns: function () { + return 'Columnes'; + }, + formatAllRows: function () { + return 'Tots'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ca-ES']); + +})(jQuery); + +/** + * Bootstrap Table Czech translation + * Author: Lukas Kral (monarcha@seznam.cz) + * Author: Jakub Svestka + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['cs-CZ'] = { + formatLoadingMessage: function () { + return 'Čekejte, prosím...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' položek na stránku'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Zobrazena ' + pageFrom + '. - ' + pageTo + '. položka z celkových ' + totalRows; + }, + formatSearch: function () { + return 'Vyhledávání'; + }, + formatNoMatches: function () { + return 'Nenalezena žádná vyhovující položka'; + }, + formatPaginationSwitch: function () { + return 'Skrýt/Zobrazit stránkování'; + }, + formatRefresh: function () { + return 'Aktualizovat'; + }, + formatToggle: function () { + return 'Přepni'; + }, + formatColumns: function () { + return 'Sloupce'; + }, + formatAllRows: function () { + return 'Vše'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['cs-CZ']); + +})(jQuery); + +/** + * Bootstrap Table danish translation + * Author: Your Name Jan Borup Coyle, github@coyle.dk + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['da-DK'] = { + formatLoadingMessage: function () { + return 'Indlæser, vent venligst...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' poster pr side'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Viser ' + pageFrom + ' til ' + pageTo + ' af ' + totalRows + ' rækker'; + }, + formatSearch: function () { + return 'Søg'; + }, + formatNoMatches: function () { + return 'Ingen poster fundet'; + }, + formatRefresh: function () { + return 'Opdater'; + }, + formatToggle: function () { + return 'Skift'; + }, + formatColumns: function () { + return 'Kolonner'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['da-DK']); + +})(jQuery); +/** +* Bootstrap Table German translation +* Author: Paul Mohr - Sopamo +*/ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['de-DE'] = { + formatLoadingMessage: function () { + return 'Lade, bitte warten...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' Einträge pro Seite.'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Zeige Zeile ' + pageFrom + ' bis ' + pageTo + ' von ' + totalRows + ' Zeile' + ((totalRows > 1) ? "n" : "")+"."; + }, + formatDetailPagination: function (totalRows) { + return 'Zeige ' + totalRows + ' Zeile' + ((totalRows > 1) ? "n" : "")+"."; + }, + formatSearch: function () { + return 'Suchen ...'; + }, + formatNoMatches: function () { + return 'Keine passenden Ergebnisse gefunden.'; + }, + formatRefresh: function () { + return 'Neu laden'; + }, + formatToggle: function () { + return 'Umschalten'; + }, + formatColumns: function () { + return 'Spalten'; + }, + formatAllRows: function () { + return 'Alle'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['de-DE']); + +})(jQuery); + +/** + * Bootstrap Table Greek translation + * Author: giannisdallas + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['el-GR'] = { + formatLoadingMessage: function () { + return 'Φορτώνει, παρακαλώ περιμένετε...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' αποτελέσματα ανά σελίδα'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Εμφανίζονται από την ' + pageFrom + ' ως την ' + pageTo + ' από σύνολο ' + totalRows + ' σειρών'; + }, + formatSearch: function () { + return 'Αναζητήστε'; + }, + formatNoMatches: function () { + return 'Δεν βρέθηκαν αποτελέσματα'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['el-GR']); + +})(jQuery); + +/** + * Bootstrap Table English translation + * Author: Zhixin Wen + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['en-US'] = { + formatLoadingMessage: function () { + return 'Loading, please wait...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' rows per page'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Showing ' + pageFrom + ' to ' + pageTo + ' of ' + totalRows + ' rows'; + }, + formatSearch: function () { + return 'Search'; + }, + formatNoMatches: function () { + return 'No matching records found'; + }, + formatPaginationSwitch: function () { + return 'Hide/Show pagination'; + }, + formatRefresh: function () { + return 'Refresh'; + }, + formatToggle: function () { + return 'Toggle'; + }, + formatColumns: function () { + return 'Columns'; + }, + formatAllRows: function () { + return 'All'; + }, + formatExport: function () { + return 'Export data'; + }, + formatClearFilters: function () { + return 'Clear filters'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['en-US']); + +})(jQuery); + +/** + * Bootstrap Table Spanish (Argentina) translation + * Author: Felix Vera (felix.vera@gmail.com) + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['es-AR'] = { + formatLoadingMessage: function () { + return 'Cargando, espere por favor...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' registros por página'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas'; + }, + formatSearch: function () { + return 'Buscar'; + }, + formatNoMatches: function () { + return 'No se encontraron registros'; + }, + formatAllRows: function () { + return 'Todo'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-AR']); + +})(jQuery); +/** + * Traducción de librería Bootstrap Table a Español (Chile) + * @author Brian Álvarez Azócar + * email brianalvarezazocar@gmail.com + */ +(function($) { + 'use strict'; + + $.fn.bootstrapTable.locales['es-CL'] = { + formatLoadingMessage: function() { + return 'Cargando, espere por favor...'; + }, + formatRecordsPerPage: function(pageNumber) { + return pageNumber + ' filas por p\u00E1gina'; + }, + formatShowingRows: function(pageFrom, pageTo, totalRows) { + return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas'; + }, + formatSearch: function() { + return 'Buscar'; + }, + formatNoMatches: function() { + return 'No se encontraron registros'; + }, + formatPaginationSwitch: function() { + return 'Ocultar/Mostrar paginaci\u00F3n'; + }, + formatRefresh: function() { + return 'Refrescar'; + }, + formatToggle: function() { + return 'Cambiar'; + }, + formatColumns: function() { + return 'Columnas'; + }, + formatAllRows: function() { + return 'Todo'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-CL']); + +})(jQuery); + +/** + * Bootstrap Table Spanish (Costa Rica) translation + * Author: Dennis Hernández (http://djhvscf.github.io/Blog/) + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['es-CR'] = { + formatLoadingMessage: function () { + return 'Cargando, por favor espere...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' registros por página'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Mostrando de ' + pageFrom + ' a ' + pageTo + ' registros de ' + totalRows + ' registros en total'; + }, + formatSearch: function () { + return 'Buscar'; + }, + formatNoMatches: function () { + return 'No se encontraron registros'; + }, + formatRefresh: function () { + return 'Refrescar'; + }, + formatToggle: function () { + return 'Alternar'; + }, + formatColumns: function () { + return 'Columnas'; + }, + formatAllRows: function () { + return 'Todo'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-CR']); + +})(jQuery); + +/** + * Bootstrap Table Spanish Spain translation + * Author: Marc Pina + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['es-ES'] = { + formatLoadingMessage: function () { + return 'Por favor espere...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' resultados por página'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Mostrando desde ' + pageFrom + ' hasta ' + pageTo + ' - En total ' + totalRows + ' resultados'; + }, + formatSearch: function () { + return 'Buscar'; + }, + formatNoMatches: function () { + return 'No se encontraron resultados'; + }, + formatPaginationSwitch: function () { + return 'Ocultar/Mostrar paginación'; + }, + formatRefresh: function () { + return 'Refrescar'; + }, + formatToggle: function () { + return 'Ocultar/Mostrar'; + }, + formatColumns: function () { + return 'Columnas'; + }, + formatAllRows: function () { + return 'Todos'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-ES']); + +})(jQuery); + +/** + * Bootstrap Table Spanish (México) translation (Obtenido de traducción de Argentina) + * Author: Felix Vera (felix.vera@gmail.com) + * Copiado: Mauricio Vera (mauricioa.vera@gmail.com) + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['es-MX'] = { + formatLoadingMessage: function () { + return 'Cargando, espere por favor...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' registros por página'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Mostrando ' + pageFrom + ' a ' + pageTo + ' de ' + totalRows + ' filas'; + }, + formatSearch: function () { + return 'Buscar'; + }, + formatNoMatches: function () { + return 'No se encontraron registros'; + }, + formatAllRows: function () { + return 'Todo'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-MX']); + +})(jQuery); + +/** + * Bootstrap Table Spanish (Nicaragua) translation + * Author: Dennis Hernández (http://djhvscf.github.io/Blog/) + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['es-NI'] = { + formatLoadingMessage: function () { + return 'Cargando, por favor espere...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' registros por página'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Mostrando de ' + pageFrom + ' a ' + pageTo + ' registros de ' + totalRows + ' registros en total'; + }, + formatSearch: function () { + return 'Buscar'; + }, + formatNoMatches: function () { + return 'No se encontraron registros'; + }, + formatRefresh: function () { + return 'Refrescar'; + }, + formatToggle: function () { + return 'Alternar'; + }, + formatColumns: function () { + return 'Columnas'; + }, + formatAllRows: function () { + return 'Todo'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-NI']); + +})(jQuery); + +/** + * Bootstrap Table Spanish (España) translation + * Author: Antonio Pérez + */ + (function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['es-SP'] = { + formatLoadingMessage: function () { + return 'Cargando, por favor espera...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' registros por página.'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return pageFrom + ' - ' + pageTo + ' de ' + totalRows + ' registros.'; + }, + formatSearch: function () { + return 'Buscar'; + }, + formatNoMatches: function () { + return 'No se han encontrado registros.'; + }, + formatRefresh: function () { + return 'Actualizar'; + }, + formatToggle: function () { + return 'Alternar'; + }, + formatColumns: function () { + return 'Columnas'; + }, + formatAllRows: function () { + return 'Todo'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['es-SP']); + +})(jQuery); +/** + * Bootstrap Table Estonian translation + * Author: kristjan@logist.it> + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['et-EE'] = { + formatLoadingMessage: function () { + return 'Päring käib, palun oota...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' rida lehe kohta'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Näitan tulemusi ' + pageFrom + ' kuni ' + pageTo + ' - kokku ' + totalRows + ' tulemust'; + }, + formatSearch: function () { + return 'Otsi'; + }, + formatNoMatches: function () { + return 'Päringu tingimustele ei vastanud ühtegi tulemust'; + }, + formatPaginationSwitch: function () { + return 'Näita/Peida lehtedeks jagamine'; + }, + formatRefresh: function () { + return 'Värskenda'; + }, + formatToggle: function () { + return 'Lülita'; + }, + formatColumns: function () { + return 'Veerud'; + }, + formatAllRows: function () { + return 'Kõik'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['et-EE']); + +})(jQuery); +/** + * Bootstrap Table Persian translation + * Author: MJ Vakili + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['fa-IR'] = { + formatLoadingMessage: function () { + return 'در حال بارگذاری, لطفا صبر کنید...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' رکورد در صفحه'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'نمایش ' + pageFrom + ' تا ' + pageTo + ' از ' + totalRows + ' ردیف'; + }, + formatSearch: function () { + return 'جستجو'; + }, + formatNoMatches: function () { + return 'رکوردی یافت نشد.'; + }, + formatPaginationSwitch: function () { + return 'نمایش/مخفی صفحه بندی'; + }, + formatRefresh: function () { + return 'به روز رسانی'; + }, + formatToggle: function () { + return 'تغییر نمایش'; + }, + formatColumns: function () { + return 'سطر ها'; + }, + formatAllRows: function () { + return 'همه'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fa-IR']); + +})(jQuery); +/** + * Bootstrap Table French (Belgium) translation + * Author: Julien Bisconti (julien.bisconti@gmail.com) + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['fr-BE'] = { + formatLoadingMessage: function () { + return 'Chargement en cours...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' entrées par page'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Affiche de' + pageFrom + ' à ' + pageTo + ' sur ' + totalRows + ' lignes'; + }, + formatSearch: function () { + return 'Recherche'; + }, + formatNoMatches: function () { + return 'Pas de fichiers trouvés'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fr-BE']); + +})(jQuery); + +/** + * Bootstrap Table French (France) translation + * Author: Dennis Hernández (http://djhvscf.github.io/Blog/) + * Modification: Tidalf (https://github.com/TidalfFR) + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['fr-FR'] = { + formatLoadingMessage: function () { + return 'Chargement en cours, patientez, s´il vous plaît ...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' lignes par page'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Affichage des lignes ' + pageFrom + ' à ' + pageTo + ' sur ' + totalRows + ' lignes au total'; + }, + formatSearch: function () { + return 'Rechercher'; + }, + formatNoMatches: function () { + return 'Aucun résultat trouvé'; + }, + formatRefresh: function () { + return 'Rafraîchir'; + }, + formatToggle: function () { + return 'Alterner'; + }, + formatColumns: function () { + return 'Colonnes'; + }, + formatAllRows: function () { + return 'Tous'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['fr-FR']); + +})(jQuery); + +/** + * Bootstrap Table Hebrew translation + * Author: legshooter + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['he-IL'] = { + formatLoadingMessage: function () { + return 'טוען, נא להמתין...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' שורות בעמוד'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'מציג ' + pageFrom + ' עד ' + pageTo + ' מ-' + totalRows + ' שורות'; + }, + formatSearch: function () { + return 'חיפוש'; + }, + formatNoMatches: function () { + return 'לא נמצאו רשומות תואמות'; + }, + formatPaginationSwitch: function () { + return 'הסתר/הצג מספור דפים'; + }, + formatRefresh: function () { + return 'רענן'; + }, + formatToggle: function () { + return 'החלף תצוגה'; + }, + formatColumns: function () { + return 'עמודות'; + }, + formatAllRows: function () { + return 'הכל'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['he-IL']); + +})(jQuery); + +/** + * Bootstrap Table Croatian translation + * Author: Petra Štrbenac (petra.strbenac@gmail.com) + * Author: Petra Štrbenac (petra.strbenac@gmail.com) + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['hr-HR'] = { + formatLoadingMessage: function () { + return 'Molimo pričekajte ...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' broj zapisa po stranici'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Prikazujem ' + pageFrom + '. - ' + pageTo + '. od ukupnog broja zapisa ' + totalRows; + }, + formatSearch: function () { + return 'Pretraži'; + }, + formatNoMatches: function () { + return 'Nije pronađen niti jedan zapis'; + }, + formatPaginationSwitch: function () { + return 'Prikaži/sakrij stranice'; + }, + formatRefresh: function () { + return 'Osvježi'; + }, + formatToggle: function () { + return 'Promijeni prikaz'; + }, + formatColumns: function () { + return 'Kolone'; + }, + formatAllRows: function () { + return 'Sve'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['hr-HR']); + +})(jQuery); + +/** + * Bootstrap Table Hungarian translation + * Author: Nagy Gergely + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['hu-HU'] = { + formatLoadingMessage: function () { + return 'Betöltés, kérem várjon...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' rekord per oldal'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Megjelenítve ' + pageFrom + ' - ' + pageTo + ' / ' + totalRows + ' összesen'; + }, + formatSearch: function () { + return 'Keresés'; + }, + formatNoMatches: function () { + return 'Nincs találat'; + }, + formatPaginationSwitch: function () { + return 'Lapozó elrejtése/megjelenítése'; + }, + formatRefresh: function () { + return 'Frissítés'; + }, + formatToggle: function () { + return 'Összecsuk/Kinyit'; + }, + formatColumns: function () { + return 'Oszlopok'; + }, + formatAllRows: function () { + return 'Összes'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['hu-HU']); + +})(jQuery); + +/** + * Bootstrap Table Indonesian translation + * Author: Andre Gardiner + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['id-ID'] = { + formatLoadingMessage: function () { + return 'Memuat, mohon tunggu...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' baris per halaman'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Menampilkan ' + pageFrom + ' sampai ' + pageTo + ' dari ' + totalRows + ' baris'; + }, + formatSearch: function () { + return 'Pencarian'; + }, + formatNoMatches: function () { + return 'Tidak ditemukan data yang cocok'; + }, + formatPaginationSwitch: function () { + return 'Sembunyikan/Tampilkan halaman'; + }, + formatRefresh: function () { + return 'Muat ulang'; + }, + formatToggle: function () { + return 'Beralih'; + }, + formatColumns: function () { + return 'kolom'; + }, + formatAllRows: function () { + return 'Semua'; + }, + formatExport: function () { + return 'Ekspor data'; + }, + formatClearFilters: function () { + return 'Bersihkan filter'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['id-ID']); + +})(jQuery); + +/** + * Bootstrap Table Italian translation + * Author: Davide Renzi + * Author: Davide Borsatto + * Author: Alessio Felicioni + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['it-IT'] = { + formatLoadingMessage: function () { + return 'Caricamento in corso...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' elementi per pagina'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Elementi mostrati da ' + pageFrom + ' a ' + pageTo + ' (Numero totali di elementi ' + totalRows + ')'; + }, + formatSearch: function () { + return 'Cerca'; + }, + formatNoMatches: function () { + return 'Nessun elemento trovato'; + }, + formatPaginationSwitch: function () { + return 'Nascondi/Mostra paginazione'; + }, + formatRefresh: function () { + return 'Aggiorna'; + }, + formatToggle: function () { + return 'Attiva/Disattiva'; + }, + formatColumns: function () { + return 'Colonne'; + }, + formatAllRows: function () { + return 'Tutto'; + }, + formatExport: function () { + return 'Esporta dati'; + }, + formatClearFilters: function () { + return 'Pulisci filtri'; + } + + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['it-IT']); + +})(jQuery); + +/** + * Bootstrap Table Japanese translation + * Author: Azamshul Azizy + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['ja-JP'] = { + formatLoadingMessage: function () { + return '読み込み中です。少々お待ちください。'; + }, + formatRecordsPerPage: function (pageNumber) { + return 'ページ当たり最大' + pageNumber + '件'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return '全' + totalRows + '件から、'+ pageFrom + 'から' + pageTo + '件目まで表示しています'; + }, + formatSearch: function () { + return '検索'; + }, + formatNoMatches: function () { + return '該当するレコードが見つかりません'; + }, + formatPaginationSwitch: function () { + return 'ページ数を表示・非表示'; + }, + formatRefresh: function () { + return '更新'; + }, + formatToggle: function () { + return 'トグル'; + }, + formatColumns: function () { + return '列'; + }, + formatAllRows: function () { + return 'すべて'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ja-JP']); + +})(jQuery); +/** + * Bootstrap Table Georgian translation + * Author: Levan Lotuashvili + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['ka-GE'] = { + formatLoadingMessage: function() { + return 'იტვირთება, გთხოვთ მოიცადოთ...'; + }, + formatRecordsPerPage: function(pageNumber) { + return pageNumber + ' ჩანაწერი თითო გვერდზე'; + }, + formatShowingRows: function(pageFrom, pageTo, totalRows) { + return 'ნაჩვენებია ' + pageFrom + '-დან ' + pageTo + '-მდე ჩანაწერი ჯამური ' + totalRows + '-დან'; + }, + formatSearch: function() { + return 'ძებნა'; + }, + formatNoMatches: function() { + return 'მონაცემები არ არის'; + }, + formatPaginationSwitch: function() { + return 'გვერდების გადამრთველის დამალვა/გამოჩენა'; + }, + formatRefresh: function() { + return 'განახლება'; + }, + formatToggle: function() { + return 'ჩართვა/გამორთვა'; + }, + formatColumns: function() { + return 'სვეტები'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ka-GE']); + +})(jQuery); + +/** + * Bootstrap Table Korean translation + * Author: Yi Tae-Hyeong (jsonobject@gmail.com) + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['ko-KR'] = { + formatLoadingMessage: function () { + return '데이터를 불러오는 중입니다...'; + }, + formatRecordsPerPage: function (pageNumber) { + return '페이지 당 ' + pageNumber + '개 데이터 출력'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return '전체 ' + totalRows + '개 중 ' + pageFrom + '~' + pageTo + '번째 데이터 출력,'; + }, + formatSearch: function () { + return '검색'; + }, + formatNoMatches: function () { + return '조회된 데이터가 없습니다.'; + }, + formatRefresh: function () { + return '새로 고침'; + }, + formatToggle: function () { + return '전환'; + }, + formatColumns: function () { + return '컬럼 필터링'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ko-KR']); + +})(jQuery); +/** + * Bootstrap Table Malay translation + * Author: Azamshul Azizy + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['ms-MY'] = { + formatLoadingMessage: function () { + return 'Permintaan sedang dimuatkan. Sila tunggu sebentar...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' rekod setiap muka surat'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Sedang memaparkan rekod ' + pageFrom + ' hingga ' + pageTo + ' daripada jumlah ' + totalRows + ' rekod'; + }, + formatSearch: function () { + return 'Cari'; + }, + formatNoMatches: function () { + return 'Tiada rekod yang menyamai permintaan'; + }, + formatPaginationSwitch: function () { + return 'Tunjuk/sembunyi muka surat'; + }, + formatRefresh: function () { + return 'Muatsemula'; + }, + formatToggle: function () { + return 'Tukar'; + }, + formatColumns: function () { + return 'Lajur'; + }, + formatAllRows: function () { + return 'Semua'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ms-MY']); + +})(jQuery); + +/** + * Bootstrap Table norwegian translation + * Author: Jim Nordbø, jim@nordb.no + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['nb-NO'] = { + formatLoadingMessage: function () { + return 'Oppdaterer, vennligst vent...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' poster pr side'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Viser ' + pageFrom + ' til ' + pageTo + ' av ' + totalRows + ' rekker'; + }, + formatSearch: function () { + return 'Søk'; + }, + formatNoMatches: function () { + return 'Ingen poster funnet'; + }, + formatRefresh: function () { + return 'Oppdater'; + }, + formatToggle: function () { + return 'Endre'; + }, + formatColumns: function () { + return 'Kolonner'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['nb-NO']); + +})(jQuery); +/** + * Bootstrap Table Dutch translation + * Author: Your Name + */ +(function($) { + 'use strict'; + + $.fn.bootstrapTable.locales['nl-NL'] = { + formatLoadingMessage: function() { + return 'Laden, even geduld...'; + }, + formatRecordsPerPage: function(pageNumber) { + return pageNumber + ' records per pagina'; + }, + formatShowingRows: function(pageFrom, pageTo, totalRows) { + return 'Toon ' + pageFrom + ' tot ' + pageTo + ' van ' + totalRows + ' record' + ((totalRows > 1) ? 's' : ''); + }, + formatDetailPagination: function(totalRows) { + return 'Toon ' + totalRows + ' record' + ((totalRows > 1) ? 's' : ''); + }, + formatSearch: function() { + return 'Zoeken'; + }, + formatNoMatches: function() { + return 'Geen resultaten gevonden'; + }, + formatRefresh: function() { + return 'Vernieuwen'; + }, + formatToggle: function() { + return 'Omschakelen'; + }, + formatColumns: function() { + return 'Kolommen'; + }, + formatAllRows: function() { + return 'Alle'; + }, + formatPaginationSwitch: function() { + return 'Verberg/Toon paginatie'; + }, + formatExport: function() { + return 'Exporteer data'; + }, + formatClearFilters: function() { + return 'Verwijder filters'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['nl-NL']); + +})(jQuery); + +/** + * Bootstrap Table Polish translation + * Author: zergu + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['pl-PL'] = { + formatLoadingMessage: function () { + return 'Ładowanie, proszę czekać...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' rekordów na stronę'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Wyświetlanie rekordów od ' + pageFrom + ' do ' + pageTo + ' z ' + totalRows; + }, + formatSearch: function () { + return 'Szukaj'; + }, + formatNoMatches: function () { + return 'Niestety, nic nie znaleziono'; + }, + formatRefresh: function () { + return 'Odśwież'; + }, + formatToggle: function () { + return 'Przełącz'; + }, + formatColumns: function () { + return 'Kolumny'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pl-PL']); + +})(jQuery); + +/** + * Bootstrap Table Brazilian Portuguese Translation + * Author: Eduardo Cerqueira + * Update: João Mello + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['pt-BR'] = { + formatLoadingMessage: function () { + return 'Carregando, aguarde...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' registros por página'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Exibindo ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas'; + }, + formatSearch: function () { + return 'Pesquisar'; + }, + formatRefresh: function () { + return 'Recarregar'; + }, + formatToggle: function () { + return 'Alternar'; + }, + formatColumns: function () { + return 'Colunas'; + }, + formatPaginationSwitch: function () { + return 'Ocultar/Exibir paginação'; + }, + formatNoMatches: function () { + return 'Nenhum registro encontrado'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-BR']); + +})(jQuery); + +/** + * Bootstrap Table Portuguese Portugal Translation + * Author: Burnspirit + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['pt-PT'] = { + formatLoadingMessage: function () { + return 'A carregar, por favor aguarde...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' registos por página'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'A mostrar ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas'; + }, + formatSearch: function () { + return 'Pesquisa'; + }, + formatNoMatches: function () { + return 'Nenhum registo encontrado'; + }, + formatPaginationSwitch: function () { + return 'Esconder/Mostrar paginação'; + }, + formatRefresh: function () { + return 'Atualizar'; + }, + formatToggle: function () { + return 'Alternar'; + }, + formatColumns: function () { + return 'Colunas'; + }, + formatAllRows: function () { + return 'Tudo'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-PT']); + +})(jQuery); + +/** + * Bootstrap Table Romanian translation + * Author: cristake + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['ro-RO'] = { + formatLoadingMessage: function () { + return 'Se incarca, va rugam asteptati...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' inregistrari pe pagina'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Arata de la ' + pageFrom + ' pana la ' + pageTo + ' din ' + totalRows + ' randuri'; + }, + formatSearch: function () { + return 'Cauta'; + }, + formatNoMatches: function () { + return 'Nu au fost gasite inregistrari'; + }, + formatPaginationSwitch: function () { + return 'Ascunde/Arata paginatia'; + }, + formatRefresh: function () { + return 'Reincarca'; + }, + formatToggle: function () { + return 'Comuta'; + }, + formatColumns: function () { + return 'Coloane'; + }, + formatAllRows: function () { + return 'Toate'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ro-RO']); + +})(jQuery); +/** + * Bootstrap Table Russian translation + * Author: Dunaevsky Maxim + */ +(function ($) { + 'use strict'; + $.fn.bootstrapTable.locales['ru-RU'] = { + formatLoadingMessage: function () { + return 'Пожалуйста, подождите, идёт загрузка...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' записей на страницу'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Записи с ' + pageFrom + ' по ' + pageTo + ' из ' + totalRows; + }, + formatSearch: function () { + return 'Поиск'; + }, + formatNoMatches: function () { + return 'Ничего не найдено'; + }, + formatRefresh: function () { + return 'Обновить'; + }, + formatToggle: function () { + return 'Переключить'; + }, + formatColumns: function () { + return 'Колонки'; + }, + formatClearFilters: function () { + return 'Очистить фильтры'; + }, + formatMultipleSort: function () { + return 'Множественная сортировка'; + }, + formatAddLevel: function () { + return 'Добавить уровень'; + }, + formatDeleteLevel: function () { + return 'Удалить уровень'; + }, + formatColumn: function () { + return 'Колонка'; + }, + formatOrder: function () { + return 'Порядок'; + }, + formatSortBy: function () { + return 'Сортировать по'; + }, + formatThenBy: function () { + return 'затем по'; + }, + formatSort: function () { + return 'Сортировать'; + }, + formatCancel: function () { + return 'Отмена'; + }, + formatDuplicateAlertTitle: function () { + return 'Дублирование колонок!'; + }, + formatDuplicateAlertDescription: function () { + return 'Удалите, пожалуйста, дублирующую колонку, или замените ее на другую.'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ru-RU']); + +})(jQuery); + +/** + * Bootstrap Table Slovak translation + * Author: Jozef Dúc + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['sk-SK'] = { + formatLoadingMessage: function () { + return 'Prosím čakajte ...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' záznamov na stranu'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Zobrazená ' + pageFrom + '. - ' + pageTo + '. položka z celkových ' + totalRows; + }, + formatSearch: function () { + return 'Vyhľadávanie'; + }, + formatNoMatches: function () { + return 'Nenájdená žiadna vyhovujúca položka'; + }, + formatRefresh: function () { + return 'Obnoviť'; + }, + formatToggle: function () { + return 'Prepni'; + }, + formatColumns: function () { + return 'Stĺpce'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['sk-SK']); + +})(jQuery); + +/** + * Bootstrap Table Swedish translation + * Author: C Bratt + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['sv-SE'] = { + formatLoadingMessage: function () { + return 'Laddar, vänligen vänta...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' rader per sida'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Visa ' + pageFrom + ' till ' + pageTo + ' av ' + totalRows + ' rader'; + }, + formatSearch: function () { + return 'Sök'; + }, + formatNoMatches: function () { + return 'Inga matchande resultat funna.'; + }, + formatRefresh: function () { + return 'Uppdatera'; + }, + formatToggle: function () { + return 'Skifta'; + }, + formatColumns: function () { + return 'kolumn'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['sv-SE']); + +})(jQuery); + +/** + * Bootstrap Table Thai translation + * Author: Monchai S. + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['th-TH'] = { + formatLoadingMessage: function () { + return 'กำลังโหลดข้อมูล, กรุณารอสักครู่...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' รายการต่อหน้า'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'รายการที่ ' + pageFrom + ' ถึง ' + pageTo + ' จากทั้งหมด ' + totalRows + ' รายการ'; + }, + formatSearch: function () { + return 'ค้นหา'; + }, + formatNoMatches: function () { + return 'ไม่พบรายการที่ค้นหา !'; + }, + formatRefresh: function () { + return 'รีเฟรส'; + }, + formatToggle: function () { + return 'สลับมุมมอง'; + }, + formatColumns: function () { + return 'คอลัมน์'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['th-TH']); + +})(jQuery); + +/** + * Bootstrap Table Turkish translation + * Author: Emin Şen + * Author: Sercan Cakir + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['tr-TR'] = { + formatLoadingMessage: function () { + return 'Yükleniyor, lütfen bekleyin...'; + }, + formatRecordsPerPage: function (pageNumber) { + return 'Sayfa başına ' + pageNumber + ' kayıt.'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return totalRows + ' kayıttan ' + pageFrom + '-' + pageTo + ' arası gösteriliyor.'; + }, + formatSearch: function () { + return 'Ara'; + }, + formatNoMatches: function () { + return 'Eşleşen kayıt bulunamadı.'; + }, + formatRefresh: function () { + return 'Yenile'; + }, + formatToggle: function () { + return 'Değiştir'; + }, + formatColumns: function () { + return 'Sütunlar'; + }, + formatAllRows: function () { + return 'Tüm Satırlar'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['tr-TR']); + +})(jQuery); + +/** + * Bootstrap Table Ukrainian translation + * Author: Vitaliy Timchenko + */ + (function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['uk-UA'] = { + formatLoadingMessage: function () { + return 'Завантаження, будь ласка, зачекайте...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' записів на сторінку'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Показано з ' + pageFrom + ' по ' + pageTo + '. Всього: ' + totalRows; + }, + formatSearch: function () { + return 'Пошук'; + }, + formatNoMatches: function () { + return 'Не знайдено жодного запису'; + }, + formatRefresh: function () { + return 'Оновити'; + }, + formatToggle: function () { + return 'Змінити'; + }, + formatColumns: function () { + return 'Стовпці'; + }, + formatClearFilters: function () { + return 'Очистити фільтри'; + }, + formatMultipleSort: function () { + return 'Сортування за кількома стовпцями'; + }, + formatAddLevel: function () { + return 'Додати рівень'; + }, + formatDeleteLevel: function () { + return 'Видалити рівень'; + }, + formatColumn: function () { + return 'Стовпець'; + }, + formatOrder: function () { + return 'Порядок'; + }, + formatSortBy: function () { + return 'Сортувати за'; + }, + formatThenBy: function () { + return 'потім за'; + }, + formatSort: function () { + return 'Сортувати'; + }, + formatCancel: function () { + return 'Скасувати'; + }, + formatDuplicateAlertTitle: function () { + return 'Дублювання стовпців!'; + }, + formatDuplicateAlertDescription: function () { + return 'Видаліть, будь ласка, дублюючий стовпець, або замініть його на інший.'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['uk-UA']); + +})(jQuery); + +/** + * Bootstrap Table Urdu translation + * Author: Malik + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['ur-PK'] = { + formatLoadingMessage: function () { + return 'براۓ مہربانی انتظار کیجئے'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' ریکارڈز فی صفہ '; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'دیکھیں ' + pageFrom + ' سے ' + pageTo + ' کے ' + totalRows + 'ریکارڈز'; + }, + formatSearch: function () { + return 'تلاش'; + }, + formatNoMatches: function () { + return 'کوئی ریکارڈ نہیں ملا'; + }, + formatRefresh: function () { + return 'تازہ کریں'; + }, + formatToggle: function () { + return 'تبدیل کریں'; + }, + formatColumns: function () { + return 'کالم'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['ur-PK']); + +})(jQuery); + +/** + * Bootstrap Table Uzbek translation + * Author: Nabijon Masharipov + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['uz-Latn-UZ'] = { + formatLoadingMessage: function () { + return 'Yuklanyapti, iltimos kuting...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' qator har sahifada'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Ko\'rsatypati ' + pageFrom + ' dan ' + pageTo + ' gacha ' + totalRows + ' qatorlarni'; + }, + formatSearch: function () { + return 'Qidirish'; + }, + formatNoMatches: function () { + return 'Hech narsa topilmadi'; + }, + formatPaginationSwitch: function () { + return 'Sahifalashni yashirish/ko\'rsatish'; + }, + formatRefresh: function () { + return 'Yangilash'; + }, + formatToggle: function () { + return 'Ko\'rinish'; + }, + formatColumns: function () { + return 'Ustunlar'; + }, + formatAllRows: function () { + return 'Hammasi'; + }, + formatExport: function () { + return 'Eksport'; + }, + formatClearFilters: function () { + return 'Filtrlarni tozalash'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['uz-Latn-UZ']); + +})(jQuery); + +/** + * Bootstrap Table Vietnamese translation + * Author: Duc N. PHAM + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['vi-VN'] = { + formatLoadingMessage: function () { + return 'Đang tải...'; + }, + formatRecordsPerPage: function (pageNumber) { + return pageNumber + ' bản ghi mỗi trang'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return 'Hiển thị từ trang ' + pageFrom + ' đến ' + pageTo + ' của ' + totalRows + ' bảng ghi'; + }, + formatSearch: function () { + return 'Tìm kiếm'; + }, + formatNoMatches: function () { + return 'Không có dữ liệu'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['vi-VN']); + +})(jQuery); +/** + * Bootstrap Table Chinese translation + * Author: Zhixin Wen + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['zh-CN'] = { + formatLoadingMessage: function () { + return '正在努力地加载数据中,请稍候……'; + }, + formatRecordsPerPage: function (pageNumber) { + return '每页显示 ' + pageNumber + ' 条记录'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return '显示第 ' + pageFrom + ' 到第 ' + pageTo + ' 条记录,总共 ' + totalRows + ' 条记录'; + }, + formatSearch: function () { + return '搜索'; + }, + formatNoMatches: function () { + return '没有找到匹配的记录'; + }, + formatPaginationSwitch: function () { + return '隐藏/显示分页'; + }, + formatRefresh: function () { + return '刷新'; + }, + formatToggle: function () { + return '切换'; + }, + formatColumns: function () { + return '列'; + }, + formatExport: function () { + return '导出数据'; + }, + formatClearFilters: function () { + return '清空过滤'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']); + +})(jQuery); + +/** + * Bootstrap Table Chinese translation + * Author: Zhixin Wen + */ +(function ($) { + 'use strict'; + + $.fn.bootstrapTable.locales['zh-TW'] = { + formatLoadingMessage: function () { + return '正在努力地載入資料,請稍候……'; + }, + formatRecordsPerPage: function (pageNumber) { + return '每頁顯示 ' + pageNumber + ' 項記錄'; + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return '顯示第 ' + pageFrom + ' 到第 ' + pageTo + ' 項記錄,總共 ' + totalRows + ' 項記錄'; + }, + formatSearch: function () { + return '搜尋'; + }, + formatNoMatches: function () { + return '沒有找到符合的結果'; + }, + formatPaginationSwitch: function () { + return '隱藏/顯示分頁'; + }, + formatRefresh: function () { + return '重新整理'; + }, + formatToggle: function () { + return '切換'; + }, + formatColumns: function () { + return '列'; + } + }; + + $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-TW']); + +})(jQuery); diff --git a/public/assets/libs/bootstrap-table/dist/bootstrap-table-locale-all.min.js b/public/assets/libs/bootstrap-table/dist/bootstrap-table-locale-all.min.js new file mode 100644 index 0000000000000000000000000000000000000000..176ef0d415a92556d9f5d37f059b2b6cd4c5da2b --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/bootstrap-table-locale-all.min.js @@ -0,0 +1,7 @@ +/* +* bootstrap-table - v1.11.1 - 2017-02-22 +* https://github.com/wenzhixin/bootstrap-table +* Copyright (c) 2017 zhixin wen +* Licensed MIT License +*/ +!function(a){"use strict";a.fn.bootstrapTable.locales["af-ZA"]={formatLoadingMessage:function(){return"Besig om te laai, wag asseblief ..."},formatRecordsPerPage:function(a){return a+" rekords per bladsy"},formatShowingRows:function(a,b,c){return"Resultate "+a+" tot "+b+" van "+c+" rye"},formatSearch:function(){return"Soek"},formatNoMatches:function(){return"Geen rekords gevind nie"},formatPaginationSwitch:function(){return"Wys/verberg bladsy nummering"},formatRefresh:function(){return"Herlaai"},formatToggle:function(){return"Wissel"},formatColumns:function(){return"Kolomme"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["af-ZA"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ar-SA"]={formatLoadingMessage:function(){return"جاري التحميل, يرجى الإنتظار..."},formatRecordsPerPage:function(a){return a+" سجل لكل صفحة"},formatShowingRows:function(a,b,c){return"الظاهر "+a+" إلى "+b+" من "+c+" سجل"},formatSearch:function(){return"بحث"},formatNoMatches:function(){return"لا توجد نتائج مطابقة للبحث"},formatPaginationSwitch:function(){return"إخفاءإظهار ترقيم الصفحات"},formatRefresh:function(){return"تحديث"},formatToggle:function(){return"تغيير"},formatColumns:function(){return"أعمدة"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ar-SA"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ca-ES"]={formatLoadingMessage:function(){return"Espereu, si us plau..."},formatRecordsPerPage:function(a){return a+" resultats per pàgina"},formatShowingRows:function(a,b,c){return"Mostrant de "+a+" fins "+b+" - total "+c+" resultats"},formatSearch:function(){return"Cerca"},formatNoMatches:function(){return"No s'han trobat resultats"},formatPaginationSwitch:function(){return"Amaga/Mostra paginació"},formatRefresh:function(){return"Refresca"},formatToggle:function(){return"Alterna formatació"},formatColumns:function(){return"Columnes"},formatAllRows:function(){return"Tots"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ca-ES"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["cs-CZ"]={formatLoadingMessage:function(){return"Čekejte, prosím..."},formatRecordsPerPage:function(a){return a+" položek na stránku"},formatShowingRows:function(a,b,c){return"Zobrazena "+a+". - "+b+". položka z celkových "+c},formatSearch:function(){return"Vyhledávání"},formatNoMatches:function(){return"Nenalezena žádná vyhovující položka"},formatPaginationSwitch:function(){return"Skrýt/Zobrazit stránkování"},formatRefresh:function(){return"Aktualizovat"},formatToggle:function(){return"Přepni"},formatColumns:function(){return"Sloupce"},formatAllRows:function(){return"Vše"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["cs-CZ"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["da-DK"]={formatLoadingMessage:function(){return"Indlæser, vent venligst..."},formatRecordsPerPage:function(a){return a+" poster pr side"},formatShowingRows:function(a,b,c){return"Viser "+a+" til "+b+" af "+c+" rækker"},formatSearch:function(){return"Søg"},formatNoMatches:function(){return"Ingen poster fundet"},formatRefresh:function(){return"Opdater"},formatToggle:function(){return"Skift"},formatColumns:function(){return"Kolonner"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["da-DK"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["de-DE"]={formatLoadingMessage:function(){return"Lade, bitte warten..."},formatRecordsPerPage:function(a){return a+" Einträge pro Seite."},formatShowingRows:function(a,b,c){return"Zeige Zeile "+a+" bis "+b+" von "+c+" Zeile"+(c>1?"n":"")+"."},formatDetailPagination:function(a){return"Zeige "+a+" Zeile"+(a>1?"n":"")+"."},formatSearch:function(){return"Suchen ..."},formatNoMatches:function(){return"Keine passenden Ergebnisse gefunden."},formatRefresh:function(){return"Neu laden"},formatToggle:function(){return"Umschalten"},formatColumns:function(){return"Spalten"},formatAllRows:function(){return"Alle"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["de-DE"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["el-GR"]={formatLoadingMessage:function(){return"Φορτώνει, παρακαλώ περιμένετε..."},formatRecordsPerPage:function(a){return a+" αποτελέσματα ανά σελίδα"},formatShowingRows:function(a,b,c){return"Εμφανίζονται από την "+a+" ως την "+b+" από σύνολο "+c+" σειρών"},formatSearch:function(){return"Αναζητήστε"},formatNoMatches:function(){return"Δεν βρέθηκαν αποτελέσματα"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["el-GR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["en-US"]={formatLoadingMessage:function(){return"Loading, please wait..."},formatRecordsPerPage:function(a){return a+" rows per page"},formatShowingRows:function(a,b,c){return"Showing "+a+" to "+b+" of "+c+" rows"},formatSearch:function(){return"Search"},formatNoMatches:function(){return"No matching records found"},formatPaginationSwitch:function(){return"Hide/Show pagination"},formatRefresh:function(){return"Refresh"},formatToggle:function(){return"Toggle"},formatColumns:function(){return"Columns"},formatAllRows:function(){return"All"},formatExport:function(){return"Export data"},formatClearFilters:function(){return"Clear filters"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["en-US"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["es-AR"]={formatLoadingMessage:function(){return"Cargando, espere por favor..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Mostrando "+a+" a "+b+" de "+c+" filas"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-AR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["es-CL"]={formatLoadingMessage:function(){return"Cargando, espere por favor..."},formatRecordsPerPage:function(a){return a+" filas por página"},formatShowingRows:function(a,b,c){return"Mostrando "+a+" a "+b+" de "+c+" filas"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatPaginationSwitch:function(){return"Ocultar/Mostrar paginación"},formatRefresh:function(){return"Refrescar"},formatToggle:function(){return"Cambiar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-CL"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["es-CR"]={formatLoadingMessage:function(){return"Cargando, por favor espere..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Mostrando de "+a+" a "+b+" registros de "+c+" registros en total"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatRefresh:function(){return"Refrescar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-CR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["es-ES"]={formatLoadingMessage:function(){return"Por favor espere..."},formatRecordsPerPage:function(a){return a+" resultados por página"},formatShowingRows:function(a,b,c){return"Mostrando desde "+a+" hasta "+b+" - En total "+c+" resultados"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron resultados"},formatPaginationSwitch:function(){return"Ocultar/Mostrar paginación"},formatRefresh:function(){return"Refrescar"},formatToggle:function(){return"Ocultar/Mostrar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todos"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-ES"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["es-MX"]={formatLoadingMessage:function(){return"Cargando, espere por favor..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Mostrando "+a+" a "+b+" de "+c+" filas"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-MX"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["es-NI"]={formatLoadingMessage:function(){return"Cargando, por favor espere..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Mostrando de "+a+" a "+b+" registros de "+c+" registros en total"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatRefresh:function(){return"Refrescar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-NI"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["es-SP"]={formatLoadingMessage:function(){return"Cargando, por favor espera..."},formatRecordsPerPage:function(a){return a+" registros por página."},formatShowingRows:function(a,b,c){return a+" - "+b+" de "+c+" registros."},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se han encontrado registros."},formatRefresh:function(){return"Actualizar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-SP"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["et-EE"]={formatLoadingMessage:function(){return"Päring käib, palun oota..."},formatRecordsPerPage:function(a){return a+" rida lehe kohta"},formatShowingRows:function(a,b,c){return"Näitan tulemusi "+a+" kuni "+b+" - kokku "+c+" tulemust"},formatSearch:function(){return"Otsi"},formatNoMatches:function(){return"Päringu tingimustele ei vastanud ühtegi tulemust"},formatPaginationSwitch:function(){return"Näita/Peida lehtedeks jagamine"},formatRefresh:function(){return"Värskenda"},formatToggle:function(){return"Lülita"},formatColumns:function(){return"Veerud"},formatAllRows:function(){return"Kõik"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["et-EE"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["fa-IR"]={formatLoadingMessage:function(){return"در حال بارگذاری, لطفا صبر کنید..."},formatRecordsPerPage:function(a){return a+" رکورد در صفحه"},formatShowingRows:function(a,b,c){return"نمایش "+a+" تا "+b+" از "+c+" ردیف"},formatSearch:function(){return"جستجو"},formatNoMatches:function(){return"رکوردی یافت نشد."},formatPaginationSwitch:function(){return"نمایش/مخفی صفحه بندی"},formatRefresh:function(){return"به روز رسانی"},formatToggle:function(){return"تغییر نمایش"},formatColumns:function(){return"سطر ها"},formatAllRows:function(){return"همه"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["fa-IR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["fr-BE"]={formatLoadingMessage:function(){return"Chargement en cours..."},formatRecordsPerPage:function(a){return a+" entrées par page"},formatShowingRows:function(a,b,c){return"Affiche de"+a+" à "+b+" sur "+c+" lignes"},formatSearch:function(){return"Recherche"},formatNoMatches:function(){return"Pas de fichiers trouvés"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["fr-BE"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["fr-FR"]={formatLoadingMessage:function(){return"Chargement en cours, patientez, s´il vous plaît ..."},formatRecordsPerPage:function(a){return a+" lignes par page"},formatShowingRows:function(a,b,c){return"Affichage des lignes "+a+" à "+b+" sur "+c+" lignes au total"},formatSearch:function(){return"Rechercher"},formatNoMatches:function(){return"Aucun résultat trouvé"},formatRefresh:function(){return"Rafraîchir"},formatToggle:function(){return"Alterner"},formatColumns:function(){return"Colonnes"},formatAllRows:function(){return"Tous"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["fr-FR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["he-IL"]={formatLoadingMessage:function(){return"טוען, נא להמתין..."},formatRecordsPerPage:function(a){return a+" שורות בעמוד"},formatShowingRows:function(a,b,c){return"מציג "+a+" עד "+b+" מ-"+c+" שורות"},formatSearch:function(){return"חיפוש"},formatNoMatches:function(){return"לא נמצאו רשומות תואמות"},formatPaginationSwitch:function(){return"הסתר/הצג מספור דפים"},formatRefresh:function(){return"רענן"},formatToggle:function(){return"החלף תצוגה"},formatColumns:function(){return"עמודות"},formatAllRows:function(){return"הכל"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["he-IL"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["hr-HR"]={formatLoadingMessage:function(){return"Molimo pričekajte ..."},formatRecordsPerPage:function(a){return a+" broj zapisa po stranici"},formatShowingRows:function(a,b,c){return"Prikazujem "+a+". - "+b+". od ukupnog broja zapisa "+c},formatSearch:function(){return"Pretraži"},formatNoMatches:function(){return"Nije pronađen niti jedan zapis"},formatPaginationSwitch:function(){return"Prikaži/sakrij stranice"},formatRefresh:function(){return"Osvježi"},formatToggle:function(){return"Promijeni prikaz"},formatColumns:function(){return"Kolone"},formatAllRows:function(){return"Sve"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["hr-HR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["hu-HU"]={formatLoadingMessage:function(){return"Betöltés, kérem várjon..."},formatRecordsPerPage:function(a){return a+" rekord per oldal"},formatShowingRows:function(a,b,c){return"Megjelenítve "+a+" - "+b+" / "+c+" összesen"},formatSearch:function(){return"Keresés"},formatNoMatches:function(){return"Nincs találat"},formatPaginationSwitch:function(){return"Lapozó elrejtése/megjelenítése"},formatRefresh:function(){return"Frissítés"},formatToggle:function(){return"Összecsuk/Kinyit"},formatColumns:function(){return"Oszlopok"},formatAllRows:function(){return"Összes"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["hu-HU"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["id-ID"]={formatLoadingMessage:function(){return"Memuat, mohon tunggu..."},formatRecordsPerPage:function(a){return a+" baris per halaman"},formatShowingRows:function(a,b,c){return"Menampilkan "+a+" sampai "+b+" dari "+c+" baris"},formatSearch:function(){return"Pencarian"},formatNoMatches:function(){return"Tidak ditemukan data yang cocok"},formatPaginationSwitch:function(){return"Sembunyikan/Tampilkan halaman"},formatRefresh:function(){return"Muat ulang"},formatToggle:function(){return"Beralih"},formatColumns:function(){return"kolom"},formatAllRows:function(){return"Semua"},formatExport:function(){return"Ekspor data"},formatClearFilters:function(){return"Bersihkan filter"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["id-ID"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["it-IT"]={formatLoadingMessage:function(){return"Caricamento in corso..."},formatRecordsPerPage:function(a){return a+" elementi per pagina"},formatShowingRows:function(a,b,c){return"Elementi mostrati da "+a+" a "+b+" (Numero totali di elementi "+c+")"},formatSearch:function(){return"Cerca"},formatNoMatches:function(){return"Nessun elemento trovato"},formatPaginationSwitch:function(){return"Nascondi/Mostra paginazione"},formatRefresh:function(){return"Aggiorna"},formatToggle:function(){return"Attiva/Disattiva"},formatColumns:function(){return"Colonne"},formatAllRows:function(){return"Tutto"},formatExport:function(){return"Esporta dati"},formatClearFilters:function(){return"Pulisci filtri"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["it-IT"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ja-JP"]={formatLoadingMessage:function(){return"読み込み中です。少々お待ちください。"},formatRecordsPerPage:function(a){return"ページ当たり最大"+a+"件"},formatShowingRows:function(a,b,c){return"全"+c+"件から、"+a+"から"+b+"件目まで表示しています"},formatSearch:function(){return"検索"},formatNoMatches:function(){return"該当するレコードが見つかりません"},formatPaginationSwitch:function(){return"ページ数を表示・非表示"},formatRefresh:function(){return"更新"},formatToggle:function(){return"トグル"},formatColumns:function(){return"列"},formatAllRows:function(){return"すべて"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ja-JP"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ka-GE"]={formatLoadingMessage:function(){return"იტვირთება, გთხოვთ მოიცადოთ..."},formatRecordsPerPage:function(a){return a+" ჩანაწერი თითო გვერდზე"},formatShowingRows:function(a,b,c){return"ნაჩვენებია "+a+"-დან "+b+"-მდე ჩანაწერი ჯამური "+c+"-დან"},formatSearch:function(){return"ძებნა"},formatNoMatches:function(){return"მონაცემები არ არის"},formatPaginationSwitch:function(){return"გვერდების გადამრთველის დამალვა/გამოჩენა"},formatRefresh:function(){return"განახლება"},formatToggle:function(){return"ჩართვა/გამორთვა"},formatColumns:function(){return"სვეტები"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ka-GE"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ko-KR"]={formatLoadingMessage:function(){return"데이터를 불러오는 중입니다..."},formatRecordsPerPage:function(a){return"페이지 당 "+a+"개 데이터 출력"},formatShowingRows:function(a,b,c){return"전체 "+c+"개 중 "+a+"~"+b+"번째 데이터 출력,"},formatSearch:function(){return"검색"},formatNoMatches:function(){return"조회된 데이터가 없습니다."},formatRefresh:function(){return"새로 고침"},formatToggle:function(){return"전환"},formatColumns:function(){return"컬럼 필터링"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ko-KR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ms-MY"]={formatLoadingMessage:function(){return"Permintaan sedang dimuatkan. Sila tunggu sebentar..."},formatRecordsPerPage:function(a){return a+" rekod setiap muka surat"},formatShowingRows:function(a,b,c){return"Sedang memaparkan rekod "+a+" hingga "+b+" daripada jumlah "+c+" rekod"},formatSearch:function(){return"Cari"},formatNoMatches:function(){return"Tiada rekod yang menyamai permintaan"},formatPaginationSwitch:function(){return"Tunjuk/sembunyi muka surat"},formatRefresh:function(){return"Muatsemula"},formatToggle:function(){return"Tukar"},formatColumns:function(){return"Lajur"},formatAllRows:function(){return"Semua"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ms-MY"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["nb-NO"]={formatLoadingMessage:function(){return"Oppdaterer, vennligst vent..."},formatRecordsPerPage:function(a){return a+" poster pr side"},formatShowingRows:function(a,b,c){return"Viser "+a+" til "+b+" av "+c+" rekker"},formatSearch:function(){return"Søk"},formatNoMatches:function(){return"Ingen poster funnet"},formatRefresh:function(){return"Oppdater"},formatToggle:function(){return"Endre"},formatColumns:function(){return"Kolonner"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["nb-NO"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["nl-NL"]={formatLoadingMessage:function(){return"Laden, even geduld..."},formatRecordsPerPage:function(a){return a+" records per pagina"},formatShowingRows:function(a,b,c){return"Toon "+a+" tot "+b+" van "+c+" record"+(c>1?"s":"")},formatDetailPagination:function(a){return"Toon "+a+" record"+(a>1?"s":"")},formatSearch:function(){return"Zoeken"},formatNoMatches:function(){return"Geen resultaten gevonden"},formatRefresh:function(){return"Vernieuwen"},formatToggle:function(){return"Omschakelen"},formatColumns:function(){return"Kolommen"},formatAllRows:function(){return"Alle"},formatPaginationSwitch:function(){return"Verberg/Toon paginatie"},formatExport:function(){return"Exporteer data"},formatClearFilters:function(){return"Verwijder filters"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["nl-NL"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["pl-PL"]={formatLoadingMessage:function(){return"Ładowanie, proszę czekać..."},formatRecordsPerPage:function(a){return a+" rekordów na stronę"},formatShowingRows:function(a,b,c){return"Wyświetlanie rekordów od "+a+" do "+b+" z "+c},formatSearch:function(){return"Szukaj"},formatNoMatches:function(){return"Niestety, nic nie znaleziono"},formatRefresh:function(){return"Odśwież"},formatToggle:function(){return"Przełącz"},formatColumns:function(){return"Kolumny"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["pl-PL"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["pt-BR"]={formatLoadingMessage:function(){return"Carregando, aguarde..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Exibindo "+a+" até "+b+" de "+c+" linhas"},formatSearch:function(){return"Pesquisar"},formatRefresh:function(){return"Recarregar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Colunas"},formatPaginationSwitch:function(){return"Ocultar/Exibir paginação"},formatNoMatches:function(){return"Nenhum registro encontrado"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["pt-BR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["pt-PT"]={formatLoadingMessage:function(){return"A carregar, por favor aguarde..."},formatRecordsPerPage:function(a){return a+" registos por página"},formatShowingRows:function(a,b,c){return"A mostrar "+a+" até "+b+" de "+c+" linhas"},formatSearch:function(){return"Pesquisa"},formatNoMatches:function(){return"Nenhum registo encontrado"},formatPaginationSwitch:function(){return"Esconder/Mostrar paginação"},formatRefresh:function(){return"Atualizar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Colunas"},formatAllRows:function(){return"Tudo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["pt-PT"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ro-RO"]={formatLoadingMessage:function(){return"Se incarca, va rugam asteptati..."},formatRecordsPerPage:function(a){return a+" inregistrari pe pagina"},formatShowingRows:function(a,b,c){return"Arata de la "+a+" pana la "+b+" din "+c+" randuri"},formatSearch:function(){return"Cauta"},formatNoMatches:function(){return"Nu au fost gasite inregistrari"},formatPaginationSwitch:function(){return"Ascunde/Arata paginatia"},formatRefresh:function(){return"Reincarca"},formatToggle:function(){return"Comuta"},formatColumns:function(){return"Coloane"},formatAllRows:function(){return"Toate"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ro-RO"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ru-RU"]={formatLoadingMessage:function(){return"Пожалуйста, подождите, идёт загрузка..."},formatRecordsPerPage:function(a){return a+" записей на страницу"},formatShowingRows:function(a,b,c){return"Записи с "+a+" по "+b+" из "+c},formatSearch:function(){return"Поиск"},formatNoMatches:function(){return"Ничего не найдено"},formatRefresh:function(){return"Обновить"},formatToggle:function(){return"Переключить"},formatColumns:function(){return"Колонки"},formatClearFilters:function(){return"Очистить фильтры"},formatMultipleSort:function(){return"Множественная сортировка"},formatAddLevel:function(){return"Добавить уровень"},formatDeleteLevel:function(){return"Удалить уровень"},formatColumn:function(){return"Колонка"},formatOrder:function(){return"Порядок"},formatSortBy:function(){return"Сортировать по"},formatThenBy:function(){return"затем по"},formatSort:function(){return"Сортировать"},formatCancel:function(){return"Отмена"},formatDuplicateAlertTitle:function(){return"Дублирование колонок!"},formatDuplicateAlertDescription:function(){return"Удалите, пожалуйста, дублирующую колонку, или замените ее на другую."}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ru-RU"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["sk-SK"]={formatLoadingMessage:function(){return"Prosím čakajte ..."},formatRecordsPerPage:function(a){return a+" záznamov na stranu"},formatShowingRows:function(a,b,c){return"Zobrazená "+a+". - "+b+". položka z celkových "+c},formatSearch:function(){return"Vyhľadávanie"},formatNoMatches:function(){return"Nenájdená žiadna vyhovujúca položka"},formatRefresh:function(){return"Obnoviť"},formatToggle:function(){return"Prepni"},formatColumns:function(){return"Stĺpce"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["sk-SK"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["sv-SE"]={formatLoadingMessage:function(){return"Laddar, vänligen vänta..."},formatRecordsPerPage:function(a){return a+" rader per sida"},formatShowingRows:function(a,b,c){return"Visa "+a+" till "+b+" av "+c+" rader"},formatSearch:function(){return"Sök"},formatNoMatches:function(){return"Inga matchande resultat funna."},formatRefresh:function(){return"Uppdatera"},formatToggle:function(){return"Skifta"},formatColumns:function(){return"kolumn"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["sv-SE"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["th-TH"]={formatLoadingMessage:function(){return"กำลังโหลดข้อมูล, กรุณารอสักครู่..."},formatRecordsPerPage:function(a){return a+" รายการต่อหน้า"},formatShowingRows:function(a,b,c){return"รายการที่ "+a+" ถึง "+b+" จากทั้งหมด "+c+" รายการ"},formatSearch:function(){return"ค้นหา"},formatNoMatches:function(){return"ไม่พบรายการที่ค้นหา !"},formatRefresh:function(){return"รีเฟรส"},formatToggle:function(){return"สลับมุมมอง"},formatColumns:function(){return"คอลัมน์"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["th-TH"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["tr-TR"]={formatLoadingMessage:function(){return"Yükleniyor, lütfen bekleyin..."},formatRecordsPerPage:function(a){return"Sayfa başına "+a+" kayıt."},formatShowingRows:function(a,b,c){return c+" kayıttan "+a+"-"+b+" arası gösteriliyor."},formatSearch:function(){return"Ara"},formatNoMatches:function(){return"Eşleşen kayıt bulunamadı."},formatRefresh:function(){return"Yenile"},formatToggle:function(){return"Değiştir"},formatColumns:function(){return"Sütunlar"},formatAllRows:function(){return"Tüm Satırlar"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["tr-TR"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["uk-UA"]={formatLoadingMessage:function(){return"Завантаження, будь ласка, зачекайте..."},formatRecordsPerPage:function(a){return a+" записів на сторінку"},formatShowingRows:function(a,b,c){return"Показано з "+a+" по "+b+". Всього: "+c},formatSearch:function(){return"Пошук"},formatNoMatches:function(){return"Не знайдено жодного запису"},formatRefresh:function(){return"Оновити"},formatToggle:function(){return"Змінити"},formatColumns:function(){return"Стовпці"},formatClearFilters:function(){return"Очистити фільтри"},formatMultipleSort:function(){return"Сортування за кількома стовпцями"},formatAddLevel:function(){return"Додати рівень"},formatDeleteLevel:function(){return"Видалити рівень"},formatColumn:function(){return"Стовпець"},formatOrder:function(){return"Порядок"},formatSortBy:function(){return"Сортувати за"},formatThenBy:function(){return"потім за"},formatSort:function(){return"Сортувати"},formatCancel:function(){return"Скасувати"},formatDuplicateAlertTitle:function(){return"Дублювання стовпців!"},formatDuplicateAlertDescription:function(){return"Видаліть, будь ласка, дублюючий стовпець, або замініть його на інший."}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["uk-UA"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["ur-PK"]={formatLoadingMessage:function(){return"براۓ مہربانی انتظار کیجئے"},formatRecordsPerPage:function(a){return a+" ریکارڈز فی صفہ "},formatShowingRows:function(a,b,c){return"دیکھیں "+a+" سے "+b+" کے "+c+"ریکارڈز"},formatSearch:function(){return"تلاش"},formatNoMatches:function(){return"کوئی ریکارڈ نہیں ملا"},formatRefresh:function(){return"تازہ کریں"},formatToggle:function(){return"تبدیل کریں"},formatColumns:function(){return"کالم"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ur-PK"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["uz-Latn-UZ"]={formatLoadingMessage:function(){return"Yuklanyapti, iltimos kuting..."},formatRecordsPerPage:function(a){return a+" qator har sahifada"},formatShowingRows:function(a,b,c){return"Ko'rsatypati "+a+" dan "+b+" gacha "+c+" qatorlarni"},formatSearch:function(){return"Qidirish"},formatNoMatches:function(){return"Hech narsa topilmadi"},formatPaginationSwitch:function(){return"Sahifalashni yashirish/ko'rsatish"},formatRefresh:function(){return"Yangilash"},formatToggle:function(){return"Ko'rinish"},formatColumns:function(){return"Ustunlar"},formatAllRows:function(){return"Hammasi"},formatExport:function(){return"Eksport"},formatClearFilters:function(){return"Filtrlarni tozalash"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["uz-Latn-UZ"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["vi-VN"]={formatLoadingMessage:function(){return"Đang tải..."},formatRecordsPerPage:function(a){return a+" bản ghi mỗi trang"},formatShowingRows:function(a,b,c){return"Hiển thị từ trang "+a+" đến "+b+" của "+c+" bảng ghi"},formatSearch:function(){return"Tìm kiếm"},formatNoMatches:function(){return"Không có dữ liệu"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["vi-VN"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["zh-CN"]={formatLoadingMessage:function(){return"正在努力地加载数据中,请稍候……"},formatRecordsPerPage:function(a){return"每页显示 "+a+" 条记录"},formatShowingRows:function(a,b,c){return"显示第 "+a+" 到第 "+b+" 条记录,总共 "+c+" 条记录"},formatSearch:function(){return"搜索"},formatNoMatches:function(){return"没有找到匹配的记录"},formatPaginationSwitch:function(){return"隐藏/显示分页"},formatRefresh:function(){return"刷新"},formatToggle:function(){return"切换"},formatColumns:function(){return"列"},formatExport:function(){return"导出数据"},formatClearFilters:function(){return"清空过滤"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["zh-CN"])}(jQuery),function(a){"use strict";a.fn.bootstrapTable.locales["zh-TW"]={formatLoadingMessage:function(){return"正在努力地載入資料,請稍候……"},formatRecordsPerPage:function(a){return"每頁顯示 "+a+" 項記錄"},formatShowingRows:function(a,b,c){return"顯示第 "+a+" 到第 "+b+" 項記錄,總共 "+c+" 項記錄"},formatSearch:function(){return"搜尋"},formatNoMatches:function(){return"沒有找到符合的結果"},formatPaginationSwitch:function(){return"隱藏/顯示分頁"},formatRefresh:function(){return"重新整理"},formatToggle:function(){return"切換"},formatColumns:function(){return"列"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["zh-TW"])}(jQuery); \ No newline at end of file diff --git a/public/assets/libs/bootstrap-table/dist/bootstrap-table.css b/public/assets/libs/bootstrap-table/dist/bootstrap-table.css new file mode 100644 index 0000000000000000000000000000000000000000..ebf5e95a1a81ead05854e1c84ec39b5a10956835 --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/bootstrap-table.css @@ -0,0 +1,313 @@ +/** + * @author zhixin wen + * version: 1.11.1 + * https://github.com/wenzhixin/bootstrap-table/ + */ + +.bootstrap-table .table { + margin-bottom: 0 !important; + border-bottom: 1px solid #dddddd; + border-collapse: collapse !important; + border-radius: 1px; +} + +.bootstrap-table .table:not(.table-condensed), +.bootstrap-table .table:not(.table-condensed) > tbody > tr > th, +.bootstrap-table .table:not(.table-condensed) > tfoot > tr > th, +.bootstrap-table .table:not(.table-condensed) > thead > tr > td, +.bootstrap-table .table:not(.table-condensed) > tbody > tr > td, +.bootstrap-table .table:not(.table-condensed) > tfoot > tr > td { + padding: 8px; +} + +.bootstrap-table .table.table-no-bordered > thead > tr > th, +.bootstrap-table .table.table-no-bordered > tbody > tr > td { + border-right: 2px solid transparent; +} + +.bootstrap-table .table.table-no-bordered > tbody > tr > td:last-child { + border-right: none; +} + +.fixed-table-container { + position: relative; + clear: both; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; +} + +.fixed-table-container.table-no-bordered { + border: 1px solid transparent; +} + +.fixed-table-footer, +.fixed-table-header { + overflow: hidden; +} + +.fixed-table-footer { + border-top: 1px solid #dddddd; +} + +.fixed-table-body { + overflow-x: auto; + overflow-y: auto; + height: 100%; +} + +.fixed-table-container table { + width: 100%; +} + +.fixed-table-container thead th { + height: 0; + padding: 0; + margin: 0; + border-left: 1px solid #dddddd; +} + +.fixed-table-container thead th:focus { + outline: 0 solid transparent; +} + +.fixed-table-container thead th:first-child { + border-left: none; + border-top-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.fixed-table-container thead th .th-inner, +.fixed-table-container tbody td .th-inner { + padding: 8px; + line-height: 24px; + vertical-align: top; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.fixed-table-container thead th .sortable { + cursor: pointer; + background-position: right; + background-repeat: no-repeat; + padding-right: 30px; +} + +.fixed-table-container thead th .both { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC'); +} + +.fixed-table-container thead th .asc { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg=='); +} + +.fixed-table-container thead th .desc { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= '); +} + +.fixed-table-container th.detail { + width: 30px; +} + +.fixed-table-container tbody td { + border-left: 1px solid #dddddd; +} + +.fixed-table-container tbody tr:first-child td { + border-top: none; +} + +.fixed-table-container tbody td:first-child { + border-left: none; +} + +/* the same color with .active */ +.fixed-table-container tbody .selected td { + background-color: #f5f5f5; +} + +.fixed-table-container .bs-checkbox { + text-align: center; +} + +.fixed-table-container .bs-checkbox .th-inner { + padding: 8px 0; +} + +.fixed-table-container input[type="radio"], +.fixed-table-container input[type="checkbox"] { + margin: 0 auto !important; +} + +.fixed-table-container .no-records-found { + text-align: center; +} + +.fixed-table-pagination div.pagination, +.fixed-table-pagination .pagination-detail { + margin-top: 10px; + margin-bottom: 10px; +} + +.fixed-table-pagination div.pagination .pagination { + margin: 0; +} + +.fixed-table-pagination .pagination a { + padding: 6px 12px; + line-height: 1.428571429; +} + +.fixed-table-pagination .pagination-info { + line-height: 34px; + margin-right: 5px; +} + +.fixed-table-pagination .btn-group { + position: relative; + display: inline-block; + vertical-align: middle; +} + +.fixed-table-pagination .dropup .dropdown-menu { + margin-bottom: 0; +} + +.fixed-table-pagination .page-list { + display: inline-block; +} + +.fixed-table-toolbar .columns-left { + margin-right: 5px; +} + +.fixed-table-toolbar .columns-right { + margin-left: 5px; +} + +.fixed-table-toolbar .columns label { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.428571429; +} + +.fixed-table-toolbar .bs-bars, +.fixed-table-toolbar .search, +.fixed-table-toolbar .columns { + position: relative; + margin-top: 10px; + margin-bottom: 10px; + line-height: 34px; +} + +.fixed-table-pagination li.disabled a { + pointer-events: none; + cursor: default; +} + +.fixed-table-loading { + display: none; + position: absolute; + top: 42px; + right: 0; + bottom: 0; + left: 0; + z-index: 99; + background-color: #fff; + text-align: center; +} + +.fixed-table-body .card-view .title { + font-weight: bold; + display: inline-block; + min-width: 30%; + text-align: left !important; +} + +/* support bootstrap 2 */ +.fixed-table-body thead th .th-inner { + box-sizing: border-box; +} + +.table th, .table td { + vertical-align: middle; + box-sizing: border-box; +} + +.fixed-table-toolbar .dropdown-menu { + text-align: left; + max-height: 300px; + overflow: auto; +} + +.fixed-table-toolbar .btn-group > .btn-group { + display: inline-block; + margin-left: -1px !important; +} + +.fixed-table-toolbar .btn-group > .btn-group > .btn { + border-radius: 0; +} + +.fixed-table-toolbar .btn-group > .btn-group:first-child > .btn { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.fixed-table-toolbar .btn-group > .btn-group:last-child > .btn { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.bootstrap-table .table > thead > tr > th { + vertical-align: bottom; + border-bottom: 1px solid #ddd; +} + +/* support bootstrap 3 */ +.bootstrap-table .table thead > tr > th { + padding: 0; + margin: 0; +} + +.bootstrap-table .fixed-table-footer tbody > tr > td { + padding: 0 !important; +} + +.bootstrap-table .fixed-table-footer .table { + border-bottom: none; + border-radius: 0; + padding: 0 !important; +} + +.bootstrap-table .pull-right .dropdown-menu { + right: 0; + left: auto; +} + +/* calculate scrollbar width */ +p.fixed-table-scroll-inner { + width: 100%; + height: 200px; +} + +div.fixed-table-scroll-outer { + top: 0; + left: 0; + visibility: hidden; + width: 200px; + height: 150px; + overflow: hidden; +} + +/* for get correct heights */ +.fixed-table-toolbar:after, .fixed-table-pagination:after { + content: ""; + display: block; + clear: both; +} diff --git a/public/assets/libs/bootstrap-table/dist/bootstrap-table.js b/public/assets/libs/bootstrap-table/dist/bootstrap-table.js new file mode 100644 index 0000000000000000000000000000000000000000..7888f607bff99a88f91102c758a42a5d5d0aa3e3 --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/bootstrap-table.js @@ -0,0 +1,3100 @@ +/** + * @author zhixin wen + * version: 1.11.2 + * https://github.com/wenzhixin/bootstrap-table/ + */ + +(function ($) { + 'use strict'; + + // TOOLS DEFINITION + // ====================== + + var cachedWidth = null; + + // it only does '%s', and return '' when arguments are undefined + var sprintf = function (str) { + var args = arguments, + flag = true, + i = 1; + + str = str.replace(/%s/g, function () { + var arg = args[i++]; + + if (typeof arg === 'undefined') { + flag = false; + return ''; + } + return arg; + }); + return flag ? str : ''; + }; + + var getPropertyFromOther = function (list, from, to, value) { + var result = ''; + $.each(list, function (i, item) { + if (item[from] === value) { + result = item[to]; + return false; + } + return true; + }); + return result; + }; + + var getFieldIndex = function (columns, field) { + var index = -1; + + $.each(columns, function (i, column) { + if (column.field === field) { + index = i; + return false; + } + return true; + }); + return index; + }; + + // http://jsfiddle.net/wenyi/47nz7ez9/3/ + var setFieldIndex = function (columns) { + var i, j, k, + totalCol = 0, + flag = []; + + for (i = 0; i < columns[0].length; i++) { + totalCol += columns[0][i].colspan || 1; + } + + for (i = 0; i < columns.length; i++) { + flag[i] = []; + for (j = 0; j < totalCol; j++) { + flag[i][j] = false; + } + } + + for (i = 0; i < columns.length; i++) { + for (j = 0; j < columns[i].length; j++) { + var r = columns[i][j], + rowspan = r.rowspan || 1, + colspan = r.colspan || 1, + index = $.inArray(false, flag[i]); + + if (colspan === 1) { + r.fieldIndex = index; + // when field is undefined, use index instead + if (typeof r.field === 'undefined') { + r.field = index; + } + } + + for (k = 0; k < rowspan; k++) { + flag[i + k][index] = true; + } + for (k = 0; k < colspan; k++) { + flag[i][index + k] = true; + } + } + } + }; + + var getScrollBarWidth = function () { + if (cachedWidth === null) { + var inner = $('

            ').addClass('fixed-table-scroll-inner'), + outer = $('

            ').addClass('fixed-table-scroll-outer'), + w1, w2; + + outer.append(inner); + $('body').append(outer); + + w1 = inner[0].offsetWidth; + outer.css('overflow', 'scroll'); + w2 = inner[0].offsetWidth; + + if (w1 === w2) { + w2 = outer[0].clientWidth; + } + + outer.remove(); + cachedWidth = w1 - w2; + } + return cachedWidth; + }; + + var calculateObjectValue = function (self, name, args, defaultValue) { + var func = name; + + if (typeof name === 'string') { + // support obj.func1.func2 + var names = name.split('.'); + + if (names.length > 1) { + func = window; + $.each(names, function (i, f) { + func = func[f]; + }); + } else { + func = window[name]; + } + } + if (typeof func === 'object') { + return func; + } + if (typeof func === 'function') { + return func.apply(self, args || []); + } + if (!func && typeof name === 'string' && sprintf.apply(this, [name].concat(args))) { + return sprintf.apply(this, [name].concat(args)); + } + return defaultValue; + }; + + var compareObjects = function (objectA, objectB, compareLength) { + // Create arrays of property names + var objectAProperties = Object.getOwnPropertyNames(objectA), + objectBProperties = Object.getOwnPropertyNames(objectB), + propName = ''; + + if (compareLength) { + // If number of properties is different, objects are not equivalent + if (objectAProperties.length !== objectBProperties.length) { + return false; + } + } + + for (var i = 0; i < objectAProperties.length; i++) { + propName = objectAProperties[i]; + + // If the property is not in the object B properties, continue with the next property + if ($.inArray(propName, objectBProperties) > -1) { + // If values of same property are not equal, objects are not equivalent + if (objectA[propName] !== objectB[propName]) { + return false; + } + } + } + + // If we made it this far, objects are considered equivalent + return true; + }; + + var escapeHTML = function (text) { + if (typeof text === 'string') { + return text + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(/`/g, '`'); + } + return text; + }; + + var getRealDataAttr = function (dataAttr) { + for (var attr in dataAttr) { + var auxAttr = attr.split(/(?=[A-Z])/).join('-').toLowerCase(); + if (auxAttr !== attr) { + dataAttr[auxAttr] = dataAttr[attr]; + delete dataAttr[attr]; + } + } + + return dataAttr; + }; + + var getItemField = function (item, field, escape) { + var value = item; + + if (typeof field !== 'string' || item.hasOwnProperty(field)) { + return escape ? escapeHTML(item[field]) : item[field]; + } + var props = field.split('.'); + for (var p in props) { + if (props.hasOwnProperty(p)) { + value = value && value[props[p]]; + } + } + return escape ? escapeHTML(value) : value; + }; + + var isIEBrowser = function () { + return !!(navigator.userAgent.indexOf("MSIE ") > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)); + }; + + var objectKeys = function () { + // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys + if (!Object.keys) { + Object.keys = (function() { + var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'), + dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ], + dontEnumsLength = dontEnums.length; + + return function(obj) { + if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { + throw new TypeError('Object.keys called on non-object'); + } + + var result = [], prop, i; + + for (prop in obj) { + if (hasOwnProperty.call(obj, prop)) { + result.push(prop); + } + } + + if (hasDontEnumBug) { + for (i = 0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) { + result.push(dontEnums[i]); + } + } + } + return result; + }; + }()); + } + }; + + // BOOTSTRAP TABLE CLASS DEFINITION + // ====================== + + var BootstrapTable = function (el, options) { + this.options = options; + this.$el = $(el); + this.$el_ = this.$el.clone(); + this.timeoutId_ = 0; + this.timeoutFooter_ = 0; + + this.init(); + }; + + BootstrapTable.DEFAULTS = { + classes: 'table table-hover', + sortClass: undefined, + locale: undefined, + height: undefined, + undefinedText: '-', + sortName: undefined, + sortOrder: 'asc', + sortStable: false, + striped: false, + columns: [[]], + data: [], + totalField: 'total', + dataField: 'rows', + method: 'get', + url: undefined, + ajax: undefined, + cache: true, + contentType: 'application/json', + dataType: 'json', + ajaxOptions: {}, + queryParams: function (params) { + return params; + }, + queryParamsType: 'limit', // undefined + responseHandler: function (res) { + return res; + }, + pagination: false, + onlyInfoPagination: false, + paginationLoop: true, + sidePagination: 'client', // client or server + totalRows: 0, // server side need to set + pageNumber: 1, + pageSize: 10, + pageList: [10, 25, 50, 100], + paginationHAlign: 'right', //right, left + paginationVAlign: 'bottom', //bottom, top, both + paginationDetailHAlign: 'left', //right, left + paginationPreText: '‹', + paginationNextText: '›', + search: false, + searchOnEnterKey: false, + strictSearch: false, + searchAlign: 'right', + selectItemName: 'btSelectItem', + showHeader: true, + showFooter: false, + showColumns: false, + showPaginationSwitch: false, + showRefresh: false, + showToggle: false, + buttonsAlign: 'right', + smartDisplay: true, + escape: false, + minimumCountColumns: 1, + idField: undefined, + uniqueId: undefined, + cardView: false, + detailView: false, + detailFormatter: function (index, row) { + return ''; + }, + trimOnSearch: true, + clickToSelect: false, + singleSelect: false, + toolbar: undefined, + toolbarAlign: 'left', + checkboxHeader: true, + sortable: true, + silentSort: true, + maintainSelected: false, + searchTimeOut: 500, + searchText: '', + iconSize: undefined, + buttonsClass: 'default', + iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome) + icons: { + paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down', + paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up', + refresh: 'glyphicon-refresh icon-refresh', + toggle: 'glyphicon-list-alt icon-list-alt', + columns: 'glyphicon-th icon-th', + detailOpen: 'glyphicon-plus icon-plus', + detailClose: 'glyphicon-minus icon-minus' + }, + + customSearch: $.noop, + + customSort: $.noop, + + rowStyle: function (row, index) { + return {}; + }, + + rowAttributes: function (row, index) { + return {}; + }, + + footerStyle: function (row, index) { + return {}; + }, + + onAll: function (name, args) { + return false; + }, + onClickCell: function (field, value, row, $element) { + return false; + }, + onDblClickCell: function (field, value, row, $element) { + return false; + }, + onClickRow: function (item, $element) { + return false; + }, + onDblClickRow: function (item, $element) { + return false; + }, + onSort: function (name, order) { + return false; + }, + onCheck: function (row) { + return false; + }, + onUncheck: function (row) { + return false; + }, + onCheckAll: function (rows) { + return false; + }, + onUncheckAll: function (rows) { + return false; + }, + onCheckSome: function (rows) { + return false; + }, + onUncheckSome: function (rows) { + return false; + }, + onLoadSuccess: function (data) { + return false; + }, + onLoadError: function (status) { + return false; + }, + onColumnSwitch: function (field, checked) { + return false; + }, + onPageChange: function (number, size) { + return false; + }, + onSearch: function (text) { + return false; + }, + onToggle: function (cardView) { + return false; + }, + onPreBody: function (data) { + return false; + }, + onPostBody: function () { + return false; + }, + onPostHeader: function () { + return false; + }, + onExpandRow: function (index, row, $detail) { + return false; + }, + onCollapseRow: function (index, row) { + return false; + }, + onRefreshOptions: function (options) { + return false; + }, + onRefresh: function (params) { + return false; + }, + onResetView: function () { + return false; + } + }; + + BootstrapTable.LOCALES = {}; + + BootstrapTable.LOCALES['en-US'] = BootstrapTable.LOCALES.en = { + formatLoadingMessage: function () { + return 'Loading, please wait...'; + }, + formatRecordsPerPage: function (pageNumber) { + return sprintf('%s rows per page', pageNumber); + }, + formatShowingRows: function (pageFrom, pageTo, totalRows) { + return sprintf('Showing %s to %s of %s rows', pageFrom, pageTo, totalRows); + }, + formatDetailPagination: function (totalRows) { + return sprintf('Showing %s rows', totalRows); + }, + formatSearch: function () { + return 'Search'; + }, + formatNoMatches: function () { + return 'No matching records found'; + }, + formatPaginationSwitch: function () { + return 'Hide/Show pagination'; + }, + formatRefresh: function () { + return 'Refresh'; + }, + formatToggle: function () { + return 'Toggle'; + }, + formatColumns: function () { + return 'Columns'; + }, + formatAllRows: function () { + return 'All'; + } + }; + + $.extend(BootstrapTable.DEFAULTS, BootstrapTable.LOCALES['en-US']); + + BootstrapTable.COLUMN_DEFAULTS = { + radio: false, + checkbox: false, + checkboxEnabled: true, + field: undefined, + title: undefined, + titleTooltip: undefined, + 'class': undefined, + align: undefined, // left, right, center + halign: undefined, // left, right, center + falign: undefined, // left, right, center + valign: undefined, // top, middle, bottom + width: undefined, + sortable: false, + order: 'asc', // asc, desc + visible: true, + switchable: true, + clickToSelect: true, + formatter: undefined, + footerFormatter: undefined, + events: undefined, + sorter: undefined, + sortName: undefined, + cellStyle: undefined, + searchable: true, + searchFormatter: true, + cardVisible: true, + escape : false + }; + + BootstrapTable.EVENTS = { + 'all.bs.table': 'onAll', + 'click-cell.bs.table': 'onClickCell', + 'dbl-click-cell.bs.table': 'onDblClickCell', + 'click-row.bs.table': 'onClickRow', + 'dbl-click-row.bs.table': 'onDblClickRow', + 'sort.bs.table': 'onSort', + 'check.bs.table': 'onCheck', + 'uncheck.bs.table': 'onUncheck', + 'check-all.bs.table': 'onCheckAll', + 'uncheck-all.bs.table': 'onUncheckAll', + 'check-some.bs.table': 'onCheckSome', + 'uncheck-some.bs.table': 'onUncheckSome', + 'load-success.bs.table': 'onLoadSuccess', + 'load-error.bs.table': 'onLoadError', + 'column-switch.bs.table': 'onColumnSwitch', + 'page-change.bs.table': 'onPageChange', + 'search.bs.table': 'onSearch', + 'toggle.bs.table': 'onToggle', + 'pre-body.bs.table': 'onPreBody', + 'post-body.bs.table': 'onPostBody', + 'post-header.bs.table': 'onPostHeader', + 'expand-row.bs.table': 'onExpandRow', + 'collapse-row.bs.table': 'onCollapseRow', + 'refresh-options.bs.table': 'onRefreshOptions', + 'reset-view.bs.table': 'onResetView', + 'refresh.bs.table': 'onRefresh' + }; + + BootstrapTable.prototype.init = function () { + this.initLocale(); + this.initContainer(); + this.initTable(); + this.initHeader(); + this.initData(); + this.initHiddenRows(); + this.initFooter(); + this.initToolbar(); + this.initPagination(); + this.initBody(); + this.initSearchText(); + this.initServer(); + }; + + BootstrapTable.prototype.initLocale = function () { + if (this.options.locale) { + var parts = this.options.locale.split(/-|_/); + parts[0].toLowerCase(); + if (parts[1]) parts[1].toUpperCase(); + if ($.fn.bootstrapTable.locales[this.options.locale]) { + // locale as requested + $.extend(this.options, $.fn.bootstrapTable.locales[this.options.locale]); + } else if ($.fn.bootstrapTable.locales[parts.join('-')]) { + // locale with sep set to - (in case original was specified with _) + $.extend(this.options, $.fn.bootstrapTable.locales[parts.join('-')]); + } else if ($.fn.bootstrapTable.locales[parts[0]]) { + // short locale language code (i.e. 'en') + $.extend(this.options, $.fn.bootstrapTable.locales[parts[0]]); + } + } + }; + + BootstrapTable.prototype.initContainer = function () { + this.$container = $([ + '
            ', + '
            ', + this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ? + '
            ' : + '', + '
            ', + '
            ', + '
            ', + '
            ', + this.options.formatLoadingMessage(), + '
            ', + '
            ', + '', + this.options.paginationVAlign === 'bottom' || this.options.paginationVAlign === 'both' ? + '
            ' : + '', + '
            ', + '
            ' + ].join('')); + + this.$container.insertAfter(this.$el); + this.$tableContainer = this.$container.find('.fixed-table-container'); + this.$tableHeader = this.$container.find('.fixed-table-header'); + this.$tableBody = this.$container.find('.fixed-table-body'); + this.$tableLoading = this.$container.find('.fixed-table-loading'); + this.$tableFooter = this.$container.find('.fixed-table-footer'); + this.$toolbar = this.$container.find('.fixed-table-toolbar'); + this.$pagination = this.$container.find('.fixed-table-pagination'); + + this.$tableBody.append(this.$el); + this.$container.after('
            '); + + this.$el.addClass(this.options.classes); + if (this.options.striped) { + this.$el.addClass('table-striped'); + } + if ($.inArray('table-no-bordered', this.options.classes.split(' ')) !== -1) { + this.$tableContainer.addClass('table-no-bordered'); + } + }; + + BootstrapTable.prototype.initTable = function () { + var that = this, + columns = [], + data = []; + + this.$header = this.$el.find('>thead'); + if (!this.$header.length) { + this.$header = $('').appendTo(this.$el); + } + this.$header.find('tr').each(function () { + var column = []; + + $(this).find('th').each(function () { + // Fix #2014 - getFieldIndex and elsewhere assume this is string, causes issues if not + if (typeof $(this).data('field') !== 'undefined') { + $(this).data('field', $(this).data('field') + ''); + } + column.push($.extend({}, { + title: $(this).html(), + 'class': $(this).attr('class'), + titleTooltip: $(this).attr('title'), + rowspan: $(this).attr('rowspan') ? +$(this).attr('rowspan') : undefined, + colspan: $(this).attr('colspan') ? +$(this).attr('colspan') : undefined + }, $(this).data())); + }); + columns.push(column); + }); + if (!$.isArray(this.options.columns[0])) { + this.options.columns = [this.options.columns]; + } + this.options.columns = $.extend(true, [], columns, this.options.columns); + this.columns = []; + + setFieldIndex(this.options.columns); + $.each(this.options.columns, function (i, columns) { + $.each(columns, function (j, column) { + column = $.extend({}, BootstrapTable.COLUMN_DEFAULTS, column); + + if (typeof column.fieldIndex !== 'undefined') { + that.columns[column.fieldIndex] = column; + } + + that.options.columns[i][j] = column; + }); + }); + + // if options.data is setting, do not process tbody data + if (this.options.data.length) { + return; + } + + var m = []; + this.$el.find('>tbody>tr').each(function (y) { + var row = {}; + + // save tr's id, class and data-* attributes + row._id = $(this).attr('id'); + row._class = $(this).attr('class'); + row._data = getRealDataAttr($(this).data()); + + $(this).find('>td').each(function (x) { + var $this = $(this), + cspan = +$this.attr('colspan') || 1, + rspan = +$this.attr('rowspan') || 1, + tx, ty; + + for (; m[y] && m[y][x]; x++); //skip already occupied cells in current row + + for (tx = x; tx < x + cspan; tx++) { //mark matrix elements occupied by current cell with true + for (ty = y; ty < y + rspan; ty++) { + if (!m[ty]) { //fill missing rows + m[ty] = []; + } + m[ty][tx] = true; + } + } + + var field = that.columns[x].field; + + row[field] = $(this).html(); + // save td's id, class and data-* attributes + row['_' + field + '_id'] = $(this).attr('id'); + row['_' + field + '_class'] = $(this).attr('class'); + row['_' + field + '_rowspan'] = $(this).attr('rowspan'); + row['_' + field + '_colspan'] = $(this).attr('colspan'); + row['_' + field + '_title'] = $(this).attr('title'); + row['_' + field + '_data'] = getRealDataAttr($(this).data()); + }); + data.push(row); + }); + this.options.data = data; + if (data.length) this.fromHtml = true; + }; + + BootstrapTable.prototype.initHeader = function () { + var that = this, + visibleColumns = {}, + html = []; + + this.header = { + fields: [], + styles: [], + classes: [], + formatters: [], + events: [], + sorters: [], + sortNames: [], + cellStyles: [], + searchables: [] + }; + + $.each(this.options.columns, function (i, columns) { + html.push(''); + + if (i === 0 && !that.options.cardView && that.options.detailView) { + html.push(sprintf('
            ', + that.options.columns.length)); + } + + $.each(columns, function (j, column) { + var text = '', + halign = '', // header align style + align = '', // body align style + style = '', + class_ = sprintf(' class="%s"', column['class']), + order = that.options.sortOrder || column.order, + unitWidth = 'px', + width = column.width; + + if (column.width !== undefined && (!that.options.cardView)) { + if (typeof column.width === 'string') { + if (column.width.indexOf('%') !== -1) { + unitWidth = '%'; + } + } + } + if (column.width && typeof column.width === 'string') { + width = column.width.replace('%', '').replace('px', ''); + } + + halign = sprintf('text-align: %s; ', column.halign ? column.halign : column.align); + align = sprintf('text-align: %s; ', column.align); + style = sprintf('vertical-align: %s; ', column.valign); + style += sprintf('width: %s; ', (column.checkbox || column.radio) && !width ? + '36px' : (width ? width + unitWidth : undefined)); + + if (typeof column.fieldIndex !== 'undefined') { + that.header.fields[column.fieldIndex] = column.field; + that.header.styles[column.fieldIndex] = align + style; + that.header.classes[column.fieldIndex] = class_; + that.header.formatters[column.fieldIndex] = column.formatter; + that.header.events[column.fieldIndex] = column.events; + that.header.sorters[column.fieldIndex] = column.sorter; + that.header.sortNames[column.fieldIndex] = column.sortName; + that.header.cellStyles[column.fieldIndex] = column.cellStyle; + that.header.searchables[column.fieldIndex] = column.searchable; + + if (!column.visible) { + return; + } + + if (that.options.cardView && (!column.cardVisible)) { + return; + } + + visibleColumns[column.field] = column; + } + + html.push(''); + + html.push(sprintf('
            ', that.options.sortable && column.sortable ? + 'sortable both' : '')); + + text = that.options.escape ? escapeHTML(column.title) : column.title; + + if (column.checkbox) { + if (!that.options.singleSelect && that.options.checkboxHeader) { + text = ''; + } + that.header.stateField = column.field; + } + if (column.radio) { + text = ''; + that.header.stateField = column.field; + that.options.singleSelect = true; + } + + html.push(text); + html.push('
            '); + html.push('
            '); + html.push('
            '); + html.push(''); + }); + html.push(''); + }); + + this.$header.html(html.join('')); + this.$header.find('th[data-field]').each(function (i) { + $(this).data(visibleColumns[$(this).data('field')]); + }); + this.$container.off('click', '.th-inner').on('click', '.th-inner', function (event) { + var target = $(this); + + if (that.options.detailView) { + if (target.closest('.bootstrap-table')[0] !== that.$container[0]) + return false; + } + + if (that.options.sortable && target.parent().data().sortable) { + that.onSort(event); + } + }); + + this.$header.children().children().off('keypress').on('keypress', function (event) { + if (that.options.sortable && $(this).data().sortable) { + var code = event.keyCode || event.which; + if (code == 13) { //Enter keycode + that.onSort(event); + } + } + }); + + $(window).off('resize.bootstrap-table'); + if (!this.options.showHeader || this.options.cardView) { + this.$header.hide(); + this.$tableHeader.hide(); + this.$tableLoading.css('top', 0); + } else { + this.$header.show(); + this.$tableHeader.show(); + this.$tableLoading.css('top', this.$header.outerHeight() + 1); + // Assign the correct sortable arrow + this.getCaret(); + $(window).on('resize.bootstrap-table', $.proxy(this.resetWidth, this)); + } + + this.$selectAll = this.$header.find('[name="btSelectAll"]'); + this.$selectAll.off('click').on('click', function () { + var checked = $(this).prop('checked'); + that[checked ? 'checkAll' : 'uncheckAll'](); + that.updateSelected(); + }); + }; + + BootstrapTable.prototype.initFooter = function () { + if (!this.options.showFooter || this.options.cardView) { + this.$tableFooter.hide(); + } else { + this.$tableFooter.show(); + } + }; + + /** + * @param data + * @param type: append / prepend + */ + BootstrapTable.prototype.initData = function (data, type) { + if (type === 'append') { + this.data = this.data.concat(data); + } else if (type === 'prepend') { + this.data = [].concat(data).concat(this.data); + } else { + this.data = data || this.options.data; + } + + // Fix #839 Records deleted when adding new row on filtered table + if (type === 'append') { + this.options.data = this.options.data.concat(data); + } else if (type === 'prepend') { + this.options.data = [].concat(data).concat(this.options.data); + } else { + this.options.data = this.data; + } + + if (this.options.sidePagination === 'server') { + return; + } + this.initSort(); + }; + + BootstrapTable.prototype.initSort = function () { + var that = this, + name = this.options.sortName, + order = this.options.sortOrder === 'desc' ? -1 : 1, + index = $.inArray(this.options.sortName, this.header.fields), + timeoutId = 0; + + if (this.options.customSort !== $.noop) { + this.options.customSort.apply(this, [this.options.sortName, this.options.sortOrder]); + return; + } + + if (index !== -1) { + if (this.options.sortStable) { + $.each(this.data, function (i, row) { + if (!row.hasOwnProperty('_position')) row._position = i; + }); + } + + this.data.sort(function (a, b) { + if (that.header.sortNames[index]) { + name = that.header.sortNames[index]; + } + var aa = getItemField(a, name, that.options.escape), + bb = getItemField(b, name, that.options.escape), + value = calculateObjectValue(that.header, that.header.sorters[index], [aa, bb]); + + if (value !== undefined) { + return order * value; + } + + // Fix #161: undefined or null string sort bug. + if (aa === undefined || aa === null) { + aa = ''; + } + if (bb === undefined || bb === null) { + bb = ''; + } + + if (that.options.sortStable && aa === bb) { + aa = a._position; + bb = b._position; + } + + // IF both values are numeric, do a numeric comparison + if ($.isNumeric(aa) && $.isNumeric(bb)) { + // Convert numerical values form string to float. + aa = parseFloat(aa); + bb = parseFloat(bb); + if (aa < bb) { + return order * -1; + } + return order; + } + + if (aa === bb) { + return 0; + } + + // If value is not a string, convert to string + if (typeof aa !== 'string') { + aa = aa.toString(); + } + + if (aa.localeCompare(bb) === -1) { + return order * -1; + } + + return order; + }); + + if (this.options.sortClass !== undefined) { + clearTimeout(timeoutId); + timeoutId = setTimeout(function () { + that.$el.removeClass(that.options.sortClass); + var index = that.$header.find(sprintf('[data-field="%s"]', + that.options.sortName).index() + 1); + that.$el.find(sprintf('tr td:nth-child(%s)', index)) + .addClass(that.options.sortClass); + }, 250); + } + } + }; + + BootstrapTable.prototype.onSort = function (event) { + var $this = event.type === "keypress" ? $(event.currentTarget) : $(event.currentTarget).parent(), + $this_ = this.$header.find('th').eq($this.index()); + + this.$header.add(this.$header_).find('span.order').remove(); + + if (this.options.sortName === $this.data('field')) { + this.options.sortOrder = this.options.sortOrder === 'asc' ? 'desc' : 'asc'; + } else { + this.options.sortName = $this.data('field'); + this.options.sortOrder = $this.data('order') === 'asc' ? 'desc' : 'asc'; + } + this.trigger('sort', this.options.sortName, this.options.sortOrder); + + $this.add($this_).data('order', this.options.sortOrder); + + // Assign the correct sortable arrow + this.getCaret(); + + if (this.options.sidePagination === 'server') { + this.initServer(this.options.silentSort); + return; + } + + this.initSort(); + this.initBody(); + }; + + BootstrapTable.prototype.initToolbar = function () { + var that = this, + html = [], + timeoutId = 0, + $keepOpen, + $search, + switchableCount = 0; + + if (this.$toolbar.find('.bs-bars').children().length) { + $('body').append($(this.options.toolbar)); + } + this.$toolbar.html(''); + + if (typeof this.options.toolbar === 'string' || typeof this.options.toolbar === 'object') { + $(sprintf('
            ', this.options.toolbarAlign)) + .appendTo(this.$toolbar) + .append($(this.options.toolbar)); + } + + // showColumns, showToggle, showRefresh + html = [sprintf('
            ', + this.options.buttonsAlign, this.options.buttonsAlign)]; + + if (typeof this.options.icons === 'string') { + this.options.icons = calculateObjectValue(null, this.options.icons); + } + + if (this.options.showPaginationSwitch) { + html.push(sprintf(''); + } + + if (this.options.showRefresh) { + html.push(sprintf(''); + } + + if (this.options.showToggle) { + html.push(sprintf(''); + } + + if (this.options.showColumns) { + html.push(sprintf('
            ', + this.options.formatColumns()), + '', + '', + '
            '); + } + + html.push('
            '); + + // Fix #188: this.showToolbar is for extensions + if (this.showToolbar || html.length > 2) { + this.$toolbar.append(html.join('')); + } + + if (this.options.showPaginationSwitch) { + this.$toolbar.find('button[name="paginationSwitch"]') + .off('click').on('click', $.proxy(this.togglePagination, this)); + } + + if (this.options.showRefresh) { + this.$toolbar.find('button[name="refresh"]') + .off('click').on('click', $.proxy(this.refresh, this)); + } + + if (this.options.showToggle) { + this.$toolbar.find('button[name="toggle"]') + .off('click').on('click', function () { + that.toggleView(); + }); + } + + if (this.options.showColumns) { + $keepOpen = this.$toolbar.find('.keep-open'); + + if (switchableCount <= this.options.minimumCountColumns) { + $keepOpen.find('input').prop('disabled', true); + } + + $keepOpen.find('li').off('click').on('click', function (event) { + event.stopImmediatePropagation(); + }); + $keepOpen.find('input').off('click').on('click', function () { + var $this = $(this); + + that.toggleColumn($(this).val(), $this.prop('checked'), false); + that.trigger('column-switch', $(this).data('field'), $this.prop('checked')); + }); + } + + if (this.options.search) { + html = []; + html.push( + ''); + + this.$toolbar.append(html.join('')); + $search = this.$toolbar.find('.search input'); + $search.off('keyup drop blur').on('keyup drop blur', function (event) { + if (that.options.searchOnEnterKey && event.keyCode !== 13) { + return; + } + + if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) { + return; + } + + clearTimeout(timeoutId); // doesn't matter if it's 0 + timeoutId = setTimeout(function () { + that.onSearch(event); + }, that.options.searchTimeOut); + }); + + if (isIEBrowser()) { + $search.off('mouseup').on('mouseup', function (event) { + clearTimeout(timeoutId); // doesn't matter if it's 0 + timeoutId = setTimeout(function () { + that.onSearch(event); + }, that.options.searchTimeOut); + }); + } + } + }; + + BootstrapTable.prototype.onSearch = function (event) { + var text = $.trim($(event.currentTarget).val()); + + // trim search input + if (this.options.trimOnSearch && $(event.currentTarget).val() !== text) { + $(event.currentTarget).val(text); + } + + if (text === this.searchText) { + return; + } + this.searchText = text; + this.options.searchText = text; + + this.options.pageNumber = 1; + this.initSearch(); + this.updatePagination(); + this.trigger('search', text); + }; + + BootstrapTable.prototype.initSearch = function () { + var that = this; + + if (this.options.sidePagination !== 'server') { + if (this.options.customSearch !== $.noop) { + this.options.customSearch.apply(this, [this.searchText]); + return; + } + + var s = this.searchText && (this.options.escape ? + escapeHTML(this.searchText) : this.searchText).toLowerCase(); + var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns; + + // Check filter + this.data = f ? $.grep(this.options.data, function (item, i) { + for (var key in f) { + if ($.isArray(f[key]) && $.inArray(item[key], f[key]) === -1 || + !$.isArray(f[key]) && item[key] !== f[key]) { + return false; + } + } + return true; + }) : this.options.data; + + this.data = s ? $.grep(this.data, function (item, i) { + for (var j = 0; j < that.header.fields.length; j++) { + + if (!that.header.searchables[j]) { + continue; + } + + var key = $.isNumeric(that.header.fields[j]) ? parseInt(that.header.fields[j], 10) : that.header.fields[j]; + var column = that.columns[getFieldIndex(that.columns, key)]; + var value; + + if (typeof key === 'string') { + value = item; + var props = key.split('.'); + for (var prop_index = 0; prop_index < props.length; prop_index++) { + value = value[props[prop_index]]; + } + + // Fix #142: respect searchForamtter boolean + if (column && column.searchFormatter) { + value = calculateObjectValue(column, + that.header.formatters[j], [value, item, i], value); + } + } else { + value = item[key]; + } + + if (typeof value === 'string' || typeof value === 'number') { + if (that.options.strictSearch) { + if ((value + '').toLowerCase() === s) { + return true; + } + } else { + if ((value + '').toLowerCase().indexOf(s) !== -1) { + return true; + } + } + } + } + return false; + }) : this.data; + } + }; + + BootstrapTable.prototype.initPagination = function () { + if (!this.options.pagination) { + this.$pagination.hide(); + return; + } else { + this.$pagination.show(); + } + + var that = this, + html = [], + $allSelected = false, + i, from, to, + $pageList, + $first, $pre, + $next, $last, + $number, + data = this.getData(), + pageList = this.options.pageList; + + if (this.options.sidePagination !== 'server') { + this.options.totalRows = data.length; + } + + this.totalPages = 0; + if (this.options.totalRows) { + if (this.options.pageSize === this.options.formatAllRows()) { + this.options.pageSize = this.options.totalRows; + $allSelected = true; + } else if (this.options.pageSize === this.options.totalRows) { + // Fix #667 Table with pagination, + // multiple pages and a search that matches to one page throws exception + var pageLst = typeof this.options.pageList === 'string' ? + this.options.pageList.replace('[', '').replace(']', '') + .replace(/ /g, '').toLowerCase().split(',') : this.options.pageList; + if ($.inArray(this.options.formatAllRows().toLowerCase(), pageLst) > -1) { + $allSelected = true; + } + } + + this.totalPages = ~~((this.options.totalRows - 1) / this.options.pageSize) + 1; + + this.options.totalPages = this.totalPages; + } + if (this.totalPages > 0 && this.options.pageNumber > this.totalPages) { + this.options.pageNumber = this.totalPages; + } + + this.pageFrom = (this.options.pageNumber - 1) * this.options.pageSize + 1; + this.pageTo = this.options.pageNumber * this.options.pageSize; + if (this.pageTo > this.options.totalRows) { + this.pageTo = this.options.totalRows; + } + + html.push( + '
            ', + '', + this.options.onlyInfoPagination ? this.options.formatDetailPagination(this.options.totalRows) : + this.options.formatShowingRows(this.pageFrom, this.pageTo, this.options.totalRows), + ''); + + if (!this.options.onlyInfoPagination) { + html.push(''); + + var pageNumber = [ + sprintf('', + this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ? + 'dropdown' : 'dropup'), + '', + ''); + + html.push(this.options.formatRecordsPerPage(pageNumber.join(''))); + html.push(''); + + html.push('
            ', + ''); + } + this.$pagination.html(html.join('')); + + if (!this.options.onlyInfoPagination) { + $pageList = this.$pagination.find('.page-list a'); + $first = this.$pagination.find('.page-first'); + $pre = this.$pagination.find('.page-pre'); + $next = this.$pagination.find('.page-next'); + $last = this.$pagination.find('.page-last'); + $number = this.$pagination.find('.page-number'); + + if (this.options.smartDisplay) { + if (this.totalPages <= 1) { + this.$pagination.find('div.pagination').hide(); + } + if (pageList.length < 2 || this.options.totalRows <= pageList[0]) { + this.$pagination.find('span.page-list').hide(); + } + + // when data is empty, hide the pagination + this.$pagination[this.getData().length ? 'show' : 'hide'](); + } + + if (!this.options.paginationLoop) { + if (this.options.pageNumber === 1) { + $pre.addClass('disabled'); + } + if (this.options.pageNumber === this.totalPages) { + $next.addClass('disabled'); + } + } + + if ($allSelected) { + this.options.pageSize = this.options.formatAllRows(); + } + $pageList.off('click').on('click', $.proxy(this.onPageListChange, this)); + $first.off('click').on('click', $.proxy(this.onPageFirst, this)); + $pre.off('click').on('click', $.proxy(this.onPagePre, this)); + $next.off('click').on('click', $.proxy(this.onPageNext, this)); + $last.off('click').on('click', $.proxy(this.onPageLast, this)); + $number.off('click').on('click', $.proxy(this.onPageNumber, this)); + } + }; + + BootstrapTable.prototype.updatePagination = function (event) { + // Fix #171: IE disabled button can be clicked bug. + if (event && $(event.currentTarget).hasClass('disabled')) { + return; + } + + if (!this.options.maintainSelected) { + this.resetRows(); + } + + this.initPagination(); + if (this.options.sidePagination === 'server') { + this.initServer(); + } else { + this.initBody(); + } + + this.trigger('page-change', this.options.pageNumber, this.options.pageSize); + }; + + BootstrapTable.prototype.onPageListChange = function (event) { + var $this = $(event.currentTarget); + + $this.parent().addClass('active').siblings().removeClass('active'); + this.options.pageSize = $this.text().toUpperCase() === this.options.formatAllRows().toUpperCase() ? + this.options.formatAllRows() : +$this.text(); + this.$toolbar.find('.page-size').text(this.options.pageSize); + + this.updatePagination(event); + return false; + }; + + BootstrapTable.prototype.onPageFirst = function (event) { + this.options.pageNumber = 1; + this.updatePagination(event); + return false; + }; + + BootstrapTable.prototype.onPagePre = function (event) { + if ((this.options.pageNumber - 1) === 0) { + this.options.pageNumber = this.options.totalPages; + } else { + this.options.pageNumber--; + } + this.updatePagination(event); + return false; + }; + + BootstrapTable.prototype.onPageNext = function (event) { + if ((this.options.pageNumber + 1) > this.options.totalPages) { + this.options.pageNumber = 1; + } else { + this.options.pageNumber++; + } + this.updatePagination(event); + return false; + }; + + BootstrapTable.prototype.onPageLast = function (event) { + this.options.pageNumber = this.totalPages; + this.updatePagination(event); + return false; + }; + + BootstrapTable.prototype.onPageNumber = function (event) { + if (this.options.pageNumber === +$(event.currentTarget).text()) { + return; + } + this.options.pageNumber = +$(event.currentTarget).text(); + this.updatePagination(event); + return false; + }; + + BootstrapTable.prototype.initRow = function(item, i, data, parentDom) { + var that=this, + key, + html = [], + style = {}, + csses = [], + data_ = '', + attributes = {}, + htmlAttributes = []; + + if ($.inArray(item, this.hiddenRows) > -1) { + return; + } + + style = calculateObjectValue(this.options, this.options.rowStyle, [item, i], style); + + if (style && style.css) { + for (key in style.css) { + csses.push(key + ': ' + style.css[key]); + } + } + + attributes = calculateObjectValue(this.options, + this.options.rowAttributes, [item, i], attributes); + + if (attributes) { + for (key in attributes) { + htmlAttributes.push(sprintf('%s="%s"', key, escapeHTML(attributes[key]))); + } + } + + if (item._data && !$.isEmptyObject(item._data)) { + $.each(item._data, function(k, v) { + // ignore data-index + if (k === 'index') { + return; + } + data_ += sprintf(' data-%s="%s"', k, v); + }); + } + + html.push('' + ); + + if (this.options.cardView) { + html.push(sprintf('
            ', this.header.fields.length)); + } + + if (!this.options.cardView && this.options.detailView) { + html.push('', + '', + sprintf('', this.options.iconsPrefix, this.options.icons.detailOpen), + '', + ''); + } + + $.each(this.header.fields, function(j, field) { + var text = '', + value_ = getItemField(item, field, that.options.escape), + value = '', + type = '', + cellStyle = {}, + id_ = '', + class_ = that.header.classes[j], + data_ = '', + rowspan_ = '', + colspan_ = '', + title_ = '', + column = that.columns[j]; + + if (that.fromHtml && typeof value_ === 'undefined') { + return; + } + + if (!column.visible) { + return; + } + + if (that.options.cardView && (!column.cardVisible)) { + return; + } + + if (column.escape) { + value_ = escapeHTML(value_); + } + + style = sprintf('style="%s"', csses.concat(that.header.styles[j]).join('; ')); + + // handle td's id and class + if (item['_' + field + '_id']) { + id_ = sprintf(' id="%s"', item['_' + field + '_id']); + } + if (item['_' + field + '_class']) { + class_ = sprintf(' class="%s"', item['_' + field + '_class']); + } + if (item['_' + field + '_rowspan']) { + rowspan_ = sprintf(' rowspan="%s"', item['_' + field + '_rowspan']); + } + if (item['_' + field + '_colspan']) { + colspan_ = sprintf(' colspan="%s"', item['_' + field + '_colspan']); + } + if (item['_' + field + '_title']) { + title_ = sprintf(' title="%s"', item['_' + field + '_title']); + } + cellStyle = calculateObjectValue(that.header, + that.header.cellStyles[j], [value_, item, i, field], cellStyle); + if (cellStyle.classes) { + class_ = sprintf(' class="%s"', cellStyle.classes); + } + if (cellStyle.css) { + var csses_ = []; + for (var key in cellStyle.css) { + csses_.push(key + ': ' + cellStyle.css[key]); + } + style = sprintf('style="%s"', csses_.concat(that.header.styles[j]).join('; ')); + } + + value = calculateObjectValue(column, + that.header.formatters[j], [value_, item, i], value_); + + if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) { + $.each(item['_' + field + '_data'], function(k, v) { + // ignore data-index + if (k === 'index') { + return; + } + data_ += sprintf(' data-%s="%s"', k, v); + }); + } + + if (column.checkbox || column.radio) { + type = column.checkbox ? 'checkbox' : type; + type = column.radio ? 'radio' : type; + + text = [sprintf(that.options.cardView ? + '
            ' : '', column['class'] || ''), + '', + that.header.formatters[j] && typeof value === 'string' ? value : '', + that.options.cardView ? '
            ' : '' + ].join(''); + + item[that.header.stateField] = value === true || (value && value.checked); + } else { + value = typeof value === 'undefined' || value === null ? + that.options.undefinedText : value; + + text = that.options.cardView ? ['
            ', + that.options.showHeader ? sprintf('%s', style, + getPropertyFromOther(that.columns, 'field', 'title', field)) : '', + sprintf('%s', value), + '
            ' + ].join('') : [sprintf('', + id_, class_, style, data_, rowspan_, colspan_, title_), + value, + '' + ].join(''); + + // Hide empty data on Card view when smartDisplay is set to true. + if (that.options.cardView && that.options.smartDisplay && value === '') { + // Should set a placeholder for event binding correct fieldIndex + text = '
            '; + } + } + + html.push(text); + }); + + if (this.options.cardView) { + html.push('
            '); + } + html.push(''); + + return html.join(' '); + }; + + BootstrapTable.prototype.initBody = function (fixedScroll) { + var that = this, + html = [], + data = this.getData(); + + this.trigger('pre-body', data); + + this.$body = this.$el.find('>tbody'); + if (!this.$body.length) { + this.$body = $('').appendTo(this.$el); + } + + //Fix #389 Bootstrap-table-flatJSON is not working + + if (!this.options.pagination || this.options.sidePagination === 'server') { + this.pageFrom = 1; + this.pageTo = data.length; + } + + var trFragments = $(document.createDocumentFragment()); + var hasTr; + + for (var i = this.pageFrom - 1; i < this.pageTo; i++) { + var item = data[i]; + var tr = this.initRow(item, i, data, trFragments); + hasTr = hasTr || !!tr; + if (tr&&tr!==true) { + trFragments.append(tr); + } + } + + // show no records + if (!hasTr) { + trFragments.append('' + + sprintf('%s', + this.$header.find('th').length, + this.options.formatNoMatches()) + + ''); + } + + this.$body.html(trFragments); + + if (!fixedScroll) { + this.scrollTo(0); + } + + // click to select by column + this.$body.find('> tr[data-index] > td').off('click dblclick').on('click dblclick', function (e) { + var $td = $(this), + $tr = $td.parent(), + item = that.data[$tr.data('index')], + index = $td[0].cellIndex, + fields = that.getVisibleFields(), + field = fields[that.options.detailView && !that.options.cardView ? index - 1 : index], + column = that.columns[getFieldIndex(that.columns, field)], + value = getItemField(item, field, that.options.escape); + + if ($td.find('.detail-icon').length) { + return; + } + + that.trigger(e.type === 'click' ? 'click-cell' : 'dbl-click-cell', field, value, item, $td); + that.trigger(e.type === 'click' ? 'click-row' : 'dbl-click-row', item, $tr, field); + + // if click to select - then trigger the checkbox/radio click + if (e.type === 'click' && that.options.clickToSelect && column.clickToSelect) { + var $selectItem = $tr.find(sprintf('[name="%s"]', that.options.selectItemName)); + if ($selectItem.length) { + $selectItem[0].click(); // #144: .trigger('click') bug + } + } + }); + + this.$body.find('> tr[data-index] > td > .detail-icon').off('click').on('click', function () { + var $this = $(this), + $tr = $this.parent().parent(), + index = $tr.data('index'), + row = data[index]; // Fix #980 Detail view, when searching, returns wrong row + + // remove and update + if ($tr.next().is('tr.detail-view')) { + $this.find('i').attr('class', sprintf('%s %s', that.options.iconsPrefix, that.options.icons.detailOpen)); + that.trigger('collapse-row', index, row); + $tr.next().remove(); + } else { + $this.find('i').attr('class', sprintf('%s %s', that.options.iconsPrefix, that.options.icons.detailClose)); + $tr.after(sprintf('', $tr.find('td').length)); + var $element = $tr.next().find('td'); + var content = calculateObjectValue(that.options, that.options.detailFormatter, [index, row, $element], ''); + if($element.length === 1) { + $element.append(content); + } + that.trigger('expand-row', index, row, $element); + } + that.resetView(); + return false; + }); + + this.$selectItem = this.$body.find(sprintf('[name="%s"]', this.options.selectItemName)); + this.$selectItem.off('click').on('click', function (event) { + event.stopImmediatePropagation(); + + var $this = $(this), + checked = $this.prop('checked'), + row = that.data[$this.data('index')]; + + if (that.options.maintainSelected && $(this).is(':radio')) { + $.each(that.options.data, function (i, row) { + row[that.header.stateField] = false; + }); + } + + row[that.header.stateField] = checked; + + if (that.options.singleSelect) { + that.$selectItem.not(this).each(function () { + that.data[$(this).data('index')][that.header.stateField] = false; + }); + that.$selectItem.filter(':checked').not(this).prop('checked', false); + } + + that.updateSelected(); + that.trigger(checked ? 'check' : 'uncheck', row, $this); + }); + + $.each(this.header.events, function (i, events) { + if (!events) { + return; + } + // fix bug, if events is defined with namespace + if (typeof events === 'string') { + events = calculateObjectValue(null, events); + } + + var field = that.header.fields[i], + fieldIndex = $.inArray(field, that.getVisibleFields()); + + if (that.options.detailView && !that.options.cardView) { + fieldIndex += 1; + } + + for (var key in events) { + that.$body.find('>tr:not(.no-records-found)').each(function () { + var $tr = $(this), + $td = $tr.find(that.options.cardView ? '.card-view' : 'td').eq(fieldIndex), + index = key.indexOf(' '), + name = key.substring(0, index), + el = key.substring(index + 1), + func = events[key]; + + $td.find(el).off(name).on(name, function (e) { + var index = $tr.data('index'), + row = that.data[index], + value = row[field]; + var props = field.split('.'); + if(props.length > 1) { + value = row; + for (var prop_index = 0; prop_index < props.length; prop_index++) { + value = value[props[prop_index]]; + } + } + func.apply(this, [e, value, row, index]); + }); + }); + } + }); + + this.updateSelected(); + this.resetView(); + + this.trigger('post-body', data); + }; + + BootstrapTable.prototype.initServer = function (silent, query, url) { + var that = this, + data = {}, + params = { + searchText: this.searchText, + sortName: this.options.sortName, + sortOrder: this.options.sortOrder + }, + request; + + if (this.options.pagination) { + params.pageSize = this.options.pageSize === this.options.formatAllRows() ? + this.options.totalRows : this.options.pageSize; + params.pageNumber = this.options.pageNumber; + } + + if (!(url || this.options.url) && !this.options.ajax) { + return; + } + + if (this.options.queryParamsType === 'limit') { + params = { + search: params.searchText, + sort: params.sortName, + order: params.sortOrder + }; + + if (this.options.pagination) { + params.offset = this.options.pageSize === this.options.formatAllRows() ? + 0 : this.options.pageSize * (this.options.pageNumber - 1); + params.limit = this.options.pageSize === this.options.formatAllRows() ? + this.options.totalRows : this.options.pageSize; + } + } + + if (!($.isEmptyObject(this.filterColumnsPartial))) { + params.filter = JSON.stringify(this.filterColumnsPartial, null); + } + + data = calculateObjectValue(this.options, this.options.queryParams, [params], data); + + $.extend(data, query || {}); + + // false to stop request + if (data === false) { + return; + } + + if (!silent) { + this.$tableLoading.show(); + } + request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), { + type: this.options.method, + url: url || this.options.url, + data: this.options.contentType === 'application/json' && this.options.method === 'post' ? + JSON.stringify(data) : data, + cache: this.options.cache, + contentType: this.options.contentType, + dataType: this.options.dataType, + success: function (res) { + res = calculateObjectValue(that.options, that.options.responseHandler, [res], res); + + that.load(res); + that.trigger('load-success', res); + if (!silent) that.$tableLoading.hide(); + }, + error: function (res) { + that.trigger('load-error', res.status, res); + if (!silent) that.$tableLoading.hide(); + } + }); + + if (this.options.ajax) { + calculateObjectValue(this, this.options.ajax, [request], null); + } else { + if (this._xhr && this._xhr.readyState !== 4) { + this._xhr.abort(); + } + this._xhr = $.ajax(request); + } + }; + + BootstrapTable.prototype.initSearchText = function () { + if (this.options.search) { + if (this.options.searchText !== '') { + var $search = this.$toolbar.find('.search input'); + $search.val(this.options.searchText); + this.onSearch({currentTarget: $search}); + } + } + }; + + BootstrapTable.prototype.getCaret = function () { + var that = this; + + $.each(this.$header.find('th'), function (i, th) { + $(th).find('.sortable').removeClass('desc asc').addClass($(th).data('field') === that.options.sortName ? that.options.sortOrder : 'both'); + }); + }; + + BootstrapTable.prototype.updateSelected = function () { + var checkAll = this.$selectItem.filter(':enabled').length && + this.$selectItem.filter(':enabled').length === + this.$selectItem.filter(':enabled').filter(':checked').length; + + this.$selectAll.add(this.$selectAll_).prop('checked', checkAll); + + this.$selectItem.each(function () { + $(this).closest('tr')[$(this).prop('checked') ? 'addClass' : 'removeClass']('selected'); + }); + }; + + BootstrapTable.prototype.updateRows = function () { + var that = this; + + this.$selectItem.each(function () { + that.data[$(this).data('index')][that.header.stateField] = $(this).prop('checked'); + }); + }; + + BootstrapTable.prototype.resetRows = function () { + var that = this; + + $.each(this.data, function (i, row) { + that.$selectAll.prop('checked', false); + that.$selectItem.prop('checked', false); + if (that.header.stateField) { + row[that.header.stateField] = false; + } + }); + this.initHiddenRows(); + }; + + BootstrapTable.prototype.trigger = function (name) { + var args = Array.prototype.slice.call(arguments, 1); + + name += '.bs.table'; + this.options[BootstrapTable.EVENTS[name]].apply(this.options, args); + this.$el.trigger($.Event(name), args); + + this.options.onAll(name, args); + this.$el.trigger($.Event('all.bs.table'), [name, args]); + }; + + BootstrapTable.prototype.resetHeader = function () { + // fix #61: the hidden table reset header bug. + // fix bug: get $el.css('width') error sometime (height = 500) + clearTimeout(this.timeoutId_); + this.timeoutId_ = setTimeout($.proxy(this.fitHeader, this), this.$el.is(':hidden') ? 100 : 0); + }; + + BootstrapTable.prototype.fitHeader = function () { + var that = this, + fixedBody, + scrollWidth, + focused, + focusedTemp; + + if (that.$el.is(':hidden')) { + that.timeoutId_ = setTimeout($.proxy(that.fitHeader, that), 100); + return; + } + fixedBody = this.$tableBody.get(0); + + scrollWidth = fixedBody.scrollWidth > fixedBody.clientWidth && + fixedBody.scrollHeight > fixedBody.clientHeight + this.$header.outerHeight() ? + getScrollBarWidth() : 0; + + this.$el.css('margin-top', -this.$header.outerHeight()); + + focused = $(':focus'); + if (focused.length > 0) { + var $th = focused.parents('th'); + if ($th.length > 0) { + var dataField = $th.attr('data-field'); + if (dataField !== undefined) { + var $headerTh = this.$header.find("[data-field='" + dataField + "']"); + if ($headerTh.length > 0) { + $headerTh.find(":input").addClass("focus-temp"); + } + } + } + } + + this.$header_ = this.$header.clone(true, true); + this.$selectAll_ = this.$header_.find('[name="btSelectAll"]'); + this.$tableHeader.css({ + 'margin-right': scrollWidth + }).find('table').css('width', this.$el.outerWidth()) + .html('').attr('class', this.$el.attr('class')) + .append(this.$header_); + + + focusedTemp = $('.focus-temp:visible:eq(0)'); + if (focusedTemp.length > 0) { + focusedTemp.focus(); + this.$header.find('.focus-temp').removeClass('focus-temp'); + } + + // fix bug: $.data() is not working as expected after $.append() + this.$header.find('th[data-field]').each(function (i) { + that.$header_.find(sprintf('th[data-field="%s"]', $(this).data('field'))).data($(this).data()); + }); + + var visibleFields = this.getVisibleFields(), + $ths = this.$header_.find('th'); + + this.$body.find('>tr:first-child:not(.no-records-found) > *').each(function (i) { + var $this = $(this), + index = i; + + if (that.options.detailView && !that.options.cardView) { + if (i === 0) { + that.$header_.find('th.detail').find('.fht-cell').width($this.innerWidth()); + } + index = i - 1; + } + + var $th = that.$header_.find(sprintf('th[data-field="%s"]', visibleFields[index])); + if ($th.length > 1) { + $th = $($ths[$this[0].cellIndex]); + } + + $th.find('.fht-cell').width($this.innerWidth()); + }); + // horizontal scroll event + // TODO: it's probably better improving the layout than binding to scroll event + this.$tableBody.off('scroll').on('scroll', function () { + that.$tableHeader.scrollLeft($(this).scrollLeft()); + + if (that.options.showFooter && !that.options.cardView) { + that.$tableFooter.scrollLeft($(this).scrollLeft()); + } + }); + that.trigger('post-header'); + }; + + BootstrapTable.prototype.resetFooter = function () { + var that = this, + data = that.getData(), + html = []; + + if (!this.options.showFooter || this.options.cardView) { //do nothing + return; + } + + if (!this.options.cardView && this.options.detailView) { + html.push('
             
            '); + } + + $.each(this.columns, function (i, column) { + var key, + falign = '', // footer align style + valign = '', + csses = [], + style = {}, + class_ = sprintf(' class="%s"', column['class']); + + if (!column.visible) { + return; + } + + if (that.options.cardView && (!column.cardVisible)) { + return; + } + + falign = sprintf('text-align: %s; ', column.falign ? column.falign : column.align); + valign = sprintf('vertical-align: %s; ', column.valign); + + style = calculateObjectValue(null, that.options.footerStyle); + + if (style && style.css) { + for (key in style.css) { + csses.push(key + ': ' + style.css[key]); + } + } + + html.push(''); + html.push('
            '); + + html.push(calculateObjectValue(column, column.footerFormatter, [data], ' ') || ' '); + + html.push('
            '); + html.push('
            '); + html.push(''); + html.push(''); + }); + + this.$tableFooter.find('tr').html(html.join('')); + this.$tableFooter.show(); + clearTimeout(this.timeoutFooter_); + this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this), + this.$el.is(':hidden') ? 100 : 0); + }; + + BootstrapTable.prototype.fitFooter = function () { + var that = this, + $footerTd, + elWidth, + scrollWidth; + + clearTimeout(this.timeoutFooter_); + if (this.$el.is(':hidden')) { + this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this), 100); + return; + } + + elWidth = this.$el.css('width'); + scrollWidth = elWidth > this.$tableBody.width() ? getScrollBarWidth() : 0; + + this.$tableFooter.css({ + 'margin-right': scrollWidth + }).find('table').css('width', elWidth) + .attr('class', this.$el.attr('class')); + + $footerTd = this.$tableFooter.find('td'); + + this.$body.find('>tr:first-child:not(.no-records-found) > *').each(function (i) { + var $this = $(this); + + $footerTd.eq(i).find('.fht-cell').width($this.innerWidth()); + }); + }; + + BootstrapTable.prototype.toggleColumn = function (index, checked, needUpdate) { + if (index === -1) { + return; + } + this.columns[index].visible = checked; + this.initHeader(); + this.initSearch(); + this.initPagination(); + this.initBody(); + + if (this.options.showColumns) { + var $items = this.$toolbar.find('.keep-open input').prop('disabled', false); + + if (needUpdate) { + $items.filter(sprintf('[value="%s"]', index)).prop('checked', checked); + } + + if ($items.filter(':checked').length <= this.options.minimumCountColumns) { + $items.filter(':checked').prop('disabled', true); + } + } + }; + + BootstrapTable.prototype.getVisibleFields = function () { + var that = this, + visibleFields = []; + + $.each(this.header.fields, function (j, field) { + var column = that.columns[getFieldIndex(that.columns, field)]; + + if (!column.visible) { + return; + } + visibleFields.push(field); + }); + return visibleFields; + }; + + // PUBLIC FUNCTION DEFINITION + // ======================= + + BootstrapTable.prototype.resetView = function (params) { + var padding = 0; + + if (params && params.height) { + this.options.height = params.height; + } + + this.$selectAll.prop('checked', this.$selectItem.length > 0 && + this.$selectItem.length === this.$selectItem.filter(':checked').length); + + if (this.options.height) { + var toolbarHeight = this.$toolbar.outerHeight(true), + paginationHeight = this.$pagination.outerHeight(true), + height = this.options.height - toolbarHeight - paginationHeight; + + this.$tableContainer.css('height', height + 'px'); + } + + if (this.options.cardView) { + // remove the element css + this.$el.css('margin-top', '0'); + this.$tableContainer.css('padding-bottom', '0'); + this.$tableFooter.hide(); + return; + } + + if (this.options.showHeader && this.options.height) { + this.$tableHeader.show(); + this.resetHeader(); + padding += this.$header.outerHeight(); + } else { + this.$tableHeader.hide(); + this.trigger('post-header'); + } + + if (this.options.showFooter) { + this.resetFooter(); + if (this.options.height) { + padding += this.$tableFooter.outerHeight() + 1; + } + } + + // Assign the correct sortable arrow + this.getCaret(); + this.$tableContainer.css('padding-bottom', padding + 'px'); + this.trigger('reset-view'); + }; + + BootstrapTable.prototype.getData = function (useCurrentPage) { + return (this.searchText || !$.isEmptyObject(this.filterColumns) || !$.isEmptyObject(this.filterColumnsPartial)) ? + (useCurrentPage ? this.data.slice(this.pageFrom - 1, this.pageTo) : this.data) : + (useCurrentPage ? this.options.data.slice(this.pageFrom - 1, this.pageTo) : this.options.data); + }; + + BootstrapTable.prototype.load = function (data) { + var fixedScroll = false; + + // #431: support pagination + if (this.options.sidePagination === 'server') { + this.options.totalRows = data[this.options.totalField]; + fixedScroll = data.fixedScroll; + data = data[this.options.dataField]; + } else if (!$.isArray(data)) { // support fixedScroll + fixedScroll = data.fixedScroll; + data = data.data; + } + + this.initData(data); + this.initSearch(); + this.initPagination(); + this.initBody(fixedScroll); + }; + + BootstrapTable.prototype.append = function (data) { + this.initData(data, 'append'); + this.initSearch(); + this.initPagination(); + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.prepend = function (data) { + this.initData(data, 'prepend'); + this.initSearch(); + this.initPagination(); + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.remove = function (params) { + var len = this.options.data.length, + i, row; + + if (!params.hasOwnProperty('field') || !params.hasOwnProperty('values')) { + return; + } + + for (i = len - 1; i >= 0; i--) { + row = this.options.data[i]; + + if (!row.hasOwnProperty(params.field)) { + continue; + } + if ($.inArray(row[params.field], params.values) !== -1) { + this.options.data.splice(i, 1); + if (this.options.sidePagination === 'server') { + this.options.totalRows -= 1; + } + } + } + + if (len === this.options.data.length) { + return; + } + + this.initSearch(); + this.initPagination(); + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.removeAll = function () { + if (this.options.data.length > 0) { + this.options.data.splice(0, this.options.data.length); + this.initSearch(); + this.initPagination(); + this.initBody(true); + } + }; + + BootstrapTable.prototype.getRowByUniqueId = function (id) { + var uniqueId = this.options.uniqueId, + len = this.options.data.length, + dataRow = null, + i, row, rowUniqueId; + + for (i = len - 1; i >= 0; i--) { + row = this.options.data[i]; + + if (row.hasOwnProperty(uniqueId)) { // uniqueId is a column + rowUniqueId = row[uniqueId]; + } else if(row._data.hasOwnProperty(uniqueId)) { // uniqueId is a row data property + rowUniqueId = row._data[uniqueId]; + } else { + continue; + } + + if (typeof rowUniqueId === 'string') { + id = id.toString(); + } else if (typeof rowUniqueId === 'number') { + if ((Number(rowUniqueId) === rowUniqueId) && (rowUniqueId % 1 === 0)) { + id = parseInt(id); + } else if ((rowUniqueId === Number(rowUniqueId)) && (rowUniqueId !== 0)) { + id = parseFloat(id); + } + } + + if (rowUniqueId === id) { + dataRow = row; + break; + } + } + + return dataRow; + }; + + BootstrapTable.prototype.removeByUniqueId = function (id) { + var len = this.options.data.length, + row = this.getRowByUniqueId(id); + + if (row) { + this.options.data.splice(this.options.data.indexOf(row), 1); + } + + if (len === this.options.data.length) { + return; + } + + this.initSearch(); + this.initPagination(); + this.initBody(true); + }; + + BootstrapTable.prototype.updateByUniqueId = function (params) { + var that = this; + var allParams = $.isArray(params) ? params : [ params ]; + + $.each(allParams, function(i, params) { + var rowId; + + if (!params.hasOwnProperty('id') || !params.hasOwnProperty('row')) { + return; + } + + rowId = $.inArray(that.getRowByUniqueId(params.id), that.options.data); + + if (rowId === -1) { + return; + } + $.extend(that.options.data[rowId], params.row); + }); + + this.initSearch(); + this.initPagination(); + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.insertRow = function (params) { + if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) { + return; + } + this.data.splice(params.index, 0, params.row); + this.initSearch(); + this.initPagination(); + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.updateRow = function (params) { + var that = this; + var allParams = $.isArray(params) ? params : [ params ]; + + $.each(allParams, function(i, params) { + if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) { + return; + } + $.extend(that.options.data[params.index], params.row); + }); + + this.initSearch(); + this.initPagination(); + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.initHiddenRows = function () { + this.hiddenRows = []; + }; + + BootstrapTable.prototype.showRow = function (params) { + this.toggleRow(params, true); + }; + + BootstrapTable.prototype.hideRow = function (params) { + this.toggleRow(params, false); + }; + + BootstrapTable.prototype.toggleRow = function (params, visible) { + var row, index; + + if (params.hasOwnProperty('index')) { + row = this.getData()[params.index]; + } else if (params.hasOwnProperty('uniqueId')) { + row = this.getRowByUniqueId(params.uniqueId); + } + + if (!row) { + return; + } + + index = $.inArray(row, this.hiddenRows); + + if (!visible && index === -1) { + this.hiddenRows.push(row); + } else if (visible && index > -1) { + this.hiddenRows.splice(index, 1); + } + this.initBody(true); + }; + + BootstrapTable.prototype.getHiddenRows = function (show) { + var that = this, + data = this.getData(), + rows = []; + + $.each(data, function (i, row) { + if ($.inArray(row, that.hiddenRows) > -1) { + rows.push(row); + } + }); + this.hiddenRows = rows; + return rows; + }; + + BootstrapTable.prototype.mergeCells = function (options) { + var row = options.index, + col = $.inArray(options.field, this.getVisibleFields()), + rowspan = options.rowspan || 1, + colspan = options.colspan || 1, + i, j, + $tr = this.$body.find('>tr'), + $td; + + if (this.options.detailView && !this.options.cardView) { + col += 1; + } + + $td = $tr.eq(row).find('>td').eq(col); + + if (row < 0 || col < 0 || row >= this.data.length) { + return; + } + + for (i = row; i < row + rowspan; i++) { + for (j = col; j < col + colspan; j++) { + $tr.eq(i).find('>td').eq(j).hide(); + } + } + + $td.attr('rowspan', rowspan).attr('colspan', colspan).show(); + }; + + BootstrapTable.prototype.updateCell = function (params) { + if (!params.hasOwnProperty('index') || + !params.hasOwnProperty('field') || + !params.hasOwnProperty('value')) { + return; + } + this.data[params.index][params.field] = params.value; + + if (params.reinit === false) { + return; + } + this.initSort(); + this.initBody(true); + }; + + BootstrapTable.prototype.getOptions = function () { + return this.options; + }; + + BootstrapTable.prototype.getSelections = function () { + var that = this; + + return $.grep(this.options.data, function (row) { + // fix #2424: from html with checkbox + return row[that.header.stateField] === true; + }); + }; + + BootstrapTable.prototype.getAllSelections = function () { + var that = this; + + return $.grep(this.options.data, function (row) { + return row[that.header.stateField]; + }); + }; + + BootstrapTable.prototype.checkAll = function () { + this.checkAll_(true); + }; + + BootstrapTable.prototype.uncheckAll = function () { + this.checkAll_(false); + }; + + BootstrapTable.prototype.checkInvert = function () { + var that = this; + var rows = that.$selectItem.filter(':enabled'); + var checked = rows.filter(':checked'); + rows.each(function() { + $(this).prop('checked', !$(this).prop('checked')); + }); + that.updateRows(); + that.updateSelected(); + that.trigger('uncheck-some', checked); + checked = that.getSelections(); + that.trigger('check-some', checked); + }; + + BootstrapTable.prototype.checkAll_ = function (checked) { + var rows; + if (!checked) { + rows = this.getSelections(); + } + this.$selectAll.add(this.$selectAll_).prop('checked', checked); + this.$selectItem.filter(':enabled').prop('checked', checked); + this.updateRows(); + if (checked) { + rows = this.getSelections(); + } + this.trigger(checked ? 'check-all' : 'uncheck-all', rows); + }; + + BootstrapTable.prototype.check = function (index) { + this.check_(true, index); + }; + + BootstrapTable.prototype.uncheck = function (index) { + this.check_(false, index); + }; + + BootstrapTable.prototype.check_ = function (checked, index) { + var $el = this.$selectItem.filter(sprintf('[data-index="%s"]', index)).prop('checked', checked); + this.data[index][this.header.stateField] = checked; + this.updateSelected(); + this.trigger(checked ? 'check' : 'uncheck', this.data[index], $el); + }; + + BootstrapTable.prototype.checkBy = function (obj) { + this.checkBy_(true, obj); + }; + + BootstrapTable.prototype.uncheckBy = function (obj) { + this.checkBy_(false, obj); + }; + + BootstrapTable.prototype.checkBy_ = function (checked, obj) { + if (!obj.hasOwnProperty('field') || !obj.hasOwnProperty('values')) { + return; + } + + var that = this, + rows = []; + $.each(this.options.data, function (index, row) { + if (!row.hasOwnProperty(obj.field)) { + return false; + } + if ($.inArray(row[obj.field], obj.values) !== -1) { + var $el = that.$selectItem.filter(':enabled') + .filter(sprintf('[data-index="%s"]', index)).prop('checked', checked); + row[that.header.stateField] = checked; + rows.push(row); + that.trigger(checked ? 'check' : 'uncheck', row, $el); + } + }); + this.updateSelected(); + this.trigger(checked ? 'check-some' : 'uncheck-some', rows); + }; + + BootstrapTable.prototype.destroy = function () { + this.$el.insertBefore(this.$container); + $(this.options.toolbar).insertBefore(this.$el); + this.$container.next().remove(); + this.$container.remove(); + this.$el.html(this.$el_.html()) + .css('margin-top', '0') + .attr('class', this.$el_.attr('class') || ''); // reset the class + }; + + BootstrapTable.prototype.showLoading = function () { + this.$tableLoading.show(); + }; + + BootstrapTable.prototype.hideLoading = function () { + this.$tableLoading.hide(); + }; + + BootstrapTable.prototype.togglePagination = function () { + this.options.pagination = !this.options.pagination; + var button = this.$toolbar.find('button[name="paginationSwitch"] i'); + if (this.options.pagination) { + button.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchDown); + } else { + button.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchUp); + } + this.updatePagination(); + }; + + BootstrapTable.prototype.refresh = function (params) { + if (params && params.url) { + this.options.url = params.url; + } + if (params && params.pageNumber) { + this.options.pageNumber = params.pageNumber; + } + if (params && params.pageSize) { + this.options.pageSize = params.pageSize; + } + this.initServer(params && params.silent, + params && params.query, params && params.url); + this.trigger('refresh', params); + }; + + BootstrapTable.prototype.resetWidth = function () { + if (this.options.showHeader && this.options.height) { + this.fitHeader(); + } + if (this.options.showFooter) { + this.fitFooter(); + } + }; + + BootstrapTable.prototype.showColumn = function (field) { + this.toggleColumn(getFieldIndex(this.columns, field), true, true); + }; + + BootstrapTable.prototype.hideColumn = function (field) { + this.toggleColumn(getFieldIndex(this.columns, field), false, true); + }; + + BootstrapTable.prototype.getHiddenColumns = function () { + return $.grep(this.columns, function (column) { + return !column.visible; + }); + }; + + BootstrapTable.prototype.getVisibleColumns = function () { + return $.grep(this.columns, function (column) { + return column.visible; + }); + }; + + BootstrapTable.prototype.toggleAllColumns = function (visible) { + $.each(this.columns, function (i, column) { + this.columns[i].visible = visible; + }); + + this.initHeader(); + this.initSearch(); + this.initPagination(); + this.initBody(); + if (this.options.showColumns) { + var $items = this.$toolbar.find('.keep-open input').prop('disabled', false); + + if ($items.filter(':checked').length <= this.options.minimumCountColumns) { + $items.filter(':checked').prop('disabled', true); + } + } + }; + + BootstrapTable.prototype.showAllColumns = function () { + this.toggleAllColumns(true); + }; + + BootstrapTable.prototype.hideAllColumns = function () { + this.toggleAllColumns(false); + }; + + BootstrapTable.prototype.filterBy = function (columns) { + this.filterColumns = $.isEmptyObject(columns) ? {} : columns; + this.options.pageNumber = 1; + this.initSearch(); + this.updatePagination(); + }; + + BootstrapTable.prototype.scrollTo = function (value) { + if (typeof value === 'string') { + value = value === 'bottom' ? this.$tableBody[0].scrollHeight : 0; + } + if (typeof value === 'number') { + this.$tableBody.scrollTop(value); + } + if (typeof value === 'undefined') { + return this.$tableBody.scrollTop(); + } + }; + + BootstrapTable.prototype.getScrollPosition = function () { + return this.scrollTo(); + }; + + BootstrapTable.prototype.selectPage = function (page) { + if (page > 0 && page <= this.options.totalPages) { + this.options.pageNumber = page; + this.updatePagination(); + } + }; + + BootstrapTable.prototype.prevPage = function () { + if (this.options.pageNumber > 1) { + this.options.pageNumber--; + this.updatePagination(); + } + }; + + BootstrapTable.prototype.nextPage = function () { + if (this.options.pageNumber < this.options.totalPages) { + this.options.pageNumber++; + this.updatePagination(); + } + }; + + BootstrapTable.prototype.toggleView = function () { + this.options.cardView = !this.options.cardView; + this.initHeader(); + // Fixed remove toolbar when click cardView button. + //that.initToolbar(); + this.initBody(); + this.trigger('toggle', this.options.cardView); + }; + + BootstrapTable.prototype.refreshOptions = function (options) { + //If the objects are equivalent then avoid the call of destroy / init methods + if (compareObjects(this.options, options, true)) { + return; + } + this.options = $.extend(this.options, options); + this.trigger('refresh-options', this.options); + this.destroy(); + this.init(); + }; + + BootstrapTable.prototype.resetSearch = function (text) { + var $search = this.$toolbar.find('.search input'); + $search.val(text || ''); + this.onSearch({currentTarget: $search}); + }; + + BootstrapTable.prototype.expandRow_ = function (expand, index) { + var $tr = this.$body.find(sprintf('> tr[data-index="%s"]', index)); + if ($tr.next().is('tr.detail-view') === (expand ? false : true)) { + $tr.find('> td > .detail-icon').click(); + } + }; + + BootstrapTable.prototype.expandRow = function (index) { + this.expandRow_(true, index); + }; + + BootstrapTable.prototype.collapseRow = function (index) { + this.expandRow_(false, index); + }; + + BootstrapTable.prototype.expandAllRows = function (isSubTable) { + if (isSubTable) { + var $tr = this.$body.find(sprintf('> tr[data-index="%s"]', 0)), + that = this, + detailIcon = null, + executeInterval = false, + idInterval = -1; + + if (!$tr.next().is('tr.detail-view')) { + $tr.find('> td > .detail-icon').click(); + executeInterval = true; + } else if (!$tr.next().next().is('tr.detail-view')) { + $tr.next().find(".detail-icon").click(); + executeInterval = true; + } + + if (executeInterval) { + try { + idInterval = setInterval(function () { + detailIcon = that.$body.find("tr.detail-view").last().find(".detail-icon"); + if (detailIcon.length > 0) { + detailIcon.click(); + } else { + clearInterval(idInterval); + } + }, 1); + } catch (ex) { + clearInterval(idInterval); + } + } + } else { + var trs = this.$body.children(); + for (var i = 0; i < trs.length; i++) { + this.expandRow_(true, $(trs[i]).data("index")); + } + } + }; + + BootstrapTable.prototype.collapseAllRows = function (isSubTable) { + if (isSubTable) { + this.expandRow_(false, 0); + } else { + var trs = this.$body.children(); + for (var i = 0; i < trs.length; i++) { + this.expandRow_(false, $(trs[i]).data("index")); + } + } + }; + + BootstrapTable.prototype.updateFormatText = function (name, text) { + if (this.options[sprintf('format%s', name)]) { + if (typeof text === 'string') { + this.options[sprintf('format%s', name)] = function () { + return text; + }; + } else if (typeof text === 'function') { + this.options[sprintf('format%s', name)] = text; + } + } + this.initToolbar(); + this.initPagination(); + this.initBody(); + }; + + // BOOTSTRAP TABLE PLUGIN DEFINITION + // ======================= + + var allowedMethods = [ + 'getOptions', + 'getSelections', 'getAllSelections', 'getData', + 'load', 'append', 'prepend', 'remove', 'removeAll', + 'insertRow', 'updateRow', 'updateCell', 'updateByUniqueId', 'removeByUniqueId', + 'getRowByUniqueId', 'showRow', 'hideRow', 'getHiddenRows', + 'mergeCells', + 'checkAll', 'uncheckAll', 'checkInvert', + 'check', 'uncheck', + 'checkBy', 'uncheckBy', + 'refresh', + 'resetView', + 'resetWidth', + 'destroy', + 'showLoading', 'hideLoading', + 'showColumn', 'hideColumn', 'getHiddenColumns', 'getVisibleColumns', + 'showAllColumns', 'hideAllColumns', + 'filterBy', + 'scrollTo', + 'getScrollPosition', + 'selectPage', 'prevPage', 'nextPage', + 'togglePagination', + 'toggleView', + 'refreshOptions', + 'resetSearch', + 'expandRow', 'collapseRow', 'expandAllRows', 'collapseAllRows', + 'updateFormatText' + ]; + + $.fn.bootstrapTable = function (option) { + var value, + args = Array.prototype.slice.call(arguments, 1); + + this.each(function () { + var $this = $(this), + data = $this.data('bootstrap.table'), + options = $.extend({}, BootstrapTable.DEFAULTS, $this.data(), + typeof option === 'object' && option); + + if (typeof option === 'string') { + if ($.inArray(option, allowedMethods) < 0) { + throw new Error("Unknown method: " + option); + } + + if (!data) { + return; + } + + value = data[option].apply(data, args); + + if (option === 'destroy') { + $this.removeData('bootstrap.table'); + } + } + + if (!data) { + $this.data('bootstrap.table', (data = new BootstrapTable(this, options))); + } + }); + + return typeof value === 'undefined' ? this : value; + }; + + $.fn.bootstrapTable.Constructor = BootstrapTable; + $.fn.bootstrapTable.defaults = BootstrapTable.DEFAULTS; + $.fn.bootstrapTable.columnDefaults = BootstrapTable.COLUMN_DEFAULTS; + $.fn.bootstrapTable.locales = BootstrapTable.LOCALES; + $.fn.bootstrapTable.methods = allowedMethods; + $.fn.bootstrapTable.utils = { + sprintf: sprintf, + getFieldIndex: getFieldIndex, + compareObjects: compareObjects, + calculateObjectValue: calculateObjectValue, + getItemField: getItemField, + objectKeys: objectKeys, + isIEBrowser: isIEBrowser + }; + + // BOOTSTRAP TABLE INIT + // ======================= + + $(function () { + $('[data-toggle="table"]').bootstrapTable(); + }); +})(jQuery); diff --git a/public/assets/libs/bootstrap-table/dist/bootstrap-table.min.css b/public/assets/libs/bootstrap-table/dist/bootstrap-table.min.css new file mode 100644 index 0000000000000000000000000000000000000000..f65b30883547258875a5808e31a13890ec04b559 --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/bootstrap-table.min.css @@ -0,0 +1 @@ +.fixed-table-container .bs-checkbox,.fixed-table-container .no-records-found{text-align:center}.fixed-table-body thead th .th-inner,.table td,.table th{box-sizing:border-box}.bootstrap-table .table{margin-bottom:0!important;border-bottom:1px solid #ddd;border-collapse:collapse!important;border-radius:1px}.bootstrap-table .table:not(.table-condensed),.bootstrap-table .table:not(.table-condensed)>tbody>tr>td,.bootstrap-table .table:not(.table-condensed)>tbody>tr>th,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>td,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>th,.bootstrap-table .table:not(.table-condensed)>thead>tr>td{padding:8px}.bootstrap-table .table.table-no-bordered>tbody>tr>td,.bootstrap-table .table.table-no-bordered>thead>tr>th{border-right:2px solid transparent}.bootstrap-table .table.table-no-bordered>tbody>tr>td:last-child{border-right:none}.fixed-table-container{position:relative;clear:both;border:1px solid #ddd;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px}.fixed-table-container.table-no-bordered{border:1px solid transparent}.fixed-table-footer,.fixed-table-header{overflow:hidden}.fixed-table-footer{border-top:1px solid #ddd}.fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.fixed-table-container table{width:100%}.fixed-table-container thead th{height:0;padding:0;margin:0;border-left:1px solid #ddd}.fixed-table-container thead th:focus{outline:transparent solid 0}.fixed-table-container thead th:first-child{border-left:none;border-top-left-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px}.fixed-table-container tbody td .th-inner,.fixed-table-container thead th .th-inner{padding:8px;line-height:24px;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fixed-table-container thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.fixed-table-container thead th .both{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC')}.fixed-table-container thead th .asc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==)}.fixed-table-container thead th .desc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII=)}.fixed-table-container th.detail{width:30px}.fixed-table-container tbody td{border-left:1px solid #ddd}.fixed-table-container tbody tr:first-child td{border-top:none}.fixed-table-container tbody td:first-child{border-left:none}.fixed-table-container tbody .selected td{background-color:#f5f5f5}.fixed-table-container .bs-checkbox .th-inner{padding:8px 0}.fixed-table-container input[type=radio],.fixed-table-container input[type=checkbox]{margin:0 auto!important}.fixed-table-pagination .pagination-detail,.fixed-table-pagination div.pagination{margin-top:10px;margin-bottom:10px}.fixed-table-pagination div.pagination .pagination{margin:0}.fixed-table-pagination .pagination a{padding:6px 12px;line-height:1.428571429}.fixed-table-pagination .pagination-info{line-height:34px;margin-right:5px}.fixed-table-pagination .btn-group{position:relative;display:inline-block;vertical-align:middle}.fixed-table-pagination .dropup .dropdown-menu{margin-bottom:0}.fixed-table-pagination .page-list{display:inline-block}.fixed-table-toolbar .columns-left{margin-right:5px}.fixed-table-toolbar .columns-right{margin-left:5px}.fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.fixed-table-toolbar .bs-bars,.fixed-table-toolbar .columns,.fixed-table-toolbar .search{position:relative;margin-top:10px;margin-bottom:10px;line-height:34px}.fixed-table-pagination li.disabled a{pointer-events:none;cursor:default}.fixed-table-loading{display:none;position:absolute;top:42px;right:0;bottom:0;left:0;z-index:99;background-color:#fff;text-align:center}.fixed-table-body .card-view .title{font-weight:700;display:inline-block;min-width:30%;text-align:left!important}.table td,.table th{vertical-align:middle}.fixed-table-toolbar .dropdown-menu{text-align:left;max-height:300px;overflow:auto}.fixed-table-toolbar .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.fixed-table-toolbar .btn-group>.btn-group>.btn{border-radius:0}.fixed-table-toolbar .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.fixed-table-toolbar .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .table>thead>tr>th{vertical-align:bottom;border-bottom:1px solid #ddd}.bootstrap-table .table thead>tr>th{padding:0;margin:0}.bootstrap-table .fixed-table-footer tbody>tr>td{padding:0!important}.bootstrap-table .fixed-table-footer .table{border-bottom:none;border-radius:0;padding:0!important}.bootstrap-table .pull-right .dropdown-menu{right:0;left:auto}p.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden}.fixed-table-pagination:after,.fixed-table-toolbar:after{content:"";display:block;clear:both} \ No newline at end of file diff --git a/public/assets/libs/bootstrap-table/dist/bootstrap-table.min.js b/public/assets/libs/bootstrap-table/dist/bootstrap-table.min.js new file mode 100644 index 0000000000000000000000000000000000000000..55bd9f253a03548813227ef0f2d3f54a08dac97c --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/bootstrap-table.min.js @@ -0,0 +1 @@ +(function($){"use strict";var cachedWidth=null;var sprintf=function(str){var args=arguments,flag=true,i=1;str=str.replace(/%s/g,function(){var arg=args[i++];if(typeof arg==="undefined"){flag=false;return""}return arg});return flag?str:""};var getPropertyFromOther=function(list,from,to,value){var result="";$.each(list,function(i,item){if(item[from]===value){result=item[to];return false}return true});return result};var getFieldIndex=function(columns,field){var index=-1;$.each(columns,function(i,column){if(column.field===field){index=i;return false}return true});return index};var setFieldIndex=function(columns){var i,j,k,totalCol=0,flag=[];for(i=0;i").addClass("fixed-table-scroll-inner"),outer=$("
            ").addClass("fixed-table-scroll-outer"),w1,w2;outer.append(inner);$("body").append(outer);w1=inner[0].offsetWidth;outer.css("overflow","scroll");w2=inner[0].offsetWidth;if(w1===w2){w2=outer[0].clientWidth}outer.remove();cachedWidth=w1-w2}return cachedWidth};var calculateObjectValue=function(self,name,args,defaultValue){var func=name;if(typeof name==="string"){var names=name.split(".");if(names.length>1){func=window;$.each(names,function(i,f){func=func[f]})}else{func=window[name]}}if(typeof func==="object"){return func}if(typeof func==="function"){return func.apply(self,args||[])}if(!func&&typeof name==="string"&&sprintf.apply(this,[name].concat(args))){return sprintf.apply(this,[name].concat(args))}return defaultValue};var compareObjects=function(objectA,objectB,compareLength){var objectAProperties=Object.getOwnPropertyNames(objectA),objectBProperties=Object.getOwnPropertyNames(objectB),propName="";if(compareLength){if(objectAProperties.length!==objectBProperties.length){return false}}for(var i=0;i-1){if(objectA[propName]!==objectB[propName]){return false}}}return true};var escapeHTML=function(text){if(typeof text==="string"){return text.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/`/g,"`")}return text};var getRealDataAttr=function(dataAttr){for(var attr in dataAttr){var auxAttr=attr.split(/(?=[A-Z])/).join("-").toLowerCase();if(auxAttr!==attr){dataAttr[auxAttr]=dataAttr[attr];delete dataAttr[attr]}}return dataAttr};var getItemField=function(item,field,escape){var value=item;if(typeof field!=="string"||item.hasOwnProperty(field)){return escape?escapeHTML(item[field]):item[field]}var props=field.split(".");for(var p in props){if(props.hasOwnProperty(p)){value=value&&value[props[p]]}}return escape?escapeHTML(value):value};var isIEBrowser=function(){return!!(navigator.userAgent.indexOf("MSIE ")>0||!!navigator.userAgent.match(/Trident.*rv\:11\./))};var objectKeys=function(){if(!Object.keys){Object.keys=function(){var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;return function(obj){if(typeof obj!=="object"&&(typeof obj!=="function"||obj===null)){throw new TypeError("Object.keys called on non-object")}var result=[],prop,i;for(prop in obj){if(hasOwnProperty.call(obj,prop)){result.push(prop)}}if(hasDontEnumBug){for(i=0;i','
            ',this.options.paginationVAlign==="top"||this.options.paginationVAlign==="both"?'
            ':"",'
            ','
            ','
            ','
            ',this.options.formatLoadingMessage(),"
            ","
            ",'',this.options.paginationVAlign==="bottom"||this.options.paginationVAlign==="both"?'
            ':"","
            ","
            "].join(""));this.$container.insertAfter(this.$el);this.$tableContainer=this.$container.find(".fixed-table-container");this.$tableHeader=this.$container.find(".fixed-table-header");this.$tableBody=this.$container.find(".fixed-table-body");this.$tableLoading=this.$container.find(".fixed-table-loading");this.$tableFooter=this.$container.find(".fixed-table-footer");this.$toolbar=this.$container.find(".fixed-table-toolbar");this.$pagination=this.$container.find(".fixed-table-pagination");this.$tableBody.append(this.$el);this.$container.after('
            ');this.$el.addClass(this.options.classes);if(this.options.striped){this.$el.addClass("table-striped")}if($.inArray("table-no-bordered",this.options.classes.split(" "))!==-1){this.$tableContainer.addClass("table-no-bordered")}};BootstrapTable.prototype.initTable=function(){var that=this,columns=[],data=[];this.$header=this.$el.find(">thead");if(!this.$header.length){this.$header=$("").appendTo(this.$el)}this.$header.find("tr").each(function(){var column=[];$(this).find("th").each(function(){if(typeof $(this).data("field")!=="undefined"){$(this).data("field",$(this).data("field")+"")}column.push($.extend({},{title:$(this).html(),class:$(this).attr("class"),titleTooltip:$(this).attr("title"),rowspan:$(this).attr("rowspan")?+$(this).attr("rowspan"):undefined,colspan:$(this).attr("colspan")?+$(this).attr("colspan"):undefined},$(this).data()))});columns.push(column)});if(!$.isArray(this.options.columns[0])){this.options.columns=[this.options.columns]}this.options.columns=$.extend(true,[],columns,this.options.columns);this.columns=[];setFieldIndex(this.options.columns);$.each(this.options.columns,function(i,columns){$.each(columns,function(j,column){column=$.extend({},BootstrapTable.COLUMN_DEFAULTS,column);if(typeof column.fieldIndex!=="undefined"){that.columns[column.fieldIndex]=column}that.options.columns[i][j]=column})});if(this.options.data.length){return}var m=[];this.$el.find(">tbody>tr").each(function(y){var row={};row._id=$(this).attr("id");row._class=$(this).attr("class");row._data=getRealDataAttr($(this).data());$(this).find(">td").each(function(x){var $this=$(this),cspan=+$this.attr("colspan")||1,rspan=+$this.attr("rowspan")||1,tx,ty;for(;m[y]&&m[y][x];x++);for(tx=x;tx");if(i===0&&!that.options.cardView&&that.options.detailView){html.push(sprintf('
            ',that.options.columns.length))}$.each(columns,function(j,column){var text="",halign="",align="",style="",class_=sprintf(' class="%s"',column["class"]),order=that.options.sortOrder||column.order,unitWidth="px",width=column.width;if(column.width!==undefined&&!that.options.cardView){if(typeof column.width==="string"){if(column.width.indexOf("%")!==-1){unitWidth="%"}}}if(column.width&&typeof column.width==="string"){width=column.width.replace("%","").replace("px","")}halign=sprintf("text-align: %s; ",column.halign?column.halign:column.align);align=sprintf("text-align: %s; ",column.align);style=sprintf("vertical-align: %s; ",column.valign);style+=sprintf("width: %s; ",(column.checkbox||column.radio)&&!width?"36px":width?width+unitWidth:undefined);if(typeof column.fieldIndex!=="undefined"){that.header.fields[column.fieldIndex]=column.field;that.header.styles[column.fieldIndex]=align+style;that.header.classes[column.fieldIndex]=class_;that.header.formatters[column.fieldIndex]=column.formatter;that.header.events[column.fieldIndex]=column.events;that.header.sorters[column.fieldIndex]=column.sorter;that.header.sortNames[column.fieldIndex]=column.sortName;that.header.cellStyles[column.fieldIndex]=column.cellStyle;that.header.searchables[column.fieldIndex]=column.searchable;if(!column.visible){return}if(that.options.cardView&&!column.cardVisible){return}visibleColumns[column.field]=column}html.push("");html.push(sprintf('
            ',that.options.sortable&&column.sortable?"sortable both":""));text=that.options.escape?escapeHTML(column.title):column.title;if(column.checkbox){if(!that.options.singleSelect&&that.options.checkboxHeader){text=''}that.header.stateField=column.field}if(column.radio){text="";that.header.stateField=column.field;that.options.singleSelect=true}html.push(text);html.push("
            ");html.push('
            ');html.push("");html.push("")});html.push("")});this.$header.html(html.join(""));this.$header.find("th[data-field]").each(function(i){$(this).data(visibleColumns[$(this).data("field")])});this.$container.off("click",".th-inner").on("click",".th-inner",function(event){var target=$(this);if(that.options.detailView){if(target.closest(".bootstrap-table")[0]!==that.$container[0])return false}if(that.options.sortable&&target.parent().data().sortable){that.onSort(event)}});this.$header.children().children().off("keypress").on("keypress",function(event){if(that.options.sortable&&$(this).data().sortable){var code=event.keyCode||event.which;if(code==13){that.onSort(event)}}});$(window).off("resize.bootstrap-table");if(!this.options.showHeader||this.options.cardView){this.$header.hide();this.$tableHeader.hide();this.$tableLoading.css("top",0)}else{this.$header.show();this.$tableHeader.show();this.$tableLoading.css("top",this.$header.outerHeight()+1);this.getCaret();$(window).on("resize.bootstrap-table",$.proxy(this.resetWidth,this))}this.$selectAll=this.$header.find('[name="btSelectAll"]');this.$selectAll.off("click").on("click",function(){var checked=$(this).prop("checked");that[checked?"checkAll":"uncheckAll"]();that.updateSelected()})};BootstrapTable.prototype.initFooter=function(){if(!this.options.showFooter||this.options.cardView){this.$tableFooter.hide()}else{this.$tableFooter.show()}};BootstrapTable.prototype.initData=function(data,type){if(type==="append"){this.data=this.data.concat(data)}else if(type==="prepend"){this.data=[].concat(data).concat(this.data)}else{this.data=data||this.options.data}if(type==="append"){this.options.data=this.options.data.concat(data)}else if(type==="prepend"){this.options.data=[].concat(data).concat(this.options.data)}else{this.options.data=this.data}if(this.options.sidePagination==="server"){return}this.initSort()};BootstrapTable.prototype.initSort=function(){var that=this,name=this.options.sortName,order=this.options.sortOrder==="desc"?-1:1,index=$.inArray(this.options.sortName,this.header.fields),timeoutId=0;if(this.options.customSort!==$.noop){this.options.customSort.apply(this,[this.options.sortName,this.options.sortOrder]);return}if(index!==-1){if(this.options.sortStable){$.each(this.data,function(i,row){if(!row.hasOwnProperty("_position"))row._position=i})}this.data.sort(function(a,b){if(that.header.sortNames[index]){name=that.header.sortNames[index]}var aa=getItemField(a,name,that.options.escape),bb=getItemField(b,name,that.options.escape),value=calculateObjectValue(that.header,that.header.sorters[index],[aa,bb]);if(value!==undefined){return order*value}if(aa===undefined||aa===null){aa=""}if(bb===undefined||bb===null){bb=""}if(that.options.sortStable&&aa===bb){aa=a._position;bb=b._position}if($.isNumeric(aa)&&$.isNumeric(bb)){aa=parseFloat(aa);bb=parseFloat(bb);if(aa',this.options.toolbarAlign)).appendTo(this.$toolbar).append($(this.options.toolbar))}html=[sprintf('
            ',this.options.buttonsAlign,this.options.buttonsAlign)];if(typeof this.options.icons==="string"){this.options.icons=calculateObjectValue(null,this.options.icons)}if(this.options.showPaginationSwitch){html.push(sprintf('")}if(this.options.showRefresh){html.push(sprintf('")}if(this.options.showToggle){html.push(sprintf('")}if(this.options.showColumns){html.push(sprintf('
            ',this.options.formatColumns()),'",'","
            ")}html.push("
            ");if(this.showToolbar||html.length>2){this.$toolbar.append(html.join(""))}if(this.options.showPaginationSwitch){this.$toolbar.find('button[name="paginationSwitch"]').off("click").on("click",$.proxy(this.togglePagination,this))}if(this.options.showRefresh){this.$toolbar.find('button[name="refresh"]').off("click").on("click",$.proxy(this.refresh,this))}if(this.options.showToggle){this.$toolbar.find('button[name="toggle"]').off("click").on("click",function(){that.toggleView()})}if(this.options.showColumns){$keepOpen=this.$toolbar.find(".keep-open");if(switchableCount<=this.options.minimumCountColumns){$keepOpen.find("input").prop("disabled",true)}$keepOpen.find("li").off("click").on("click",function(event){event.stopImmediatePropagation()});$keepOpen.find("input").off("click").on("click",function(){var $this=$(this);that.toggleColumn($(this).val(),$this.prop("checked"),false);that.trigger("column-switch",$(this).data("field"),$this.prop("checked"))})}if(this.options.search){html=[];html.push('");this.$toolbar.append(html.join(""));$search=this.$toolbar.find(".search input");$search.off("keyup drop blur").on("keyup drop blur",function(event){if(that.options.searchOnEnterKey&&event.keyCode!==13){return}if($.inArray(event.keyCode,[37,38,39,40])>-1){return}clearTimeout(timeoutId);timeoutId=setTimeout(function(){that.onSearch(event)},that.options.searchTimeOut)});if(isIEBrowser()){$search.off("mouseup").on("mouseup",function(event){clearTimeout(timeoutId);timeoutId=setTimeout(function(){that.onSearch(event)},that.options.searchTimeOut)})}}};BootstrapTable.prototype.onSearch=function(event){var text=$.trim($(event.currentTarget).val());if(this.options.trimOnSearch&&$(event.currentTarget).val()!==text){$(event.currentTarget).val(text)}if(text===this.searchText){return}this.searchText=text;this.options.searchText=text;this.options.pageNumber=1;this.initSearch();this.updatePagination();this.trigger("search",text)};BootstrapTable.prototype.initSearch=function(){var that=this;if(this.options.sidePagination!=="server"){if(this.options.customSearch!==$.noop){this.options.customSearch.apply(this,[this.searchText]);return}var s=this.searchText&&(this.options.escape?escapeHTML(this.searchText):this.searchText).toLowerCase();var f=$.isEmptyObject(this.filterColumns)?null:this.filterColumns;this.data=f?$.grep(this.options.data,function(item,i){for(var key in f){if($.isArray(f[key])&&$.inArray(item[key],f[key])===-1||!$.isArray(f[key])&&item[key]!==f[key]){return false}}return true}):this.options.data;this.data=s?$.grep(this.data,function(item,i){for(var j=0;j-1){$allSelected=true}}this.totalPages=~~((this.options.totalRows-1)/this.options.pageSize)+1;this.options.totalPages=this.totalPages}if(this.totalPages>0&&this.options.pageNumber>this.totalPages){this.options.pageNumber=this.totalPages}this.pageFrom=(this.options.pageNumber-1)*this.options.pageSize+1;this.pageTo=this.options.pageNumber*this.options.pageSize;if(this.pageTo>this.options.totalRows){this.pageTo=this.options.totalRows}html.push('
            ','',this.options.onlyInfoPagination?this.options.formatDetailPagination(this.options.totalRows):this.options.formatShowingRows(this.pageFrom,this.pageTo,this.options.totalRows),"");if(!this.options.onlyInfoPagination){html.push('');var pageNumber=[sprintf('',this.options.paginationVAlign==="top"||this.options.paginationVAlign==="both"?"dropdown":"dropup"),'",'");html.push(this.options.formatRecordsPerPage(pageNumber.join("")));html.push("");html.push("
            ",'")}this.$pagination.html(html.join(""));if(!this.options.onlyInfoPagination){$pageList=this.$pagination.find(".page-list a");$first=this.$pagination.find(".page-first");$pre=this.$pagination.find(".page-pre");$next=this.$pagination.find(".page-next");$last=this.$pagination.find(".page-last");$number=this.$pagination.find(".page-number");if(this.options.smartDisplay){if(this.totalPages<=1){this.$pagination.find("div.pagination").hide()}if(pageList.length<2||this.options.totalRows<=pageList[0]){this.$pagination.find("span.page-list").hide()}this.$pagination[this.getData().length?"show":"hide"]()}if(!this.options.paginationLoop){if(this.options.pageNumber===1){$pre.addClass("disabled")}if(this.options.pageNumber===this.totalPages){$next.addClass("disabled")}}if($allSelected){this.options.pageSize=this.options.formatAllRows()}$pageList.off("click").on("click",$.proxy(this.onPageListChange,this));$first.off("click").on("click",$.proxy(this.onPageFirst,this));$pre.off("click").on("click",$.proxy(this.onPagePre,this));$next.off("click").on("click",$.proxy(this.onPageNext,this));$last.off("click").on("click",$.proxy(this.onPageLast,this));$number.off("click").on("click",$.proxy(this.onPageNumber,this))}};BootstrapTable.prototype.updatePagination=function(event){if(event&&$(event.currentTarget).hasClass("disabled")){return}if(!this.options.maintainSelected){this.resetRows()}this.initPagination();if(this.options.sidePagination==="server"){this.initServer()}else{this.initBody()}this.trigger("page-change",this.options.pageNumber,this.options.pageSize)};BootstrapTable.prototype.onPageListChange=function(event){var $this=$(event.currentTarget);$this.parent().addClass("active").siblings().removeClass("active");this.options.pageSize=$this.text().toUpperCase()===this.options.formatAllRows().toUpperCase()?this.options.formatAllRows():+$this.text();this.$toolbar.find(".page-size").text(this.options.pageSize);this.updatePagination(event);return false};BootstrapTable.prototype.onPageFirst=function(event){this.options.pageNumber=1;this.updatePagination(event);return false};BootstrapTable.prototype.onPagePre=function(event){if(this.options.pageNumber-1===0){this.options.pageNumber=this.options.totalPages}else{this.options.pageNumber--}this.updatePagination(event);return false};BootstrapTable.prototype.onPageNext=function(event){if(this.options.pageNumber+1>this.options.totalPages){this.options.pageNumber=1}else{this.options.pageNumber++}this.updatePagination(event);return false};BootstrapTable.prototype.onPageLast=function(event){this.options.pageNumber=this.totalPages;this.updatePagination(event);return false};BootstrapTable.prototype.onPageNumber=function(event){if(this.options.pageNumber===+$(event.currentTarget).text()){return}this.options.pageNumber=+$(event.currentTarget).text();this.updatePagination(event);return false};BootstrapTable.prototype.initRow=function(item,i,data,parentDom){var that=this,key,html=[],style={},csses=[],data_="",attributes={},htmlAttributes=[];if($.inArray(item,this.hiddenRows)>-1){return}style=calculateObjectValue(this.options,this.options.rowStyle,[item,i],style);if(style&&style.css){for(key in style.css){csses.push(key+": "+style.css[key])}}attributes=calculateObjectValue(this.options,this.options.rowAttributes,[item,i],attributes);if(attributes){for(key in attributes){htmlAttributes.push(sprintf('%s="%s"',key,escapeHTML(attributes[key])))}}if(item._data&&!$.isEmptyObject(item._data)){$.each(item._data,function(k,v){if(k==="index"){return}data_+=sprintf(' data-%s="%s"',k,v)})}html.push("");if(this.options.cardView){html.push(sprintf('
            ',this.header.fields.length))}if(!this.options.cardView&&this.options.detailView){html.push("",'',sprintf('',this.options.iconsPrefix,this.options.icons.detailOpen),"","")}$.each(this.header.fields,function(j,field){var text="",value_=getItemField(item,field,that.options.escape),value="",type="",cellStyle={},id_="",class_=that.header.classes[j],data_="",rowspan_="",colspan_="",title_="",column=that.columns[j];if(that.fromHtml&&typeof value_==="undefined"){return}if(!column.visible){return}if(that.options.cardView&&!column.cardVisible){return}if(column.escape){value_=escapeHTML(value_)}style=sprintf('style="%s"',csses.concat(that.header.styles[j]).join("; "));if(item["_"+field+"_id"]){id_=sprintf(' id="%s"',item["_"+field+"_id"])}if(item["_"+field+"_class"]){class_=sprintf(' class="%s"',item["_"+field+"_class"])}if(item["_"+field+"_rowspan"]){rowspan_=sprintf(' rowspan="%s"',item["_"+field+"_rowspan"])}if(item["_"+field+"_colspan"]){colspan_=sprintf(' colspan="%s"',item["_"+field+"_colspan"])}if(item["_"+field+"_title"]){title_=sprintf(' title="%s"',item["_"+field+"_title"])}cellStyle=calculateObjectValue(that.header,that.header.cellStyles[j],[value_,item,i,field],cellStyle);if(cellStyle.classes){class_=sprintf(' class="%s"',cellStyle.classes)}if(cellStyle.css){var csses_=[];for(var key in cellStyle.css){csses_.push(key+": "+cellStyle.css[key])}style=sprintf('style="%s"',csses_.concat(that.header.styles[j]).join("; "))}value=calculateObjectValue(column,that.header.formatters[j],[value_,item,i],value_);if(item["_"+field+"_data"]&&!$.isEmptyObject(item["_"+field+"_data"])){$.each(item["_"+field+"_data"],function(k,v){if(k==="index"){return}data_+=sprintf(' data-%s="%s"',k,v)})}if(column.checkbox||column.radio){type=column.checkbox?"checkbox":type;type=column.radio?"radio":type;text=[sprintf(that.options.cardView?'
            ':'',column["class"]||""),"",that.header.formatters[j]&&typeof value==="string"?value:"",that.options.cardView?"
            ":""].join("");item[that.header.stateField]=value===true||value&&value.checked}else{value=typeof value==="undefined"||value===null?that.options.undefinedText:value;text=that.options.cardView?['
            ',that.options.showHeader?sprintf('%s',style,getPropertyFromOther(that.columns,"field","title",field)):"",sprintf('%s',value),"
            "].join(""):[sprintf("",id_,class_,style,data_,rowspan_,colspan_,title_),value,""].join("");if(that.options.cardView&&that.options.smartDisplay&&value===""){text='
            '}}html.push(text)});if(this.options.cardView){html.push("
            ")}html.push("");return html.join(" ")};BootstrapTable.prototype.initBody=function(fixedScroll){var that=this,html=[],data=this.getData();this.trigger("pre-body",data);this.$body=this.$el.find(">tbody");if(!this.$body.length){this.$body=$("").appendTo(this.$el)}if(!this.options.pagination||this.options.sidePagination==="server"){this.pageFrom=1;this.pageTo=data.length}var trFragments=$(document.createDocumentFragment());var hasTr;for(var i=this.pageFrom-1;i'+sprintf('%s',this.$header.find("th").length,this.options.formatNoMatches())+"")}this.$body.html(trFragments);if(!fixedScroll){this.scrollTo(0)}this.$body.find("> tr[data-index] > td").off("click dblclick").on("click dblclick",function(e){var $td=$(this),$tr=$td.parent(),item=that.data[$tr.data("index")],index=$td[0].cellIndex,fields=that.getVisibleFields(),field=fields[that.options.detailView&&!that.options.cardView?index-1:index],column=that.columns[getFieldIndex(that.columns,field)],value=getItemField(item,field,that.options.escape);if($td.find(".detail-icon").length){return}that.trigger(e.type==="click"?"click-cell":"dbl-click-cell",field,value,item,$td);that.trigger(e.type==="click"?"click-row":"dbl-click-row",item,$tr,field);if(e.type==="click"&&that.options.clickToSelect&&column.clickToSelect){var $selectItem=$tr.find(sprintf('[name="%s"]',that.options.selectItemName));if($selectItem.length){$selectItem[0].click()}}});this.$body.find("> tr[data-index] > td > .detail-icon").off("click").on("click",function(){var $this=$(this),$tr=$this.parent().parent(),index=$tr.data("index"),row=data[index];if($tr.next().is("tr.detail-view")){$this.find("i").attr("class",sprintf("%s %s",that.options.iconsPrefix,that.options.icons.detailOpen));that.trigger("collapse-row",index,row);$tr.next().remove()}else{$this.find("i").attr("class",sprintf("%s %s",that.options.iconsPrefix,that.options.icons.detailClose));$tr.after(sprintf('',$tr.find("td").length));var $element=$tr.next().find("td");var content=calculateObjectValue(that.options,that.options.detailFormatter,[index,row,$element],"");if($element.length===1){$element.append(content)}that.trigger("expand-row",index,row,$element)}that.resetView();return false});this.$selectItem=this.$body.find(sprintf('[name="%s"]',this.options.selectItemName));this.$selectItem.off("click").on("click",function(event){event.stopImmediatePropagation();var $this=$(this),checked=$this.prop("checked"),row=that.data[$this.data("index")];if(that.options.maintainSelected&&$(this).is(":radio")){$.each(that.options.data,function(i,row){row[that.header.stateField]=false})}row[that.header.stateField]=checked;if(that.options.singleSelect){that.$selectItem.not(this).each(function(){that.data[$(this).data("index")][that.header.stateField]=false});that.$selectItem.filter(":checked").not(this).prop("checked",false)}that.updateSelected();that.trigger(checked?"check":"uncheck",row,$this)});$.each(this.header.events,function(i,events){if(!events){return}if(typeof events==="string"){events=calculateObjectValue(null,events)}var field=that.header.fields[i],fieldIndex=$.inArray(field,that.getVisibleFields());if(that.options.detailView&&!that.options.cardView){fieldIndex+=1}for(var key in events){that.$body.find(">tr:not(.no-records-found)").each(function(){var $tr=$(this),$td=$tr.find(that.options.cardView?".card-view":"td").eq(fieldIndex),index=key.indexOf(" "),name=key.substring(0,index),el=key.substring(index+1),func=events[key];$td.find(el).off(name).on(name,function(e){var index=$tr.data("index"),row=that.data[index],value=row[field];var props=field.split(".");if(props.length>1){value=row;for(var prop_index=0;prop_indexfixedBody.clientWidth&&fixedBody.scrollHeight>fixedBody.clientHeight+this.$header.outerHeight()?getScrollBarWidth():0;this.$el.css("margin-top",-this.$header.outerHeight());focused=$(":focus");if(focused.length>0){var $th=focused.parents("th");if($th.length>0){var dataField=$th.attr("data-field");if(dataField!==undefined){var $headerTh=this.$header.find("[data-field='"+dataField+"']");if($headerTh.length>0){$headerTh.find(":input").addClass("focus-temp")}}}}this.$header_=this.$header.clone(true,true);this.$selectAll_=this.$header_.find('[name="btSelectAll"]');this.$tableHeader.css({"margin-right":scrollWidth}).find("table").css("width",this.$el.outerWidth()).html("").attr("class",this.$el.attr("class")).append(this.$header_);focusedTemp=$(".focus-temp:visible:eq(0)");if(focusedTemp.length>0){focusedTemp.focus();this.$header.find(".focus-temp").removeClass("focus-temp")}this.$header.find("th[data-field]").each(function(i){that.$header_.find(sprintf('th[data-field="%s"]',$(this).data("field"))).data($(this).data())});var visibleFields=this.getVisibleFields(),$ths=this.$header_.find("th");this.$body.find(">tr:first-child:not(.no-records-found) > *").each(function(i){var $this=$(this),index=i;if(that.options.detailView&&!that.options.cardView){if(i===0){that.$header_.find("th.detail").find(".fht-cell").width($this.innerWidth())}index=i-1}var $th=that.$header_.find(sprintf('th[data-field="%s"]',visibleFields[index]));if($th.length>1){$th=$($ths[$this[0].cellIndex])}$th.find(".fht-cell").width($this.innerWidth())});this.$tableBody.off("scroll").on("scroll",function(){that.$tableHeader.scrollLeft($(this).scrollLeft());if(that.options.showFooter&&!that.options.cardView){that.$tableFooter.scrollLeft($(this).scrollLeft())}});that.trigger("post-header")};BootstrapTable.prototype.resetFooter=function(){var that=this,data=that.getData(),html=[];if(!this.options.showFooter||this.options.cardView){return}if(!this.options.cardView&&this.options.detailView){html.push('
             
            ')}$.each(this.columns,function(i,column){var key,falign="",valign="",csses=[],style={},class_=sprintf(' class="%s"',column["class"]);if(!column.visible){return}if(that.options.cardView&&!column.cardVisible){return}falign=sprintf("text-align: %s; ",column.falign?column.falign:column.align);valign=sprintf("vertical-align: %s; ",column.valign);style=calculateObjectValue(null,that.options.footerStyle);if(style&&style.css){for(key in style.css){csses.push(key+": "+style.css[key])}}html.push("");html.push('
            ');html.push(calculateObjectValue(column,column.footerFormatter,[data]," ")||" ");html.push("
            ");html.push('
            ');html.push("");html.push("")});this.$tableFooter.find("tr").html(html.join(""));this.$tableFooter.show();clearTimeout(this.timeoutFooter_);this.timeoutFooter_=setTimeout($.proxy(this.fitFooter,this),this.$el.is(":hidden")?100:0)};BootstrapTable.prototype.fitFooter=function(){var that=this,$footerTd,elWidth,scrollWidth;clearTimeout(this.timeoutFooter_);if(this.$el.is(":hidden")){this.timeoutFooter_=setTimeout($.proxy(this.fitFooter,this),100);return}elWidth=this.$el.css("width");scrollWidth=elWidth>this.$tableBody.width()?getScrollBarWidth():0;this.$tableFooter.css({"margin-right":scrollWidth}).find("table").css("width",elWidth).attr("class",this.$el.attr("class"));$footerTd=this.$tableFooter.find("td");this.$body.find(">tr:first-child:not(.no-records-found) > *").each(function(i){var $this=$(this);$footerTd.eq(i).find(".fht-cell").width($this.innerWidth())})};BootstrapTable.prototype.toggleColumn=function(index,checked,needUpdate){if(index===-1){return}this.columns[index].visible=checked;this.initHeader();this.initSearch();this.initPagination();this.initBody();if(this.options.showColumns){var $items=this.$toolbar.find(".keep-open input").prop("disabled",false);if(needUpdate){$items.filter(sprintf('[value="%s"]',index)).prop("checked",checked)}if($items.filter(":checked").length<=this.options.minimumCountColumns){$items.filter(":checked").prop("disabled",true)}}};BootstrapTable.prototype.getVisibleFields=function(){var that=this,visibleFields=[];$.each(this.header.fields,function(j,field){var column=that.columns[getFieldIndex(that.columns,field)];if(!column.visible){return}visibleFields.push(field)});return visibleFields};BootstrapTable.prototype.resetView=function(params){var padding=0;if(params&¶ms.height){this.options.height=params.height}this.$selectAll.prop("checked",this.$selectItem.length>0&&this.$selectItem.length===this.$selectItem.filter(":checked").length);if(this.options.height){var toolbarHeight=this.$toolbar.outerHeight(true),paginationHeight=this.$pagination.outerHeight(true),height=this.options.height-toolbarHeight-paginationHeight;this.$tableContainer.css("height",height+"px")}if(this.options.cardView){this.$el.css("margin-top","0");this.$tableContainer.css("padding-bottom","0");this.$tableFooter.hide();return}if(this.options.showHeader&&this.options.height){this.$tableHeader.show();this.resetHeader();padding+=this.$header.outerHeight()}else{this.$tableHeader.hide();this.trigger("post-header")}if(this.options.showFooter){this.resetFooter();if(this.options.height){padding+=this.$tableFooter.outerHeight()+1}}this.getCaret();this.$tableContainer.css("padding-bottom",padding+"px");this.trigger("reset-view")};BootstrapTable.prototype.getData=function(useCurrentPage){return this.searchText||!$.isEmptyObject(this.filterColumns)||!$.isEmptyObject(this.filterColumnsPartial)?useCurrentPage?this.data.slice(this.pageFrom-1,this.pageTo):this.data:useCurrentPage?this.options.data.slice(this.pageFrom-1,this.pageTo):this.options.data};BootstrapTable.prototype.load=function(data){var fixedScroll=false;if(this.options.sidePagination==="server"){this.options.totalRows=data[this.options.totalField];fixedScroll=data.fixedScroll;data=data[this.options.dataField]}else if(!$.isArray(data)){fixedScroll=data.fixedScroll;data=data.data}this.initData(data);this.initSearch();this.initPagination();this.initBody(fixedScroll)};BootstrapTable.prototype.append=function(data){this.initData(data,"append");this.initSearch();this.initPagination();this.initSort();this.initBody(true)};BootstrapTable.prototype.prepend=function(data){this.initData(data,"prepend");this.initSearch();this.initPagination();this.initSort();this.initBody(true)};BootstrapTable.prototype.remove=function(params){var len=this.options.data.length,i,row;if(!params.hasOwnProperty("field")||!params.hasOwnProperty("values")){return}for(i=len-1;i>=0;i--){row=this.options.data[i];if(!row.hasOwnProperty(params.field)){continue}if($.inArray(row[params.field],params.values)!==-1){this.options.data.splice(i,1);if(this.options.sidePagination==="server"){this.options.totalRows-=1}}}if(len===this.options.data.length){return}this.initSearch();this.initPagination();this.initSort();this.initBody(true)};BootstrapTable.prototype.removeAll=function(){if(this.options.data.length>0){this.options.data.splice(0,this.options.data.length);this.initSearch();this.initPagination();this.initBody(true)}};BootstrapTable.prototype.getRowByUniqueId=function(id){var uniqueId=this.options.uniqueId,len=this.options.data.length,dataRow=null,i,row,rowUniqueId;for(i=len-1;i>=0;i--){row=this.options.data[i];if(row.hasOwnProperty(uniqueId)){rowUniqueId=row[uniqueId]}else if(row._data.hasOwnProperty(uniqueId)){rowUniqueId=row._data[uniqueId]}else{continue}if(typeof rowUniqueId==="string"){id=id.toString()}else if(typeof rowUniqueId==="number"){if(Number(rowUniqueId)===rowUniqueId&&rowUniqueId%1===0){id=parseInt(id)}else if(rowUniqueId===Number(rowUniqueId)&&rowUniqueId!==0){id=parseFloat(id)}}if(rowUniqueId===id){dataRow=row;break}}return dataRow};BootstrapTable.prototype.removeByUniqueId=function(id){var len=this.options.data.length,row=this.getRowByUniqueId(id);if(row){this.options.data.splice(this.options.data.indexOf(row),1)}if(len===this.options.data.length){return}this.initSearch();this.initPagination();this.initBody(true)};BootstrapTable.prototype.updateByUniqueId=function(params){var that=this;var allParams=$.isArray(params)?params:[params];$.each(allParams,function(i,params){var rowId;if(!params.hasOwnProperty("id")||!params.hasOwnProperty("row")){return}rowId=$.inArray(that.getRowByUniqueId(params.id),that.options.data);if(rowId===-1){return}$.extend(that.options.data[rowId],params.row)});this.initSearch();this.initPagination();this.initSort();this.initBody(true)};BootstrapTable.prototype.insertRow=function(params){if(!params.hasOwnProperty("index")||!params.hasOwnProperty("row")){return}this.data.splice(params.index,0,params.row);this.initSearch();this.initPagination();this.initSort();this.initBody(true)};BootstrapTable.prototype.updateRow=function(params){var that=this;var allParams=$.isArray(params)?params:[params];$.each(allParams,function(i,params){if(!params.hasOwnProperty("index")||!params.hasOwnProperty("row")){return}$.extend(that.options.data[params.index],params.row)});this.initSearch();this.initPagination();this.initSort();this.initBody(true)};BootstrapTable.prototype.initHiddenRows=function(){this.hiddenRows=[]};BootstrapTable.prototype.showRow=function(params){this.toggleRow(params,true)};BootstrapTable.prototype.hideRow=function(params){this.toggleRow(params,false)};BootstrapTable.prototype.toggleRow=function(params,visible){var row,index;if(params.hasOwnProperty("index")){row=this.getData()[params.index]}else if(params.hasOwnProperty("uniqueId")){row=this.getRowByUniqueId(params.uniqueId)}if(!row){return}index=$.inArray(row,this.hiddenRows);if(!visible&&index===-1){this.hiddenRows.push(row)}else if(visible&&index>-1){this.hiddenRows.splice(index,1)}this.initBody(true)};BootstrapTable.prototype.getHiddenRows=function(show){var that=this,data=this.getData(),rows=[];$.each(data,function(i,row){if($.inArray(row,that.hiddenRows)>-1){rows.push(row)}});this.hiddenRows=rows;return rows};BootstrapTable.prototype.mergeCells=function(options){var row=options.index,col=$.inArray(options.field,this.getVisibleFields()),rowspan=options.rowspan||1,colspan=options.colspan||1,i,j,$tr=this.$body.find(">tr"),$td;if(this.options.detailView&&!this.options.cardView){col+=1}$td=$tr.eq(row).find(">td").eq(col);if(row<0||col<0||row>=this.data.length){return}for(i=row;itd").eq(j).hide()}}$td.attr("rowspan",rowspan).attr("colspan",colspan).show()};BootstrapTable.prototype.updateCell=function(params){if(!params.hasOwnProperty("index")||!params.hasOwnProperty("field")||!params.hasOwnProperty("value")){return}this.data[params.index][params.field]=params.value;if(params.reinit===false){return}this.initSort();this.initBody(true)};BootstrapTable.prototype.getOptions=function(){return this.options};BootstrapTable.prototype.getSelections=function(){var that=this;return $.grep(this.options.data,function(row){return row[that.header.stateField]===true})};BootstrapTable.prototype.getAllSelections=function(){var that=this;return $.grep(this.options.data,function(row){return row[that.header.stateField]})};BootstrapTable.prototype.checkAll=function(){this.checkAll_(true)};BootstrapTable.prototype.uncheckAll=function(){this.checkAll_(false)};BootstrapTable.prototype.checkInvert=function(){var that=this;var rows=that.$selectItem.filter(":enabled");var checked=rows.filter(":checked");rows.each(function(){$(this).prop("checked",!$(this).prop("checked"))});that.updateRows();that.updateSelected();that.trigger("uncheck-some",checked);checked=that.getSelections();that.trigger("check-some",checked)};BootstrapTable.prototype.checkAll_=function(checked){var rows;if(!checked){rows=this.getSelections()}this.$selectAll.add(this.$selectAll_).prop("checked",checked);this.$selectItem.filter(":enabled").prop("checked",checked);this.updateRows();if(checked){rows=this.getSelections()}this.trigger(checked?"check-all":"uncheck-all",rows)};BootstrapTable.prototype.check=function(index){this.check_(true,index)};BootstrapTable.prototype.uncheck=function(index){this.check_(false,index)};BootstrapTable.prototype.check_=function(checked,index){var $el=this.$selectItem.filter(sprintf('[data-index="%s"]',index)).prop("checked",checked);this.data[index][this.header.stateField]=checked;this.updateSelected();this.trigger(checked?"check":"uncheck",this.data[index],$el)};BootstrapTable.prototype.checkBy=function(obj){this.checkBy_(true,obj)};BootstrapTable.prototype.uncheckBy=function(obj){this.checkBy_(false,obj)};BootstrapTable.prototype.checkBy_=function(checked,obj){if(!obj.hasOwnProperty("field")||!obj.hasOwnProperty("values")){return}var that=this,rows=[];$.each(this.options.data,function(index,row){if(!row.hasOwnProperty(obj.field)){return false}if($.inArray(row[obj.field],obj.values)!==-1){var $el=that.$selectItem.filter(":enabled").filter(sprintf('[data-index="%s"]',index)).prop("checked",checked);row[that.header.stateField]=checked;rows.push(row);that.trigger(checked?"check":"uncheck",row,$el)}});this.updateSelected();this.trigger(checked?"check-some":"uncheck-some",rows)};BootstrapTable.prototype.destroy=function(){this.$el.insertBefore(this.$container);$(this.options.toolbar).insertBefore(this.$el);this.$container.next().remove();this.$container.remove();this.$el.html(this.$el_.html()).css("margin-top","0").attr("class",this.$el_.attr("class")||"")};BootstrapTable.prototype.showLoading=function(){this.$tableLoading.show()};BootstrapTable.prototype.hideLoading=function(){this.$tableLoading.hide()};BootstrapTable.prototype.togglePagination=function(){this.options.pagination=!this.options.pagination;var button=this.$toolbar.find('button[name="paginationSwitch"] i');if(this.options.pagination){button.attr("class",this.options.iconsPrefix+" "+this.options.icons.paginationSwitchDown)}else{button.attr("class",this.options.iconsPrefix+" "+this.options.icons.paginationSwitchUp)}this.updatePagination()};BootstrapTable.prototype.refresh=function(params){if(params&¶ms.url){this.options.url=params.url}if(params&¶ms.pageNumber){this.options.pageNumber=params.pageNumber}if(params&¶ms.pageSize){this.options.pageSize=params.pageSize}this.initServer(params&¶ms.silent,params&¶ms.query,params&¶ms.url);this.trigger("refresh",params)};BootstrapTable.prototype.resetWidth=function(){if(this.options.showHeader&&this.options.height){this.fitHeader()}if(this.options.showFooter){this.fitFooter()}};BootstrapTable.prototype.showColumn=function(field){this.toggleColumn(getFieldIndex(this.columns,field),true,true)};BootstrapTable.prototype.hideColumn=function(field){this.toggleColumn(getFieldIndex(this.columns,field),false,true)};BootstrapTable.prototype.getHiddenColumns=function(){return $.grep(this.columns,function(column){return!column.visible})};BootstrapTable.prototype.getVisibleColumns=function(){return $.grep(this.columns,function(column){return column.visible})};BootstrapTable.prototype.toggleAllColumns=function(visible){$.each(this.columns,function(i,column){this.columns[i].visible=visible});this.initHeader();this.initSearch();this.initPagination();this.initBody();if(this.options.showColumns){var $items=this.$toolbar.find(".keep-open input").prop("disabled",false);if($items.filter(":checked").length<=this.options.minimumCountColumns){$items.filter(":checked").prop("disabled",true)}}};BootstrapTable.prototype.showAllColumns=function(){this.toggleAllColumns(true)};BootstrapTable.prototype.hideAllColumns=function(){this.toggleAllColumns(false)};BootstrapTable.prototype.filterBy=function(columns){this.filterColumns=$.isEmptyObject(columns)?{}:columns;this.options.pageNumber=1;this.initSearch();this.updatePagination()};BootstrapTable.prototype.scrollTo=function(value){if(typeof value==="string"){value=value==="bottom"?this.$tableBody[0].scrollHeight:0}if(typeof value==="number"){this.$tableBody.scrollTop(value)}if(typeof value==="undefined"){return this.$tableBody.scrollTop()}};BootstrapTable.prototype.getScrollPosition=function(){return this.scrollTo()};BootstrapTable.prototype.selectPage=function(page){if(page>0&&page<=this.options.totalPages){this.options.pageNumber=page;this.updatePagination()}};BootstrapTable.prototype.prevPage=function(){if(this.options.pageNumber>1){this.options.pageNumber--;this.updatePagination()}};BootstrapTable.prototype.nextPage=function(){if(this.options.pageNumber tr[data-index="%s"]',index));if($tr.next().is("tr.detail-view")===(expand?false:true)){$tr.find("> td > .detail-icon").click()}};BootstrapTable.prototype.expandRow=function(index){this.expandRow_(true,index)};BootstrapTable.prototype.collapseRow=function(index){this.expandRow_(false,index)};BootstrapTable.prototype.expandAllRows=function(isSubTable){if(isSubTable){var $tr=this.$body.find(sprintf('> tr[data-index="%s"]',0)),that=this,detailIcon=null,executeInterval=false,idInterval=-1;if(!$tr.next().is("tr.detail-view")){$tr.find("> td > .detail-icon").click();executeInterval=true}else if(!$tr.next().next().is("tr.detail-view")){$tr.next().find(".detail-icon").click();executeInterval=true}if(executeInterval){try{idInterval=setInterval(function(){detailIcon=that.$body.find("tr.detail-view").last().find(".detail-icon");if(detailIcon.length>0){detailIcon.click()}else{clearInterval(idInterval)}},1)}catch(ex){clearInterval(idInterval)}}}else{var trs=this.$body.children();for(var i=0;i.btn-group'); + var $btnAutoRefresh = $btnGroup.find('.auto-refresh'); + + if (!$btnAutoRefresh.length) { + $btnAutoRefresh = $([ + sprintf('' + ].join('')).appendTo($btnGroup); + + $btnAutoRefresh.on('click', $.proxy(this.toggleAutoRefresh, this)); + } + } + }; + + BootstrapTable.prototype.toggleAutoRefresh = function() { + if (this.options.autoRefresh) { + if (this.options.autoRefreshStatus) { + clearInterval(this.options.autoRefreshFunction); + this.$toolbar.find('>.btn-group').find('.auto-refresh').removeClass('enabled'); + } else { + var that = this; + this.options.autoRefreshFunction = setInterval(function () { + that.refresh({silent: that.options.autoRefreshSilent}); + }, this.options.autoRefreshInterval*1000); + this.$toolbar.find('>.btn-group').find('.auto-refresh').addClass('enabled'); + } + this.options.autoRefreshStatus = !this.options.autoRefreshStatus; + } + }; + +})(jQuery); diff --git a/public/assets/libs/bootstrap-table/dist/extensions/auto-refresh/bootstrap-table-auto-refresh.min.js b/public/assets/libs/bootstrap-table/dist/extensions/auto-refresh/bootstrap-table-auto-refresh.min.js new file mode 100644 index 0000000000000000000000000000000000000000..bb7f5952c3b54e9d3cc29b4c9a1c707bba31c45f --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/extensions/auto-refresh/bootstrap-table-auto-refresh.min.js @@ -0,0 +1,7 @@ +/* +* bootstrap-table - v1.11.1 - 2017-02-22 +* https://github.com/wenzhixin/bootstrap-table +* Copyright (c) 2017 zhixin wen +* Licensed MIT License +*/ +!function(a){"use strict";a.extend(a.fn.bootstrapTable.defaults,{autoRefresh:!1,autoRefreshInterval:60,autoRefreshSilent:!0,autoRefreshStatus:!0,autoRefreshFunction:null}),a.extend(a.fn.bootstrapTable.defaults.icons,{autoRefresh:"glyphicon-time icon-time"}),a.extend(a.fn.bootstrapTable.locales,{formatAutoRefresh:function(){return"Auto Refresh"}}),a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales);var b=a.fn.bootstrapTable.Constructor,c=b.prototype.init,d=b.prototype.initToolbar,e=a.fn.bootstrapTable.utils.sprintf;b.prototype.init=function(){if(c.apply(this,Array.prototype.slice.apply(arguments)),this.options.autoRefresh&&this.options.autoRefreshStatus){var a=this;this.options.autoRefreshFunction=setInterval(function(){a.refresh({silent:a.options.autoRefreshSilent})},1e3*this.options.autoRefreshInterval)}},b.prototype.initToolbar=function(){if(d.apply(this,Array.prototype.slice.apply(arguments)),this.options.autoRefresh){var b=this.$toolbar.find(">.btn-group"),c=b.find(".auto-refresh");c.length||(c=a([e('"].join("")).appendTo(b),c.on("click",a.proxy(this.toggleAutoRefresh,this)))}},b.prototype.toggleAutoRefresh=function(){if(this.options.autoRefresh){if(this.options.autoRefreshStatus)clearInterval(this.options.autoRefreshFunction),this.$toolbar.find(">.btn-group").find(".auto-refresh").removeClass("enabled");else{var a=this;this.options.autoRefreshFunction=setInterval(function(){a.refresh({silent:a.options.autoRefreshSilent})},1e3*this.options.autoRefreshInterval),this.$toolbar.find(">.btn-group").find(".auto-refresh").addClass("enabled")}this.options.autoRefreshStatus=!this.options.autoRefreshStatus}}}(jQuery); \ No newline at end of file diff --git a/public/assets/libs/bootstrap-table/dist/extensions/click-edit-row/bootstrap-table-click-edit-row.css b/public/assets/libs/bootstrap-table/dist/extensions/click-edit-row/bootstrap-table-click-edit-row.css new file mode 100644 index 0000000000000000000000000000000000000000..85c36455bd421abab46faa667221822bd1936fee --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/extensions/click-edit-row/bootstrap-table-click-edit-row.css @@ -0,0 +1,21 @@ +#tooling{ + float: right; +} +.clear{ + display: block; + width: 13px; + height: 13px; + position: absolute; + opacity: 0.6; + z-index: 100; + top: 50%; + right: 26px; + margin-top: -10px; + cursor: pointer; +} +.clear > i{ + font-size: 1.5em; +} +.clear > i:hover{ + color: hsl(0, 0%, 75%); +} \ No newline at end of file diff --git a/public/assets/libs/bootstrap-table/dist/extensions/click-edit-row/bootstrap-table-click-edit-row.js b/public/assets/libs/bootstrap-table/dist/extensions/click-edit-row/bootstrap-table-click-edit-row.js new file mode 100644 index 0000000000000000000000000000000000000000..3af4e5c186e2baa474cce713c7117324449614dd --- /dev/null +++ b/public/assets/libs/bootstrap-table/dist/extensions/click-edit-row/bootstrap-table-click-edit-row.js @@ -0,0 +1,142 @@ +/** + * @author horken wong + * @version: v1.0.0 + * https://github.com/horkenw/bootstrap-table + * Click to edit row for bootstrap-table + */ + +(function ($) { + 'use strict'; + + $.extend($.fn.bootstrapTable.defaults, { + clickEdit: false + }); + + function setDivision(node, options){ + var $option = $('