From 422f9d8d6a5146999b248320640df130d52937c9 Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Sun, 3 Mar 2019 20:26:25 +0800 Subject: [PATCH] Feat:initial test --- application/config.php | 2 +- application/index/controller/File.php | 2 +- application/index/view/home/home.html | 127 +- application/index/view/home/home1.html | 100 + composer.lock | 981 ++ static/js/uploader/i18n/zh_CN.js | 2 + static/js/uploader/main.js | 274 + static/js/uploader/moxie.js | 11509 ++++++++++++++++ static/js/uploader/plupload.dev.js | 2476 ++++ static/js/uploader/qiniu.js | 1831 +++ static/js/uploader/ui.js | 278 + thinkphp/.gitignore | 4 + thinkphp/CONTRIBUTING.md | 4 +- thinkphp/LICENSE.txt | 2 +- thinkphp/README.md | 114 + thinkphp/base.php | 6 +- thinkphp/convention.php | 15 +- thinkphp/helper.php | 4 +- thinkphp/lang/zh-cn.php | 172 +- thinkphp/library/think/App.php | 451 +- thinkphp/library/think/Build.php | 167 +- thinkphp/library/think/Cache.php | 111 +- thinkphp/library/think/Collection.php | 330 +- thinkphp/library/think/Config.php | 160 +- thinkphp/library/think/Console.php | 388 +- thinkphp/library/think/Controller.php | 105 +- thinkphp/library/think/Cookie.php | 164 +- thinkphp/library/think/Db.php | 81 +- thinkphp/library/think/Debug.php | 128 +- thinkphp/library/think/Env.php | 13 +- thinkphp/library/think/Error.php | 75 +- thinkphp/library/think/Exception.php | 21 +- thinkphp/library/think/File.php | 246 +- thinkphp/library/think/Hook.php | 62 +- thinkphp/library/think/Lang.php | 127 +- thinkphp/library/think/Loader.php | 501 +- thinkphp/library/think/Log.php | 180 +- thinkphp/library/think/Model.php | 353 +- thinkphp/library/think/Paginator.php | 58 +- thinkphp/library/think/Request.php | 242 +- thinkphp/library/think/Response.php | 11 +- thinkphp/library/think/Route.php | 342 +- thinkphp/library/think/Session.php | 7 +- thinkphp/library/think/Template.php | 60 +- thinkphp/library/think/Url.php | 27 +- thinkphp/library/think/Validate.php | 300 +- thinkphp/library/think/View.php | 23 +- thinkphp/library/think/cache/Driver.php | 42 +- thinkphp/library/think/cache/driver/File.php | 64 +- thinkphp/library/think/cache/driver/Lite.php | 22 +- .../library/think/cache/driver/Memcache.php | 13 +- .../library/think/cache/driver/Memcached.php | 11 +- thinkphp/library/think/cache/driver/Redis.php | 50 +- .../library/think/cache/driver/Sqlite.php | 16 +- .../library/think/cache/driver/Wincache.php | 11 +- .../library/think/cache/driver/Xcache.php | 11 +- thinkphp/library/think/config/driver/Ini.php | 2 +- thinkphp/library/think/config/driver/Json.php | 2 +- thinkphp/library/think/config/driver/Xml.php | 2 +- .../library/think/console/command/Clear.php | 13 +- .../think/console/command/optimize/Config.php | 2 +- .../think/console/command/optimize/Route.php | 5 + .../think/console/command/optimize/Schema.php | 6 +- .../think/console/output/Descriptor.php | 10 +- thinkphp/library/think/controller/Rest.php | 6 +- thinkphp/library/think/db/Builder.php | 177 +- thinkphp/library/think/db/Connection.php | 113 +- thinkphp/library/think/db/Expression.php | 48 + thinkphp/library/think/db/Query.php | 580 +- thinkphp/library/think/db/builder/Mysql.php | 81 +- thinkphp/library/think/db/builder/Pgsql.php | 14 +- thinkphp/library/think/db/builder/Sqlite.php | 13 +- thinkphp/library/think/db/builder/Sqlsrv.php | 50 +- thinkphp/library/think/db/connector/Mysql.php | 15 +- thinkphp/library/think/db/connector/Pgsql.php | 2 +- .../library/think/db/connector/Sqlite.php | 2 +- .../library/think/db/connector/Sqlsrv.php | 5 +- .../think/db/exception/BindParamException.php | 2 +- .../db/exception/DataNotFoundException.php | 2 +- .../db/exception/ModelNotFoundException.php | 2 +- thinkphp/library/think/debug/Console.php | 2 +- thinkphp/library/think/debug/Html.php | 2 +- .../library/think/exception/DbException.php | 3 +- .../think/exception/ErrorException.php | 2 +- thinkphp/library/think/exception/Handle.php | 18 +- .../library/think/exception/PDOException.php | 2 +- .../exception/RouteNotFoundException.php | 2 +- thinkphp/library/think/log/driver/File.php | 243 +- thinkphp/library/think/log/driver/Socket.php | 2 +- thinkphp/library/think/model/Collection.php | 18 +- thinkphp/library/think/model/Merge.php | 2 +- thinkphp/library/think/model/Pivot.php | 8 +- thinkphp/library/think/model/Relation.php | 35 +- .../think/model/relation/BelongsTo.php | 54 +- .../think/model/relation/BelongsToMany.php | 104 +- .../library/think/model/relation/HasMany.php | 77 +- .../think/model/relation/HasManyThrough.php | 25 +- .../library/think/model/relation/HasOne.php | 78 +- .../think/model/relation/MorphMany.php | 47 +- .../library/think/model/relation/MorphOne.php | 44 +- .../library/think/model/relation/MorphTo.php | 42 +- .../library/think/model/relation/OneToOne.php | 42 +- .../think/paginator/driver/Bootstrap.php | 2 +- thinkphp/library/think/response/Json.php | 2 +- thinkphp/library/think/response/Jsonp.php | 2 +- thinkphp/library/think/response/Redirect.php | 8 +- thinkphp/library/think/response/View.php | 2 +- thinkphp/library/think/response/Xml.php | 9 +- .../library/think/session/driver/Memcache.php | 2 +- .../think/session/driver/Memcached.php | 2 +- .../library/think/session/driver/Redis.php | 2 +- thinkphp/library/think/template/TagLib.php | 6 +- .../library/think/template/driver/File.php | 7 +- thinkphp/library/think/template/taglib/Cx.php | 2 +- thinkphp/library/think/view/driver/Php.php | 32 +- thinkphp/library/think/view/driver/Think.php | 6 +- thinkphp/library/traits/controller/Jump.php | 110 +- thinkphp/library/traits/model/SoftDelete.php | 101 +- thinkphp/library/traits/think/Instance.php | 35 +- thinkphp/start.php | 7 +- thinkphp/tests/.gitignore | 4 - thinkphp/tests/README.md | 132 - thinkphp/tests/application/config.php | 33 - thinkphp/tests/application/database.php | 44 - .../application/index/controller/Index.php | 10 - thinkphp/tests/application/route.php | 22 - thinkphp/tests/conf/apcu.ini | 3 - thinkphp/tests/conf/apcu_bc.ini | 4 - thinkphp/tests/conf/memcached.ini | 1 - thinkphp/tests/conf/redis.ini | 1 - thinkphp/tests/conf/timezone.ini | 1 - thinkphp/tests/extensions/5.4/apcu.so | Bin 404136 -> 0 bytes thinkphp/tests/extensions/5.5/apcu.so | Bin 402984 -> 0 bytes thinkphp/tests/extensions/5.6/apcu.so | Bin 404405 -> 0 bytes thinkphp/tests/extensions/7.0/apc.so | Bin 43511 -> 0 bytes thinkphp/tests/extensions/7.0/apcu.so | Bin 320965 -> 0 bytes thinkphp/tests/extensions/7.0/memcached.so | Bin 323764 -> 0 bytes thinkphp/tests/extensions/7.0/redis.so | Bin 1541380 -> 0 bytes thinkphp/tests/mock.php | 20 - thinkphp/tests/script/install.sh | 18 - thinkphp/tests/thinkphp/baseTest.php | 39 - .../tests/thinkphp/library/think/appTest.php | 90 - .../thinkphp/library/think/behavior/One.php | 15 - .../thinkphp/library/think/behavior/Three.php | 9 - .../thinkphp/library/think/behavior/Two.php | 9 - .../thinkphp/library/think/buildTest.php | 73 - .../think/cache/driver/cacheTestCase.php | 207 - .../library/think/cache/driver/fileTest.php | 46 - .../library/think/cache/driver/liteTest.php | 69 - .../think/cache/driver/memcacheTest.php | 49 - .../think/cache/driver/memcachedTest.php | 72 - .../library/think/cache/driver/redisTest.php | 66 - .../think/config/driver/fixtures/config.ini | 1 - .../think/config/driver/fixtures/config.json | 1 - .../think/config/driver/fixtures/config.xml | 6 - .../library/think/config/driver/iniTest.php | 33 - .../library/think/config/driver/jsonTest.php | 33 - .../library/think/config/driver/xmlTest.php | 33 - .../thinkphp/library/think/configTest.php | 169 - .../library/think/controller/.gitignore | 2 - .../thinkphp/library/think/controllerTest.php | 194 - .../thinkphp/library/think/cookieTest.php | 150 - .../library/think/db/driver/.gitignore | 2 - .../tests/thinkphp/library/think/dbTest.php | 352 - .../thinkphp/library/think/debugTest.php | 179 - .../tests/thinkphp/library/think/display.html | 1 - .../thinkphp/library/think/exceptionTest.php | 52 - .../tests/thinkphp/library/think/extend.html | 2 - .../tests/thinkphp/library/think/extend2.html | 17 - .../tests/thinkphp/library/think/hookTest.php | 67 - .../tests/thinkphp/library/think/include.html | 2 - .../thinkphp/library/think/include2.html | 1 - .../thinkphp/library/think/lang/lang.php | 4 - .../tests/thinkphp/library/think/langTest.php | 76 - .../tests/thinkphp/library/think/layout.html | 2 - .../tests/thinkphp/library/think/layout2.html | 2 - .../library/think/loader/test/Hello.php | 7 - .../thinkphp/library/think/loaderTest.php | 71 - .../library/think/log/driver/fileTest.php | 34 - .../tests/thinkphp/library/think/logTest.php | 39 - .../thinkphp/library/think/model/.gitignore | 2 - .../thinkphp/library/think/paginateTest.php | 40 - .../thinkphp/library/think/requestTest.php | 187 - .../thinkphp/library/think/responseTest.php | 95 - .../thinkphp/library/think/routeTest.php | 287 - .../thinkphp/library/think/session/.gitignore | 2 - .../thinkphp/library/think/sessionTest.php | 319 - .../library/think/template/driver/.gitignore | 2 - .../library/think/template/taglib/cxTest.php | 575 - .../thinkphp/library/think/templateTest.php | 414 - .../tests/thinkphp/library/think/urlTest.php | 127 - .../thinkphp/library/think/validateTest.php | 200 - .../library/think/view/driver/.gitignore | 2 - .../think/view/theme/index/template.html | 14 - .../tests/thinkphp/library/think/viewTest.php | 76 - .../library/traits/controller/.gitignore | 2 - .../thinkphp/library/traits/model/.gitignore | 2 - thinkphp/tpl/dispatch_jump.tpl | 1 + thinkphp/tpl/think_exception.tpl | 10 +- 199 files changed, 22557 insertions(+), 7588 deletions(-) create mode 100644 application/index/view/home/home1.html create mode 100644 composer.lock create mode 100644 static/js/uploader/i18n/zh_CN.js create mode 100644 static/js/uploader/main.js create mode 100644 static/js/uploader/moxie.js create mode 100644 static/js/uploader/plupload.dev.js create mode 100644 static/js/uploader/qiniu.js create mode 100644 static/js/uploader/ui.js create mode 100644 thinkphp/.gitignore create mode 100644 thinkphp/README.md create mode 100644 thinkphp/library/think/db/Expression.php delete mode 100644 thinkphp/tests/.gitignore delete mode 100644 thinkphp/tests/README.md delete mode 100644 thinkphp/tests/application/config.php delete mode 100644 thinkphp/tests/application/database.php delete mode 100644 thinkphp/tests/application/index/controller/Index.php delete mode 100644 thinkphp/tests/application/route.php delete mode 100644 thinkphp/tests/conf/apcu.ini delete mode 100644 thinkphp/tests/conf/apcu_bc.ini delete mode 100644 thinkphp/tests/conf/memcached.ini delete mode 100644 thinkphp/tests/conf/redis.ini delete mode 100644 thinkphp/tests/conf/timezone.ini delete mode 100644 thinkphp/tests/extensions/5.4/apcu.so delete mode 100644 thinkphp/tests/extensions/5.5/apcu.so delete mode 100644 thinkphp/tests/extensions/5.6/apcu.so delete mode 100644 thinkphp/tests/extensions/7.0/apc.so delete mode 100644 thinkphp/tests/extensions/7.0/apcu.so delete mode 100644 thinkphp/tests/extensions/7.0/memcached.so delete mode 100644 thinkphp/tests/extensions/7.0/redis.so delete mode 100644 thinkphp/tests/mock.php delete mode 100644 thinkphp/tests/script/install.sh delete mode 100644 thinkphp/tests/thinkphp/baseTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/appTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/behavior/One.php delete mode 100644 thinkphp/tests/thinkphp/library/think/behavior/Three.php delete mode 100644 thinkphp/tests/thinkphp/library/think/behavior/Two.php delete mode 100644 thinkphp/tests/thinkphp/library/think/buildTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/cache/driver/cacheTestCase.php delete mode 100644 thinkphp/tests/thinkphp/library/think/cache/driver/fileTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/cache/driver/liteTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/cache/driver/memcacheTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/cache/driver/memcachedTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/cache/driver/redisTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.ini delete mode 100644 thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.json delete mode 100644 thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.xml delete mode 100644 thinkphp/tests/thinkphp/library/think/config/driver/iniTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/config/driver/jsonTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/config/driver/xmlTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/configTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/controller/.gitignore delete mode 100644 thinkphp/tests/thinkphp/library/think/controllerTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/cookieTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/db/driver/.gitignore delete mode 100644 thinkphp/tests/thinkphp/library/think/dbTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/debugTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/display.html delete mode 100644 thinkphp/tests/thinkphp/library/think/exceptionTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/extend.html delete mode 100644 thinkphp/tests/thinkphp/library/think/extend2.html delete mode 100644 thinkphp/tests/thinkphp/library/think/hookTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/include.html delete mode 100644 thinkphp/tests/thinkphp/library/think/include2.html delete mode 100644 thinkphp/tests/thinkphp/library/think/lang/lang.php delete mode 100644 thinkphp/tests/thinkphp/library/think/langTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/layout.html delete mode 100644 thinkphp/tests/thinkphp/library/think/layout2.html delete mode 100644 thinkphp/tests/thinkphp/library/think/loader/test/Hello.php delete mode 100644 thinkphp/tests/thinkphp/library/think/loaderTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/log/driver/fileTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/logTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/model/.gitignore delete mode 100644 thinkphp/tests/thinkphp/library/think/paginateTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/requestTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/responseTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/routeTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/session/.gitignore delete mode 100644 thinkphp/tests/thinkphp/library/think/sessionTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/template/driver/.gitignore delete mode 100644 thinkphp/tests/thinkphp/library/think/template/taglib/cxTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/templateTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/urlTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/validateTest.php delete mode 100644 thinkphp/tests/thinkphp/library/think/view/driver/.gitignore delete mode 100644 thinkphp/tests/thinkphp/library/think/view/theme/index/template.html delete mode 100644 thinkphp/tests/thinkphp/library/think/viewTest.php delete mode 100644 thinkphp/tests/thinkphp/library/traits/controller/.gitignore delete mode 100644 thinkphp/tests/thinkphp/library/traits/model/.gitignore diff --git a/application/config.php b/application/config.php index 38405e4a..fd8a9488 100644 --- a/application/config.php +++ b/application/config.php @@ -18,7 +18,7 @@ return [ // 应用命名空间 'app_namespace' => 'app', // 应用调试模式 - 'app_debug' => false, + 'app_debug' => true, // 应用Trace 'app_trace' => false, // 应用模式状态 diff --git a/application/index/controller/File.php b/application/index/controller/File.php index eb729005..fd744e59 100644 --- a/application/index/controller/File.php +++ b/application/index/controller/File.php @@ -44,7 +44,7 @@ class File extends Controller{ */ public function ListFile(){ $reqPath = stripslashes(json_decode(file_get_contents("php://input"),true)['path']); - return FileManage::ListFile($reqPath,$this->userObj->uid); + return json(FileManage::ListFile($reqPath,$this->userObj->uid)); } public function Delete(){ diff --git a/application/index/view/home/home.html b/application/index/view/home/home.html index 76332275..fa7b77ed 100644 --- a/application/index/view/home/home.html +++ b/application/index/view/home/home.html @@ -1,25 +1,26 @@ - - - - - - - 我的文件 - {$options.siteName} - - - - - - - - - - - - - - - - - -
- {include file="navbar_home" /} - - -
- -
-
- - - + + + + + +
+ + + diff --git a/application/index/view/home/home1.html b/application/index/view/home/home1.html new file mode 100644 index 00000000..76332275 --- /dev/null +++ b/application/index/view/home/home1.html @@ -0,0 +1,100 @@ + + + + + + + 我的文件 - {$options.siteName} + + + + + + + + + + + + + + + + + +
+ {include file="navbar_home" /} + + +
+ +
+
+ + + + + +{$options.js_code} + diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..99877299 --- /dev/null +++ b/composer.lock @@ -0,0 +1,981 @@ +{ + "_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#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "1d88e4f4d3f5fc270f16d563f3fb7c5e", + "packages": [ + { + "name": "aliyuncs/oss-sdk-php", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/aliyun/aliyun-oss-php-sdk.git", + "reference": "e69f57916678458642ac9d2fd341ae78a56996c8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aliyun/aliyun-oss-php-sdk/zipball/e69f57916678458642ac9d2fd341ae78a56996c8", + "reference": "e69f57916678458642ac9d2fd341ae78a56996c8", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "~1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "OSS\\": "src/OSS" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aliyuncs", + "homepage": "http://www.aliyun.com" + } + ], + "description": "Aliyun OSS SDK for PHP", + "homepage": "http://www.aliyun.com/product/oss/", + "time": "2018-01-08T06:59:35+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.3.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.3-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "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": "2018-04-22T15:46:56+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": "" + }, + "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.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "9f83dded91781a01c63574e387eaa769be769115" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", + "reference": "9f83dded91781a01c63574e387eaa769be769115", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-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": "2018-12-04T20:46:45+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": "" + }, + "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.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.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": "2018-11-20T15:27:04+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.0", + "satooshi/php-coveralls": ">=1.0" + }, + "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": "2016-02-11T07:05:27+00:00" + }, + { + "name": "sabre/dav", + "version": "3.2.3", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/dav.git", + "reference": "a9780ce4f35560ecbd0af524ad32d9d2c8954b80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/dav/zipball/a9780ce4f35560ecbd0af524ad32d9d2c8954b80", + "reference": "a9780ce4f35560ecbd0af524ad32d9d2c8954b80", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-dom": "*", + "ext-iconv": "*", + "ext-mbstring": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "lib-libxml": ">=2.7.0", + "php": ">=5.5.0", + "psr/log": "^1.0", + "sabre/event": ">=2.0.0, <4.0.0", + "sabre/http": "^4.2.1", + "sabre/uri": "^1.0.1", + "sabre/vobject": "^4.1.0", + "sabre/xml": "^1.4.0" + }, + "require-dev": { + "evert/phpdoc-md": "~0.1.0", + "monolog/monolog": "^1.18", + "phpunit/phpunit": "> 4.8, <6.0.0", + "sabre/cs": "^1.0.0" + }, + "suggest": { + "ext-curl": "*", + "ext-pdo": "*" + }, + "bin": [ + "bin/sabredav", + "bin/naturalselection" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Sabre\\DAV\\": "lib/DAV/", + "Sabre\\DAVACL\\": "lib/DAVACL/", + "Sabre\\CalDAV\\": "lib/CalDAV/", + "Sabre\\CardDAV\\": "lib/CardDAV/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "WebDAV Framework for PHP", + "homepage": "http://sabre.io/", + "keywords": [ + "CalDAV", + "CardDAV", + "WebDAV", + "framework", + "iCalendar" + ], + "time": "2018-10-19T09:58:27+00:00" + }, + { + "name": "sabre/event", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/831d586f5a442dceacdcf5e9c4c36a4db99a3534", + "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "*", + "sabre/cs": "~0.0.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\Event\\": "lib/" + }, + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "events", + "hooks", + "plugin", + "promise", + "signal" + ], + "time": "2015-11-05T20:14:39+00:00" + }, + { + "name": "sabre/http", + "version": "v4.2.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/http.git", + "reference": "acccec4ba863959b2d10c1fa0fb902736c5c8956" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/http/zipball/acccec4ba863959b2d10c1fa0fb902736c5c8956", + "reference": "acccec4ba863959b2d10c1fa0fb902736c5c8956", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-mbstring": "*", + "php": ">=5.4", + "sabre/event": ">=1.0.0,<4.0.0", + "sabre/uri": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.3", + "sabre/cs": "~0.0.1" + }, + "suggest": { + "ext-curl": " to make http requests with the Client class" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\HTTP\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "The sabre/http library provides utilities for dealing with http requests and responses. ", + "homepage": "https://github.com/fruux/sabre-http", + "keywords": [ + "http" + ], + "time": "2018-02-23T11:10:29+00:00" + }, + { + "name": "sabre/uri", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/uri.git", + "reference": "ada354d83579565949d80b2e15593c2371225e61" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/uri/zipball/ada354d83579565949d80b2e15593c2371225e61", + "reference": "ada354d83579565949d80b2e15593c2371225e61", + "shasum": "" + }, + "require": { + "php": ">=5.4.7" + }, + "require-dev": { + "phpunit/phpunit": ">=4.0,<6.0", + "sabre/cs": "~1.0.0" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\Uri\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "Functions for making sense out of URIs.", + "homepage": "http://sabre.io/uri/", + "keywords": [ + "rfc3986", + "uri", + "url" + ], + "time": "2017-02-20T19:59:28+00:00" + }, + { + "name": "sabre/vobject", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/vobject.git", + "reference": "bd500019764e434ff65872d426f523e7882a0739" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/vobject/zipball/bd500019764e434ff65872d426f523e7882a0739", + "reference": "bd500019764e434ff65872d426f523e7882a0739", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.5", + "sabre/xml": ">=1.5 <3.0" + }, + "require-dev": { + "phpunit/phpunit": "> 4.8.35, <6.0.0" + }, + "suggest": { + "hoa/bench": "If you would like to run the benchmark scripts" + }, + "bin": [ + "bin/vobject", + "bin/generate_vcards" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sabre\\VObject\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Dominik Tobschall", + "email": "dominik@fruux.com", + "homepage": "http://tobschall.de/", + "role": "Developer" + }, + { + "name": "Ivan Enderlin", + "email": "ivan.enderlin@hoa-project.net", + "homepage": "http://mnt.io/", + "role": "Developer" + } + ], + "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects", + "homepage": "http://sabre.io/vobject/", + "keywords": [ + "availability", + "freebusy", + "iCalendar", + "ical", + "ics", + "jCal", + "jCard", + "recurrence", + "rfc2425", + "rfc2426", + "rfc2739", + "rfc4770", + "rfc5545", + "rfc5546", + "rfc6321", + "rfc6350", + "rfc6351", + "rfc6474", + "rfc6638", + "rfc6715", + "rfc6868", + "vCalendar", + "vCard", + "vcf", + "xCal", + "xCard" + ], + "time": "2019-02-19T13:05:37+00:00" + }, + { + "name": "sabre/xml", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/xml.git", + "reference": "a367665f1df614c3b8fefc30a54de7cd295e444e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/a367665f1df614c3b8fefc30a54de7cd295e444e", + "reference": "a367665f1df614c3b8fefc30a54de7cd295e444e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "lib-libxml": ">=2.6.20", + "php": ">=5.5.5", + "sabre/uri": ">=1.0,<3.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.7", + "sabre/cs": "~1.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\Xml\\": "lib/" + }, + "files": [ + "lib/Deserializer/functions.php", + "lib/Serializer/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Markus Staab", + "email": "markus.staab@redaxo.de", + "role": "Developer" + } + ], + "description": "sabre/xml is an XML library that you may not hate.", + "homepage": "https://sabre.io/xml/", + "keywords": [ + "XMLReader", + "XMLWriter", + "dom", + "xml" + ], + "time": "2019-01-09T13:51:57+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": "" + }, + "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": "" + }, + "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": "" + }, + "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" + }, + { + "name": "upyun/sdk", + "version": "3.3.0", + "source": { + "type": "git", + "url": "https://github.com/upyun/php-sdk.git", + "reference": "1a2dd5ae31047956c733aef0f764f3a527d30628" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/upyun/php-sdk/zipball/1a2dd5ae31047956c733aef0f764f3a527d30628", + "reference": "1a2dd5ae31047956c733aef0f764f3a527d30628", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "guzzlehttp/guzzle": "~6.0", + "php": ">=5.5.0" + }, + "require-dev": { + "consolidation/robo": "^1.0", + "phpdocumentor/phpdocumentor": "^2.9", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Upyun\\": "src/Upyun/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "totoleo", + "email": "totoleo@163.com" + }, + { + "name": "lfeng", + "email": "bonevv@gmail.com" + }, + { + "name": "lvtongda", + "email": "riyao.lyu@gmail.com" + }, + { + "name": "sabakugaara", + "email": "senellise@gmail.com" + } + ], + "description": "UPYUN sdk for php", + "homepage": "https://github.com/upyun/php-sdk/", + "keywords": [ + "sdk", + "upyun" + ], + "time": "2017-11-12T09:17:42+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "ext-curl": "*", + "ext-fileinfo": "*", + "ext-gd": "*" + }, + "platform-dev": [] +} diff --git a/static/js/uploader/i18n/zh_CN.js b/static/js/uploader/i18n/zh_CN.js new file mode 100644 index 00000000..f48e0c43 --- /dev/null +++ b/static/js/uploader/i18n/zh_CN.js @@ -0,0 +1,2 @@ +// Chinese (China) (zh_CN) +plupload.addI18n({"Stop Upload":"停止上传","Upload URL might be wrong or doesn't exist.":"上传的URL可能是错误的或不存在。","tb":"tb","Size":"大小","Close":"关闭","Init error.":"初始化错误。","Add files to the upload queue and click the start button.":"将文件添加到上传队列,然后点击”开始上传“按钮。","Filename":"文件名","Image format either wrong or not supported.":"图片格式错误或者不支持。","Status":"状态","HTTP Error.":"HTTP 错误。","Start Upload":"开始上传","mb":"mb","kb":"kb","Duplicate file error.":"重复文件错误。","File size error.":"文件大小错误。","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"错误:无效的文件扩展名:","Select files":"选择文件","%s already present in the queue.":"%s 已经在当前队列里。","File: %s":"文件: %s","b":"b","Uploaded %d/%d files":"已上传 %d/%d 个文件","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"每次只接受同时上传 %d 个文件,多余的文件将会被删除。","%d files queued":"%d 个文件加入到队列","File: %s, size: %d, max file size: %d":"文件: %s, 大小: %d, 最大文件大小: %d","Drag files here.":"把文件拖到这里。","Runtime ran out of available memory.":"运行时已消耗所有可用内存。","File count error.":"文件数量错误。","File extension error.":"文件扩展名错误。","Error: File too large:":"错误: 文件太大:","Add Files":"增加文件"}); \ No newline at end of file diff --git a/static/js/uploader/main.js b/static/js/uploader/main.js new file mode 100644 index 00000000..e0fa990b --- /dev/null +++ b/static/js/uploader/main.js @@ -0,0 +1,274 @@ +// /*global Qiniu */ +// /*global plupload */ +// /*global FileProgress */ +// /*global hljs */ +// function getCookieByString(cookieName){ +// var start = document.cookie.indexOf(cookieName+'='); +// if (start == -1) return false; +// start = start+cookieName.length+1; +// var end = document.cookie.indexOf(';', start); +// if (end == -1) end=document.cookie.length; +// return document.cookie.substring(start, end); +// } + +// if(uploadConfig.saveType == "oss" || uploadConfig.saveType == "upyun" || uploadConfig.saveType == "s3"){ +// ChunkSize = "0"; +// }else{ +// ChunkSize = "4mb"; +// } + +// uploader = Qiniu.uploader({ +// runtimes: 'html5,flash,html4', +// browse_button: 'pickfiles', +// container: 'container', +// drop_element: 'container', +// max_file_size: uploadConfig.maxSize, +// flash_swf_url: '/bower_components/plupload/js/Moxie.swf', +// dragdrop: true, +// chunk_size: ChunkSize, +// filters: { +// mime_types :uploadConfig.allowedType, +// }, +// multi_selection: !(moxie.core.utils.Env.OS.toLowerCase() === "ios"), +// uptoken_url: "/Upload/Token", +// // uptoken_func: function(){ +// // var ajax = new XMLHttpRequest(); +// // ajax.open('GET', $('#uptoken_url').val(), false); +// // ajax.setRequestHeader("If-Modified-Since", "0"); +// // ajax.send(); +// // if (ajax.status === 200) { +// // var res = JSON.parse(ajax.responseText); +// // console.log('custom uptoken_func:' + res.uptoken); +// // return res.uptoken; +// // } else { +// // console.log('custom uptoken_func err'); +// // return ''; +// // } +// // }, +// domain: $('#domain').val(), +// get_new_uptoken: true, +// // downtoken_url: '/downtoken', +// // unique_names: true, +// // save_key: true, +// // x_vars: { +// // 'id': '1234', +// // 'time': function(up, file) { +// // var time = (new Date()).getTime(); +// // // do something with 'time' +// // return time; +// // }, +// // }, +// auto_start: true, +// log_level: 5, +// init: { +// 'FilesAdded': function(up, files) { +// $('table').show(); +// $('#upload_box').show(); +// $('#success').hide(); +// $('#info_box').hide(); + +// $.cookie('path', decodeURI(getCookieByString("path_tmp"))); +// plupload.each(files, function(file) { +// var progress = new FileProgress(file, 'fsUploadProgress'); +// progress.setStatus("等待..."); +// progress.bindUploadCancel(up); +// }); + +// }, +// 'BeforeUpload': function(up, file) { +// var progress = new FileProgress(file, 'fsUploadProgress'); +// var chunk_size = plupload.parseSize(this.getOption('chunk_size')); +// if (up.runtime === 'html5' && chunk_size) { +// progress.setChunkProgess(chunk_size); +// } +// }, +// 'UploadProgress': function(up, file) { +// var progress = new FileProgress(file, 'fsUploadProgress'); +// var chunk_size = plupload.parseSize(this.getOption('chunk_size')); +// progress.setProgress(file.percent + "%", file.speed, chunk_size); +// }, +// 'UploadComplete': function(up, file) { +// $('#success').show(); +// toastr["success"]("队列全部文件处理完毕"); +// getMemory(); +// }, +// 'FileUploaded': function(up, file, info) { +// var progress = new FileProgress(file, 'fsUploadProgress'); +// progress.setComplete(up, info); +// }, +// 'Error': function(up, err, errTip) { +// $('#upload_box').show(); +// $('table').show(); +// $('#info_box').hide(); +// var progress = new FileProgress(err.file, 'fsUploadProgress'); +// progress.setError(); +// progress.setStatus(errTip); +// toastr["error"]("上传时遇到错误"); +// } +// // , +// // 'Key': function(up, file) { +// // var key = ""; +// // // do something with key +// // return key +// // } +// } +// }); + +// uploader.bind('FileUploaded', function(up,file) { +// console.log('a file is uploaded'); +// }); +// $('#container').on( +// 'dragenter', +// function(e) { +// e.preventDefault(); +// $('#container').addClass('draging'); +// e.stopPropagation(); +// } +// ).on('drop', function(e) { +// e.preventDefault(); +// $('#container').removeClass('draging'); +// e.stopPropagation(); +// }).on('dragleave', function(e) { +// e.preventDefault(); +// $('#container').removeClass('draging'); +// e.stopPropagation(); +// }).on('dragover', function(e) { +// e.preventDefault(); +// $('#container').addClass('draging'); +// e.stopPropagation(); +// }); + + + +// $('#show_code').on('click', function() { +// $('#myModal-code').modal(); +// $('pre code').each(function(i, e) { +// hljs.highlightBlock(e); +// }); +// }); + + +// $('body').on('click', 'table button.btn', function() { +// $(this).parents('tr').next().toggle(); +// }); + + +// var getRotate = function(url) { +// if (!url) { +// return 0; +// } +// var arr = url.split('/'); +// for (var i = 0, len = arr.length; i < len; i++) { +// if (arr[i] === 'rotate') { +// return parseInt(arr[i + 1], 10); +// } +// } +// return 0; +// }; + +// $('#myModal-img .modal-body-footer').find('a').on('click', function() { +// var img = $('#myModal-img').find('.modal-body img'); +// var key = img.data('key'); +// var oldUrl = img.attr('src'); +// var originHeight = parseInt(img.data('h'), 10); +// var fopArr = []; +// var rotate = getRotate(oldUrl); +// if (!$(this).hasClass('no-disable-click')) { +// $(this).addClass('disabled').siblings().removeClass('disabled'); +// if ($(this).data('imagemogr') !== 'no-rotate') { +// fopArr.push({ +// 'fop': 'imageMogr2', +// 'auto-orient': true, +// 'strip': true, +// 'rotate': rotate, +// 'format': 'png' +// }); +// } +// } else { +// $(this).siblings().removeClass('disabled'); +// var imageMogr = $(this).data('imagemogr'); +// if (imageMogr === 'left') { +// rotate = rotate - 90 < 0 ? rotate + 270 : rotate - 90; +// } else if (imageMogr === 'right') { +// rotate = rotate + 90 > 360 ? rotate - 270 : rotate + 90; +// } +// fopArr.push({ +// 'fop': 'imageMogr2', +// 'auto-orient': true, +// 'strip': true, +// 'rotate': rotate, +// 'format': 'png' +// }); +// } + +// $('#myModal-img .modal-body-footer').find('a.disabled').each(function() { + +// var watermark = $(this).data('watermark'); +// var imageView = $(this).data('imageview'); +// var imageMogr = $(this).data('imagemogr'); + +// if (watermark) { +// fopArr.push({ +// fop: 'watermark', +// mode: 1, +// image: 'http://www.b1.qiniudn.com/images/logo-2.png', +// dissolve: 100, +// gravity: watermark, +// dx: 100, +// dy: 100 +// }); +// } + +// if (imageView) { +// var height; +// switch (imageView) { +// case 'large': +// height = originHeight; +// break; +// case 'middle': +// height = originHeight * 0.5; +// break; +// case 'small': +// height = originHeight * 0.1; +// break; +// default: +// height = originHeight; +// break; +// } +// fopArr.push({ +// fop: 'imageView2', +// mode: 3, +// h: parseInt(height, 10), +// q: 100, +// format: 'png' +// }); +// } + +// if (imageMogr === 'no-rotate') { +// fopArr.push({ +// 'fop': 'imageMogr2', +// 'auto-orient': true, +// 'strip': true, +// 'rotate': 0, +// 'format': 'png' +// }); +// } +// }); + + + +// var newUrl = Qiniu.pipeline(fopArr, key); + +// var newImg = new Image(); +// img.attr('src', 'images/loading.gif'); +// newImg.onload = function() { +// img.attr('src', newUrl); +// img.parent('a').attr('href', newUrl); +// }; +// newImg.src = newUrl; +// return false; +// }); + +// function t(){ +// uploader.getNewUpToken(); +// } \ No newline at end of file diff --git a/static/js/uploader/moxie.js b/static/js/uploader/moxie.js new file mode 100644 index 00000000..d41397cd --- /dev/null +++ b/static/js/uploader/moxie.js @@ -0,0 +1,11509 @@ +;var MXI_DEBUG = true; +/** + * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill + * v1.5.3 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2017-02-02 + */ +;(function (global, factory) { + var extract = function() { + var ctx = {}; + factory.apply(ctx, arguments); + return ctx.moxie; + }; + + if (typeof define === "function" && define.amd) { + define("moxie", [], extract); + } else if (typeof module === "object" && module.exports) { + module.exports = extract(); + } else { + global.moxie = extract(); + } +}(this || window, function() { +/** + * Compiled inline version. (Library mode) + */ + +/*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */ +/*globals $code */ + +(function(exports, undefined) { + "use strict"; + + var modules = {}; + + function require(ids, callback) { + var module, defs = []; + + for (var i = 0; i < ids.length; ++i) { + module = modules[ids[i]] || resolve(ids[i]); + if (!module) { + throw 'module definition dependecy not found: ' + ids[i]; + } + + defs.push(module); + } + + callback.apply(null, defs); + } + + function define(id, dependencies, definition) { + if (typeof id !== 'string') { + throw 'invalid module definition, module id must be defined and be a string'; + } + + if (dependencies === undefined) { + throw 'invalid module definition, dependencies must be specified'; + } + + if (definition === undefined) { + throw 'invalid module definition, definition function must be specified'; + } + + require(dependencies, function() { + modules[id] = definition.apply(null, arguments); + }); + } + + function defined(id) { + return !!modules[id]; + } + + function resolve(id) { + var target = exports; + var fragments = id.split(/[.\/]/); + + for (var fi = 0; fi < fragments.length; ++fi) { + if (!target[fragments[fi]]) { + return; + } + + target = target[fragments[fi]]; + } + + return target; + } + + function expose(ids) { + for (var i = 0; i < ids.length; i++) { + var target = exports; + var id = ids[i]; + var fragments = id.split(/[.\/]/); + + for (var fi = 0; fi < fragments.length - 1; ++fi) { + if (target[fragments[fi]] === undefined) { + target[fragments[fi]] = {}; + } + + target = target[fragments[fi]]; + } + + target[fragments[fragments.length - 1]] = modules[id]; + } + } + +// Included from: src/javascript/core/utils/Basic.js + +/** + * Basic.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/core/utils/Basic +@public +@static +*/ +define('moxie/core/utils/Basic', [], function() { + /** + Gets the true type of the built-in object (better version of typeof). + @author Angus Croll (http://javascriptweblog.wordpress.com/) + + @method typeOf + @for Utils + @static + @param {Object} o Object to check. + @return {String} Object [[Class]] + */ + function typeOf(o) { + var undef; + + if (o === undef) { + return 'undefined'; + } else if (o === null) { + return 'null'; + } else if (o.nodeType) { + return 'node'; + } + + // the snippet below is awesome, however it fails to detect null, undefined and arguments types in IE lte 8 + return ({}).toString.call(o).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); + } + + /** + Extends the specified object with another object(s). + + @method extend + @static + @param {Object} target Object to extend. + @param {Object} [obj]* Multiple objects to extend with. + @return {Object} Same as target, the extended object. + */ + function extend() { + return merge(false, false, arguments); + } + + + /** + Extends the specified object with another object(s), but only if the property exists in the target. + + @method extendIf + @static + @param {Object} target Object to extend. + @param {Object} [obj]* Multiple objects to extend with. + @return {Object} Same as target, the extended object. + */ + function extendIf() { + return merge(true, false, arguments); + } + + + function extendImmutable() { + return merge(false, true, arguments); + } + + + function extendImmutableIf() { + return merge(true, true, arguments); + } + + + function shallowCopy(obj) { + switch (typeOf(obj)) { + case 'array': + return Array.prototype.slice.call(obj); + + case 'object': + return extend({}, obj); + } + return obj; + } + + + function merge(strict, immutable, args) { + var undef; + var target = args[0]; + + each(args, function(arg, i) { + if (i > 0) { + each(arg, function(value, key) { + var isComplex = inArray(typeOf(value), ['array', 'object']) !== -1; + + if (value === undef || strict && target[key] === undef) { + return true; + } + + if (isComplex && immutable) { + value = shallowCopy(value); + } + + if (typeOf(target[key]) === typeOf(value) && isComplex) { + merge(strict, immutable, [target[key], value]); + } else { + target[key] = value; + } + }); + } + }); + + return target; + } + + + /** + A way to inherit one `class` from another in a consisstent way (more or less) + + @method inherit + @static + @since >1.4.1 + @param {Function} child + @param {Function} parent + @return {Function} Prepared constructor + */ + function inherit(child, parent) { + // copy over all parent properties + for (var key in parent) { + if ({}.hasOwnProperty.call(parent, key)) { + child[key] = parent[key]; + } + } + + // give child `class` a place to define its own methods + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + + // keep a way to reference parent methods + child.__parent__ = parent.prototype; + return child; + } + + + /** + Executes the callback function for each item in array/object. If you return false in the + callback it will break the loop. + + @method each + @static + @param {Object} obj Object to iterate. + @param {function} callback Callback function to execute for each item. + */ + function each(obj, callback) { + var length, key, i, undef; + + if (obj) { + try { + length = obj.length; + } catch(ex) { + length = undef; + } + + if (length === undef || typeof(length) !== 'number') { + // Loop object items + for (key in obj) { + if (obj.hasOwnProperty(key)) { + if (callback(obj[key], key) === false) { + return; + } + } + } + } else { + // Loop array items + for (i = 0; i < length; i++) { + if (callback(obj[i], i) === false) { + return; + } + } + } + } + } + + /** + Checks if object is empty. + + @method isEmptyObj + @static + @param {Object} o Object to check. + @return {Boolean} + */ + function isEmptyObj(obj) { + var prop; + + if (!obj || typeOf(obj) !== 'object') { + return true; + } + + for (prop in obj) { + return false; + } + + return true; + } + + /** + Recieve an array of functions (usually async) to call in sequence, each function + receives a callback as first argument that it should call, when it completes. Finally, + after everything is complete, main callback is called. Passing truthy value to the + callback as a first argument will interrupt the sequence and invoke main callback + immediately. + + @method inSeries + @static + @param {Array} queue Array of functions to call in sequence + @param {Function} cb Main callback that is called in the end, or in case of error + */ + function inSeries(queue, cb) { + var i = 0, length = queue.length; + + if (typeOf(cb) !== 'function') { + cb = function() {}; + } + + if (!queue || !queue.length) { + cb(); + } + + function callNext(i) { + if (typeOf(queue[i]) === 'function') { + queue[i](function(error) { + /*jshint expr:true */ + ++i < length && !error ? callNext(i) : cb(error); + }); + } + } + callNext(i); + } + + + /** + Recieve an array of functions (usually async) to call in parallel, each function + receives a callback as first argument that it should call, when it completes. After + everything is complete, main callback is called. Passing truthy value to the + callback as a first argument will interrupt the process and invoke main callback + immediately. + + @method inParallel + @static + @param {Array} queue Array of functions to call in sequence + @param {Function} cb Main callback that is called in the end, or in case of erro + */ + function inParallel(queue, cb) { + var count = 0, num = queue.length, cbArgs = new Array(num); + + each(queue, function(fn, i) { + fn(function(error) { + if (error) { + return cb(error); + } + + var args = [].slice.call(arguments); + args.shift(); // strip error - undefined or not + + cbArgs[i] = args; + count++; + + if (count === num) { + cbArgs.unshift(null); + cb.apply(this, cbArgs); + } + }); + }); + } + + + /** + Find an element in array and return it's index if present, otherwise return -1. + + @method inArray + @static + @param {Mixed} needle Element to find + @param {Array} array + @return {Int} Index of the element, or -1 if not found + */ + function inArray(needle, array) { + if (array) { + if (Array.prototype.indexOf) { + return Array.prototype.indexOf.call(array, needle); + } + + for (var i = 0, length = array.length; i < length; i++) { + if (array[i] === needle) { + return i; + } + } + } + return -1; + } + + + /** + Returns elements of first array if they are not present in second. And false - otherwise. + + @private + @method arrayDiff + @param {Array} needles + @param {Array} array + @return {Array|Boolean} + */ + function arrayDiff(needles, array) { + var diff = []; + + if (typeOf(needles) !== 'array') { + needles = [needles]; + } + + if (typeOf(array) !== 'array') { + array = [array]; + } + + for (var i in needles) { + if (inArray(needles[i], array) === -1) { + diff.push(needles[i]); + } + } + return diff.length ? diff : false; + } + + + /** + Find intersection of two arrays. + + @private + @method arrayIntersect + @param {Array} array1 + @param {Array} array2 + @return {Array} Intersection of two arrays or null if there is none + */ + function arrayIntersect(array1, array2) { + var result = []; + each(array1, function(item) { + if (inArray(item, array2) !== -1) { + result.push(item); + } + }); + return result.length ? result : null; + } + + + /** + Forces anything into an array. + + @method toArray + @static + @param {Object} obj Object with length field. + @return {Array} Array object containing all items. + */ + function toArray(obj) { + var i, arr = []; + + for (i = 0; i < obj.length; i++) { + arr[i] = obj[i]; + } + + return arr; + } + + + /** + Generates an unique ID. The only way a user would be able to get the same ID is if the two persons + at the same exact millisecond manage to get the same 5 random numbers between 0-65535; it also uses + a counter so each ID is guaranteed to be unique for the given page. It is more probable for the earth + to be hit with an asteroid. + + @method guid + @static + @param {String} prefix to prepend (by default 'o' will be prepended). + @method guid + @return {String} Virtually unique id. + */ + var guid = (function() { + var counter = 0; + + return function(prefix) { + var guid = new Date().getTime().toString(32), i; + + for (i = 0; i < 5; i++) { + guid += Math.floor(Math.random() * 65535).toString(32); + } + + return (prefix || 'o_') + guid + (counter++).toString(32); + }; + }()); + + + /** + Trims white spaces around the string + + @method trim + @static + @param {String} str + @return {String} + */ + function trim(str) { + if (!str) { + return str; + } + return String.prototype.trim ? String.prototype.trim.call(str) : str.toString().replace(/^\s*/, '').replace(/\s*$/, ''); + } + + + /** + Parses the specified size string into a byte value. For example 10kb becomes 10240. + + @method parseSizeStr + @static + @param {String/Number} size String to parse or number to just pass through. + @return {Number} Size in bytes. + */ + function parseSizeStr(size) { + if (typeof(size) !== 'string') { + return size; + } + + var muls = { + t: 1099511627776, + g: 1073741824, + m: 1048576, + k: 1024 + }, + mul; + + size = /^([0-9\.]+)([tmgk]?)$/.exec(size.toLowerCase().replace(/[^0-9\.tmkg]/g, '')); + mul = size[2]; + size = +size[1]; + + if (muls.hasOwnProperty(mul)) { + size *= muls[mul]; + } + return Math.floor(size); + } + + + /** + * Pseudo sprintf implementation - simple way to replace tokens with specified values. + * + * @param {String} str String with tokens + * @return {String} String with replaced tokens + */ + function sprintf(str) { + var args = [].slice.call(arguments, 1); + + return str.replace(/%[a-z]/g, function() { + var value = args.shift(); + return typeOf(value) !== 'undefined' ? value : ''; + }); + } + + + + function delay(cb, timeout) { + var self = this; + setTimeout(function() { + cb.call(self); + }, timeout || 1); + } + + + return { + guid: guid, + typeOf: typeOf, + extend: extend, + extendIf: extendIf, + extendImmutable: extendImmutable, + extendImmutableIf: extendImmutableIf, + inherit: inherit, + each: each, + isEmptyObj: isEmptyObj, + inSeries: inSeries, + inParallel: inParallel, + inArray: inArray, + arrayDiff: arrayDiff, + arrayIntersect: arrayIntersect, + toArray: toArray, + trim: trim, + sprintf: sprintf, + parseSizeStr: parseSizeStr, + delay: delay + }; +}); + +// Included from: src/javascript/core/utils/Encode.js + +/** + * Encode.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Encode', [], function() { + + /** + @class moxie/core/utils/Encode + */ + + /** + Encode string with UTF-8 + + @method utf8_encode + @for Utils + @static + @param {String} str String to encode + @return {String} UTF-8 encoded string + */ + var utf8_encode = function(str) { + return unescape(encodeURIComponent(str)); + }; + + /** + Decode UTF-8 encoded string + + @method utf8_decode + @static + @param {String} str String to decode + @return {String} Decoded string + */ + var utf8_decode = function(str_data) { + return decodeURIComponent(escape(str_data)); + }; + + /** + Decode Base64 encoded string (uses browser's default method if available), + from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_decode.js + + @method atob + @static + @param {String} data String to decode + @return {String} Decoded string + */ + var atob = function(data, utf8) { + if (typeof(window.atob) === 'function') { + return utf8 ? utf8_decode(window.atob(data)) : window.atob(data); + } + + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Thunder.m + // + input by: Aman Gupta + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Onno Marsman + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Brett Zamir (http://brett-zamir.me) + // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); + // * returns 1: 'Kevin van Zonneveld' + // mozilla has this native + // - but breaks in 2.0.0.12! + //if (typeof this.window.atob == 'function') { + // return atob(data); + //} + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + dec = "", + tmp_arr = []; + + if (!data) { + return data; + } + + data += ''; + + do { // unpack four hexets into three octets using index points in b64 + h1 = b64.indexOf(data.charAt(i++)); + h2 = b64.indexOf(data.charAt(i++)); + h3 = b64.indexOf(data.charAt(i++)); + h4 = b64.indexOf(data.charAt(i++)); + + bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; + + o1 = bits >> 16 & 0xff; + o2 = bits >> 8 & 0xff; + o3 = bits & 0xff; + + if (h3 == 64) { + tmp_arr[ac++] = String.fromCharCode(o1); + } else if (h4 == 64) { + tmp_arr[ac++] = String.fromCharCode(o1, o2); + } else { + tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); + } + } while (i < data.length); + + dec = tmp_arr.join(''); + + return utf8 ? utf8_decode(dec) : dec; + }; + + /** + Base64 encode string (uses browser's default method if available), + from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_encode.js + + @method btoa + @static + @param {String} data String to encode + @return {String} Base64 encoded string + */ + var btoa = function(data, utf8) { + if (utf8) { + data = utf8_encode(data); + } + + if (typeof(window.btoa) === 'function') { + return window.btoa(data); + } + + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Bayron Guevara + // + improved by: Thunder.m + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: Rafał Kukawski (http://kukawski.pl) + // * example 1: base64_encode('Kevin van Zonneveld'); + // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' + // mozilla has this native + // - but breaks in 2.0.0.12! + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + enc = "", + tmp_arr = []; + + if (!data) { + return data; + } + + do { // pack three octets into four hexets + o1 = data.charCodeAt(i++); + o2 = data.charCodeAt(i++); + o3 = data.charCodeAt(i++); + + bits = o1 << 16 | o2 << 8 | o3; + + h1 = bits >> 18 & 0x3f; + h2 = bits >> 12 & 0x3f; + h3 = bits >> 6 & 0x3f; + h4 = bits & 0x3f; + + // use hexets to index into b64, and append result to encoded string + tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); + } while (i < data.length); + + enc = tmp_arr.join(''); + + var r = data.length % 3; + + return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3); + }; + + + return { + utf8_encode: utf8_encode, + utf8_decode: utf8_decode, + atob: atob, + btoa: btoa + }; +}); + +// Included from: src/javascript/core/utils/Env.js + +/** + * Env.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/core/utils/Env", [ + "moxie/core/utils/Basic" +], function(Basic) { + + /** + * UAParser.js v0.7.7 + * Lightweight JavaScript-based User-Agent string parser + * https://github.com/faisalman/ua-parser-js + * + * Copyright © 2012-2015 Faisal Salman + * Dual licensed under GPLv2 & MIT + */ + var UAParser = (function (undefined) { + + ////////////// + // Constants + ///////////// + + + var EMPTY = '', + UNKNOWN = '?', + FUNC_TYPE = 'function', + UNDEF_TYPE = 'undefined', + OBJ_TYPE = 'object', + MAJOR = 'major', + MODEL = 'model', + NAME = 'name', + TYPE = 'type', + VENDOR = 'vendor', + VERSION = 'version', + ARCHITECTURE= 'architecture', + CONSOLE = 'console', + MOBILE = 'mobile', + TABLET = 'tablet'; + + + /////////// + // Helper + ////////// + + + var util = { + has : function (str1, str2) { + return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1; + }, + lowerize : function (str) { + return str.toLowerCase(); + } + }; + + + /////////////// + // Map helper + ////////////// + + + var mapper = { + + rgx : function () { + + // loop through all regexes maps + for (var result, i = 0, j, k, p, q, matches, match, args = arguments; i < args.length; i += 2) { + + var regex = args[i], // even sequence (0,2,4,..) + props = args[i + 1]; // odd sequence (1,3,5,..) + + // construct object barebones + if (typeof(result) === UNDEF_TYPE) { + result = {}; + for (p in props) { + q = props[p]; + if (typeof(q) === OBJ_TYPE) { + result[q[0]] = undefined; + } else { + result[q] = undefined; + } + } + } + + // try matching uastring with regexes + for (j = k = 0; j < regex.length; j++) { + matches = regex[j].exec(this.getUA()); + if (!!matches) { + for (p = 0; p < props.length; p++) { + match = matches[++k]; + q = props[p]; + // check if given property is actually array + if (typeof(q) === OBJ_TYPE && q.length > 0) { + if (q.length == 2) { + if (typeof(q[1]) == FUNC_TYPE) { + // assign modified match + result[q[0]] = q[1].call(this, match); + } else { + // assign given value, ignore regex match + result[q[0]] = q[1]; + } + } else if (q.length == 3) { + // check whether function or regex + if (typeof(q[1]) === FUNC_TYPE && !(q[1].exec && q[1].test)) { + // call function (usually string mapper) + result[q[0]] = match ? q[1].call(this, match, q[2]) : undefined; + } else { + // sanitize match using given regex + result[q[0]] = match ? match.replace(q[1], q[2]) : undefined; + } + } else if (q.length == 4) { + result[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined; + } + } else { + result[q] = match ? match : undefined; + } + } + break; + } + } + + if(!!matches) break; // break the loop immediately if match found + } + return result; + }, + + str : function (str, map) { + + for (var i in map) { + // check if array + if (typeof(map[i]) === OBJ_TYPE && map[i].length > 0) { + for (var j = 0; j < map[i].length; j++) { + if (util.has(map[i][j], str)) { + return (i === UNKNOWN) ? undefined : i; + } + } + } else if (util.has(map[i], str)) { + return (i === UNKNOWN) ? undefined : i; + } + } + return str; + } + }; + + + /////////////// + // String map + ////////////// + + + var maps = { + + browser : { + oldsafari : { + major : { + '1' : ['/8', '/1', '/3'], + '2' : '/4', + '?' : '/' + }, + version : { + '1.0' : '/8', + '1.2' : '/1', + '1.3' : '/3', + '2.0' : '/412', + '2.0.2' : '/416', + '2.0.3' : '/417', + '2.0.4' : '/419', + '?' : '/' + } + } + }, + + device : { + sprint : { + model : { + 'Evo Shift 4G' : '7373KT' + }, + vendor : { + 'HTC' : 'APA', + 'Sprint' : 'Sprint' + } + } + }, + + os : { + windows : { + version : { + 'ME' : '4.90', + 'NT 3.11' : 'NT3.51', + 'NT 4.0' : 'NT4.0', + '2000' : 'NT 5.0', + 'XP' : ['NT 5.1', 'NT 5.2'], + 'Vista' : 'NT 6.0', + '7' : 'NT 6.1', + '8' : 'NT 6.2', + '8.1' : 'NT 6.3', + 'RT' : 'ARM' + } + } + } + }; + + + ////////////// + // Regex map + ///////////// + + + var regexes = { + + browser : [[ + + // Presto based + /(opera\smini)\/([\w\.-]+)/i, // Opera Mini + /(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet + /(opera).+version\/([\w\.]+)/i, // Opera > 9.80 + /(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80 + + ], [NAME, VERSION], [ + + /\s(opr)\/([\w\.]+)/i // Opera Webkit + ], [[NAME, 'Opera'], VERSION], [ + + // Mixed + /(kindle)\/([\w\.]+)/i, // Kindle + /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i, + // Lunascape/Maxthon/Netfront/Jasmine/Blazer + + // Trident based + /(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i, + // Avant/IEMobile/SlimBrowser/Baidu + /(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer + + // Webkit/KHTML based + /(rekonq)\/([\w\.]+)*/i, // Rekonq + /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi)\/([\w\.-]+)/i + // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron + ], [NAME, VERSION], [ + + /(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11 + ], [[NAME, 'IE'], VERSION], [ + + /(edge)\/((\d+)?[\w\.]+)/i // Microsoft Edge + ], [NAME, VERSION], [ + + /(yabrowser)\/([\w\.]+)/i // Yandex + ], [[NAME, 'Yandex'], VERSION], [ + + /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon + ], [[NAME, /_/g, ' '], VERSION], [ + + /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i, + // Chrome/OmniWeb/Arora/Tizen/Nokia + /(uc\s?browser|qqbrowser)[\/\s]?([\w\.]+)/i + // UCBrowser/QQBrowser + ], [NAME, VERSION], [ + + /(dolfin)\/([\w\.]+)/i // Dolphin + ], [[NAME, 'Dolphin'], VERSION], [ + + /((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS + ], [[NAME, 'Chrome'], VERSION], [ + + /XiaoMi\/MiuiBrowser\/([\w\.]+)/i // MIUI Browser + ], [VERSION, [NAME, 'MIUI Browser']], [ + + /android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i // Android Browser + ], [VERSION, [NAME, 'Android Browser']], [ + + /FBAV\/([\w\.]+);/i // Facebook App for iOS + ], [VERSION, [NAME, 'Facebook']], [ + + /version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari + ], [VERSION, [NAME, 'Mobile Safari']], [ + + /version\/([\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile + ], [VERSION, NAME], [ + + /webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 + ], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [ + + /(konqueror)\/([\w\.]+)/i, // Konqueror + /(webkit|khtml)\/([\w\.]+)/i + ], [NAME, VERSION], [ + + // Gecko based + /(navigator|netscape)\/([\w\.-]+)/i // Netscape + ], [[NAME, 'Netscape'], VERSION], [ + /(swiftfox)/i, // Swiftfox + /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, + // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror + /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i, + // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix + /(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla + + // Other + /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?([\w\.]+)/i, + // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf + /(links)\s\(([\w\.]+)/i, // Links + /(gobrowser)\/?([\w\.]+)*/i, // GoBrowser + /(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser + /(mosaic)[\/\s]([\w\.]+)/i // Mosaic + ], [NAME, VERSION] + ], + + engine : [[ + + /windows.+\sedge\/([\w\.]+)/i // EdgeHTML + ], [VERSION, [NAME, 'EdgeHTML']], [ + + /(presto)\/([\w\.]+)/i, // Presto + /(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m + /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links + /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab + ], [NAME, VERSION], [ + + /rv\:([\w\.]+).*(gecko)/i // Gecko + ], [VERSION, NAME] + ], + + os : [[ + + // Windows based + /microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes) + ], [NAME, VERSION], [ + /(windows)\snt\s6\.2;\s(arm)/i, // Windows RT + /(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i + ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [ + /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i + ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [ + + // Mobile/Embedded OS + /\((bb)(10);/i // BlackBerry 10 + ], [[NAME, 'BlackBerry'], VERSION], [ + /(blackberry)\w*\/?([\w\.]+)*/i, // Blackberry + /(tizen)[\/\s]([\w\.]+)/i, // Tizen + /(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i, + // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki + /linux;.+(sailfish);/i // Sailfish OS + ], [NAME, VERSION], [ + /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian + ], [[NAME, 'Symbian'], VERSION], [ + /\((series40);/i // Series 40 + ], [NAME], [ + /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS + ], [[NAME, 'Firefox OS'], VERSION], [ + + // Console + /(nintendo|playstation)\s([wids3portablevu]+)/i, // Nintendo/Playstation + + // GNU/Linux based + /(mint)[\/\s\(]?(\w+)*/i, // Mint + /(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux + /(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i, + // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware + // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus + /(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux + /(gnu)\s?([\w\.]+)*/i // GNU + ], [NAME, VERSION], [ + + /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS + ], [[NAME, 'Chromium OS'], VERSION],[ + + // Solaris + /(sunos)\s?([\w\.]+\d)*/i // Solaris + ], [[NAME, 'Solaris'], VERSION], [ + + // BSD based + /\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + ], [NAME, VERSION],[ + + /(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i // iOS + ], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [ + + /(mac\sos\sx)\s?([\w\s\.]+\w)*/i, + /(macintosh|mac(?=_powerpc)\s)/i // Mac OS + ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ + + // Other + /((?:open)?solaris)[\/\s-]?([\w\.]+)*/i, // Solaris + /(haiku)\s(\w+)/i, // Haiku + /(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i, // AIX + /(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i, + // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS + /(unix)\s?([\w\.]+)*/i // UNIX + ], [NAME, VERSION] + ] + }; + + + ///////////////// + // Constructor + //////////////// + + + var UAParser = function (uastring) { + + var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); + + this.getBrowser = function () { + return mapper.rgx.apply(this, regexes.browser); + }; + this.getEngine = function () { + return mapper.rgx.apply(this, regexes.engine); + }; + this.getOS = function () { + return mapper.rgx.apply(this, regexes.os); + }; + this.getResult = function() { + return { + ua : this.getUA(), + browser : this.getBrowser(), + engine : this.getEngine(), + os : this.getOS() + }; + }; + this.getUA = function () { + return ua; + }; + this.setUA = function (uastring) { + ua = uastring; + return this; + }; + this.setUA(ua); + }; + + return UAParser; + })(); + + + function version_compare(v1, v2, operator) { + // From: http://phpjs.org/functions + // + original by: Philippe Jausions (http://pear.php.net/user/jausions) + // + original by: Aidan Lister (http://aidanlister.com/) + // + reimplemented by: Kankrelune (http://www.webfaktory.info/) + // + improved by: Brett Zamir (http://brett-zamir.me) + // + improved by: Scott Baker + // + improved by: Theriault + // * example 1: version_compare('8.2.5rc', '8.2.5a'); + // * returns 1: 1 + // * example 2: version_compare('8.2.50', '8.2.52', '<'); + // * returns 2: true + // * example 3: version_compare('5.3.0-dev', '5.3.0'); + // * returns 3: -1 + // * example 4: version_compare('4.1.0.52','4.01.0.51'); + // * returns 4: 1 + + // Important: compare must be initialized at 0. + var i = 0, + x = 0, + compare = 0, + // vm maps textual PHP versions to negatives so they're less than 0. + // PHP currently defines these as CASE-SENSITIVE. It is important to + // leave these as negatives so that they can come before numerical versions + // and as if no letters were there to begin with. + // (1alpha is < 1 and < 1.1 but > 1dev1) + // If a non-numerical value can't be mapped to this table, it receives + // -7 as its value. + vm = { + 'dev': -6, + 'alpha': -5, + 'a': -5, + 'beta': -4, + 'b': -4, + 'RC': -3, + 'rc': -3, + '#': -2, + 'p': 1, + 'pl': 1 + }, + // This function will be called to prepare each version argument. + // It replaces every _, -, and + with a dot. + // It surrounds any nonsequence of numbers/dots with dots. + // It replaces sequences of dots with a single dot. + // version_compare('4..0', '4.0') == 0 + // Important: A string of 0 length needs to be converted into a value + // even less than an unexisting value in vm (-7), hence [-8]. + // It's also important to not strip spaces because of this. + // version_compare('', ' ') == 1 + prepVersion = function (v) { + v = ('' + v).replace(/[_\-+]/g, '.'); + v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); + return (!v.length ? [-8] : v.split('.')); + }, + // This converts a version component to a number. + // Empty component becomes 0. + // Non-numerical component becomes a negative number. + // Numerical component becomes itself as an integer. + numVersion = function (v) { + return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); + }; + + v1 = prepVersion(v1); + v2 = prepVersion(v2); + x = Math.max(v1.length, v2.length); + for (i = 0; i < x; i++) { + if (v1[i] == v2[i]) { + continue; + } + v1[i] = numVersion(v1[i]); + v2[i] = numVersion(v2[i]); + if (v1[i] < v2[i]) { + compare = -1; + break; + } else if (v1[i] > v2[i]) { + compare = 1; + break; + } + } + if (!operator) { + return compare; + } + + // Important: operator is CASE-SENSITIVE. + // "No operator" seems to be treated as "<." + // Any other values seem to make the function return null. + switch (operator) { + case '>': + case 'gt': + return (compare > 0); + case '>=': + case 'ge': + return (compare >= 0); + case '<=': + case 'le': + return (compare <= 0); + case '==': + case '=': + case 'eq': + return (compare === 0); + case '<>': + case '!=': + case 'ne': + return (compare !== 0); + case '': + case '<': + case 'lt': + return (compare < 0); + default: + return null; + } + } + + + var can = (function() { + var caps = { + define_property: (function() { + /* // currently too much extra code required, not exactly worth it + try { // as of IE8, getters/setters are supported only on DOM elements + var obj = {}; + if (Object.defineProperty) { + Object.defineProperty(obj, 'prop', { + enumerable: true, + configurable: true + }); + return true; + } + } catch(ex) {} + + if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { + return true; + }*/ + return false; + }()), + + create_canvas: (function() { + // On the S60 and BB Storm, getContext exists, but always returns undefined + // so we actually have to call getContext() to verify + // github.com/Modernizr/Modernizr/issues/issue/97/ + var el = document.createElement('canvas'); + return !!(el.getContext && el.getContext('2d')); + }()), + + return_response_type: function(responseType) { + try { + if (Basic.inArray(responseType, ['', 'text', 'document']) !== -1) { + return true; + } else if (window.XMLHttpRequest) { + var xhr = new XMLHttpRequest(); + xhr.open('get', '/'); // otherwise Gecko throws an exception + if ('responseType' in xhr) { + xhr.responseType = responseType; + // as of 23.0.1271.64, Chrome switched from throwing exception to merely logging it to the console (why? o why?) + if (xhr.responseType !== responseType) { + return false; + } + return true; + } + } + } catch (ex) {} + return false; + }, + + // ideas for this heavily come from Modernizr (http://modernizr.com/) + use_data_uri: (function() { + var du = new Image(); + + du.onload = function() { + caps.use_data_uri = (du.width === 1 && du.height === 1); + }; + + setTimeout(function() { + du.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="; + }, 1); + return false; + }()), + + use_data_uri_over32kb: function() { // IE8 + return caps.use_data_uri && (Env.browser !== 'IE' || Env.version >= 9); + }, + + use_data_uri_of: function(bytes) { + return (caps.use_data_uri && bytes < 33000 || caps.use_data_uri_over32kb()); + }, + + use_fileinput: function() { + if (navigator.userAgent.match(/(Android (1.0|1.1|1.5|1.6|2.0|2.1))|(Windows Phone (OS 7|8.0))|(XBLWP)|(ZuneWP)|(w(eb)?OSBrowser)|(webOS)|(Kindle\/(1.0|2.0|2.5|3.0))/)) { + return false; + } + + var el = document.createElement('input'); + el.setAttribute('type', 'file'); + return !el.disabled; + } + }; + + return function(cap) { + var args = [].slice.call(arguments); + args.shift(); // shift of cap + return Basic.typeOf(caps[cap]) === 'function' ? caps[cap].apply(this, args) : !!caps[cap]; + }; + }()); + + + var uaResult = new UAParser().getResult(); + + + var Env = { + can: can, + + uaParser: UAParser, + + browser: uaResult.browser.name, + version: uaResult.browser.version, + os: uaResult.os.name, // everybody intuitively types it in a lowercase for some reason + osVersion: uaResult.os.version, + + verComp: version_compare, + + swf_url: "../flash/Moxie.swf", + xap_url: "../silverlight/Moxie.xap", + global_event_dispatcher: "moxie.core.EventTarget.instance.dispatchEvent" + }; + + // for backward compatibility + // @deprecated Use `Env.os` instead + Env.OS = Env.os; + + if (MXI_DEBUG) { + Env.debug = { + runtime: true, + events: false + }; + + Env.log = function() { + + function logObj(data) { + // TODO: this should recursively print out the object in a pretty way + console.appendChild(document.createTextNode(data + "\n")); + } + + var data = arguments[0]; + + if (Basic.typeOf(data) === 'string') { + data = Basic.sprintf.apply(this, arguments); + } + + if (window && window.console && window.console.log) { + window.console.log(data); + } else if (document) { + var console = document.getElementById('moxie-console'); + if (!console) { + console = document.createElement('pre'); + console.id = 'moxie-console'; + //console.style.display = 'none'; + document.body.appendChild(console); + } + + if (Basic.inArray(Basic.typeOf(data), ['object', 'array']) !== -1) { + logObj(data); + } else { + console.appendChild(document.createTextNode(data + "\n")); + } + } + }; + } + + return Env; +}); + +// Included from: src/javascript/core/Exceptions.js + +/** + * Exceptions.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/Exceptions', [ + 'moxie/core/utils/Basic' +], function(Basic) { + + function _findKey(obj, value) { + var key; + for (key in obj) { + if (obj[key] === value) { + return key; + } + } + return null; + } + + /** + @class moxie/core/Exception + */ + return { + RuntimeError: (function() { + var namecodes = { + NOT_INIT_ERR: 1, + EXCEPTION_ERR: 3, + NOT_SUPPORTED_ERR: 9, + JS_ERR: 4 + }; + + function RuntimeError(code, message) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + (message || ": RuntimeError " + this.code); + } + + Basic.extend(RuntimeError, namecodes); + RuntimeError.prototype = Error.prototype; + return RuntimeError; + }()), + + OperationNotAllowedException: (function() { + + function OperationNotAllowedException(code) { + this.code = code; + this.name = 'OperationNotAllowedException'; + } + + Basic.extend(OperationNotAllowedException, { + NOT_ALLOWED_ERR: 1 + }); + + OperationNotAllowedException.prototype = Error.prototype; + + return OperationNotAllowedException; + }()), + + ImageError: (function() { + var namecodes = { + WRONG_FORMAT: 1, + MAX_RESOLUTION_ERR: 2, + INVALID_META_ERR: 3 + }; + + function ImageError(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": ImageError " + this.code; + } + + Basic.extend(ImageError, namecodes); + ImageError.prototype = Error.prototype; + + return ImageError; + }()), + + FileException: (function() { + var namecodes = { + NOT_FOUND_ERR: 1, + SECURITY_ERR: 2, + ABORT_ERR: 3, + NOT_READABLE_ERR: 4, + ENCODING_ERR: 5, + NO_MODIFICATION_ALLOWED_ERR: 6, + INVALID_STATE_ERR: 7, + SYNTAX_ERR: 8 + }; + + function FileException(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": FileException " + this.code; + } + + Basic.extend(FileException, namecodes); + FileException.prototype = Error.prototype; + return FileException; + }()), + + DOMException: (function() { + var namecodes = { + INDEX_SIZE_ERR: 1, + DOMSTRING_SIZE_ERR: 2, + HIERARCHY_REQUEST_ERR: 3, + WRONG_DOCUMENT_ERR: 4, + INVALID_CHARACTER_ERR: 5, + NO_DATA_ALLOWED_ERR: 6, + NO_MODIFICATION_ALLOWED_ERR: 7, + NOT_FOUND_ERR: 8, + NOT_SUPPORTED_ERR: 9, + INUSE_ATTRIBUTE_ERR: 10, + INVALID_STATE_ERR: 11, + SYNTAX_ERR: 12, + INVALID_MODIFICATION_ERR: 13, + NAMESPACE_ERR: 14, + INVALID_ACCESS_ERR: 15, + VALIDATION_ERR: 16, + TYPE_MISMATCH_ERR: 17, + SECURITY_ERR: 18, + NETWORK_ERR: 19, + ABORT_ERR: 20, + URL_MISMATCH_ERR: 21, + QUOTA_EXCEEDED_ERR: 22, + TIMEOUT_ERR: 23, + INVALID_NODE_TYPE_ERR: 24, + DATA_CLONE_ERR: 25 + }; + + function DOMException(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": DOMException " + this.code; + } + + Basic.extend(DOMException, namecodes); + DOMException.prototype = Error.prototype; + return DOMException; + }()), + + EventException: (function() { + function EventException(code) { + this.code = code; + this.name = 'EventException'; + } + + Basic.extend(EventException, { + UNSPECIFIED_EVENT_TYPE_ERR: 0 + }); + + EventException.prototype = Error.prototype; + + return EventException; + }()) + }; +}); + +// Included from: src/javascript/core/utils/Dom.js + +/** + * Dom.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Dom', ['moxie/core/utils/Env'], function(Env) { + + /** + Get DOM Element by it's id. + + @method get + @for Utils + @param {String} id Identifier of the DOM Element + @return {DOMElement} + */ + var get = function(id) { + if (typeof id !== 'string') { + return id; + } + return document.getElementById(id); + }; + + /** + Checks if specified DOM element has specified class. + + @method hasClass + @static + @param {Object} obj DOM element like object to add handler to. + @param {String} name Class name + */ + var hasClass = function(obj, name) { + if (!obj.className) { + return false; + } + + var regExp = new RegExp("(^|\\s+)"+name+"(\\s+|$)"); + return regExp.test(obj.className); + }; + + /** + Adds specified className to specified DOM element. + + @method addClass + @static + @param {Object} obj DOM element like object to add handler to. + @param {String} name Class name + */ + var addClass = function(obj, name) { + if (!hasClass(obj, name)) { + obj.className = !obj.className ? name : obj.className.replace(/\s+$/, '') + ' ' + name; + } + }; + + /** + Removes specified className from specified DOM element. + + @method removeClass + @static + @param {Object} obj DOM element like object to add handler to. + @param {String} name Class name + */ + var removeClass = function(obj, name) { + if (obj.className) { + var regExp = new RegExp("(^|\\s+)"+name+"(\\s+|$)"); + obj.className = obj.className.replace(regExp, function($0, $1, $2) { + return $1 === ' ' && $2 === ' ' ? ' ' : ''; + }); + } + }; + + /** + Returns a given computed style of a DOM element. + + @method getStyle + @static + @param {Object} obj DOM element like object. + @param {String} name Style you want to get from the DOM element + */ + var getStyle = function(obj, name) { + if (obj.currentStyle) { + return obj.currentStyle[name]; + } else if (window.getComputedStyle) { + return window.getComputedStyle(obj, null)[name]; + } + }; + + + /** + Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields. + + @method getPos + @static + @param {Element} node HTML element or element id to get x, y position from. + @param {Element} root Optional root element to stop calculations at. + @return {object} Absolute position of the specified element object with x, y fields. + */ + var getPos = function(node, root) { + var x = 0, y = 0, parent, doc = document, nodeRect, rootRect; + + node = node; + root = root || doc.body; + + // Returns the x, y cordinate for an element on IE 6 and IE 7 + function getIEPos(node) { + var bodyElm, rect, x = 0, y = 0; + + if (node) { + rect = node.getBoundingClientRect(); + bodyElm = doc.compatMode === "CSS1Compat" ? doc.documentElement : doc.body; + x = rect.left + bodyElm.scrollLeft; + y = rect.top + bodyElm.scrollTop; + } + + return { + x : x, + y : y + }; + } + + // Use getBoundingClientRect on IE 6 and IE 7 but not on IE 8 in standards mode + if (node && node.getBoundingClientRect && Env.browser === 'IE' && (!doc.documentMode || doc.documentMode < 8)) { + nodeRect = getIEPos(node); + rootRect = getIEPos(root); + + return { + x : nodeRect.x - rootRect.x, + y : nodeRect.y - rootRect.y + }; + } + + parent = node; + while (parent && parent != root && parent.nodeType) { + x += parent.offsetLeft || 0; + y += parent.offsetTop || 0; + parent = parent.offsetParent; + } + + parent = node.parentNode; + while (parent && parent != root && parent.nodeType) { + x -= parent.scrollLeft || 0; + y -= parent.scrollTop || 0; + parent = parent.parentNode; + } + + return { + x : x, + y : y + }; + }; + + /** + Returns the size of the specified node in pixels. + + @method getSize + @static + @param {Node} node Node to get the size of. + @return {Object} Object with a w and h property. + */ + var getSize = function(node) { + return { + w : node.offsetWidth || node.clientWidth, + h : node.offsetHeight || node.clientHeight + }; + }; + + return { + get: get, + hasClass: hasClass, + addClass: addClass, + removeClass: removeClass, + getStyle: getStyle, + getPos: getPos, + getSize: getSize + }; +}); + +// Included from: src/javascript/core/EventTarget.js + +/** + * EventTarget.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/EventTarget', [ + 'moxie/core/utils/Env', + 'moxie/core/Exceptions', + 'moxie/core/utils/Basic' +], function(Env, x, Basic) { + + // hash of event listeners by object uid + var eventpool = {}; + + /** + Parent object for all event dispatching components and objects + + @class moxie/core/EventTarget + @constructor EventTarget + */ + function EventTarget() { + /** + Unique id of the event dispatcher, usually overriden by children + + @property uid + @type String + */ + this.uid = Basic.guid(); + } + + + Basic.extend(EventTarget.prototype, { + + /** + Can be called from within a child in order to acquire uniqie id in automated manner + + @method init + */ + init: function() { + if (!this.uid) { + this.uid = Basic.guid('uid_'); + } + }, + + /** + Register a handler to a specific event dispatched by the object + + @method addEventListener + @param {String} type Type or basically a name of the event to subscribe to + @param {Function} fn Callback function that will be called when event happens + @param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first + @param {Object} [scope=this] A scope to invoke event handler in + */ + addEventListener: function(type, fn, priority, scope) { + var self = this, list; + + // without uid no event handlers can be added, so make sure we got one + if (!this.hasOwnProperty('uid')) { + this.uid = Basic.guid('uid_'); + } + + type = Basic.trim(type); + + if (/\s/.test(type)) { + // multiple event types were passed for one handler + Basic.each(type.split(/\s+/), function(type) { + self.addEventListener(type, fn, priority, scope); + }); + return; + } + + type = type.toLowerCase(); + priority = parseInt(priority, 10) || 0; + + list = eventpool[this.uid] && eventpool[this.uid][type] || []; + list.push({fn : fn, priority : priority, scope : scope || this}); + + if (!eventpool[this.uid]) { + eventpool[this.uid] = {}; + } + eventpool[this.uid][type] = list; + }, + + /** + Check if any handlers were registered to the specified event + + @method hasEventListener + @param {String} [type] Type or basically a name of the event to check + @return {Mixed} Returns a handler if it was found and false, if - not + */ + hasEventListener: function(type) { + var list; + if (type) { + type = type.toLowerCase(); + list = eventpool[this.uid] && eventpool[this.uid][type]; + } else { + list = eventpool[this.uid]; + } + return list ? list : false; + }, + + /** + Unregister the handler from the event, or if former was not specified - unregister all handlers + + @method removeEventListener + @param {String} type Type or basically a name of the event + @param {Function} [fn] Handler to unregister + */ + removeEventListener: function(type, fn) { + var self = this, list, i; + + type = type.toLowerCase(); + + if (/\s/.test(type)) { + // multiple event types were passed for one handler + Basic.each(type.split(/\s+/), function(type) { + self.removeEventListener(type, fn); + }); + return; + } + + list = eventpool[this.uid] && eventpool[this.uid][type]; + + if (list) { + if (fn) { + for (i = list.length - 1; i >= 0; i--) { + if (list[i].fn === fn) { + list.splice(i, 1); + break; + } + } + } else { + list = []; + } + + // delete event list if it has become empty + if (!list.length) { + delete eventpool[this.uid][type]; + + // and object specific entry in a hash if it has no more listeners attached + if (Basic.isEmptyObj(eventpool[this.uid])) { + delete eventpool[this.uid]; + } + } + } + }, + + /** + Remove all event handlers from the object + + @method removeAllEventListeners + */ + removeAllEventListeners: function() { + if (eventpool[this.uid]) { + delete eventpool[this.uid]; + } + }, + + /** + Dispatch the event + + @method dispatchEvent + @param {String/Object} Type of event or event object to dispatch + @param {Mixed} [...] Variable number of arguments to be passed to a handlers + @return {Boolean} true by default and false if any handler returned false + */ + dispatchEvent: function(type) { + var uid, list, args, tmpEvt, evt = {}, result = true, undef; + + if (Basic.typeOf(type) !== 'string') { + // we can't use original object directly (because of Silverlight) + tmpEvt = type; + + if (Basic.typeOf(tmpEvt.type) === 'string') { + type = tmpEvt.type; + + if (tmpEvt.total !== undef && tmpEvt.loaded !== undef) { // progress event + evt.total = tmpEvt.total; + evt.loaded = tmpEvt.loaded; + } + evt.async = tmpEvt.async || false; + } else { + throw new x.EventException(x.EventException.UNSPECIFIED_EVENT_TYPE_ERR); + } + } + + // check if event is meant to be dispatched on an object having specific uid + if (type.indexOf('::') !== -1) { + (function(arr) { + uid = arr[0]; + type = arr[1]; + }(type.split('::'))); + } else { + uid = this.uid; + } + + type = type.toLowerCase(); + + list = eventpool[uid] && eventpool[uid][type]; + + if (list) { + // sort event list by prority + list.sort(function(a, b) { return b.priority - a.priority; }); + + args = [].slice.call(arguments); + + // first argument will be pseudo-event object + args.shift(); + evt.type = type; + args.unshift(evt); + + if (MXI_DEBUG && Env.debug.events) { + Env.log("Event '%s' fired on %u", evt.type, uid); + } + + // Dispatch event to all listeners + var queue = []; + Basic.each(list, function(handler) { + // explicitly set the target, otherwise events fired from shims do not get it + args[0].target = handler.scope; + // if event is marked as async, detach the handler + if (evt.async) { + queue.push(function(cb) { + setTimeout(function() { + cb(handler.fn.apply(handler.scope, args) === false); + }, 1); + }); + } else { + queue.push(function(cb) { + cb(handler.fn.apply(handler.scope, args) === false); // if handler returns false stop propagation + }); + } + }); + if (queue.length) { + Basic.inSeries(queue, function(err) { + result = !err; + }); + } + } + return result; + }, + + /** + Register a handler to the event type that will run only once + + @method bindOnce + @since >1.4.1 + @param {String} type Type or basically a name of the event to subscribe to + @param {Function} fn Callback function that will be called when event happens + @param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first + @param {Object} [scope=this] A scope to invoke event handler in + */ + bindOnce: function(type, fn, priority, scope) { + var self = this; + self.bind.call(this, type, function cb() { + self.unbind(type, cb); + return fn.apply(this, arguments); + }, priority, scope); + }, + + /** + Alias for addEventListener + + @method bind + @protected + */ + bind: function() { + this.addEventListener.apply(this, arguments); + }, + + /** + Alias for removeEventListener + + @method unbind + @protected + */ + unbind: function() { + this.removeEventListener.apply(this, arguments); + }, + + /** + Alias for removeAllEventListeners + + @method unbindAll + @protected + */ + unbindAll: function() { + this.removeAllEventListeners.apply(this, arguments); + }, + + /** + Alias for dispatchEvent + + @method trigger + @protected + */ + trigger: function() { + return this.dispatchEvent.apply(this, arguments); + }, + + + /** + Handle properties of on[event] type. + + @method handleEventProps + @private + */ + handleEventProps: function(dispatches) { + var self = this; + + this.bind(dispatches.join(' '), function(e) { + var prop = 'on' + e.type.toLowerCase(); + if (Basic.typeOf(this[prop]) === 'function') { + this[prop].apply(this, arguments); + } + }); + + // object must have defined event properties, even if it doesn't make use of them + Basic.each(dispatches, function(prop) { + prop = 'on' + prop.toLowerCase(prop); + if (Basic.typeOf(self[prop]) === 'undefined') { + self[prop] = null; + } + }); + } + + }); + + + EventTarget.instance = new EventTarget(); + + return EventTarget; +}); + +// Included from: src/javascript/runtime/Runtime.js + +/** + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/runtime/Runtime', [ + "moxie/core/utils/Env", + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/EventTarget" +], function(Env, Basic, Dom, EventTarget) { + var runtimeConstructors = {}, runtimes = {}; + + /** + Common set of methods and properties for every runtime instance + + @class moxie/runtime/Runtime + + @param {Object} options + @param {String} type Sanitized name of the runtime + @param {Object} [caps] Set of capabilities that differentiate specified runtime + @param {Object} [modeCaps] Set of capabilities that do require specific operational mode + @param {String} [preferredMode='browser'] Preferred operational mode to choose if no required capabilities were requested + */ + function Runtime(options, type, caps, modeCaps, preferredMode) { + /** + Dispatched when runtime is initialized and ready. + Results in RuntimeInit on a connected component. + + @event Init + */ + + /** + Dispatched when runtime fails to initialize. + Results in RuntimeError on a connected component. + + @event Error + */ + + var self = this + , _shim + , _uid = Basic.guid(type + '_') + , defaultMode = preferredMode || 'browser' + ; + + options = options || {}; + + // register runtime in private hash + runtimes[_uid] = this; + + /** + Default set of capabilities, which can be redifined later by specific runtime + + @private + @property caps + @type Object + */ + caps = Basic.extend({ + // Runtime can: + // provide access to raw binary data of the file + access_binary: false, + // provide access to raw binary data of the image (image extension is optional) + access_image_binary: false, + // display binary data as thumbs for example + display_media: false, + // make cross-domain requests + do_cors: false, + // accept files dragged and dropped from the desktop + drag_and_drop: false, + // filter files in selection dialog by their extensions + filter_by_extension: true, + // resize image (and manipulate it raw data of any file in general) + resize_image: false, + // periodically report how many bytes of total in the file were uploaded (loaded) + report_upload_progress: false, + // provide access to the headers of http response + return_response_headers: false, + // support response of specific type, which should be passed as an argument + // e.g. runtime.can('return_response_type', 'blob') + return_response_type: false, + // return http status code of the response + return_status_code: true, + // send custom http header with the request + send_custom_headers: false, + // pick up the files from a dialog + select_file: false, + // select whole folder in file browse dialog + select_folder: false, + // select multiple files at once in file browse dialog + select_multiple: true, + // send raw binary data, that is generated after image resizing or manipulation of other kind + send_binary_string: false, + // send cookies with http request and therefore retain session + send_browser_cookies: true, + // send data formatted as multipart/form-data + send_multipart: true, + // slice the file or blob to smaller parts + slice_blob: false, + // upload file without preloading it to memory, stream it out directly from disk + stream_upload: false, + // programmatically trigger file browse dialog + summon_file_dialog: false, + // upload file of specific size, size should be passed as argument + // e.g. runtime.can('upload_filesize', '500mb') + upload_filesize: true, + // initiate http request with specific http method, method should be passed as argument + // e.g. runtime.can('use_http_method', 'put') + use_http_method: true + }, caps); + + + // default to the mode that is compatible with preferred caps + if (options.preferred_caps) { + defaultMode = Runtime.getMode(modeCaps, options.preferred_caps, defaultMode); + } + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\tdefault mode: %s", defaultMode); + } + + // small extension factory here (is meant to be extended with actual extensions constructors) + _shim = (function() { + var objpool = {}; + return { + exec: function(uid, comp, fn, args) { + if (_shim[comp]) { + if (!objpool[uid]) { + objpool[uid] = { + context: this, + instance: new _shim[comp]() + }; + } + if (objpool[uid].instance[fn]) { + return objpool[uid].instance[fn].apply(this, args); + } + } + }, + + removeInstance: function(uid) { + delete objpool[uid]; + }, + + removeAllInstances: function() { + var self = this; + Basic.each(objpool, function(obj, uid) { + if (Basic.typeOf(obj.instance.destroy) === 'function') { + obj.instance.destroy.call(obj.context); + } + self.removeInstance(uid); + }); + } + }; + }()); + + + // public methods + Basic.extend(this, { + /** + Specifies whether runtime instance was initialized or not + + @property initialized + @type {Boolean} + @default false + */ + initialized: false, // shims require this flag to stop initialization retries + + /** + Unique ID of the runtime + + @property uid + @type {String} + */ + uid: _uid, + + /** + Runtime type (e.g. flash, html5, etc) + + @property type + @type {String} + */ + type: type, + + /** + Runtime (not native one) may operate in browser or client mode. + + @property mode + @private + @type {String|Boolean} current mode or false, if none possible + */ + mode: Runtime.getMode(modeCaps, (options.required_caps), defaultMode), + + /** + id of the DOM container for the runtime (if available) + + @property shimid + @type {String} + */ + shimid: _uid + '_container', + + /** + Number of connected clients. If equal to zero, runtime can be destroyed + + @property clients + @type {Number} + */ + clients: 0, + + /** + Runtime initialization options + + @property options + @type {Object} + */ + options: options, + + /** + Checks if the runtime has specific capability + + @method can + @param {String} cap Name of capability to check + @param {Mixed} [value] If passed, capability should somehow correlate to the value + @param {Object} [refCaps] Set of capabilities to check the specified cap against (defaults to internal set) + @return {Boolean} true if runtime has such capability and false, if - not + */ + can: function(cap, value) { + var refCaps = arguments[2] || caps; + + // if cap var is a comma-separated list of caps, convert it to object (key/value) + if (Basic.typeOf(cap) === 'string' && Basic.typeOf(value) === 'undefined') { + cap = Runtime.parseCaps(cap); + } + + if (Basic.typeOf(cap) === 'object') { + for (var key in cap) { + if (!this.can(key, cap[key], refCaps)) { + return false; + } + } + return true; + } + + // check the individual cap + if (Basic.typeOf(refCaps[cap]) === 'function') { + return refCaps[cap].call(this, value); + } else { + return (value === refCaps[cap]); + } + }, + + /** + Returns container for the runtime as DOM element + + @method getShimContainer + @return {DOMElement} + */ + getShimContainer: function() { + var container, shimContainer = Dom.get(this.shimid); + + // if no container for shim, create one + if (!shimContainer) { + container = Dom.get(this.options.container) || document.body; + + // create shim container and insert it at an absolute position into the outer container + shimContainer = document.createElement('div'); + shimContainer.id = this.shimid; + shimContainer.className = 'moxie-shim moxie-shim-' + this.type; + + Basic.extend(shimContainer.style, { + position: 'absolute', + top: '0px', + left: '0px', + width: '1px', + height: '1px', + overflow: 'hidden' + }); + + container.appendChild(shimContainer); + container = null; + } + + return shimContainer; + }, + + /** + Returns runtime as DOM element (if appropriate) + + @method getShim + @return {DOMElement} + */ + getShim: function() { + return _shim; + }, + + /** + Invokes a method within the runtime itself (might differ across the runtimes) + + @method shimExec + @param {Mixed} [] + @protected + @return {Mixed} Depends on the action and component + */ + shimExec: function(component, action) { + var args = [].slice.call(arguments, 2); + return self.getShim().exec.call(this, this.uid, component, action, args); + }, + + /** + Operaional interface that is used by components to invoke specific actions on the runtime + (is invoked in the scope of component) + + @method exec + @param {Mixed} []* + @protected + @return {Mixed} Depends on the action and component + */ + exec: function(component, action) { // this is called in the context of component, not runtime + var args = [].slice.call(arguments, 2); + + if (self[component] && self[component][action]) { + return self[component][action].apply(this, args); + } + return self.shimExec.apply(this, arguments); + }, + + /** + Destroys the runtime (removes all events and deletes DOM structures) + + @method destroy + */ + destroy: function() { + if (!self) { + return; // obviously already destroyed + } + + var shimContainer = Dom.get(this.shimid); + if (shimContainer) { + shimContainer.parentNode.removeChild(shimContainer); + } + + if (_shim) { + _shim.removeAllInstances(); + } + + this.unbindAll(); + delete runtimes[this.uid]; + this.uid = null; // mark this runtime as destroyed + _uid = self = _shim = shimContainer = null; + } + }); + + // once we got the mode, test against all caps + if (this.mode && options.required_caps && !this.can(options.required_caps)) { + this.mode = false; + } + } + + + /** + Default order to try different runtime types + + @property order + @type String + @static + */ + Runtime.order = 'html5,flash,silverlight,html4'; + + + /** + Retrieves runtime from private hash by it's uid + + @method getRuntime + @private + @static + @param {String} uid Unique identifier of the runtime + @return {Runtime|Boolean} Returns runtime, if it exists and false, if - not + */ + Runtime.getRuntime = function(uid) { + return runtimes[uid] ? runtimes[uid] : false; + }; + + + /** + Register constructor for the Runtime of new (or perhaps modified) type + + @method addConstructor + @static + @param {String} type Runtime type (e.g. flash, html5, etc) + @param {Function} construct Constructor for the Runtime type + */ + Runtime.addConstructor = function(type, constructor) { + constructor.prototype = EventTarget.instance; + runtimeConstructors[type] = constructor; + }; + + + /** + Get the constructor for the specified type. + + method getConstructor + @static + @param {String} type Runtime type (e.g. flash, html5, etc) + @return {Function} Constructor for the Runtime type + */ + Runtime.getConstructor = function(type) { + return runtimeConstructors[type] || null; + }; + + + /** + Get info about the runtime (uid, type, capabilities) + + @method getInfo + @static + @param {String} uid Unique identifier of the runtime + @return {Mixed} Info object or null if runtime doesn't exist + */ + Runtime.getInfo = function(uid) { + var runtime = Runtime.getRuntime(uid); + + if (runtime) { + return { + uid: runtime.uid, + type: runtime.type, + mode: runtime.mode, + can: function() { + return runtime.can.apply(runtime, arguments); + } + }; + } + return null; + }; + + + /** + Convert caps represented by a comma-separated string to the object representation. + + @method parseCaps + @static + @param {String} capStr Comma-separated list of capabilities + @return {Object} + */ + Runtime.parseCaps = function(capStr) { + var capObj = {}; + + if (Basic.typeOf(capStr) !== 'string') { + return capStr || {}; + } + + Basic.each(capStr.split(','), function(key) { + capObj[key] = true; // we assume it to be - true + }); + + return capObj; + }; + + /** + Test the specified runtime for specific capabilities. + + @method can + @static + @param {String} type Runtime type (e.g. flash, html5, etc) + @param {String|Object} caps Set of capabilities to check + @return {Boolean} Result of the test + */ + Runtime.can = function(type, caps) { + var runtime + , constructor = Runtime.getConstructor(type) + , mode + ; + if (constructor) { + runtime = new constructor({ + required_caps: caps + }); + mode = runtime.mode; + runtime.destroy(); + return !!mode; + } + return false; + }; + + + /** + Figure out a runtime that supports specified capabilities. + + @method thatCan + @static + @param {String|Object} caps Set of capabilities to check + @param {String} [runtimeOrder] Comma-separated list of runtimes to check against + @return {String} Usable runtime identifier or null + */ + Runtime.thatCan = function(caps, runtimeOrder) { + var types = (runtimeOrder || Runtime.order).split(/\s*,\s*/); + for (var i in types) { + if (Runtime.can(types[i], caps)) { + return types[i]; + } + } + return null; + }; + + + /** + Figure out an operational mode for the specified set of capabilities. + + @method getMode + @static + @param {Object} modeCaps Set of capabilities that depend on particular runtime mode + @param {Object} [requiredCaps] Supplied set of capabilities to find operational mode for + @param {String|Boolean} [defaultMode='browser'] Default mode to use + @return {String|Boolean} Compatible operational mode + */ + Runtime.getMode = function(modeCaps, requiredCaps, defaultMode) { + var mode = null; + + if (Basic.typeOf(defaultMode) === 'undefined') { // only if not specified + defaultMode = 'browser'; + } + + if (requiredCaps && !Basic.isEmptyObj(modeCaps)) { + // loop over required caps and check if they do require the same mode + Basic.each(requiredCaps, function(value, cap) { + if (modeCaps.hasOwnProperty(cap)) { + var capMode = modeCaps[cap](value); + + // make sure we always have an array + if (typeof(capMode) === 'string') { + capMode = [capMode]; + } + + if (!mode) { + mode = capMode; + } else if (!(mode = Basic.arrayIntersect(mode, capMode))) { + // if cap requires conflicting mode - runtime cannot fulfill required caps + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\t\t%c: %v (conflicting mode requested: %s)", cap, value, capMode); + } + + return (mode = false); + } + } + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\t\t%c: %v (compatible modes: %s)", cap, value, mode); + } + }); + + if (mode) { + return Basic.inArray(defaultMode, mode) !== -1 ? defaultMode : mode[0]; + } else if (mode === false) { + return false; + } + } + return defaultMode; + }; + + + /** + Capability check that always returns true + + @private + @static + @return {True} + */ + Runtime.capTrue = function() { + return true; + }; + + /** + Capability check that always returns false + + @private + @static + @return {False} + */ + Runtime.capFalse = function() { + return false; + }; + + /** + Evaluate the expression to boolean value and create a function that always returns it. + + @private + @static + @param {Mixed} expr Expression to evaluate + @return {Function} Function returning the result of evaluation + */ + Runtime.capTest = function(expr) { + return function() { + return !!expr; + }; + }; + + return Runtime; +}); + +// Included from: src/javascript/runtime/RuntimeClient.js + +/** + * RuntimeClient.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/runtime/RuntimeClient', [ + 'moxie/core/utils/Env', + 'moxie/core/Exceptions', + 'moxie/core/utils/Basic', + 'moxie/runtime/Runtime' +], function(Env, x, Basic, Runtime) { + /** + Set of methods and properties, required by a component to acquire ability to connect to a runtime + + @class moxie/runtime/RuntimeClient + */ + return function RuntimeClient() { + var runtime; + + Basic.extend(this, { + /** + Connects to the runtime specified by the options. Will either connect to existing runtime or create a new one. + Increments number of clients connected to the specified runtime. + + @private + @method connectRuntime + @param {Mixed} options Can be a runtme uid or a set of key-value pairs defining requirements and pre-requisites + */ + connectRuntime: function(options) { + var comp = this, ruid; + + function initialize(items) { + var type, constructor; + + // if we ran out of runtimes + if (!items.length) { + comp.trigger('RuntimeError', new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR)); + runtime = null; + return; + } + + type = items.shift().toLowerCase(); + constructor = Runtime.getConstructor(type); + if (!constructor) { + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("Constructor for '%s' runtime is not available.", type); + } + initialize(items); + return; + } + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("Trying runtime: %s", type); + Env.log(options); + } + + // try initializing the runtime + runtime = new constructor(options); + + runtime.bind('Init', function() { + // mark runtime as initialized + runtime.initialized = true; + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("Runtime '%s' initialized", runtime.type); + } + + // jailbreak ... + setTimeout(function() { + runtime.clients++; + comp.ruid = runtime.uid; + // this will be triggered on component + comp.trigger('RuntimeInit', runtime); + }, 1); + }); + + runtime.bind('Error', function() { + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("Runtime '%s' failed to initialize", runtime.type); + } + + runtime.destroy(); // runtime cannot destroy itself from inside at a right moment, thus we do it here + initialize(items); + }); + + runtime.bind('Exception', function(e, err) { + var message = err.name + "(#" + err.code + ")" + (err.message ? ", from: " + err.message : ''); + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("Runtime '%s' has thrown an exception: %s", this.type, message); + } + comp.trigger('RuntimeError', new x.RuntimeError(x.RuntimeError.EXCEPTION_ERR, message)); + }); + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\tselected mode: %s", runtime.mode); + } + + // check if runtime managed to pick-up operational mode + if (!runtime.mode) { + runtime.trigger('Error'); + return; + } + + runtime.init(); + } + + // check if a particular runtime was requested + if (Basic.typeOf(options) === 'string') { + ruid = options; + } else if (Basic.typeOf(options.ruid) === 'string') { + ruid = options.ruid; + } + + if (ruid) { + runtime = Runtime.getRuntime(ruid); + if (runtime) { + comp.ruid = ruid; + runtime.clients++; + return runtime; + } else { + // there should be a runtime and there's none - weird case + throw new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR); + } + } + + // initialize a fresh one, that fits runtime list and required features best + initialize((options.runtime_order || Runtime.order).split(/\s*,\s*/)); + }, + + + /** + Disconnects from the runtime. Decrements number of clients connected to the specified runtime. + + @private + @method disconnectRuntime + */ + disconnectRuntime: function() { + if (runtime && --runtime.clients <= 0) { + runtime.destroy(); + } + + // once the component is disconnected, it shouldn't have access to the runtime + runtime = null; + }, + + + /** + Returns the runtime to which the client is currently connected. + + @method getRuntime + @return {Runtime} Runtime or null if client is not connected + */ + getRuntime: function() { + if (runtime && runtime.uid) { + return runtime; + } + return runtime = null; // make sure we do not leave zombies rambling around + }, + + + /** + Handy shortcut to safely invoke runtime extension methods. + + @private + @method exec + @return {Mixed} Whatever runtime extension method returns + */ + exec: function() { + return runtime ? runtime.exec.apply(this, arguments) : null; + }, + + + /** + Test runtime client for specific capability + + @method can + @param {String} cap + @return {Bool} + */ + can: function(cap) { + return runtime ? runtime.can(cap) : false; + } + + }); + }; + + +}); + +// Included from: src/javascript/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/Blob', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Encode', + 'moxie/runtime/RuntimeClient' +], function(Basic, Encode, RuntimeClient) { + + var blobpool = {}; + + /** + @class moxie/file/Blob + @constructor + @param {String} ruid Unique id of the runtime, to which this blob belongs to + @param {Object} blob Object "Native" blob object, as it is represented in the runtime + */ + function Blob(ruid, blob) { + + function _sliceDetached(start, end, type) { + var blob, data = blobpool[this.uid]; + + if (Basic.typeOf(data) !== 'string' || !data.length) { + return null; // or throw exception + } + + blob = new Blob(null, { + type: type, + size: end - start + }); + blob.detach(data.substr(start, blob.size)); + + return blob; + } + + RuntimeClient.call(this); + + if (ruid) { + this.connectRuntime(ruid); + } + + if (!blob) { + blob = {}; + } else if (Basic.typeOf(blob) === 'string') { // dataUrl or binary string + blob = { data: blob }; + } + + Basic.extend(this, { + + /** + Unique id of the component + + @property uid + @type {String} + */ + uid: blob.uid || Basic.guid('uid_'), + + /** + Unique id of the connected runtime, if falsy, then runtime will have to be initialized + before this Blob can be used, modified or sent + + @property ruid + @type {String} + */ + ruid: ruid, + + /** + Size of blob + + @property size + @type {Number} + @default 0 + */ + size: blob.size || 0, + + /** + Mime type of blob + + @property type + @type {String} + @default '' + */ + type: blob.type || '', + + /** + @method slice + @param {Number} [start=0] + */ + slice: function(start, end, type) { + if (this.isDetached()) { + return _sliceDetached.apply(this, arguments); + } + return this.getRuntime().exec.call(this, 'Blob', 'slice', this.getSource(), start, end, type); + }, + + /** + Returns "native" blob object (as it is represented in connected runtime) or null if not found + + @method getSource + @return {Blob} Returns "native" blob object or null if not found + */ + getSource: function() { + if (!blobpool[this.uid]) { + return null; + } + return blobpool[this.uid]; + }, + + /** + Detaches blob from any runtime that it depends on and initialize with standalone value + + @method detach + @protected + @param {DOMString} [data=''] Standalone value + */ + detach: function(data) { + if (this.ruid) { + this.getRuntime().exec.call(this, 'Blob', 'destroy'); + this.disconnectRuntime(); + this.ruid = null; + } + + data = data || ''; + + // if dataUrl, convert to binary string + if (data.substr(0, 5) == 'data:') { + var base64Offset = data.indexOf(';base64,'); + this.type = data.substring(5, base64Offset); + data = Encode.atob(data.substring(base64Offset + 8)); + } + + this.size = data.length; + + blobpool[this.uid] = data; + }, + + /** + Checks if blob is standalone (detached of any runtime) + + @method isDetached + @protected + @return {Boolean} + */ + isDetached: function() { + return !this.ruid && Basic.typeOf(blobpool[this.uid]) === 'string'; + }, + + /** + Destroy Blob and free any resources it was using + + @method destroy + */ + destroy: function() { + this.detach(); + delete blobpool[this.uid]; + } + }); + + + if (blob.data) { + this.detach(blob.data); // auto-detach if payload has been passed + } else { + blobpool[this.uid] = blob; + } + } + + return Blob; +}); + +// Included from: src/javascript/core/I18n.js + +/** + * I18n.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/core/I18n", [ + "moxie/core/utils/Basic" +], function(Basic) { + var i18n = {}; + + /** + @class moxie/core/I18n + */ + return { + /** + * Extends the language pack object with new items. + * + * @param {Object} pack Language pack items to add. + * @return {Object} Extended language pack object. + */ + addI18n: function(pack) { + return Basic.extend(i18n, pack); + }, + + /** + * Translates the specified string by checking for the english string in the language pack lookup. + * + * @param {String} str String to look for. + * @return {String} Translated string or the input string if it wasn't found. + */ + translate: function(str) { + return i18n[str] || str; + }, + + /** + * Shortcut for translate function + * + * @param {String} str String to look for. + * @return {String} Translated string or the input string if it wasn't found. + */ + _: function(str) { + return this.translate(str); + }, + + /** + * Pseudo sprintf implementation - simple way to replace tokens with specified values. + * + * @param {String} str String with tokens + * @return {String} String with replaced tokens + */ + sprintf: function(str) { + var args = [].slice.call(arguments, 1); + + return str.replace(/%[a-z]/g, function() { + var value = args.shift(); + return Basic.typeOf(value) !== 'undefined' ? value : ''; + }); + } + }; +}); + +// Included from: src/javascript/core/utils/Mime.js + +/** + * Mime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/core/utils/Mime", [ + "moxie/core/utils/Basic", + "moxie/core/I18n" +], function(Basic, I18n) { + + var mimeData = "" + + "application/msword,doc dot," + + "application/pdf,pdf," + + "application/pgp-signature,pgp," + + "application/postscript,ps ai eps," + + "application/rtf,rtf," + + "application/vnd.ms-excel,xls xlb," + + "application/vnd.ms-powerpoint,ppt pps pot," + + "application/zip,zip," + + "application/x-shockwave-flash,swf swfl," + + "application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx," + + "application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx," + + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx," + + "application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx," + + "application/vnd.openxmlformats-officedocument.presentationml.template,potx," + + "application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx," + + "application/x-javascript,js," + + "application/json,json," + + "audio/mpeg,mp3 mpga mpega mp2," + + "audio/x-wav,wav," + + "audio/x-m4a,m4a," + + "audio/ogg,oga ogg," + + "audio/aiff,aiff aif," + + "audio/flac,flac," + + "audio/aac,aac," + + "audio/ac3,ac3," + + "audio/x-ms-wma,wma," + + "image/bmp,bmp," + + "image/gif,gif," + + "image/jpeg,jpg jpeg jpe," + + "image/photoshop,psd," + + "image/png,png," + + "image/svg+xml,svg svgz," + + "image/tiff,tiff tif," + + "text/plain,asc txt text diff log," + + "text/html,htm html xhtml," + + "text/css,css," + + "text/csv,csv," + + "text/rtf,rtf," + + "video/mpeg,mpeg mpg mpe m2v," + + "video/quicktime,qt mov," + + "video/mp4,mp4," + + "video/x-m4v,m4v," + + "video/x-flv,flv," + + "video/x-ms-wmv,wmv," + + "video/avi,avi," + + "video/webm,webm," + + "video/3gpp,3gpp 3gp," + + "video/3gpp2,3g2," + + "video/vnd.rn-realvideo,rv," + + "video/ogg,ogv," + + "video/x-matroska,mkv," + + "application/vnd.oasis.opendocument.formula-template,otf," + + "application/octet-stream,exe"; + + + var Mime = { + + mimes: {}, + + extensions: {}, + + // Parses the default mime types string into a mimes and extensions lookup maps + addMimeType: function (mimeData) { + var items = mimeData.split(/,/), i, ii, ext; + + for (i = 0; i < items.length; i += 2) { + ext = items[i + 1].split(/ /); + + // extension to mime lookup + for (ii = 0; ii < ext.length; ii++) { + this.mimes[ext[ii]] = items[i]; + } + // mime to extension lookup + this.extensions[items[i]] = ext; + } + }, + + + extList2mimes: function (filters, addMissingExtensions) { + var self = this, ext, i, ii, type, mimes = []; + + // convert extensions to mime types list + for (i = 0; i < filters.length; i++) { + ext = filters[i].extensions.toLowerCase().split(/\s*,\s*/); + + for (ii = 0; ii < ext.length; ii++) { + + // if there's an asterisk in the list, then accept attribute is not required + if (ext[ii] === '*') { + return []; + } + + type = self.mimes[ext[ii]]; + + // future browsers should filter by extension, finally + if (addMissingExtensions && /^\w+$/.test(ext[ii])) { + mimes.push('.' + ext[ii]); + } else if (type && Basic.inArray(type, mimes) === -1) { + mimes.push(type); + } else if (!type) { + // if we have no type in our map, then accept all + return []; + } + } + } + return mimes; + }, + + + mimes2exts: function(mimes) { + var self = this, exts = []; + + Basic.each(mimes, function(mime) { + mime = mime.toLowerCase(); + + if (mime === '*') { + exts = []; + return false; + } + + // check if this thing looks like mime type + var m = mime.match(/^(\w+)\/(\*|\w+)$/); + if (m) { + if (m[2] === '*') { + // wildcard mime type detected + Basic.each(self.extensions, function(arr, mime) { + if ((new RegExp('^' + m[1] + '/')).test(mime)) { + [].push.apply(exts, self.extensions[mime]); + } + }); + } else if (self.extensions[mime]) { + [].push.apply(exts, self.extensions[mime]); + } + } + }); + return exts; + }, + + + mimes2extList: function(mimes) { + var accept = [], exts = []; + + if (Basic.typeOf(mimes) === 'string') { + mimes = Basic.trim(mimes).split(/\s*,\s*/); + } + + exts = this.mimes2exts(mimes); + + accept.push({ + title: I18n.translate('Files'), + extensions: exts.length ? exts.join(',') : '*' + }); + + // save original mimes string + accept.mimes = mimes; + + return accept; + }, + + + getFileExtension: function(fileName) { + var matches = fileName && fileName.match(/\.([^.]+)$/); + if (matches) { + return matches[1].toLowerCase(); + } + return ''; + }, + + getFileMime: function(fileName) { + return this.mimes[this.getFileExtension(fileName)] || ''; + } + }; + + Mime.addMimeType(mimeData); + + return Mime; +}); + +// Included from: src/javascript/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileInput', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Env', + 'moxie/core/utils/Mime', + 'moxie/core/utils/Dom', + 'moxie/core/Exceptions', + 'moxie/core/EventTarget', + 'moxie/core/I18n', + 'moxie/runtime/Runtime', + 'moxie/runtime/RuntimeClient' +], function(Basic, Env, Mime, Dom, x, EventTarget, I18n, Runtime, RuntimeClient) { + /** + Provides a convenient way to create cross-browser file-picker. Generates file selection dialog on click, + converts selected files to _File_ objects, to be used in conjunction with _Image_, preloaded in memory + with _FileReader_ or uploaded to a server through _XMLHttpRequest_. + + @class moxie/file/FileInput + @constructor + @extends EventTarget + @uses RuntimeClient + @param {Object|String|DOMElement} options If options is string or node, argument is considered as _browse\_button_. + @param {String|DOMElement} options.browse_button DOM Element to turn into file picker. + @param {Array} [options.accept] Array of mime types to accept. By default accepts all. + @param {Boolean} [options.multiple=false] Enable selection of multiple files. + @param {Boolean} [options.directory=false] Turn file input into the folder input (cannot be both at the same time). + @param {String|DOMElement} [options.container] DOM Element to use as a container for file-picker. Defaults to parentNode + for _browse\_button_. + @param {Object|String} [options.required_caps] Set of required capabilities, that chosen runtime must support. + + @example +
+ Browse... +
+ + + */ + var dispatches = [ + /** + Dispatched when runtime is connected and file-picker is ready to be used. + + @event ready + @param {Object} event + */ + 'ready', + + /** + Dispatched right after [ready](#event_ready) event, and whenever [refresh()](#method_refresh) is invoked. + Check [corresponding documentation entry](#method_refresh) for more info. + + @event refresh + @param {Object} event + */ + + /** + Dispatched when selection of files in the dialog is complete. + + @event change + @param {Object} event + */ + 'change', + + 'cancel', // TODO: might be useful + + /** + Dispatched when mouse cursor enters file-picker area. Can be used to style element + accordingly. + + @event mouseenter + @param {Object} event + */ + 'mouseenter', + + /** + Dispatched when mouse cursor leaves file-picker area. Can be used to style element + accordingly. + + @event mouseleave + @param {Object} event + */ + 'mouseleave', + + /** + Dispatched when functional mouse button is pressed on top of file-picker area. + + @event mousedown + @param {Object} event + */ + 'mousedown', + + /** + Dispatched when functional mouse button is released on top of file-picker area. + + @event mouseup + @param {Object} event + */ + 'mouseup' + ]; + + function FileInput(options) { + if (MXI_DEBUG) { + Env.log("Instantiating FileInput..."); + } + + var container, browseButton, defaults; + + // if flat argument passed it should be browse_button id + if (Basic.inArray(Basic.typeOf(options), ['string', 'node']) !== -1) { + options = { browse_button : options }; + } + + // this will help us to find proper default container + browseButton = Dom.get(options.browse_button); + if (!browseButton) { + // browse button is required + throw new x.DOMException(x.DOMException.NOT_FOUND_ERR); + } + + // figure out the options + defaults = { + accept: [{ + title: I18n.translate('All Files'), + extensions: '*' + }], + multiple: false, + required_caps: false, + container: browseButton.parentNode || document.body + }; + + options = Basic.extend({}, defaults, options); + + // convert to object representation + if (typeof(options.required_caps) === 'string') { + options.required_caps = Runtime.parseCaps(options.required_caps); + } + + // normalize accept option (could be list of mime types or array of title/extensions pairs) + if (typeof(options.accept) === 'string') { + options.accept = Mime.mimes2extList(options.accept); + } + + container = Dom.get(options.container); + // make sure we have container + if (!container) { + container = document.body; + } + + // make container relative, if it's not + if (Dom.getStyle(container, 'position') === 'static') { + container.style.position = 'relative'; + } + + container = browseButton = null; // IE + + RuntimeClient.call(this); + + Basic.extend(this, { + /** + Unique id of the component + + @property uid + @protected + @readOnly + @type {String} + @default UID + */ + uid: Basic.guid('uid_'), + + /** + Unique id of the connected runtime, if any. + + @property ruid + @protected + @type {String} + */ + ruid: null, + + /** + Unique id of the runtime container. Useful to get hold of it for various manipulations. + + @property shimid + @protected + @type {String} + */ + shimid: null, + + /** + Array of selected mOxie.File objects + + @property files + @type {Array} + @default null + */ + files: null, + + /** + Initializes the file-picker, connects it to runtime and dispatches event ready when done. + + @method init + */ + init: function() { + var self = this; + + self.bind('RuntimeInit', function(e, runtime) { + self.ruid = runtime.uid; + self.shimid = runtime.shimid; + + self.bind("Ready", function() { + self.trigger("Refresh"); + }, 999); + + // re-position and resize shim container + self.bind('Refresh', function() { + var pos, size, browseButton, shimContainer, zIndex; + + browseButton = Dom.get(options.browse_button); + shimContainer = Dom.get(runtime.shimid); // do not use runtime.getShimContainer(), since it will create container if it doesn't exist + + if (browseButton) { + pos = Dom.getPos(browseButton, Dom.get(options.container)); + size = Dom.getSize(browseButton); + zIndex = parseInt(Dom.getStyle(browseButton, 'z-index'), 10) || 0; + + if (shimContainer) { + Basic.extend(shimContainer.style, { + top: pos.y + 'px', + left: pos.x + 'px', + width: size.w + 'px', + height: size.h + 'px', + zIndex: zIndex + 1 + }); + } + } + shimContainer = browseButton = null; + }); + + runtime.exec.call(self, 'FileInput', 'init', options); + }); + + // runtime needs: options.required_features, options.runtime_order and options.container + self.connectRuntime(Basic.extend({}, options, { + required_caps: { + select_file: true + } + })); + }, + + + /** + * Get current option value by its name + * + * @method getOption + * @param name + * @return {Mixed} + */ + getOption: function(name) { + return options[name]; + }, + + + /** + * Sets a new value for the option specified by name + * + * @method setOption + * @param name + * @param value + */ + setOption: function(name, value) { + if (!options.hasOwnProperty(name)) { + return; + } + + var oldValue = options[name]; + + switch (name) { + case 'accept': + if (typeof(value) === 'string') { + value = Mime.mimes2extList(value); + } + break; + + case 'container': + case 'required_caps': + throw new x.FileException(x.FileException.NO_MODIFICATION_ALLOWED_ERR); + } + + options[name] = value; + this.exec('FileInput', 'setOption', name, value); + + this.trigger('OptionChanged', name, value, oldValue); + }, + + /** + Disables file-picker element, so that it doesn't react to mouse clicks. + + @method disable + @param {Boolean} [state=true] Disable component if - true, enable if - false + */ + disable: function(state) { + var runtime = this.getRuntime(); + if (runtime) { + this.exec('FileInput', 'disable', Basic.typeOf(state) === 'undefined' ? true : state); + } + }, + + + /** + Reposition and resize dialog trigger to match the position and size of browse_button element. + + @method refresh + */ + refresh: function() { + this.trigger("Refresh"); + }, + + + /** + Destroy component. + + @method destroy + */ + destroy: function() { + var runtime = this.getRuntime(); + if (runtime) { + runtime.exec.call(this, 'FileInput', 'destroy'); + this.disconnectRuntime(); + } + + if (Basic.typeOf(this.files) === 'array') { + // no sense in leaving associated files behind + Basic.each(this.files, function(file) { + file.destroy(); + }); + } + this.files = null; + + this.unbindAll(); + } + }); + + this.handleEventProps(dispatches); + } + + FileInput.prototype = EventTarget.instance; + + return FileInput; +}); + +// Included from: src/javascript/file/File.js + +/** + * File.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/File', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Mime', + 'moxie/file/Blob' +], function(Basic, Mime, Blob) { + /** + @class moxie/file/File + @extends Blob + @constructor + @param {String} ruid Unique id of the runtime, to which this blob belongs to + @param {Object} file Object "Native" file object, as it is represented in the runtime + */ + function File(ruid, file) { + if (!file) { // avoid extra errors in case we overlooked something + file = {}; + } + + Blob.apply(this, arguments); + + if (!this.type) { + this.type = Mime.getFileMime(file.name); + } + + // sanitize file name or generate new one + var name; + if (file.name) { + name = file.name.replace(/\\/g, '/'); + name = name.substr(name.lastIndexOf('/') + 1); + } else if (this.type) { + var prefix = this.type.split('/')[0]; + name = Basic.guid((prefix !== '' ? prefix : 'file') + '_'); + + if (Mime.extensions[this.type]) { + name += '.' + Mime.extensions[this.type][0]; // append proper extension if possible + } + } + + + Basic.extend(this, { + /** + File name + + @property name + @type {String} + @default UID + */ + name: name || Basic.guid('file_'), + + /** + Relative path to the file inside a directory + + @property relativePath + @type {String} + @default '' + */ + relativePath: '', + + /** + Date of last modification + + @property lastModifiedDate + @type {String} + @default now + */ + lastModifiedDate: file.lastModifiedDate || (new Date()).toLocaleString() // Thu Aug 23 2012 19:40:00 GMT+0400 (GET) + }); + } + + File.prototype = Blob.prototype; + + return File; +}); + +// Included from: src/javascript/file/FileDrop.js + +/** + * FileDrop.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileDrop', [ + 'moxie/core/I18n', + 'moxie/core/utils/Dom', + 'moxie/core/Exceptions', + 'moxie/core/utils/Basic', + 'moxie/core/utils/Env', + 'moxie/file/File', + 'moxie/runtime/RuntimeClient', + 'moxie/core/EventTarget', + 'moxie/core/utils/Mime' +], function(I18n, Dom, x, Basic, Env, File, RuntimeClient, EventTarget, Mime) { + /** + Turn arbitrary DOM element to a drop zone accepting files. Converts selected files to _File_ objects, to be used + in conjunction with _Image_, preloaded in memory with _FileReader_ or uploaded to a server through + _XMLHttpRequest_. + + @example +
+ Drop files here +
+
+
+ + + + @class moxie/file/FileDrop + @constructor + @extends EventTarget + @uses RuntimeClient + @param {Object|String} options If options has typeof string, argument is considered as options.drop_zone + @param {String|DOMElement} options.drop_zone DOM Element to turn into a drop zone + @param {Array} [options.accept] Array of mime types to accept. By default accepts all + @param {Object|String} [options.required_caps] Set of required capabilities, that chosen runtime must support + */ + var dispatches = [ + /** + Dispatched when runtime is connected and drop zone is ready to accept files. + + @event ready + @param {Object} event + */ + 'ready', + + /** + Dispatched when dragging cursor enters the drop zone. + + @event dragenter + @param {Object} event + */ + 'dragenter', + + /** + Dispatched when dragging cursor leaves the drop zone. + + @event dragleave + @param {Object} event + */ + 'dragleave', + + /** + Dispatched when file is dropped onto the drop zone. + + @event drop + @param {Object} event + */ + 'drop', + + /** + Dispatched if error occurs. + + @event error + @param {Object} event + */ + 'error' + ]; + + function FileDrop(options) { + if (MXI_DEBUG) { + Env.log("Instantiating FileDrop..."); + } + + var self = this, defaults; + + // if flat argument passed it should be drop_zone id + if (typeof(options) === 'string') { + options = { drop_zone : options }; + } + + // figure out the options + defaults = { + accept: [{ + title: I18n.translate('All Files'), + extensions: '*' + }], + required_caps: { + drag_and_drop: true + } + }; + + options = typeof(options) === 'object' ? Basic.extend({}, defaults, options) : defaults; + + // this will help us to find proper default container + options.container = Dom.get(options.drop_zone) || document.body; + + // make container relative, if it is not + if (Dom.getStyle(options.container, 'position') === 'static') { + options.container.style.position = 'relative'; + } + + // normalize accept option (could be list of mime types or array of title/extensions pairs) + if (typeof(options.accept) === 'string') { + options.accept = Mime.mimes2extList(options.accept); + } + + RuntimeClient.call(self); + + Basic.extend(self, { + uid: Basic.guid('uid_'), + + ruid: null, + + files: null, + + init: function() { + self.bind('RuntimeInit', function(e, runtime) { + self.ruid = runtime.uid; + runtime.exec.call(self, 'FileDrop', 'init', options); + self.dispatchEvent('ready'); + }); + + // runtime needs: options.required_features, options.runtime_order and options.container + self.connectRuntime(options); // throws RuntimeError + }, + + destroy: function() { + var runtime = this.getRuntime(); + if (runtime) { + runtime.exec.call(this, 'FileDrop', 'destroy'); + this.disconnectRuntime(); + } + this.files = null; + + this.unbindAll(); + } + }); + + this.handleEventProps(dispatches); + } + + FileDrop.prototype = EventTarget.instance; + + return FileDrop; +}); + +// Included from: src/javascript/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileReader', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Encode', + 'moxie/core/Exceptions', + 'moxie/core/EventTarget', + 'moxie/file/Blob', + 'moxie/runtime/RuntimeClient' +], function(Basic, Encode, x, EventTarget, Blob, RuntimeClient) { + /** + Utility for preloading o.Blob/o.File objects in memory. By design closely follows [W3C FileReader](http://www.w3.org/TR/FileAPI/#dfn-filereader) + interface. Where possible uses native FileReader, where - not falls back to shims. + + @class moxie/file/FileReader + @constructor FileReader + @extends EventTarget + @uses RuntimeClient + */ + var dispatches = [ + + /** + Dispatched when the read starts. + + @event loadstart + @param {Object} event + */ + 'loadstart', + + /** + Dispatched while reading (and decoding) blob, and reporting partial Blob data (progess.loaded/progress.total). + + @event progress + @param {Object} event + */ + 'progress', + + /** + Dispatched when the read has successfully completed. + + @event load + @param {Object} event + */ + 'load', + + /** + Dispatched when the read has been aborted. For instance, by invoking the abort() method. + + @event abort + @param {Object} event + */ + 'abort', + + /** + Dispatched when the read has failed. + + @event error + @param {Object} event + */ + 'error', + + /** + Dispatched when the request has completed (either in success or failure). + + @event loadend + @param {Object} event + */ + 'loadend' + ]; + + function FileReader() { + + RuntimeClient.call(this); + + Basic.extend(this, { + /** + UID of the component instance. + + @property uid + @type {String} + */ + uid: Basic.guid('uid_'), + + /** + Contains current state of FileReader object. Can take values of FileReader.EMPTY, FileReader.LOADING + and FileReader.DONE. + + @property readyState + @type {Number} + @default FileReader.EMPTY + */ + readyState: FileReader.EMPTY, + + /** + Result of the successful read operation. + + @property result + @type {String} + */ + result: null, + + /** + Stores the error of failed asynchronous read operation. + + @property error + @type {DOMError} + */ + error: null, + + /** + Initiates reading of File/Blob object contents to binary string. + + @method readAsBinaryString + @param {Blob|File} blob Object to preload + */ + readAsBinaryString: function(blob) { + _read.call(this, 'readAsBinaryString', blob); + }, + + /** + Initiates reading of File/Blob object contents to dataURL string. + + @method readAsDataURL + @param {Blob|File} blob Object to preload + */ + readAsDataURL: function(blob) { + _read.call(this, 'readAsDataURL', blob); + }, + + /** + Initiates reading of File/Blob object contents to string. + + @method readAsText + @param {Blob|File} blob Object to preload + */ + readAsText: function(blob) { + _read.call(this, 'readAsText', blob); + }, + + /** + Aborts preloading process. + + @method abort + */ + abort: function() { + this.result = null; + + if (Basic.inArray(this.readyState, [FileReader.EMPTY, FileReader.DONE]) !== -1) { + return; + } else if (this.readyState === FileReader.LOADING) { + this.readyState = FileReader.DONE; + } + + this.exec('FileReader', 'abort'); + + this.trigger('abort'); + this.trigger('loadend'); + }, + + /** + Destroy component and release resources. + + @method destroy + */ + destroy: function() { + this.abort(); + this.exec('FileReader', 'destroy'); + this.disconnectRuntime(); + this.unbindAll(); + } + }); + + // uid must already be assigned + this.handleEventProps(dispatches); + + this.bind('Error', function(e, err) { + this.readyState = FileReader.DONE; + this.error = err; + }, 999); + + this.bind('Load', function(e) { + this.readyState = FileReader.DONE; + }, 999); + + + function _read(op, blob) { + var self = this; + + this.trigger('loadstart'); + + if (this.readyState === FileReader.LOADING) { + this.trigger('error', new x.DOMException(x.DOMException.INVALID_STATE_ERR)); + this.trigger('loadend'); + return; + } + + // if source is not o.Blob/o.File + if (!(blob instanceof Blob)) { + this.trigger('error', new x.DOMException(x.DOMException.NOT_FOUND_ERR)); + this.trigger('loadend'); + return; + } + + this.result = null; + this.readyState = FileReader.LOADING; + + if (blob.isDetached()) { + var src = blob.getSource(); + switch (op) { + case 'readAsText': + case 'readAsBinaryString': + this.result = src; + break; + case 'readAsDataURL': + this.result = 'data:' + blob.type + ';base64,' + Encode.btoa(src); + break; + } + this.readyState = FileReader.DONE; + this.trigger('load'); + this.trigger('loadend'); + } else { + this.connectRuntime(blob.ruid); + this.exec('FileReader', 'read', op, blob); + } + } + } + + /** + Initial FileReader state + + @property EMPTY + @type {Number} + @final + @static + @default 0 + */ + FileReader.EMPTY = 0; + + /** + FileReader switches to this state when it is preloading the source + + @property LOADING + @type {Number} + @final + @static + @default 1 + */ + FileReader.LOADING = 1; + + /** + Preloading is complete, this is a final state + + @property DONE + @type {Number} + @final + @static + @default 2 + */ + FileReader.DONE = 2; + + FileReader.prototype = EventTarget.instance; + + return FileReader; +}); + +// Included from: src/javascript/core/utils/Url.js + +/** + * Url.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Url', [ + 'moxie/core/utils/Basic' +], function(Basic) { + /** + Parse url into separate components and fill in absent parts with parts from current url, + based on https://raw.github.com/kvz/phpjs/master/functions/url/parse_url.js + + @method parseUrl + @for Utils + @static + @param {String} url Url to parse (defaults to empty string if undefined) + @return {Object} Hash containing extracted uri components + */ + var parseUrl = function(url, currentUrl) { + var key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'] + , i = key.length + , ports = { + http: 80, + https: 443 + } + , uri = {} + , regex = /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@\/]*):?([^:@\/]*))?@)?(\[[\da-fA-F:]+\]|[^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/ + , m = regex.exec(url || '') + , isRelative + , isSchemeLess = /^\/\/\w/.test(url) + ; + + switch (Basic.typeOf(currentUrl)) { + case 'undefined': + currentUrl = parseUrl(document.location.href, false); + break; + + case 'string': + currentUrl = parseUrl(currentUrl, false); + break; + } + + while (i--) { + if (m[i]) { + uri[key[i]] = m[i]; + } + } + + isRelative = !isSchemeLess && !uri.scheme; + + if (isSchemeLess || isRelative) { + uri.scheme = currentUrl.scheme; + } + + // when url is relative, we set the origin and the path ourselves + if (isRelative) { + uri.host = currentUrl.host; + uri.port = currentUrl.port; + + var path = ''; + // for urls without trailing slash we need to figure out the path + if (/^[^\/]/.test(uri.path)) { + path = currentUrl.path; + // if path ends with a filename, strip it + if (/\/[^\/]*\.[^\/]*$/.test(path)) { + path = path.replace(/\/[^\/]+$/, '/'); + } else { + // avoid double slash at the end (see #127) + path = path.replace(/\/?$/, '/'); + } + } + uri.path = path + (uri.path || ''); // site may reside at domain.com or domain.com/subdir + } + + if (!uri.port) { + uri.port = ports[uri.scheme] || 80; + } + + uri.port = parseInt(uri.port, 10); + + if (!uri.path) { + uri.path = "/"; + } + + delete uri.source; + + return uri; + }; + + /** + Resolve url - among other things will turn relative url to absolute + + @method resolveUrl + @static + @param {String|Object} url Either absolute or relative, or a result of parseUrl call + @return {String} Resolved, absolute url + */ + var resolveUrl = function(url) { + var ports = { // we ignore default ports + http: 80, + https: 443 + } + , urlp = typeof(url) === 'object' ? url : parseUrl(url); + ; + + return urlp.scheme + '://' + urlp.host + (urlp.port !== ports[urlp.scheme] ? ':' + urlp.port : '') + urlp.path + (urlp.query ? urlp.query : ''); + }; + + /** + Check if specified url has the same origin as the current document + + @method hasSameOrigin + @param {String|Object} url + @return {Boolean} + */ + var hasSameOrigin = function(url) { + function origin(url) { + return [url.scheme, url.host, url.port].join('/'); + } + + if (typeof url === 'string') { + url = parseUrl(url); + } + + return origin(parseUrl()) === origin(url); + }; + + return { + parseUrl: parseUrl, + resolveUrl: resolveUrl, + hasSameOrigin: hasSameOrigin + }; +}); + +// Included from: src/javascript/runtime/RuntimeTarget.js + +/** + * RuntimeTarget.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/runtime/RuntimeTarget', [ + 'moxie/core/utils/Basic', + 'moxie/runtime/RuntimeClient', + "moxie/core/EventTarget" +], function(Basic, RuntimeClient, EventTarget) { + /** + Instance of this class can be used as a target for the events dispatched by shims, + when allowing them onto components is for either reason inappropriate + + @class moxie/runtime/RuntimeTarget + @constructor + @protected + @extends EventTarget + */ + function RuntimeTarget() { + this.uid = Basic.guid('uid_'); + + RuntimeClient.call(this); + + this.destroy = function() { + this.disconnectRuntime(); + this.unbindAll(); + }; + } + + RuntimeTarget.prototype = EventTarget.instance; + + return RuntimeTarget; +}); + +// Included from: src/javascript/file/FileReaderSync.js + +/** + * FileReaderSync.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileReaderSync', [ + 'moxie/core/utils/Basic', + 'moxie/runtime/RuntimeClient', + 'moxie/core/utils/Encode' +], function(Basic, RuntimeClient, Encode) { + /** + Synchronous FileReader implementation. Something like this is available in WebWorkers environment, here + it can be used to read only preloaded blobs/files and only below certain size (not yet sure what that'd be, + but probably < 1mb). Not meant to be used directly by user. + + @class moxie/file/FileReaderSync + @private + @constructor + */ + return function() { + RuntimeClient.call(this); + + Basic.extend(this, { + uid: Basic.guid('uid_'), + + readAsBinaryString: function(blob) { + return _read.call(this, 'readAsBinaryString', blob); + }, + + readAsDataURL: function(blob) { + return _read.call(this, 'readAsDataURL', blob); + }, + + /*readAsArrayBuffer: function(blob) { + return _read.call(this, 'readAsArrayBuffer', blob); + },*/ + + readAsText: function(blob) { + return _read.call(this, 'readAsText', blob); + } + }); + + function _read(op, blob) { + if (blob.isDetached()) { + var src = blob.getSource(); + switch (op) { + case 'readAsBinaryString': + return src; + case 'readAsDataURL': + return 'data:' + blob.type + ';base64,' + Encode.btoa(src); + case 'readAsText': + var txt = ''; + for (var i = 0, length = src.length; i < length; i++) { + txt += String.fromCharCode(src[i]); + } + return txt; + } + } else { + var result = this.connectRuntime(blob.ruid).exec.call(this, 'FileReaderSync', 'read', op, blob); + this.disconnectRuntime(); + return result; + } + } + }; +}); + +// Included from: src/javascript/xhr/FormData.js + +/** + * FormData.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/xhr/FormData", [ + "moxie/core/Exceptions", + "moxie/core/utils/Basic", + "moxie/file/Blob" +], function(x, Basic, Blob) { + /** + FormData + + @class moxie/xhr/FormData + @constructor + */ + function FormData() { + var _blob, _fields = []; + + Basic.extend(this, { + /** + Append another key-value pair to the FormData object + + @method append + @param {String} name Name for the new field + @param {String|Blob|Array|Object} value Value for the field + */ + append: function(name, value) { + var self = this, valueType = Basic.typeOf(value); + + // according to specs value might be either Blob or String + if (value instanceof Blob) { + _blob = { + name: name, + value: value // unfortunately we can only send single Blob in one FormData + }; + } else if ('array' === valueType) { + name += '[]'; + + Basic.each(value, function(value) { + self.append(name, value); + }); + } else if ('object' === valueType) { + Basic.each(value, function(value, key) { + self.append(name + '[' + key + ']', value); + }); + } else if ('null' === valueType || 'undefined' === valueType || 'number' === valueType && isNaN(value)) { + self.append(name, "false"); + } else { + _fields.push({ + name: name, + value: value.toString() + }); + } + }, + + /** + Checks if FormData contains Blob. + + @method hasBlob + @return {Boolean} + */ + hasBlob: function() { + return !!this.getBlob(); + }, + + /** + Retrieves blob. + + @method getBlob + @return {Object} Either Blob if found or null + */ + getBlob: function() { + return _blob && _blob.value || null; + }, + + /** + Retrieves blob field name. + + @method getBlobName + @return {String} Either Blob field name or null + */ + getBlobName: function() { + return _blob && _blob.name || null; + }, + + /** + Loop over the fields in FormData and invoke the callback for each of them. + + @method each + @param {Function} cb Callback to call for each field + */ + each: function(cb) { + Basic.each(_fields, function(field) { + cb(field.value, field.name); + }); + + if (_blob) { + cb(_blob.value, _blob.name); + } + }, + + destroy: function() { + _blob = null; + _fields = []; + } + }); + } + + return FormData; +}); + +// Included from: src/javascript/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/xhr/XMLHttpRequest", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/core/EventTarget", + "moxie/core/utils/Encode", + "moxie/core/utils/Url", + "moxie/runtime/Runtime", + "moxie/runtime/RuntimeTarget", + "moxie/file/Blob", + "moxie/file/FileReaderSync", + "moxie/xhr/FormData", + "moxie/core/utils/Env", + "moxie/core/utils/Mime" +], function(Basic, x, EventTarget, Encode, Url, Runtime, RuntimeTarget, Blob, FileReaderSync, FormData, Env, Mime) { + + var httpCode = { + 100: 'Continue', + 101: 'Switching Protocols', + 102: 'Processing', + + 200: 'OK', + 201: 'Created', + 202: 'Accepted', + 203: 'Non-Authoritative Information', + 204: 'No Content', + 205: 'Reset Content', + 206: 'Partial Content', + 207: 'Multi-Status', + 226: 'IM Used', + + 300: 'Multiple Choices', + 301: 'Moved Permanently', + 302: 'Found', + 303: 'See Other', + 304: 'Not Modified', + 305: 'Use Proxy', + 306: 'Reserved', + 307: 'Temporary Redirect', + + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Request Entity Too Large', + 414: 'Request-URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Requested Range Not Satisfiable', + 417: 'Expectation Failed', + 422: 'Unprocessable Entity', + 423: 'Locked', + 424: 'Failed Dependency', + 426: 'Upgrade Required', + + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported', + 506: 'Variant Also Negotiates', + 507: 'Insufficient Storage', + 510: 'Not Extended' + }; + + function XMLHttpRequestUpload() { + this.uid = Basic.guid('uid_'); + } + + XMLHttpRequestUpload.prototype = EventTarget.instance; + + /** + Implementation of XMLHttpRequest + + @class moxie/xhr/XMLHttpRequest + @constructor + @uses RuntimeClient + @extends EventTarget + */ + var dispatches = [ + 'loadstart', + + 'progress', + + 'abort', + + 'error', + + 'load', + + 'timeout', + + 'loadend' + + // readystatechange (for historical reasons) + ]; + + var NATIVE = 1, RUNTIME = 2; + + function XMLHttpRequest() { + var self = this, + // this (together with _p() @see below) is here to gracefully upgrade to setter/getter syntax where possible + props = { + /** + The amount of milliseconds a request can take before being terminated. Initially zero. Zero means there is no timeout. + + @property timeout + @type Number + @default 0 + */ + timeout: 0, + + /** + Current state, can take following values: + UNSENT (numeric value 0) + The object has been constructed. + + OPENED (numeric value 1) + The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the request can be made using the send() method. + + HEADERS_RECEIVED (numeric value 2) + All redirects (if any) have been followed and all HTTP headers of the final response have been received. Several response members of the object are now available. + + LOADING (numeric value 3) + The response entity body is being received. + + DONE (numeric value 4) + + @property readyState + @type Number + @default 0 (UNSENT) + */ + readyState: XMLHttpRequest.UNSENT, + + /** + True when user credentials are to be included in a cross-origin request. False when they are to be excluded + in a cross-origin request and when cookies are to be ignored in its response. Initially false. + + @property withCredentials + @type Boolean + @default false + */ + withCredentials: false, + + /** + Returns the HTTP status code. + + @property status + @type Number + @default 0 + */ + status: 0, + + /** + Returns the HTTP status text. + + @property statusText + @type String + */ + statusText: "", + + /** + Returns the response type. Can be set to change the response type. Values are: + the empty string (default), "arraybuffer", "blob", "document", "json", and "text". + + @property responseType + @type String + */ + responseType: "", + + /** + Returns the document response entity body. + + Throws an "InvalidStateError" exception if responseType is not the empty string or "document". + + @property responseXML + @type Document + */ + responseXML: null, + + /** + Returns the text response entity body. + + Throws an "InvalidStateError" exception if responseType is not the empty string or "text". + + @property responseText + @type String + */ + responseText: null, + + /** + Returns the response entity body (http://www.w3.org/TR/XMLHttpRequest/#response-entity-body). + Can become: ArrayBuffer, Blob, Document, JSON, Text + + @property response + @type Mixed + */ + response: null + }, + + _async = true, + _url, + _method, + _headers = {}, + _user, + _password, + _encoding = null, + _mimeType = null, + + // flags + _sync_flag = false, + _send_flag = false, + _upload_events_flag = false, + _upload_complete_flag = false, + _error_flag = false, + _same_origin_flag = false, + + // times + _start_time, + _timeoutset_time, + + _finalMime = null, + _finalCharset = null, + + _options = {}, + _xhr, + _responseHeaders = '', + _responseHeadersBag + ; + + + Basic.extend(this, props, { + /** + Unique id of the component + + @property uid + @type String + */ + uid: Basic.guid('uid_'), + + /** + Target for Upload events + + @property upload + @type XMLHttpRequestUpload + */ + upload: new XMLHttpRequestUpload(), + + + /** + Sets the request method, request URL, synchronous flag, request username, and request password. + + Throws a "SyntaxError" exception if one of the following is true: + + method is not a valid HTTP method. + url cannot be resolved. + url contains the "user:password" format in the userinfo production. + Throws a "SecurityError" exception if method is a case-insensitive match for CONNECT, TRACE or TRACK. + + Throws an "InvalidAccessError" exception if one of the following is true: + + Either user or password is passed as argument and the origin of url does not match the XMLHttpRequest origin. + There is an associated XMLHttpRequest document and either the timeout attribute is not zero, + the withCredentials attribute is true, or the responseType attribute is not the empty string. + + + @method open + @param {String} method HTTP method to use on request + @param {String} url URL to request + @param {Boolean} [async=true] If false request will be done in synchronous manner. Asynchronous by default. + @param {String} [user] Username to use in HTTP authentication process on server-side + @param {String} [password] Password to use in HTTP authentication process on server-side + */ + open: function(method, url, async, user, password) { + var urlp; + + // first two arguments are required + if (!method || !url) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + } + + // 2 - check if any code point in method is higher than U+00FF or after deflating method it does not match the method + if (/[\u0100-\uffff]/.test(method) || Encode.utf8_encode(method) !== method) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + } + + // 3 + if (!!~Basic.inArray(method.toUpperCase(), ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'TRACE', 'TRACK'])) { + _method = method.toUpperCase(); + } + + + // 4 - allowing these methods poses a security risk + if (!!~Basic.inArray(_method, ['CONNECT', 'TRACE', 'TRACK'])) { + throw new x.DOMException(x.DOMException.SECURITY_ERR); + } + + // 5 + url = Encode.utf8_encode(url); + + // 6 - Resolve url relative to the XMLHttpRequest base URL. If the algorithm returns an error, throw a "SyntaxError". + urlp = Url.parseUrl(url); + + _same_origin_flag = Url.hasSameOrigin(urlp); + + // 7 - manually build up absolute url + _url = Url.resolveUrl(url); + + // 9-10, 12-13 + if ((user || password) && !_same_origin_flag) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + _user = user || urlp.user; + _password = password || urlp.pass; + + // 11 + _async = async || true; + + if (_async === false && (_p('timeout') || _p('withCredentials') || _p('responseType') !== "")) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + // 14 - terminate abort() + + // 15 - terminate send() + + // 18 + _sync_flag = !_async; + _send_flag = false; + _headers = {}; + _reset.call(this); + + // 19 + _p('readyState', XMLHttpRequest.OPENED); + + // 20 + this.dispatchEvent('readystatechange'); + }, + + /** + Appends an header to the list of author request headers, or if header is already + in the list of author request headers, combines its value with value. + + Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set. + Throws a "SyntaxError" exception if header is not a valid HTTP header field name or if value + is not a valid HTTP header field value. + + @method setRequestHeader + @param {String} header + @param {String|Number} value + */ + setRequestHeader: function(header, value) { + var uaHeaders = [ // these headers are controlled by the user agent + "accept-charset", + "accept-encoding", + "access-control-request-headers", + "access-control-request-method", + "connection", + "content-length", + "cookie", + "cookie2", + "content-transfer-encoding", + "date", + "expect", + "host", + "keep-alive", + "origin", + "referer", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "user-agent", + "via" + ]; + + // 1-2 + if (_p('readyState') !== XMLHttpRequest.OPENED || _send_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 3 + if (/[\u0100-\uffff]/.test(header) || Encode.utf8_encode(header) !== header) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + } + + // 4 + /* this step is seemingly bypassed in browsers, probably to allow various unicode characters in header values + if (/[\u0100-\uffff]/.test(value) || Encode.utf8_encode(value) !== value) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + }*/ + + header = Basic.trim(header).toLowerCase(); + + // setting of proxy-* and sec-* headers is prohibited by spec + if (!!~Basic.inArray(header, uaHeaders) || /^(proxy\-|sec\-)/.test(header)) { + return false; + } + + // camelize + // browsers lowercase header names (at least for custom ones) + // header = header.replace(/\b\w/g, function($1) { return $1.toUpperCase(); }); + + if (!_headers[header]) { + _headers[header] = value; + } else { + // http://tools.ietf.org/html/rfc2616#section-4.2 (last paragraph) + _headers[header] += ', ' + value; + } + return true; + }, + + /** + * Test if the specified header is already set on this request. + * Returns a header value or boolean false if it's not yet set. + * + * @method hasRequestHeader + * @param {String} header Name of the header to test + * @return {Boolean|String} + */ + hasRequestHeader: function(header) { + return header && _headers[header.toLowerCase()] || false; + }, + + /** + Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2. + + @method getAllResponseHeaders + @return {String} reponse headers or empty string + */ + getAllResponseHeaders: function() { + return _responseHeaders || ''; + }, + + /** + Returns the header field value from the response of which the field name matches header, + unless the field name is Set-Cookie or Set-Cookie2. + + @method getResponseHeader + @param {String} header + @return {String} value(s) for the specified header or null + */ + getResponseHeader: function(header) { + header = header.toLowerCase(); + + if (_error_flag || !!~Basic.inArray(header, ['set-cookie', 'set-cookie2'])) { + return null; + } + + if (_responseHeaders && _responseHeaders !== '') { + // if we didn't parse response headers until now, do it and keep for later + if (!_responseHeadersBag) { + _responseHeadersBag = {}; + Basic.each(_responseHeaders.split(/\r\n/), function(line) { + var pair = line.split(/:\s+/); + if (pair.length === 2) { // last line might be empty, omit + pair[0] = Basic.trim(pair[0]); // just in case + _responseHeadersBag[pair[0].toLowerCase()] = { // simply to retain header name in original form + header: pair[0], + value: Basic.trim(pair[1]) + }; + } + }); + } + if (_responseHeadersBag.hasOwnProperty(header)) { + return _responseHeadersBag[header].header + ': ' + _responseHeadersBag[header].value; + } + } + return null; + }, + + /** + Sets the Content-Type header for the response to mime. + Throws an "InvalidStateError" exception if the state is LOADING or DONE. + Throws a "SyntaxError" exception if mime is not a valid media type. + + @method overrideMimeType + @param String mime Mime type to set + */ + overrideMimeType: function(mime) { + var matches, charset; + + // 1 + if (!!~Basic.inArray(_p('readyState'), [XMLHttpRequest.LOADING, XMLHttpRequest.DONE])) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 2 + mime = Basic.trim(mime.toLowerCase()); + + if (/;/.test(mime) && (matches = mime.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))) { + mime = matches[1]; + if (matches[2]) { + charset = matches[2]; + } + } + + if (!Mime.mimes[mime]) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + } + + // 3-4 + _finalMime = mime; + _finalCharset = charset; + }, + + /** + Initiates the request. The optional argument provides the request entity body. + The argument is ignored if request method is GET or HEAD. + + Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set. + + @method send + @param {Blob|Document|String|FormData} [data] Request entity body + @param {Object} [options] Set of requirements and pre-requisities for runtime initialization + */ + send: function(data, options) { + if (Basic.typeOf(options) === 'string') { + _options = { ruid: options }; + } else if (!options) { + _options = {}; + } else { + _options = options; + } + + // 1-2 + if (this.readyState !== XMLHttpRequest.OPENED || _send_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 3 + // sending Blob + if (data instanceof Blob) { + _options.ruid = data.ruid; + _mimeType = data.type || 'application/octet-stream'; + } + + // FormData + else if (data instanceof FormData) { + if (data.hasBlob()) { + var blob = data.getBlob(); + _options.ruid = blob.ruid; + _mimeType = blob.type || 'application/octet-stream'; + } + } + + // DOMString + else if (typeof data === 'string') { + _encoding = 'UTF-8'; + _mimeType = 'text/plain;charset=UTF-8'; + + // data should be converted to Unicode and encoded as UTF-8 + data = Encode.utf8_encode(data); + } + + // if withCredentials not set, but requested, set it automatically + if (!this.withCredentials) { + this.withCredentials = (_options.required_caps && _options.required_caps.send_browser_cookies) && !_same_origin_flag; + } + + // 4 - storage mutex + // 5 + _upload_events_flag = (!_sync_flag && this.upload.hasEventListener()); // DSAP + // 6 + _error_flag = false; + // 7 + _upload_complete_flag = !data; + // 8 - Asynchronous steps + if (!_sync_flag) { + // 8.1 + _send_flag = true; + // 8.2 + // this.dispatchEvent('loadstart'); // will be dispatched either by native or runtime xhr + // 8.3 + //if (!_upload_complete_flag) { + // this.upload.dispatchEvent('loadstart'); // will be dispatched either by native or runtime xhr + //} + } + // 8.5 - Return the send() method call, but continue running the steps in this algorithm. + _doXHR.call(this, data); + }, + + /** + Cancels any network activity. + + @method abort + */ + abort: function() { + _error_flag = true; + _sync_flag = false; + + if (!~Basic.inArray(_p('readyState'), [XMLHttpRequest.UNSENT, XMLHttpRequest.OPENED, XMLHttpRequest.DONE])) { + _p('readyState', XMLHttpRequest.DONE); + _send_flag = false; + + if (_xhr) { + _xhr.getRuntime().exec.call(_xhr, 'XMLHttpRequest', 'abort', _upload_complete_flag); + } else { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + _upload_complete_flag = true; + } else { + _p('readyState', XMLHttpRequest.UNSENT); + } + }, + + destroy: function() { + if (_xhr) { + if (Basic.typeOf(_xhr.destroy) === 'function') { + _xhr.destroy(); + } + _xhr = null; + } + + this.unbindAll(); + + if (this.upload) { + this.upload.unbindAll(); + this.upload = null; + } + } + }); + + this.handleEventProps(dispatches.concat(['readystatechange'])); // for historical reasons + this.upload.handleEventProps(dispatches); + + /* this is nice, but maybe too lengthy + + // if supported by JS version, set getters/setters for specific properties + o.defineProperty(this, 'readyState', { + configurable: false, + + get: function() { + return _p('readyState'); + } + }); + + o.defineProperty(this, 'timeout', { + configurable: false, + + get: function() { + return _p('timeout'); + }, + + set: function(value) { + + if (_sync_flag) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + // timeout still should be measured relative to the start time of request + _timeoutset_time = (new Date).getTime(); + + _p('timeout', value); + } + }); + + // the withCredentials attribute has no effect when fetching same-origin resources + o.defineProperty(this, 'withCredentials', { + configurable: false, + + get: function() { + return _p('withCredentials'); + }, + + set: function(value) { + // 1-2 + if (!~o.inArray(_p('readyState'), [XMLHttpRequest.UNSENT, XMLHttpRequest.OPENED]) || _send_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 3-4 + if (_anonymous_flag || _sync_flag) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + // 5 + _p('withCredentials', value); + } + }); + + o.defineProperty(this, 'status', { + configurable: false, + + get: function() { + return _p('status'); + } + }); + + o.defineProperty(this, 'statusText', { + configurable: false, + + get: function() { + return _p('statusText'); + } + }); + + o.defineProperty(this, 'responseType', { + configurable: false, + + get: function() { + return _p('responseType'); + }, + + set: function(value) { + // 1 + if (!!~o.inArray(_p('readyState'), [XMLHttpRequest.LOADING, XMLHttpRequest.DONE])) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 2 + if (_sync_flag) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + // 3 + _p('responseType', value.toLowerCase()); + } + }); + + o.defineProperty(this, 'responseText', { + configurable: false, + + get: function() { + // 1 + if (!~o.inArray(_p('responseType'), ['', 'text'])) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 2-3 + if (_p('readyState') !== XMLHttpRequest.DONE && _p('readyState') !== XMLHttpRequest.LOADING || _error_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + return _p('responseText'); + } + }); + + o.defineProperty(this, 'responseXML', { + configurable: false, + + get: function() { + // 1 + if (!~o.inArray(_p('responseType'), ['', 'document'])) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 2-3 + if (_p('readyState') !== XMLHttpRequest.DONE || _error_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + return _p('responseXML'); + } + }); + + o.defineProperty(this, 'response', { + configurable: false, + + get: function() { + if (!!~o.inArray(_p('responseType'), ['', 'text'])) { + if (_p('readyState') !== XMLHttpRequest.DONE && _p('readyState') !== XMLHttpRequest.LOADING || _error_flag) { + return ''; + } + } + + if (_p('readyState') !== XMLHttpRequest.DONE || _error_flag) { + return null; + } + + return _p('response'); + } + }); + + */ + + function _p(prop, value) { + if (!props.hasOwnProperty(prop)) { + return; + } + if (arguments.length === 1) { // get + return Env.can('define_property') ? props[prop] : self[prop]; + } else { // set + if (Env.can('define_property')) { + props[prop] = value; + } else { + self[prop] = value; + } + } + } + + /* + function _toASCII(str, AllowUnassigned, UseSTD3ASCIIRules) { + // TODO: http://tools.ietf.org/html/rfc3490#section-4.1 + return str.toLowerCase(); + } + */ + + + function _doXHR(data) { + var self = this; + + _start_time = new Date().getTime(); + + _xhr = new RuntimeTarget(); + + function loadEnd() { + if (_xhr) { // it could have been destroyed by now + _xhr.destroy(); + _xhr = null; + } + self.dispatchEvent('loadend'); + self = null; + } + + function exec(runtime) { + _xhr.bind('LoadStart', function(e) { + _p('readyState', XMLHttpRequest.LOADING); + self.dispatchEvent('readystatechange'); + + self.dispatchEvent(e); + + if (_upload_events_flag) { + self.upload.dispatchEvent(e); + } + }); + + _xhr.bind('Progress', function(e) { + if (_p('readyState') !== XMLHttpRequest.LOADING) { + _p('readyState', XMLHttpRequest.LOADING); // LoadStart unreliable (in Flash for example) + self.dispatchEvent('readystatechange'); + } + self.dispatchEvent(e); + }); + + _xhr.bind('UploadProgress', function(e) { + if (_upload_events_flag) { + self.upload.dispatchEvent({ + type: 'progress', + lengthComputable: false, + total: e.total, + loaded: e.loaded + }); + } + }); + + _xhr.bind('Load', function(e) { + _p('readyState', XMLHttpRequest.DONE); + _p('status', Number(runtime.exec.call(_xhr, 'XMLHttpRequest', 'getStatus') || 0)); + _p('statusText', httpCode[_p('status')] || ""); + + _p('response', runtime.exec.call(_xhr, 'XMLHttpRequest', 'getResponse', _p('responseType'))); + + if (!!~Basic.inArray(_p('responseType'), ['text', ''])) { + _p('responseText', _p('response')); + } else if (_p('responseType') === 'document') { + _p('responseXML', _p('response')); + } + + _responseHeaders = runtime.exec.call(_xhr, 'XMLHttpRequest', 'getAllResponseHeaders'); + + self.dispatchEvent('readystatechange'); + + if (_p('status') > 0) { // status 0 usually means that server is unreachable + if (_upload_events_flag) { + self.upload.dispatchEvent(e); + } + self.dispatchEvent(e); + } else { + _error_flag = true; + self.dispatchEvent('error'); + } + loadEnd(); + }); + + _xhr.bind('Abort', function(e) { + self.dispatchEvent(e); + loadEnd(); + }); + + _xhr.bind('Error', function(e) { + _error_flag = true; + _p('readyState', XMLHttpRequest.DONE); + self.dispatchEvent('readystatechange'); + _upload_complete_flag = true; + self.dispatchEvent(e); + loadEnd(); + }); + + runtime.exec.call(_xhr, 'XMLHttpRequest', 'send', { + url: _url, + method: _method, + async: _async, + user: _user, + password: _password, + headers: _headers, + mimeType: _mimeType, + encoding: _encoding, + responseType: self.responseType, + withCredentials: self.withCredentials, + options: _options + }, data); + } + + // clarify our requirements + if (typeof(_options.required_caps) === 'string') { + _options.required_caps = Runtime.parseCaps(_options.required_caps); + } + + _options.required_caps = Basic.extend({}, _options.required_caps, { + return_response_type: self.responseType + }); + + if (data instanceof FormData) { + _options.required_caps.send_multipart = true; + } + + if (!Basic.isEmptyObj(_headers)) { + _options.required_caps.send_custom_headers = true; + } + + if (!_same_origin_flag) { + _options.required_caps.do_cors = true; + } + + + if (_options.ruid) { // we do not need to wait if we can connect directly + exec(_xhr.connectRuntime(_options)); + } else { + _xhr.bind('RuntimeInit', function(e, runtime) { + exec(runtime); + }); + _xhr.bind('RuntimeError', function(e, err) { + self.dispatchEvent('RuntimeError', err); + }); + _xhr.connectRuntime(_options); + } + } + + + function _reset() { + _p('responseText', ""); + _p('responseXML', null); + _p('response', null); + _p('status', 0); + _p('statusText', ""); + _start_time = _timeoutset_time = null; + } + } + + XMLHttpRequest.UNSENT = 0; + XMLHttpRequest.OPENED = 1; + XMLHttpRequest.HEADERS_RECEIVED = 2; + XMLHttpRequest.LOADING = 3; + XMLHttpRequest.DONE = 4; + + XMLHttpRequest.prototype = EventTarget.instance; + + return XMLHttpRequest; +}); + +// Included from: src/javascript/runtime/Transporter.js + +/** + * Transporter.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/runtime/Transporter", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Encode", + "moxie/runtime/RuntimeClient", + "moxie/core/EventTarget" +], function(Basic, Encode, RuntimeClient, EventTarget) { + + /** + @class moxie/runtime/Transporter + @constructor + */ + function Transporter() { + var mod, _runtime, _data, _size, _pos, _chunk_size; + + RuntimeClient.call(this); + + Basic.extend(this, { + uid: Basic.guid('uid_'), + + state: Transporter.IDLE, + + result: null, + + transport: function(data, type, options) { + var self = this; + + options = Basic.extend({ + chunk_size: 204798 + }, options); + + // should divide by three, base64 requires this + if ((mod = options.chunk_size % 3)) { + options.chunk_size += 3 - mod; + } + + _chunk_size = options.chunk_size; + + _reset.call(this); + _data = data; + _size = data.length; + + if (Basic.typeOf(options) === 'string' || options.ruid) { + _run.call(self, type, this.connectRuntime(options)); + } else { + // we require this to run only once + var cb = function(e, runtime) { + self.unbind("RuntimeInit", cb); + _run.call(self, type, runtime); + }; + this.bind("RuntimeInit", cb); + this.connectRuntime(options); + } + }, + + abort: function() { + var self = this; + + self.state = Transporter.IDLE; + if (_runtime) { + _runtime.exec.call(self, 'Transporter', 'clear'); + self.trigger("TransportingAborted"); + } + + _reset.call(self); + }, + + + destroy: function() { + this.unbindAll(); + _runtime = null; + this.disconnectRuntime(); + _reset.call(this); + } + }); + + function _reset() { + _size = _pos = 0; + _data = this.result = null; + } + + function _run(type, runtime) { + var self = this; + + _runtime = runtime; + + //self.unbind("RuntimeInit"); + + self.bind("TransportingProgress", function(e) { + _pos = e.loaded; + + if (_pos < _size && Basic.inArray(self.state, [Transporter.IDLE, Transporter.DONE]) === -1) { + _transport.call(self); + } + }, 999); + + self.bind("TransportingComplete", function() { + _pos = _size; + self.state = Transporter.DONE; + _data = null; // clean a bit + self.result = _runtime.exec.call(self, 'Transporter', 'getAsBlob', type || ''); + }, 999); + + self.state = Transporter.BUSY; + self.trigger("TransportingStarted"); + _transport.call(self); + } + + function _transport() { + var self = this, + chunk, + bytesLeft = _size - _pos; + + if (_chunk_size > bytesLeft) { + _chunk_size = bytesLeft; + } + + chunk = Encode.btoa(_data.substr(_pos, _chunk_size)); + _runtime.exec.call(self, 'Transporter', 'receive', chunk, _size); + } + } + + Transporter.IDLE = 0; + Transporter.BUSY = 1; + Transporter.DONE = 2; + + Transporter.prototype = EventTarget.instance; + + return Transporter; +}); + +// Included from: src/javascript/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/image/Image", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/Exceptions", + "moxie/file/FileReaderSync", + "moxie/xhr/XMLHttpRequest", + "moxie/runtime/Runtime", + "moxie/runtime/RuntimeClient", + "moxie/runtime/Transporter", + "moxie/core/utils/Env", + "moxie/core/EventTarget", + "moxie/file/Blob", + "moxie/file/File", + "moxie/core/utils/Encode" +], function(Basic, Dom, x, FileReaderSync, XMLHttpRequest, Runtime, RuntimeClient, Transporter, Env, EventTarget, Blob, File, Encode) { + /** + Image preloading and manipulation utility. Additionally it provides access to image meta info (Exif, GPS) and raw binary data. + + @class moxie/image/Image + @constructor + @extends EventTarget + */ + var dispatches = [ + 'progress', + + /** + Dispatched when loading is complete. + + @event load + @param {Object} event + */ + 'load', + + 'error', + + /** + Dispatched when resize operation is complete. + + @event resize + @param {Object} event + */ + 'resize', + + /** + Dispatched when visual representation of the image is successfully embedded + into the corresponsing container. + + @event embedded + @param {Object} event + */ + 'embedded' + ]; + + function Image() { + + RuntimeClient.call(this); + + Basic.extend(this, { + /** + Unique id of the component + + @property uid + @type {String} + */ + uid: Basic.guid('uid_'), + + /** + Unique id of the connected runtime, if any. + + @property ruid + @type {String} + */ + ruid: null, + + /** + Name of the file, that was used to create an image, if available. If not equals to empty string. + + @property name + @type {String} + @default "" + */ + name: "", + + /** + Size of the image in bytes. Actual value is set only after image is preloaded. + + @property size + @type {Number} + @default 0 + */ + size: 0, + + /** + Width of the image. Actual value is set only after image is preloaded. + + @property width + @type {Number} + @default 0 + */ + width: 0, + + /** + Height of the image. Actual value is set only after image is preloaded. + + @property height + @type {Number} + @default 0 + */ + height: 0, + + /** + Mime type of the image. Currently only image/jpeg and image/png are supported. Actual value is set only after image is preloaded. + + @property type + @type {String} + @default "" + */ + type: "", + + /** + Holds meta info (Exif, GPS). Is populated only for image/jpeg. Actual value is set only after image is preloaded. + + @property meta + @type {Object} + @default {} + */ + meta: {}, + + /** + Alias for load method, that takes another mOxie.Image object as a source (see load). + + @method clone + @param {Image} src Source for the image + @param {Boolean} [exact=false] Whether to activate in-depth clone mode + */ + clone: function() { + this.load.apply(this, arguments); + }, + + /** + Loads image from various sources. Currently the source for new image can be: mOxie.Image, mOxie.Blob/mOxie.File, + native Blob/File, dataUrl or URL. Depending on the type of the source, arguments - differ. When source is URL, + Image will be downloaded from remote destination and loaded in memory. + + @example + var img = new mOxie.Image(); + img.onload = function() { + var blob = img.getAsBlob(); + + var formData = new mOxie.FormData(); + formData.append('file', blob); + + var xhr = new mOxie.XMLHttpRequest(); + xhr.onload = function() { + // upload complete + }; + xhr.open('post', 'upload.php'); + xhr.send(formData); + }; + img.load("http://www.moxiecode.com/images/mox-logo.jpg"); // notice file extension (.jpg) + + + @method load + @param {Image|Blob|File|String} src Source for the image + @param {Boolean|Object} [mixed] + */ + load: function() { + _load.apply(this, arguments); + }, + + + /** + Resizes the image to fit the specified width/height. If crop is specified, image will also be + cropped to the exact dimensions. + + @method resize + @since 3.0 + @param {Object} options + @param {Number} options.width Resulting width + @param {Number} [options.height=width] Resulting height (optional, if not supplied will default to width) + @param {String} [options.type='image/jpeg'] MIME type of the resulting image + @param {Number} [options.quality=90] In the case of JPEG, controls the quality of resulting image + @param {Boolean} [options.crop='cc'] If not falsy, image will be cropped, by default from center + @param {Boolean} [options.fit=true] In case of crop whether to upscale the image to fit the exact dimensions + @param {Boolean} [options.preserveHeaders=true] Whether to preserve meta headers (on JPEGs after resize) + @param {String} [options.resample='default'] Resampling algorithm to use during resize + @param {Boolean} [options.multipass=true] Whether to scale the image in steps (results in better quality) + */ + resize: function(options) { + var self = this; + var orientation; + var scale; + + var srcRect = { + x: 0, + y: 0, + width: self.width, + height: self.height + }; + + var opts = Basic.extendIf({ + width: self.width, + height: self.height, + type: self.type || 'image/jpeg', + quality: 90, + crop: false, + fit: true, + preserveHeaders: true, + resample: 'default', + multipass: true + }, options); + + try { + if (!self.size) { // only preloaded image objects can be used as source + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // no way to reliably intercept the crash due to high resolution, so we simply avoid it + if (self.width > Image.MAX_RESIZE_WIDTH || self.height > Image.MAX_RESIZE_HEIGHT) { + throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR); + } + + // take into account orientation tag + orientation = (self.meta && self.meta.tiff && self.meta.tiff.Orientation) || 1; + + if (Basic.inArray(orientation, [5,6,7,8]) !== -1) { // values that require 90 degree rotation + var tmp = opts.width; + opts.width = opts.height; + opts.height = tmp; + } + + if (opts.crop) { + scale = Math.max(opts.width/self.width, opts.height/self.height); + + if (options.fit) { + // first scale it up or down to fit the original image + srcRect.width = Math.min(Math.ceil(opts.width/scale), self.width); + srcRect.height = Math.min(Math.ceil(opts.height/scale), self.height); + + // recalculate the scale for adapted dimensions + scale = opts.width/srcRect.width; + } else { + srcRect.width = Math.min(opts.width, self.width); + srcRect.height = Math.min(opts.height, self.height); + + // now we do not need to scale it any further + scale = 1; + } + + if (typeof(opts.crop) === 'boolean') { + opts.crop = 'cc'; + } + + switch (opts.crop.toLowerCase().replace(/_/, '-')) { + case 'rb': + case 'right-bottom': + srcRect.x = self.width - srcRect.width; + srcRect.y = self.height - srcRect.height; + break; + + case 'cb': + case 'center-bottom': + srcRect.x = Math.floor((self.width - srcRect.width) / 2); + srcRect.y = self.height - srcRect.height; + break; + + case 'lb': + case 'left-bottom': + srcRect.x = 0; + srcRect.y = self.height - srcRect.height; + break; + + case 'lt': + case 'left-top': + srcRect.x = 0; + srcRect.y = 0; + break; + + case 'ct': + case 'center-top': + srcRect.x = Math.floor((self.width - srcRect.width) / 2); + srcRect.y = 0; + break; + + case 'rt': + case 'right-top': + srcRect.x = self.width - srcRect.width; + srcRect.y = 0; + break; + + case 'rc': + case 'right-center': + case 'right-middle': + srcRect.x = self.width - srcRect.width; + srcRect.y = Math.floor((self.height - srcRect.height) / 2); + break; + + + case 'lc': + case 'left-center': + case 'left-middle': + srcRect.x = 0; + srcRect.y = Math.floor((self.height - srcRect.height) / 2); + break; + + case 'cc': + case 'center-center': + case 'center-middle': + default: + srcRect.x = Math.floor((self.width - srcRect.width) / 2); + srcRect.y = Math.floor((self.height - srcRect.height) / 2); + } + + // original image might be smaller than requested crop, so - avoid negative values + srcRect.x = Math.max(srcRect.x, 0); + srcRect.y = Math.max(srcRect.y, 0); + } else { + scale = Math.min(opts.width/self.width, opts.height/self.height); + } + + this.exec('Image', 'resize', srcRect, scale, opts); + } catch(ex) { + // for now simply trigger error event + self.trigger('error', ex.code); + } + }, + + /** + Downsizes the image to fit the specified width/height. If crop is supplied, image will be cropped to exact dimensions. + + @method downsize + @deprecated use resize() + */ + downsize: function(options) { + var defaults = { + width: this.width, + height: this.height, + type: this.type || 'image/jpeg', + quality: 90, + crop: false, + preserveHeaders: true, + resample: 'default' + }, opts; + + if (typeof(options) === 'object') { + opts = Basic.extend(defaults, options); + } else { + // for backward compatibility + opts = Basic.extend(defaults, { + width: arguments[0], + height: arguments[1], + crop: arguments[2], + preserveHeaders: arguments[3] + }); + } + + this.resize(opts); + }, + + /** + Alias for downsize(width, height, true). (see downsize) + + @method crop + @param {Number} width Resulting width + @param {Number} [height=width] Resulting height (optional, if not supplied will default to width) + @param {Boolean} [preserveHeaders=true] Whether to preserve meta headers (on JPEGs after resize) + */ + crop: function(width, height, preserveHeaders) { + this.downsize(width, height, true, preserveHeaders); + }, + + getAsCanvas: function() { + if (!Env.can('create_canvas')) { + throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR); + } + return this.exec('Image', 'getAsCanvas'); + }, + + /** + Retrieves image in it's current state as mOxie.Blob object. Cannot be run on empty or image in progress (throws + DOMException.INVALID_STATE_ERR). + + @method getAsBlob + @param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png + @param {Number} [quality=90] Applicable only together with mime type image/jpeg + @return {Blob} Image as Blob + */ + getAsBlob: function(type, quality) { + if (!this.size) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + return this.exec('Image', 'getAsBlob', type || 'image/jpeg', quality || 90); + }, + + /** + Retrieves image in it's current state as dataURL string. Cannot be run on empty or image in progress (throws + DOMException.INVALID_STATE_ERR). + + @method getAsDataURL + @param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png + @param {Number} [quality=90] Applicable only together with mime type image/jpeg + @return {String} Image as dataURL string + */ + getAsDataURL: function(type, quality) { + if (!this.size) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + return this.exec('Image', 'getAsDataURL', type || 'image/jpeg', quality || 90); + }, + + /** + Retrieves image in it's current state as binary string. Cannot be run on empty or image in progress (throws + DOMException.INVALID_STATE_ERR). + + @method getAsBinaryString + @param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png + @param {Number} [quality=90] Applicable only together with mime type image/jpeg + @return {String} Image as binary string + */ + getAsBinaryString: function(type, quality) { + var dataUrl = this.getAsDataURL(type, quality); + return Encode.atob(dataUrl.substring(dataUrl.indexOf('base64,') + 7)); + }, + + /** + Embeds a visual representation of the image into the specified node. Depending on the runtime, + it might be a canvas, an img node or a thrid party shim object (Flash or SilverLight - very rare, + can be used in legacy browsers that do not have canvas or proper dataURI support). + + @method embed + @param {DOMElement} el DOM element to insert the image object into + @param {Object} [options] + @param {Number} [options.width] The width of an embed (defaults to the image width) + @param {Number} [options.height] The height of an embed (defaults to the image height) + @param {String} [options.type="image/jpeg"] Mime type + @param {Number} [options.quality=90] Quality of an embed, if mime type is image/jpeg + @param {Boolean} [options.crop=false] Whether to crop an embed to the specified dimensions + */ + embed: function(el, options) { + var self = this + , runtime // this has to be outside of all the closures to contain proper runtime + ; + + var opts = Basic.extend({ + width: this.width, + height: this.height, + type: this.type || 'image/jpeg', + quality: 90 + }, options); + + + function render(type, quality) { + var img = this; + + // if possible, embed a canvas element directly + if (Env.can('create_canvas')) { + var canvas = img.getAsCanvas(); + if (canvas) { + el.appendChild(canvas); + canvas = null; + img.destroy(); + self.trigger('embedded'); + return; + } + } + + var dataUrl = img.getAsDataURL(type, quality); + if (!dataUrl) { + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + + if (Env.can('use_data_uri_of', dataUrl.length)) { + el.innerHTML = ''; + img.destroy(); + self.trigger('embedded'); + } else { + var tr = new Transporter(); + + tr.bind("TransportingComplete", function() { + runtime = self.connectRuntime(this.result.ruid); + + self.bind("Embedded", function() { + // position and size properly + Basic.extend(runtime.getShimContainer().style, { + //position: 'relative', + top: '0px', + left: '0px', + width: img.width + 'px', + height: img.height + 'px' + }); + + // some shims (Flash/SilverLight) reinitialize, if parent element is hidden, reordered or it's + // position type changes (in Gecko), but since we basically need this only in IEs 6/7 and + // sometimes 8 and they do not have this problem, we can comment this for now + /*tr.bind("RuntimeInit", function(e, runtime) { + tr.destroy(); + runtime.destroy(); + onResize.call(self); // re-feed our image data + });*/ + + runtime = null; // release + }, 999); + + runtime.exec.call(self, "ImageView", "display", this.result.uid, width, height); + img.destroy(); + }); + + tr.transport(Encode.atob(dataUrl.substring(dataUrl.indexOf('base64,') + 7)), type, { + required_caps: { + display_media: true + }, + runtime_order: 'flash,silverlight', + container: el + }); + } + } + + try { + if (!(el = Dom.get(el))) { + throw new x.DOMException(x.DOMException.INVALID_NODE_TYPE_ERR); + } + + if (!this.size) { // only preloaded image objects can be used as source + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // high-resolution images cannot be consistently handled across the runtimes + if (this.width > Image.MAX_RESIZE_WIDTH || this.height > Image.MAX_RESIZE_HEIGHT) { + //throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR); + } + + var imgCopy = new Image(); + + imgCopy.bind("Resize", function() { + render.call(this, opts.type, opts.quality); + }); + + imgCopy.bind("Load", function() { + this.downsize(opts); + }); + + // if embedded thumb data is available and dimensions are big enough, use it + if (this.meta.thumb && this.meta.thumb.width >= opts.width && this.meta.thumb.height >= opts.height) { + imgCopy.load(this.meta.thumb.data); + } else { + imgCopy.clone(this, false); + } + + return imgCopy; + } catch(ex) { + // for now simply trigger error event + this.trigger('error', ex.code); + } + }, + + /** + Properly destroys the image and frees resources in use. If any. Recommended way to dispose mOxie.Image object. + + @method destroy + */ + destroy: function() { + if (this.ruid) { + this.getRuntime().exec.call(this, 'Image', 'destroy'); + this.disconnectRuntime(); + } + if (this.meta && this.meta.thumb) { + // thumb is blob, make sure we destroy it first + this.meta.thumb.data.destroy(); + } + this.unbindAll(); + } + }); + + + // this is here, because in order to bind properly, we need uid, which is created above + this.handleEventProps(dispatches); + + this.bind('Load Resize', function() { + return _updateInfo.call(this); // if operation fails (e.g. image is neither PNG nor JPEG) cancel all pending events + }, 999); + + + function _updateInfo(info) { + try { + if (!info) { + info = this.exec('Image', 'getInfo'); + } + + this.size = info.size; + this.width = info.width; + this.height = info.height; + this.type = info.type; + this.meta = info.meta; + + // update file name, only if empty + if (this.name === '') { + this.name = info.name; + } + + return true; + } catch(ex) { + this.trigger('error', ex.code); + return false; + } + } + + + function _load(src) { + var srcType = Basic.typeOf(src); + + try { + // if source is Image + if (src instanceof Image) { + if (!src.size) { // only preloaded image objects can be used as source + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + _loadFromImage.apply(this, arguments); + } + // if source is o.Blob/o.File + else if (src instanceof Blob) { + if (!~Basic.inArray(src.type, ['image/jpeg', 'image/png'])) { + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + _loadFromBlob.apply(this, arguments); + } + // if native blob/file + else if (Basic.inArray(srcType, ['blob', 'file']) !== -1) { + _load.call(this, new File(null, src), arguments[1]); + } + // if String + else if (srcType === 'string') { + // if dataUrl String + if (src.substr(0, 5) === 'data:') { + _load.call(this, new Blob(null, { data: src }), arguments[1]); + } + // else assume Url, either relative or absolute + else { + _loadFromUrl.apply(this, arguments); + } + } + // if source seems to be an img node + else if (srcType === 'node' && src.nodeName.toLowerCase() === 'img') { + _load.call(this, src.src, arguments[1]); + } + else { + throw new x.DOMException(x.DOMException.TYPE_MISMATCH_ERR); + } + } catch(ex) { + // for now simply trigger error event + this.trigger('error', ex.code); + } + } + + + function _loadFromImage(img, exact) { + var runtime = this.connectRuntime(img.ruid); + this.ruid = runtime.uid; + runtime.exec.call(this, 'Image', 'loadFromImage', img, (Basic.typeOf(exact) === 'undefined' ? true : exact)); + } + + + function _loadFromBlob(blob, options) { + var self = this; + + self.name = blob.name || ''; + + function exec(runtime) { + self.ruid = runtime.uid; + runtime.exec.call(self, 'Image', 'loadFromBlob', blob); + } + + if (blob.isDetached()) { + this.bind('RuntimeInit', function(e, runtime) { + exec(runtime); + }); + + // convert to object representation + if (options && typeof(options.required_caps) === 'string') { + options.required_caps = Runtime.parseCaps(options.required_caps); + } + + this.connectRuntime(Basic.extend({ + required_caps: { + access_image_binary: true, + resize_image: true + } + }, options)); + } else { + exec(this.connectRuntime(blob.ruid)); + } + } + + + function _loadFromUrl(url, options) { + var self = this, xhr; + + xhr = new XMLHttpRequest(); + + xhr.open('get', url); + xhr.responseType = 'blob'; + + xhr.onprogress = function(e) { + self.trigger(e); + }; + + xhr.onload = function() { + _loadFromBlob.call(self, xhr.response, true); + }; + + xhr.onerror = function(e) { + self.trigger(e); + }; + + xhr.onloadend = function() { + xhr.destroy(); + }; + + xhr.bind('RuntimeError', function(e, err) { + self.trigger('RuntimeError', err); + }); + + xhr.send(null, options); + } + } + + // virtual world will crash on you if image has a resolution higher than this: + Image.MAX_RESIZE_WIDTH = 8192; + Image.MAX_RESIZE_HEIGHT = 8192; + + Image.prototype = EventTarget.instance; + + return Image; +}); + +// Included from: src/javascript/runtime/html5/Runtime.js + +/** + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global File:true */ + +/** +Defines constructor for HTML5 runtime. + +@class moxie/runtime/html5/Runtime +@private +*/ +define("moxie/runtime/html5/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/runtime/Runtime", + "moxie/core/utils/Env" +], function(Basic, x, Runtime, Env) { + + var type = "html5", extensions = {}; + + function Html5Runtime(options) { + var I = this + , Test = Runtime.capTest + , True = Runtime.capTrue + ; + + var caps = Basic.extend({ + access_binary: Test(window.FileReader || window.File && window.File.getAsDataURL), + access_image_binary: function() { + return I.can('access_binary') && !!extensions.Image; + }, + display_media: Test( + (Env.can('create_canvas') || Env.can('use_data_uri_over32kb')) && + defined('moxie/image/Image') + ), + do_cors: Test(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()), + drag_and_drop: Test(function() { + // this comes directly from Modernizr: http://www.modernizr.com/ + var div = document.createElement('div'); + // IE has support for drag and drop since version 5, but doesn't support dropping files from desktop + return (('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) && + (Env.browser !== 'IE' || Env.verComp(Env.version, 9, '>')); + }()), + filter_by_extension: Test(function() { // if you know how to feature-detect this, please suggest + return !( + (Env.browser === 'Chrome' && Env.verComp(Env.version, 28, '<')) || + (Env.browser === 'IE' && Env.verComp(Env.version, 10, '<')) || + (Env.browser === 'Safari' && Env.verComp(Env.version, 7, '<')) || + (Env.browser === 'Firefox' && Env.verComp(Env.version, 37, '<')) + ); + }()), + return_response_headers: True, + return_response_type: function(responseType) { + if (responseType === 'json' && !!window.JSON) { // we can fake this one even if it's not supported + return true; + } + return Env.can('return_response_type', responseType); + }, + return_status_code: True, + report_upload_progress: Test(window.XMLHttpRequest && new XMLHttpRequest().upload), + resize_image: function() { + return I.can('access_binary') && Env.can('create_canvas'); + }, + select_file: function() { + return Env.can('use_fileinput') && window.File; + }, + select_folder: function() { + return I.can('select_file') && ( + Env.browser === 'Chrome' && Env.verComp(Env.version, 21, '>=') || + Env.browser === 'Firefox' && Env.verComp(Env.version, 42, '>=') // https://developer.mozilla.org/en-US/Firefox/Releases/42 + ); + }, + select_multiple: function() { + // it is buggy on Safari Windows and iOS + return I.can('select_file') && + !(Env.browser === 'Safari' && Env.os === 'Windows') && + !(Env.os === 'iOS' && Env.verComp(Env.osVersion, "7.0.0", '>') && Env.verComp(Env.osVersion, "8.0.0", '<')); + }, + send_binary_string: Test(window.XMLHttpRequest && (new XMLHttpRequest().sendAsBinary || (window.Uint8Array && window.ArrayBuffer))), + send_custom_headers: Test(window.XMLHttpRequest), + send_multipart: function() { + return !!(window.XMLHttpRequest && new XMLHttpRequest().upload && window.FormData) || I.can('send_binary_string'); + }, + slice_blob: Test(window.File && (File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice)), + stream_upload: function(){ + return I.can('slice_blob') && I.can('send_multipart'); + }, + summon_file_dialog: function() { // yeah... some dirty sniffing here... + return I.can('select_file') && ( + (Env.browser === 'Firefox' && Env.verComp(Env.version, 4, '>=')) || + (Env.browser === 'Opera' && Env.verComp(Env.version, 12, '>=')) || + (Env.browser === 'IE' && Env.verComp(Env.version, 10, '>=')) || + !!~Basic.inArray(Env.browser, ['Chrome', 'Safari', 'Edge']) + ); + }, + upload_filesize: True, + use_http_method: True + }, + arguments[2] + ); + + Runtime.call(this, options, (arguments[1] || type), caps); + + + Basic.extend(this, { + + init : function() { + this.trigger("Init"); + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + destroy.call(I); + destroy = I = null; + }; + }(this.destroy)) + }); + + Basic.extend(this.getShim(), extensions); + } + + Runtime.addConstructor(type, Html5Runtime); + + return extensions; +}); + +// Included from: src/javascript/runtime/html5/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/Blob +@private +*/ +define("moxie/runtime/html5/file/Blob", [ + "moxie/runtime/html5/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + function HTML5Blob() { + function w3cBlobSlice(blob, start, end) { + var blobSlice; + + if (window.File.prototype.slice) { + try { + blob.slice(); // depricated version will throw WRONG_ARGUMENTS_ERR exception + return blob.slice(start, end); + } catch (e) { + // depricated slice method + return blob.slice(start, end - start); + } + // slice method got prefixed: https://bugzilla.mozilla.org/show_bug.cgi?id=649672 + } else if ((blobSlice = window.File.prototype.webkitSlice || window.File.prototype.mozSlice)) { + return blobSlice.call(blob, start, end); + } else { + return null; // or throw some exception + } + } + + this.slice = function() { + return new Blob(this.getRuntime().uid, w3cBlobSlice.apply(this, arguments)); + }; + } + + return (extensions.Blob = HTML5Blob); +}); + +// Included from: src/javascript/core/utils/Events.js + +/** + * Events.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Events', [ + 'moxie/core/utils/Basic' +], function(Basic) { + var eventhash = {}, uid = 'moxie_' + Basic.guid(); + + // IE W3C like event funcs + function preventDefault() { + this.returnValue = false; + } + + function stopPropagation() { + this.cancelBubble = true; + } + + /** + Adds an event handler to the specified object and store reference to the handler + in objects internal Plupload registry (@see removeEvent). + + @method addEvent + @for Utils + @static + @param {Object} obj DOM element like object to add handler to. + @param {String} name Name to add event listener to. + @param {Function} callback Function to call when event occurs. + @param {String} [key] that might be used to add specifity to the event record. + */ + var addEvent = function(obj, name, callback, key) { + var func, events; + + name = name.toLowerCase(); + + // Add event listener + if (obj.addEventListener) { + func = callback; + + obj.addEventListener(name, func, false); + } else if (obj.attachEvent) { + func = function() { + var evt = window.event; + + if (!evt.target) { + evt.target = evt.srcElement; + } + + evt.preventDefault = preventDefault; + evt.stopPropagation = stopPropagation; + + callback(evt); + }; + + obj.attachEvent('on' + name, func); + } + + // Log event handler to objects internal mOxie registry + if (!obj[uid]) { + obj[uid] = Basic.guid(); + } + + if (!eventhash.hasOwnProperty(obj[uid])) { + eventhash[obj[uid]] = {}; + } + + events = eventhash[obj[uid]]; + + if (!events.hasOwnProperty(name)) { + events[name] = []; + } + + events[name].push({ + func: func, + orig: callback, // store original callback for IE + key: key + }); + }; + + + /** + Remove event handler from the specified object. If third argument (callback) + is not specified remove all events with the specified name. + + @method removeEvent + @static + @param {Object} obj DOM element to remove event listener(s) from. + @param {String} name Name of event listener to remove. + @param {Function|String} [callback] might be a callback or unique key to match. + */ + var removeEvent = function(obj, name, callback) { + var type, undef; + + name = name.toLowerCase(); + + if (obj[uid] && eventhash[obj[uid]] && eventhash[obj[uid]][name]) { + type = eventhash[obj[uid]][name]; + } else { + return; + } + + for (var i = type.length - 1; i >= 0; i--) { + // undefined or not, key should match + if (type[i].orig === callback || type[i].key === callback) { + if (obj.removeEventListener) { + obj.removeEventListener(name, type[i].func, false); + } else if (obj.detachEvent) { + obj.detachEvent('on'+name, type[i].func); + } + + type[i].orig = null; + type[i].func = null; + type.splice(i, 1); + + // If callback was passed we are done here, otherwise proceed + if (callback !== undef) { + break; + } + } + } + + // If event array got empty, remove it + if (!type.length) { + delete eventhash[obj[uid]][name]; + } + + // If mOxie registry has become empty, remove it + if (Basic.isEmptyObj(eventhash[obj[uid]])) { + delete eventhash[obj[uid]]; + + // IE doesn't let you remove DOM object property with - delete + try { + delete obj[uid]; + } catch(e) { + obj[uid] = undef; + } + } + }; + + + /** + Remove all kind of events from the specified object + + @method removeAllEvents + @static + @param {Object} obj DOM element to remove event listeners from. + @param {String} [key] unique key to match, when removing events. + */ + var removeAllEvents = function(obj, key) { + if (!obj || !obj[uid]) { + return; + } + + Basic.each(eventhash[obj[uid]], function(events, name) { + removeEvent(obj, name, key); + }); + }; + + return { + addEvent: addEvent, + removeEvent: removeEvent, + removeAllEvents: removeAllEvents + }; +}); + +// Included from: src/javascript/runtime/html5/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/FileInput +@private +*/ +define("moxie/runtime/html5/file/FileInput", [ + "moxie/runtime/html5/Runtime", + "moxie/file/File", + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/utils/Events", + "moxie/core/utils/Mime", + "moxie/core/utils/Env" +], function(extensions, File, Basic, Dom, Events, Mime, Env) { + + function FileInput() { + var _options, _browseBtnZIndex; // save original z-index + + Basic.extend(this, { + init: function(options) { + var comp = this, I = comp.getRuntime(), input, shimContainer, mimes, browseButton, zIndex, top; + + _options = options; + + // figure out accept string + mimes = _options.accept.mimes || Mime.extList2mimes(_options.accept, I.can('filter_by_extension')); + + shimContainer = I.getShimContainer(); + + shimContainer.innerHTML = ''; + + input = Dom.get(I.uid); + + // prepare file input to be placed underneath the browse_button element + Basic.extend(input.style, { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%' + }); + + + browseButton = Dom.get(_options.browse_button); + _browseBtnZIndex = Dom.getStyle(browseButton, 'z-index') || 'auto'; + + // Route click event to the input[type=file] element for browsers that support such behavior + if (I.can('summon_file_dialog')) { + if (Dom.getStyle(browseButton, 'position') === 'static') { + browseButton.style.position = 'relative'; + } + + Events.addEvent(browseButton, 'click', function(e) { + var input = Dom.get(I.uid); + if (input && !input.disabled) { // for some reason FF (up to 8.0.1 so far) lets to click disabled input[type=file] + input.click(); + } + e.preventDefault(); + }, comp.uid); + + comp.bind('Refresh', function() { + zIndex = parseInt(_browseBtnZIndex, 10) || 1; + + Dom.get(_options.browse_button).style.zIndex = zIndex; + this.getRuntime().getShimContainer().style.zIndex = zIndex - 1; + }); + } + + /* Since we have to place input[type=file] on top of the browse_button for some browsers, + browse_button loses interactivity, so we restore it here */ + top = I.can('summon_file_dialog') ? browseButton : shimContainer; + + Events.addEvent(top, 'mouseover', function() { + comp.trigger('mouseenter'); + }, comp.uid); + + Events.addEvent(top, 'mouseout', function() { + comp.trigger('mouseleave'); + }, comp.uid); + + Events.addEvent(top, 'mousedown', function() { + comp.trigger('mousedown'); + }, comp.uid); + + Events.addEvent(Dom.get(_options.container), 'mouseup', function() { + comp.trigger('mouseup'); + }, comp.uid); + + + input.onchange = function onChange(e) { // there should be only one handler for this + comp.files = []; + + Basic.each(this.files, function(file) { + var relativePath = ''; + + if (_options.directory) { + // folders are represented by dots, filter them out (Chrome 11+) + if (file.name == ".") { + // if it looks like a folder... + return true; + } + } + + if (file.webkitRelativePath) { + relativePath = '/' + file.webkitRelativePath.replace(/^\//, ''); + } + + file = new File(I.uid, file); + file.relativePath = relativePath; + + comp.files.push(file); + }); + + // clearing the value enables the user to select the same file again if they want to + if (Env.browser !== 'IE' && Env.browser !== 'IEMobile') { + this.value = ''; + } else { + // in IE input[type="file"] is read-only so the only way to reset it is to re-insert it + var clone = this.cloneNode(true); + this.parentNode.replaceChild(clone, this); + clone.onchange = onChange; + } + + if (comp.files.length) { + comp.trigger('change'); + } + }; + + // ready event is perfectly asynchronous + comp.trigger({ + type: 'ready', + async: true + }); + + shimContainer = null; + }, + + + setOption: function(name, value) { + var I = this.getRuntime(); + var input = Dom.get(I.uid); + + switch (name) { + case 'accept': + if (value) { + var mimes = value.mimes || Mime.extList2mimes(value, I.can('filter_by_extension')); + input.setAttribute('accept', mimes.join(',')); + } else { + input.removeAttribute('accept'); + } + break; + + case 'directory': + if (value && I.can('select_folder')) { + input.setAttribute('directory', ''); + input.setAttribute('webkitdirectory', ''); + } else { + input.removeAttribute('directory'); + input.removeAttribute('webkitdirectory'); + } + break; + + case 'multiple': + if (value && I.can('select_multiple')) { + input.setAttribute('multiple', ''); + } else { + input.removeAttribute('multiple'); + } + + } + }, + + + disable: function(state) { + var I = this.getRuntime(), input; + + if ((input = Dom.get(I.uid))) { + input.disabled = !!state; + } + }, + + destroy: function() { + var I = this.getRuntime() + , shim = I.getShim() + , shimContainer = I.getShimContainer() + , container = _options && Dom.get(_options.container) + , browseButton = _options && Dom.get(_options.browse_button) + ; + + if (container) { + Events.removeAllEvents(container, this.uid); + } + + if (browseButton) { + Events.removeAllEvents(browseButton, this.uid); + browseButton.style.zIndex = _browseBtnZIndex; // reset to original value + } + + if (shimContainer) { + Events.removeAllEvents(shimContainer, this.uid); + shimContainer.innerHTML = ''; + } + + shim.removeInstance(this.uid); + + _options = shimContainer = container = browseButton = shim = null; + } + }); + } + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/html5/file/FileDrop.js + +/** + * FileDrop.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/FileDrop +@private +*/ +define("moxie/runtime/html5/file/FileDrop", [ + "moxie/runtime/html5/Runtime", + 'moxie/file/File', + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/utils/Events", + "moxie/core/utils/Mime" +], function(extensions, File, Basic, Dom, Events, Mime) { + + function FileDrop() { + var _files = [], _allowedExts = [], _options, _ruid; + + Basic.extend(this, { + init: function(options) { + var comp = this, dropZone; + + _options = options; + _ruid = comp.ruid; // every dropped-in file should have a reference to the runtime + _allowedExts = _extractExts(_options.accept); + dropZone = _options.container; + + Events.addEvent(dropZone, 'dragover', function(e) { + if (!_hasFiles(e)) { + return; + } + e.preventDefault(); + e.dataTransfer.dropEffect = 'copy'; + }, comp.uid); + + Events.addEvent(dropZone, 'drop', function(e) { + if (!_hasFiles(e)) { + return; + } + e.preventDefault(); + + _files = []; + + // Chrome 21+ accepts folders via Drag'n'Drop + if (e.dataTransfer.items && e.dataTransfer.items[0].webkitGetAsEntry) { + _readItems(e.dataTransfer.items, function() { + comp.files = _files; + comp.trigger("drop"); + }); + } else { + Basic.each(e.dataTransfer.files, function(file) { + _addFile(file); + }); + comp.files = _files; + comp.trigger("drop"); + } + }, comp.uid); + + Events.addEvent(dropZone, 'dragenter', function(e) { + comp.trigger("dragenter"); + }, comp.uid); + + Events.addEvent(dropZone, 'dragleave', function(e) { + comp.trigger("dragleave"); + }, comp.uid); + }, + + destroy: function() { + Events.removeAllEvents(_options && Dom.get(_options.container), this.uid); + _ruid = _files = _allowedExts = _options = null; + } + }); + + + function _hasFiles(e) { + if (!e.dataTransfer || !e.dataTransfer.types) { // e.dataTransfer.files is not available in Gecko during dragover + return false; + } + + var types = Basic.toArray(e.dataTransfer.types || []); + + return Basic.inArray("Files", types) !== -1 || + Basic.inArray("public.file-url", types) !== -1 || // Safari < 5 + Basic.inArray("application/x-moz-file", types) !== -1 // Gecko < 1.9.2 (< Firefox 3.6) + ; + } + + + function _addFile(file, relativePath) { + if (_isAcceptable(file)) { + var fileObj = new File(_ruid, file); + fileObj.relativePath = relativePath || ''; + _files.push(fileObj); + } + } + + + function _extractExts(accept) { + var exts = []; + for (var i = 0; i < accept.length; i++) { + [].push.apply(exts, accept[i].extensions.split(/\s*,\s*/)); + } + return Basic.inArray('*', exts) === -1 ? exts : []; + } + + + function _isAcceptable(file) { + if (!_allowedExts.length) { + return true; + } + var ext = Mime.getFileExtension(file.name); + return !ext || Basic.inArray(ext, _allowedExts) !== -1; + } + + + function _readItems(items, cb) { + var entries = []; + Basic.each(items, function(item) { + var entry = item.webkitGetAsEntry(); + // Address #998 (https://code.google.com/p/chromium/issues/detail?id=332579) + if (entry) { + // file() fails on OSX when the filename contains a special character (e.g. umlaut): see #61 + if (entry.isFile) { + _addFile(item.getAsFile(), entry.fullPath); + } else { + entries.push(entry); + } + } + }); + + if (entries.length) { + _readEntries(entries, cb); + } else { + cb(); + } + } + + + function _readEntries(entries, cb) { + var queue = []; + Basic.each(entries, function(entry) { + queue.push(function(cbcb) { + _readEntry(entry, cbcb); + }); + }); + Basic.inSeries(queue, function() { + cb(); + }); + } + + + function _readEntry(entry, cb) { + if (entry.isFile) { + entry.file(function(file) { + _addFile(file, entry.fullPath); + cb(); + }, function() { + // fire an error event maybe + cb(); + }); + } else if (entry.isDirectory) { + _readDirEntry(entry, cb); + } else { + cb(); // not file, not directory? what then?.. + } + } + + + function _readDirEntry(dirEntry, cb) { + var entries = [], dirReader = dirEntry.createReader(); + + // keep quering recursively till no more entries + function getEntries(cbcb) { + dirReader.readEntries(function(moreEntries) { + if (moreEntries.length) { + [].push.apply(entries, moreEntries); + getEntries(cbcb); + } else { + cbcb(); + } + }, cbcb); + } + + // ...and you thought FileReader was crazy... + getEntries(function() { + _readEntries(entries, cb); + }); + } + } + + return (extensions.FileDrop = FileDrop); +}); + +// Included from: src/javascript/runtime/html5/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/FileReader +@private +*/ +define("moxie/runtime/html5/file/FileReader", [ + "moxie/runtime/html5/Runtime", + "moxie/core/utils/Encode", + "moxie/core/utils/Basic" +], function(extensions, Encode, Basic) { + + function FileReader() { + var _fr, _convertToBinary = false; + + Basic.extend(this, { + + read: function(op, blob) { + var comp = this; + + comp.result = ''; + + _fr = new window.FileReader(); + + _fr.addEventListener('progress', function(e) { + comp.trigger(e); + }); + + _fr.addEventListener('load', function(e) { + comp.result = _convertToBinary ? _toBinary(_fr.result) : _fr.result; + comp.trigger(e); + }); + + _fr.addEventListener('error', function(e) { + comp.trigger(e, _fr.error); + }); + + _fr.addEventListener('loadend', function(e) { + _fr = null; + comp.trigger(e); + }); + + if (Basic.typeOf(_fr[op]) === 'function') { + _convertToBinary = false; + _fr[op](blob.getSource()); + } else if (op === 'readAsBinaryString') { // readAsBinaryString is depricated in general and never existed in IE10+ + _convertToBinary = true; + _fr.readAsDataURL(blob.getSource()); + } + }, + + abort: function() { + if (_fr) { + _fr.abort(); + } + }, + + destroy: function() { + _fr = null; + } + }); + + function _toBinary(str) { + return Encode.atob(str.substring(str.indexOf('base64,') + 7)); + } + } + + return (extensions.FileReader = FileReader); +}); + +// Included from: src/javascript/runtime/html5/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global ActiveXObject:true */ + +/** +@class moxie/runtime/html5/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/html5/xhr/XMLHttpRequest", [ + "moxie/runtime/html5/Runtime", + "moxie/core/utils/Basic", + "moxie/core/utils/Mime", + "moxie/core/utils/Url", + "moxie/file/File", + "moxie/file/Blob", + "moxie/xhr/FormData", + "moxie/core/Exceptions", + "moxie/core/utils/Env" +], function(extensions, Basic, Mime, Url, File, Blob, FormData, x, Env) { + + function XMLHttpRequest() { + var self = this + , _xhr + , _filename + ; + + Basic.extend(this, { + send: function(meta, data) { + var target = this + , isGecko2_5_6 = (Env.browser === 'Mozilla' && Env.verComp(Env.version, 4, '>=') && Env.verComp(Env.version, 7, '<')) + , isAndroidBrowser = Env.browser === 'Android Browser' + , mustSendAsBinary = false + ; + + // extract file name + _filename = meta.url.replace(/^.+?\/([\w\-\.]+)$/, '$1').toLowerCase(); + + _xhr = _getNativeXHR(); + _xhr.open(meta.method, meta.url, meta.async, meta.user, meta.password); + + + // prepare data to be sent + if (data instanceof Blob) { + if (data.isDetached()) { + mustSendAsBinary = true; + } + data = data.getSource(); + } else if (data instanceof FormData) { + + if (data.hasBlob()) { + if (data.getBlob().isDetached()) { + data = _prepareMultipart.call(target, data); // _xhr must be instantiated and be in OPENED state + mustSendAsBinary = true; + } else if ((isGecko2_5_6 || isAndroidBrowser) && Basic.typeOf(data.getBlob().getSource()) === 'blob' && window.FileReader) { + // Gecko 2/5/6 can't send blob in FormData: https://bugzilla.mozilla.org/show_bug.cgi?id=649150 + // Android browsers (default one and Dolphin) seem to have the same issue, see: #613 + _preloadAndSend.call(target, meta, data); + return; // _preloadAndSend will reinvoke send() with transmutated FormData =%D + } + } + + // transfer fields to real FormData + if (data instanceof FormData) { // if still a FormData, e.g. not mangled by _prepareMultipart() + var fd = new window.FormData(); + data.each(function(value, name) { + if (value instanceof Blob) { + fd.append(name, value.getSource()); + } else { + fd.append(name, value); + } + }); + data = fd; + } + } + + + // if XHR L2 + if (_xhr.upload) { + if (meta.withCredentials) { + _xhr.withCredentials = true; + } + + _xhr.addEventListener('load', function(e) { + target.trigger(e); + }); + + _xhr.addEventListener('error', function(e) { + target.trigger(e); + }); + + // additionally listen to progress events + _xhr.addEventListener('progress', function(e) { + target.trigger(e); + }); + + _xhr.upload.addEventListener('progress', function(e) { + target.trigger({ + type: 'UploadProgress', + loaded: e.loaded, + total: e.total + }); + }); + // ... otherwise simulate XHR L2 + } else { + _xhr.onreadystatechange = function onReadyStateChange() { + + // fake Level 2 events + switch (_xhr.readyState) { + + case 1: // XMLHttpRequest.OPENED + // readystatechanged is fired twice for OPENED state (in IE and Mozilla) - neu + break; + + // looks like HEADERS_RECEIVED (state 2) is not reported in Opera (or it's old versions) - neu + case 2: // XMLHttpRequest.HEADERS_RECEIVED + break; + + case 3: // XMLHttpRequest.LOADING + // try to fire progress event for not XHR L2 + var total, loaded; + + try { + if (Url.hasSameOrigin(meta.url)) { // Content-Length not accessible for cross-domain on some browsers + total = _xhr.getResponseHeader('Content-Length') || 0; // old Safari throws an exception here + } + + if (_xhr.responseText) { // responseText was introduced in IE7 + loaded = _xhr.responseText.length; + } + } catch(ex) { + total = loaded = 0; + } + + target.trigger({ + type: 'progress', + lengthComputable: !!total, + total: parseInt(total, 10), + loaded: loaded + }); + break; + + case 4: // XMLHttpRequest.DONE + // release readystatechange handler (mostly for IE) + _xhr.onreadystatechange = function() {}; + + // usually status 0 is returned when server is unreachable, but FF also fails to status 0 for 408 timeout + if (_xhr.status === 0) { + target.trigger('error'); + } else { + target.trigger('load'); + } + break; + } + }; + } + + + // set request headers + if (!Basic.isEmptyObj(meta.headers)) { + Basic.each(meta.headers, function(value, header) { + _xhr.setRequestHeader(header, value); + }); + } + + // request response type + if ("" !== meta.responseType && 'responseType' in _xhr) { + if ('json' === meta.responseType && !Env.can('return_response_type', 'json')) { // we can fake this one + _xhr.responseType = 'text'; + } else { + _xhr.responseType = meta.responseType; + } + } + + // send ... + if (!mustSendAsBinary) { + _xhr.send(data); + } else { + if (_xhr.sendAsBinary) { // Gecko + _xhr.sendAsBinary(data); + } else { // other browsers having support for typed arrays + (function() { + // mimic Gecko's sendAsBinary + var ui8a = new Uint8Array(data.length); + for (var i = 0; i < data.length; i++) { + ui8a[i] = (data.charCodeAt(i) & 0xff); + } + _xhr.send(ui8a.buffer); + }()); + } + } + + target.trigger('loadstart'); + }, + + getStatus: function() { + // according to W3C spec it should return 0 for readyState < 3, but instead it throws an exception + try { + if (_xhr) { + return _xhr.status; + } + } catch(ex) {} + return 0; + }, + + getResponse: function(responseType) { + var I = this.getRuntime(); + + try { + switch (responseType) { + case 'blob': + var file = new File(I.uid, _xhr.response); + + // try to extract file name from content-disposition if possible (might be - not, if CORS for example) + var disposition = _xhr.getResponseHeader('Content-Disposition'); + if (disposition) { + // extract filename from response header if available + var match = disposition.match(/filename=([\'\"'])([^\1]+)\1/); + if (match) { + _filename = match[2]; + } + } + file.name = _filename; + + // pre-webkit Opera doesn't set type property on the blob response + if (!file.type) { + file.type = Mime.getFileMime(_filename); + } + return file; + + case 'json': + if (!Env.can('return_response_type', 'json')) { + return _xhr.status === 200 && !!window.JSON ? JSON.parse(_xhr.responseText) : null; + } + return _xhr.response; + + case 'document': + return _getDocument(_xhr); + + default: + return _xhr.responseText !== '' ? _xhr.responseText : null; // against the specs, but for consistency across the runtimes + } + } catch(ex) { + return null; + } + }, + + getAllResponseHeaders: function() { + try { + return _xhr.getAllResponseHeaders(); + } catch(ex) {} + return ''; + }, + + abort: function() { + if (_xhr) { + _xhr.abort(); + } + }, + + destroy: function() { + self = _filename = null; + } + }); + + + // here we go... ugly fix for ugly bug + function _preloadAndSend(meta, data) { + var target = this, blob, fr; + + // get original blob + blob = data.getBlob().getSource(); + + // preload blob in memory to be sent as binary string + fr = new window.FileReader(); + fr.onload = function() { + // overwrite original blob + data.append(data.getBlobName(), new Blob(null, { + type: blob.type, + data: fr.result + })); + // invoke send operation again + self.send.call(target, meta, data); + }; + fr.readAsBinaryString(blob); + } + + + function _getNativeXHR() { + if (window.XMLHttpRequest && !(Env.browser === 'IE' && Env.verComp(Env.version, 8, '<'))) { // IE7 has native XHR but it's buggy + return new window.XMLHttpRequest(); + } else { + return (function() { + var progIDs = ['Msxml2.XMLHTTP.6.0', 'Microsoft.XMLHTTP']; // if 6.0 available, use it, otherwise failback to default 3.0 + for (var i = 0; i < progIDs.length; i++) { + try { + return new ActiveXObject(progIDs[i]); + } catch (ex) {} + } + })(); + } + } + + // @credits Sergey Ilinsky (http://www.ilinsky.com/) + function _getDocument(xhr) { + var rXML = xhr.responseXML; + var rText = xhr.responseText; + + // Try parsing responseText (@see: http://www.ilinsky.com/articles/XMLHttpRequest/#bugs-ie-responseXML-content-type) + if (Env.browser === 'IE' && rText && rXML && !rXML.documentElement && /[^\/]+\/[^\+]+\+xml/.test(xhr.getResponseHeader("Content-Type"))) { + rXML = new window.ActiveXObject("Microsoft.XMLDOM"); + rXML.async = false; + rXML.validateOnParse = false; + rXML.loadXML(rText); + } + + // Check if there is no error in document + if (rXML) { + if ((Env.browser === 'IE' && rXML.parseError !== 0) || !rXML.documentElement || rXML.documentElement.tagName === "parsererror") { + return null; + } + } + return rXML; + } + + + function _prepareMultipart(fd) { + var boundary = '----moxieboundary' + new Date().getTime() + , dashdash = '--' + , crlf = '\r\n' + , multipart = '' + , I = this.getRuntime() + ; + + if (!I.can('send_binary_string')) { + throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR); + } + + _xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); + + // append multipart parameters + fd.each(function(value, name) { + // Firefox 3.6 failed to convert multibyte characters to UTF-8 in sendAsBinary(), + // so we try it here ourselves with: unescape(encodeURIComponent(value)) + if (value instanceof Blob) { + // Build RFC2388 blob + multipart += dashdash + boundary + crlf + + 'Content-Disposition: form-data; name="' + name + '"; filename="' + unescape(encodeURIComponent(value.name || 'blob')) + '"' + crlf + + 'Content-Type: ' + (value.type || 'application/octet-stream') + crlf + crlf + + value.getSource() + crlf; + } else { + multipart += dashdash + boundary + crlf + + 'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf + + unescape(encodeURIComponent(value)) + crlf; + } + }); + + multipart += dashdash + boundary + dashdash + crlf; + + return multipart; + } + } + + return (extensions.XMLHttpRequest = XMLHttpRequest); +}); + +// Included from: src/javascript/runtime/html5/utils/BinaryReader.js + +/** + * BinaryReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/utils/BinaryReader +@private +*/ +define("moxie/runtime/html5/utils/BinaryReader", [ + "moxie/core/utils/Basic" +], function(Basic) { + + + function BinaryReader(data) { + if (data instanceof ArrayBuffer) { + ArrayBufferReader.apply(this, arguments); + } else { + UTF16StringReader.apply(this, arguments); + } + } + + Basic.extend(BinaryReader.prototype, { + + littleEndian: false, + + + read: function(idx, size) { + var sum, mv, i; + + if (idx + size > this.length()) { + throw new Error("You are trying to read outside the source boundaries."); + } + + mv = this.littleEndian + ? 0 + : -8 * (size - 1) + ; + + for (i = 0, sum = 0; i < size; i++) { + sum |= (this.readByteAt(idx + i) << Math.abs(mv + i*8)); + } + return sum; + }, + + + write: function(idx, num, size) { + var mv, i, str = ''; + + if (idx > this.length()) { + throw new Error("You are trying to write outside the source boundaries."); + } + + mv = this.littleEndian + ? 0 + : -8 * (size - 1) + ; + + for (i = 0; i < size; i++) { + this.writeByteAt(idx + i, (num >> Math.abs(mv + i*8)) & 255); + } + }, + + + BYTE: function(idx) { + return this.read(idx, 1); + }, + + + SHORT: function(idx) { + return this.read(idx, 2); + }, + + + LONG: function(idx) { + return this.read(idx, 4); + }, + + + SLONG: function(idx) { // 2's complement notation + var num = this.read(idx, 4); + return (num > 2147483647 ? num - 4294967296 : num); + }, + + + CHAR: function(idx) { + return String.fromCharCode(this.read(idx, 1)); + }, + + + STRING: function(idx, count) { + return this.asArray('CHAR', idx, count).join(''); + }, + + + asArray: function(type, idx, count) { + var values = []; + + for (var i = 0; i < count; i++) { + values[i] = this[type](idx + i); + } + return values; + } + }); + + + function ArrayBufferReader(data) { + var _dv = new DataView(data); + + Basic.extend(this, { + + readByteAt: function(idx) { + return _dv.getUint8(idx); + }, + + + writeByteAt: function(idx, value) { + _dv.setUint8(idx, value); + }, + + + SEGMENT: function(idx, size, value) { + switch (arguments.length) { + case 2: + return data.slice(idx, idx + size); + + case 1: + return data.slice(idx); + + case 3: + if (value === null) { + value = new ArrayBuffer(); + } + + if (value instanceof ArrayBuffer) { + var arr = new Uint8Array(this.length() - size + value.byteLength); + if (idx > 0) { + arr.set(new Uint8Array(data.slice(0, idx)), 0); + } + arr.set(new Uint8Array(value), idx); + arr.set(new Uint8Array(data.slice(idx + size)), idx + value.byteLength); + + this.clear(); + data = arr.buffer; + _dv = new DataView(data); + break; + } + + default: return data; + } + }, + + + length: function() { + return data ? data.byteLength : 0; + }, + + + clear: function() { + _dv = data = null; + } + }); + } + + + function UTF16StringReader(data) { + Basic.extend(this, { + + readByteAt: function(idx) { + return data.charCodeAt(idx); + }, + + + writeByteAt: function(idx, value) { + putstr(String.fromCharCode(value), idx, 1); + }, + + + SEGMENT: function(idx, length, segment) { + switch (arguments.length) { + case 1: + return data.substr(idx); + case 2: + return data.substr(idx, length); + case 3: + putstr(segment !== null ? segment : '', idx, length); + break; + default: return data; + } + }, + + + length: function() { + return data ? data.length : 0; + }, + + clear: function() { + data = null; + } + }); + + + function putstr(segment, idx, length) { + length = arguments.length === 3 ? length : data.length - idx - 1; + data = data.substr(0, idx) + segment + data.substr(length + idx); + } + } + + + return BinaryReader; +}); + +// Included from: src/javascript/runtime/html5/image/JPEGHeaders.js + +/** + * JPEGHeaders.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/JPEGHeaders +@private +*/ +define("moxie/runtime/html5/image/JPEGHeaders", [ + "moxie/runtime/html5/utils/BinaryReader", + "moxie/core/Exceptions" +], function(BinaryReader, x) { + + return function JPEGHeaders(data) { + var headers = [], _br, idx, marker, length = 0; + + _br = new BinaryReader(data); + + // Check if data is jpeg + if (_br.SHORT(0) !== 0xFFD8) { + _br.clear(); + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + + idx = 2; + + while (idx <= _br.length()) { + marker = _br.SHORT(idx); + + // omit RST (restart) markers + if (marker >= 0xFFD0 && marker <= 0xFFD7) { + idx += 2; + continue; + } + + // no headers allowed after SOS marker + if (marker === 0xFFDA || marker === 0xFFD9) { + break; + } + + length = _br.SHORT(idx + 2) + 2; + + // APPn marker detected + if (marker >= 0xFFE1 && marker <= 0xFFEF) { + headers.push({ + hex: marker, + name: 'APP' + (marker & 0x000F), + start: idx, + length: length, + segment: _br.SEGMENT(idx, length) + }); + } + + idx += length; + } + + _br.clear(); + + return { + headers: headers, + + restore: function(data) { + var max, i, br; + + br = new BinaryReader(data); + + idx = br.SHORT(2) == 0xFFE0 ? 4 + br.SHORT(4) : 2; + + for (i = 0, max = headers.length; i < max; i++) { + br.SEGMENT(idx, 0, headers[i].segment); + idx += headers[i].length; + } + + data = br.SEGMENT(); + br.clear(); + return data; + }, + + strip: function(data) { + var br, headers, jpegHeaders, i; + + jpegHeaders = new JPEGHeaders(data); + headers = jpegHeaders.headers; + jpegHeaders.purge(); + + br = new BinaryReader(data); + + i = headers.length; + while (i--) { + br.SEGMENT(headers[i].start, headers[i].length, ''); + } + + data = br.SEGMENT(); + br.clear(); + return data; + }, + + get: function(name) { + var array = []; + + for (var i = 0, max = headers.length; i < max; i++) { + if (headers[i].name === name.toUpperCase()) { + array.push(headers[i].segment); + } + } + return array; + }, + + set: function(name, segment) { + var array = [], i, ii, max; + + if (typeof(segment) === 'string') { + array.push(segment); + } else { + array = segment; + } + + for (i = ii = 0, max = headers.length; i < max; i++) { + if (headers[i].name === name.toUpperCase()) { + headers[i].segment = array[ii]; + headers[i].length = array[ii].length; + ii++; + } + if (ii >= array.length) { + break; + } + } + }, + + purge: function() { + this.headers = headers = []; + } + }; + }; +}); + +// Included from: src/javascript/runtime/html5/image/ExifParser.js + +/** + * ExifParser.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/ExifParser +@private +*/ +define("moxie/runtime/html5/image/ExifParser", [ + "moxie/core/utils/Basic", + "moxie/runtime/html5/utils/BinaryReader", + "moxie/core/Exceptions" +], function(Basic, BinaryReader, x) { + + function ExifParser(data) { + var __super__, tags, tagDescs, offsets, idx, Tiff; + + BinaryReader.call(this, data); + + tags = { + tiff: { + /* + The image orientation viewed in terms of rows and columns. + + 1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side. + 2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side. + 3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side. + 4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side. + 5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top. + 6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top. + 7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom. + 8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom. + */ + 0x0112: 'Orientation', + 0x010E: 'ImageDescription', + 0x010F: 'Make', + 0x0110: 'Model', + 0x0131: 'Software', + 0x8769: 'ExifIFDPointer', + 0x8825: 'GPSInfoIFDPointer' + }, + exif: { + 0x9000: 'ExifVersion', + 0xA001: 'ColorSpace', + 0xA002: 'PixelXDimension', + 0xA003: 'PixelYDimension', + 0x9003: 'DateTimeOriginal', + 0x829A: 'ExposureTime', + 0x829D: 'FNumber', + 0x8827: 'ISOSpeedRatings', + 0x9201: 'ShutterSpeedValue', + 0x9202: 'ApertureValue' , + 0x9207: 'MeteringMode', + 0x9208: 'LightSource', + 0x9209: 'Flash', + 0x920A: 'FocalLength', + 0xA402: 'ExposureMode', + 0xA403: 'WhiteBalance', + 0xA406: 'SceneCaptureType', + 0xA404: 'DigitalZoomRatio', + 0xA408: 'Contrast', + 0xA409: 'Saturation', + 0xA40A: 'Sharpness' + }, + gps: { + 0x0000: 'GPSVersionID', + 0x0001: 'GPSLatitudeRef', + 0x0002: 'GPSLatitude', + 0x0003: 'GPSLongitudeRef', + 0x0004: 'GPSLongitude' + }, + + thumb: { + 0x0201: 'JPEGInterchangeFormat', + 0x0202: 'JPEGInterchangeFormatLength' + } + }; + + tagDescs = { + 'ColorSpace': { + 1: 'sRGB', + 0: 'Uncalibrated' + }, + + 'MeteringMode': { + 0: 'Unknown', + 1: 'Average', + 2: 'CenterWeightedAverage', + 3: 'Spot', + 4: 'MultiSpot', + 5: 'Pattern', + 6: 'Partial', + 255: 'Other' + }, + + 'LightSource': { + 1: 'Daylight', + 2: 'Fliorescent', + 3: 'Tungsten', + 4: 'Flash', + 9: 'Fine weather', + 10: 'Cloudy weather', + 11: 'Shade', + 12: 'Daylight fluorescent (D 5700 - 7100K)', + 13: 'Day white fluorescent (N 4600 -5400K)', + 14: 'Cool white fluorescent (W 3900 - 4500K)', + 15: 'White fluorescent (WW 3200 - 3700K)', + 17: 'Standard light A', + 18: 'Standard light B', + 19: 'Standard light C', + 20: 'D55', + 21: 'D65', + 22: 'D75', + 23: 'D50', + 24: 'ISO studio tungsten', + 255: 'Other' + }, + + 'Flash': { + 0x0000: 'Flash did not fire', + 0x0001: 'Flash fired', + 0x0005: 'Strobe return light not detected', + 0x0007: 'Strobe return light detected', + 0x0009: 'Flash fired, compulsory flash mode', + 0x000D: 'Flash fired, compulsory flash mode, return light not detected', + 0x000F: 'Flash fired, compulsory flash mode, return light detected', + 0x0010: 'Flash did not fire, compulsory flash mode', + 0x0018: 'Flash did not fire, auto mode', + 0x0019: 'Flash fired, auto mode', + 0x001D: 'Flash fired, auto mode, return light not detected', + 0x001F: 'Flash fired, auto mode, return light detected', + 0x0020: 'No flash function', + 0x0041: 'Flash fired, red-eye reduction mode', + 0x0045: 'Flash fired, red-eye reduction mode, return light not detected', + 0x0047: 'Flash fired, red-eye reduction mode, return light detected', + 0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode', + 0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected', + 0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected', + 0x0059: 'Flash fired, auto mode, red-eye reduction mode', + 0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode', + 0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode' + }, + + 'ExposureMode': { + 0: 'Auto exposure', + 1: 'Manual exposure', + 2: 'Auto bracket' + }, + + 'WhiteBalance': { + 0: 'Auto white balance', + 1: 'Manual white balance' + }, + + 'SceneCaptureType': { + 0: 'Standard', + 1: 'Landscape', + 2: 'Portrait', + 3: 'Night scene' + }, + + 'Contrast': { + 0: 'Normal', + 1: 'Soft', + 2: 'Hard' + }, + + 'Saturation': { + 0: 'Normal', + 1: 'Low saturation', + 2: 'High saturation' + }, + + 'Sharpness': { + 0: 'Normal', + 1: 'Soft', + 2: 'Hard' + }, + + // GPS related + 'GPSLatitudeRef': { + N: 'North latitude', + S: 'South latitude' + }, + + 'GPSLongitudeRef': { + E: 'East longitude', + W: 'West longitude' + } + }; + + offsets = { + tiffHeader: 10 + }; + + idx = offsets.tiffHeader; + + __super__ = { + clear: this.clear + }; + + // Public functions + Basic.extend(this, { + + read: function() { + try { + return ExifParser.prototype.read.apply(this, arguments); + } catch (ex) { + throw new x.ImageError(x.ImageError.INVALID_META_ERR); + } + }, + + + write: function() { + try { + return ExifParser.prototype.write.apply(this, arguments); + } catch (ex) { + throw new x.ImageError(x.ImageError.INVALID_META_ERR); + } + }, + + + UNDEFINED: function() { + return this.BYTE.apply(this, arguments); + }, + + + RATIONAL: function(idx) { + return this.LONG(idx) / this.LONG(idx + 4) + }, + + + SRATIONAL: function(idx) { + return this.SLONG(idx) / this.SLONG(idx + 4) + }, + + ASCII: function(idx) { + return this.CHAR(idx); + }, + + TIFF: function() { + return Tiff || null; + }, + + + EXIF: function() { + var Exif = null; + + if (offsets.exifIFD) { + try { + Exif = extractTags.call(this, offsets.exifIFD, tags.exif); + } catch(ex) { + return null; + } + + // Fix formatting of some tags + if (Exif.ExifVersion && Basic.typeOf(Exif.ExifVersion) === 'array') { + for (var i = 0, exifVersion = ''; i < Exif.ExifVersion.length; i++) { + exifVersion += String.fromCharCode(Exif.ExifVersion[i]); + } + Exif.ExifVersion = exifVersion; + } + } + + return Exif; + }, + + + GPS: function() { + var GPS = null; + + if (offsets.gpsIFD) { + try { + GPS = extractTags.call(this, offsets.gpsIFD, tags.gps); + } catch (ex) { + return null; + } + + // iOS devices (and probably some others) do not put in GPSVersionID tag (why?..) + if (GPS.GPSVersionID && Basic.typeOf(GPS.GPSVersionID) === 'array') { + GPS.GPSVersionID = GPS.GPSVersionID.join('.'); + } + } + + return GPS; + }, + + + thumb: function() { + if (offsets.IFD1) { + try { + var IFD1Tags = extractTags.call(this, offsets.IFD1, tags.thumb); + + if ('JPEGInterchangeFormat' in IFD1Tags) { + return this.SEGMENT(offsets.tiffHeader + IFD1Tags.JPEGInterchangeFormat, IFD1Tags.JPEGInterchangeFormatLength); + } + } catch (ex) {} + } + return null; + }, + + + setExif: function(tag, value) { + // Right now only setting of width/height is possible + if (tag !== 'PixelXDimension' && tag !== 'PixelYDimension') { return false; } + + return setTag.call(this, 'exif', tag, value); + }, + + + clear: function() { + __super__.clear(); + data = tags = tagDescs = Tiff = offsets = __super__ = null; + } + }); + + + // Check if that's APP1 and that it has EXIF + if (this.SHORT(0) !== 0xFFE1 || this.STRING(4, 5).toUpperCase() !== "EXIF\0") { + throw new x.ImageError(x.ImageError.INVALID_META_ERR); + } + + // Set read order of multi-byte data + this.littleEndian = (this.SHORT(idx) == 0x4949); + + // Check if always present bytes are indeed present + if (this.SHORT(idx+=2) !== 0x002A) { + throw new x.ImageError(x.ImageError.INVALID_META_ERR); + } + + offsets.IFD0 = offsets.tiffHeader + this.LONG(idx += 2); + Tiff = extractTags.call(this, offsets.IFD0, tags.tiff); + + if ('ExifIFDPointer' in Tiff) { + offsets.exifIFD = offsets.tiffHeader + Tiff.ExifIFDPointer; + delete Tiff.ExifIFDPointer; + } + + if ('GPSInfoIFDPointer' in Tiff) { + offsets.gpsIFD = offsets.tiffHeader + Tiff.GPSInfoIFDPointer; + delete Tiff.GPSInfoIFDPointer; + } + + if (Basic.isEmptyObj(Tiff)) { + Tiff = null; + } + + // check if we have a thumb as well + var IFD1Offset = this.LONG(offsets.IFD0 + this.SHORT(offsets.IFD0) * 12 + 2); + if (IFD1Offset) { + offsets.IFD1 = offsets.tiffHeader + IFD1Offset; + } + + + function extractTags(IFD_offset, tags2extract) { + var data = this; + var length, i, tag, type, count, size, offset, value, values = [], hash = {}; + + var types = { + 1 : 'BYTE', + 7 : 'UNDEFINED', + 2 : 'ASCII', + 3 : 'SHORT', + 4 : 'LONG', + 5 : 'RATIONAL', + 9 : 'SLONG', + 10: 'SRATIONAL' + }; + + var sizes = { + 'BYTE' : 1, + 'UNDEFINED' : 1, + 'ASCII' : 1, + 'SHORT' : 2, + 'LONG' : 4, + 'RATIONAL' : 8, + 'SLONG' : 4, + 'SRATIONAL' : 8 + }; + + length = data.SHORT(IFD_offset); + + // The size of APP1 including all these elements shall not exceed the 64 Kbytes specified in the JPEG standard. + + for (i = 0; i < length; i++) { + values = []; + + // Set binary reader pointer to beginning of the next tag + offset = IFD_offset + 2 + i*12; + + tag = tags2extract[data.SHORT(offset)]; + + if (tag === undefined) { + continue; // Not the tag we requested + } + + type = types[data.SHORT(offset+=2)]; + count = data.LONG(offset+=2); + size = sizes[type]; + + if (!size) { + throw new x.ImageError(x.ImageError.INVALID_META_ERR); + } + + offset += 4; + + // tag can only fit 4 bytes of data, if data is larger we should look outside + if (size * count > 4) { + // instead of data tag contains an offset of the data + offset = data.LONG(offset) + offsets.tiffHeader; + } + + // in case we left the boundaries of data throw an early exception + if (offset + size * count >= this.length()) { + throw new x.ImageError(x.ImageError.INVALID_META_ERR); + } + + // special care for the string + if (type === 'ASCII') { + hash[tag] = Basic.trim(data.STRING(offset, count).replace(/\0$/, '')); // strip trailing NULL + continue; + } else { + values = data.asArray(type, offset, count); + value = (count == 1 ? values[0] : values); + + if (tagDescs.hasOwnProperty(tag) && typeof value != 'object') { + hash[tag] = tagDescs[tag][value]; + } else { + hash[tag] = value; + } + } + } + + return hash; + } + + // At the moment only setting of simple (LONG) values, that do not require offset recalculation, is supported + function setTag(ifd, tag, value) { + var offset, length, tagOffset, valueOffset = 0; + + // If tag name passed translate into hex key + if (typeof(tag) === 'string') { + var tmpTags = tags[ifd.toLowerCase()]; + for (var hex in tmpTags) { + if (tmpTags[hex] === tag) { + tag = hex; + break; + } + } + } + offset = offsets[ifd.toLowerCase() + 'IFD']; + length = this.SHORT(offset); + + for (var i = 0; i < length; i++) { + tagOffset = offset + 12 * i + 2; + + if (this.SHORT(tagOffset) == tag) { + valueOffset = tagOffset + 8; + break; + } + } + + if (!valueOffset) { + return false; + } + + try { + this.write(valueOffset, value, 4); + } catch(ex) { + return false; + } + + return true; + } + } + + ExifParser.prototype = BinaryReader.prototype; + + return ExifParser; +}); + +// Included from: src/javascript/runtime/html5/image/JPEG.js + +/** + * JPEG.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/JPEG +@private +*/ +define("moxie/runtime/html5/image/JPEG", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/runtime/html5/image/JPEGHeaders", + "moxie/runtime/html5/utils/BinaryReader", + "moxie/runtime/html5/image/ExifParser" +], function(Basic, x, JPEGHeaders, BinaryReader, ExifParser) { + + function JPEG(data) { + var _br, _hm, _ep, _info; + + _br = new BinaryReader(data); + + // check if it is jpeg + if (_br.SHORT(0) !== 0xFFD8) { + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + + // backup headers + _hm = new JPEGHeaders(data); + + // extract exif info + try { + _ep = new ExifParser(_hm.get('app1')[0]); + } catch(ex) {} + + // get dimensions + _info = _getDimensions.call(this); + + Basic.extend(this, { + type: 'image/jpeg', + + size: _br.length(), + + width: _info && _info.width || 0, + + height: _info && _info.height || 0, + + setExif: function(tag, value) { + if (!_ep) { + return false; // or throw an exception + } + + if (Basic.typeOf(tag) === 'object') { + Basic.each(tag, function(value, tag) { + _ep.setExif(tag, value); + }); + } else { + _ep.setExif(tag, value); + } + + // update internal headers + _hm.set('app1', _ep.SEGMENT()); + }, + + writeHeaders: function() { + if (!arguments.length) { + // if no arguments passed, update headers internally + return _hm.restore(data); + } + return _hm.restore(arguments[0]); + }, + + stripHeaders: function(data) { + return _hm.strip(data); + }, + + purge: function() { + _purge.call(this); + } + }); + + if (_ep) { + this.meta = { + tiff: _ep.TIFF(), + exif: _ep.EXIF(), + gps: _ep.GPS(), + thumb: _getThumb() + }; + } + + + function _getDimensions(br) { + var idx = 0 + , marker + , length + ; + + if (!br) { + br = _br; + } + + // examine all through the end, since some images might have very large APP segments + while (idx <= br.length()) { + marker = br.SHORT(idx += 2); + + if (marker >= 0xFFC0 && marker <= 0xFFC3) { // SOFn + idx += 5; // marker (2 bytes) + length (2 bytes) + Sample precision (1 byte) + return { + height: br.SHORT(idx), + width: br.SHORT(idx += 2) + }; + } + length = br.SHORT(idx += 2); + idx += length - 2; + } + return null; + } + + + function _getThumb() { + var data = _ep.thumb() + , br + , info + ; + + if (data) { + br = new BinaryReader(data); + info = _getDimensions(br); + br.clear(); + + if (info) { + info.data = data; + return info; + } + } + return null; + } + + + function _purge() { + if (!_ep || !_hm || !_br) { + return; // ignore any repeating purge requests + } + _ep.clear(); + _hm.purge(); + _br.clear(); + _info = _hm = _ep = _br = null; + } + } + + return JPEG; +}); + +// Included from: src/javascript/runtime/html5/image/PNG.js + +/** + * PNG.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/PNG +@private +*/ +define("moxie/runtime/html5/image/PNG", [ + "moxie/core/Exceptions", + "moxie/core/utils/Basic", + "moxie/runtime/html5/utils/BinaryReader" +], function(x, Basic, BinaryReader) { + + function PNG(data) { + var _br, _hm, _ep, _info; + + _br = new BinaryReader(data); + + // check if it's png + (function() { + var idx = 0, i = 0 + , signature = [0x8950, 0x4E47, 0x0D0A, 0x1A0A] + ; + + for (i = 0; i < signature.length; i++, idx += 2) { + if (signature[i] != _br.SHORT(idx)) { + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + } + }()); + + function _getDimensions() { + var chunk, idx; + + chunk = _getChunkAt.call(this, 8); + + if (chunk.type == 'IHDR') { + idx = chunk.start; + return { + width: _br.LONG(idx), + height: _br.LONG(idx += 4) + }; + } + return null; + } + + function _purge() { + if (!_br) { + return; // ignore any repeating purge requests + } + _br.clear(); + data = _info = _hm = _ep = _br = null; + } + + _info = _getDimensions.call(this); + + Basic.extend(this, { + type: 'image/png', + + size: _br.length(), + + width: _info.width, + + height: _info.height, + + purge: function() { + _purge.call(this); + } + }); + + // for PNG we can safely trigger purge automatically, as we do not keep any data for later + _purge.call(this); + + function _getChunkAt(idx) { + var length, type, start, CRC; + + length = _br.LONG(idx); + type = _br.STRING(idx += 4, 4); + start = idx += 4; + CRC = _br.LONG(idx + length); + + return { + length: length, + type: type, + start: start, + CRC: CRC + }; + } + } + + return PNG; +}); + +// Included from: src/javascript/runtime/html5/image/ImageInfo.js + +/** + * ImageInfo.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/ImageInfo +@private +*/ +define("moxie/runtime/html5/image/ImageInfo", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/runtime/html5/image/JPEG", + "moxie/runtime/html5/image/PNG" +], function(Basic, x, JPEG, PNG) { + /** + Optional image investigation tool for HTML5 runtime. Provides the following features: + - ability to distinguish image type (JPEG or PNG) by signature + - ability to extract image width/height directly from it's internals, without preloading in memory (fast) + - ability to extract APP headers from JPEGs (Exif, GPS, etc) + - ability to replace width/height tags in extracted JPEG headers + - ability to restore APP headers, that were for example stripped during image manipulation + + @class ImageInfo + @constructor + @param {String} data Image source as binary string + */ + return function(data) { + var _cs = [JPEG, PNG], _img; + + // figure out the format, throw: ImageError.WRONG_FORMAT if not supported + _img = (function() { + for (var i = 0; i < _cs.length; i++) { + try { + return new _cs[i](data); + } catch (ex) { + // console.info(ex); + } + } + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + }()); + + Basic.extend(this, { + /** + Image Mime Type extracted from it's depths + + @property type + @type {String} + @default '' + */ + type: '', + + /** + Image size in bytes + + @property size + @type {Number} + @default 0 + */ + size: 0, + + /** + Image width extracted from image source + + @property width + @type {Number} + @default 0 + */ + width: 0, + + /** + Image height extracted from image source + + @property height + @type {Number} + @default 0 + */ + height: 0, + + /** + Sets Exif tag. Currently applicable only for width and height tags. Obviously works only with JPEGs. + + @method setExif + @param {String} tag Tag to set + @param {Mixed} value Value to assign to the tag + */ + setExif: function() {}, + + /** + Restores headers to the source. + + @method writeHeaders + @param {String} data Image source as binary string + @return {String} Updated binary string + */ + writeHeaders: function(data) { + return data; + }, + + /** + Strip all headers from the source. + + @method stripHeaders + @param {String} data Image source as binary string + @return {String} Updated binary string + */ + stripHeaders: function(data) { + return data; + }, + + /** + Dispose resources. + + @method purge + */ + purge: function() { + data = null; + } + }); + + Basic.extend(this, _img); + + this.purge = function() { + _img.purge(); + _img = null; + }; + }; +}); + +// Included from: src/javascript/runtime/html5/image/ResizerCanvas.js + +/** + * ResizerCanvas.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** + * Resizes image/canvas using canvas + */ +define("moxie/runtime/html5/image/ResizerCanvas", [], function() { + + function scale(image, ratio) { + var sW = image.width; + var dW = Math.floor(sW * ratio); + var scaleCapped = false; + + if (ratio < 0.5 || ratio > 2) { + ratio = ratio < 0.5 ? 0.5 : 2; + scaleCapped = true; + } + + var tCanvas = _scale(image, ratio); + + if (scaleCapped) { + return scale(tCanvas, dW / tCanvas.width); + } else { + return tCanvas; + } + } + + + function _scale(image, ratio) { + var sW = image.width; + var sH = image.height; + var dW = Math.floor(sW * ratio); + var dH = Math.floor(sH * ratio); + + var canvas = document.createElement('canvas'); + canvas.width = dW; + canvas.height = dH; + canvas.getContext("2d").drawImage(image, 0, 0, sW, sH, 0, 0, dW, dH); + + image = null; // just in case + return canvas; + } + + return { + scale: scale + }; + +}); + +// Included from: src/javascript/runtime/html5/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/Image +@private +*/ +define("moxie/runtime/html5/image/Image", [ + "moxie/runtime/html5/Runtime", + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/core/utils/Encode", + "moxie/file/Blob", + "moxie/file/File", + "moxie/runtime/html5/image/ImageInfo", + "moxie/runtime/html5/image/ResizerCanvas", + "moxie/core/utils/Mime", + "moxie/core/utils/Env" +], function(extensions, Basic, x, Encode, Blob, File, ImageInfo, ResizerCanvas, Mime, Env) { + + function HTML5Image() { + var me = this + , _img, _imgInfo, _canvas, _binStr, _blob + , _modified = false // is set true whenever image is modified + , _preserveHeaders = true + ; + + Basic.extend(this, { + loadFromBlob: function(blob) { + var I = this.getRuntime() + , asBinary = arguments.length > 1 ? arguments[1] : true + ; + + if (!I.can('access_binary')) { + throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR); + } + + _blob = blob; + + if (blob.isDetached()) { + _binStr = blob.getSource(); + _preload.call(this, _binStr); + return; + } else { + _readAsDataUrl.call(this, blob.getSource(), function(dataUrl) { + if (asBinary) { + _binStr = _toBinary(dataUrl); + } + _preload.call(this, dataUrl); + }); + } + }, + + loadFromImage: function(img, exact) { + this.meta = img.meta; + + _blob = new File(null, { + name: img.name, + size: img.size, + type: img.type + }); + + _preload.call(this, exact ? (_binStr = img.getAsBinaryString()) : img.getAsDataURL()); + }, + + getInfo: function() { + var I = this.getRuntime(), info; + + if (!_imgInfo && _binStr && I.can('access_image_binary')) { + _imgInfo = new ImageInfo(_binStr); + } + + // this stuff below is definitely having fun with itself + info = { + width: _getImg().width || 0, + height: _getImg().height || 0, + type: _blob.type || Mime.getFileMime(_blob.name), + size: _binStr && _binStr.length || _blob.size || 0, + name: _blob.name || '', + meta: null + }; + + if (_preserveHeaders) { + info.meta = _imgInfo && _imgInfo.meta || this.meta || {}; + + // if data was taken from ImageInfo it will be a binary string, so we convert it to blob + if (info.meta && info.meta.thumb && !(info.meta.thumb.data instanceof Blob)) { + info.meta.thumb.data = new Blob(null, { + type: 'image/jpeg', + data: info.meta.thumb.data + }); + } + } + + return info; + }, + + + resize: function(rect, ratio, options) { + var canvas = document.createElement('canvas'); + canvas.width = rect.width; + canvas.height = rect.height; + + canvas.getContext("2d").drawImage(_getImg(), rect.x, rect.y, rect.width, rect.height, 0, 0, canvas.width, canvas.height); + + _canvas = ResizerCanvas.scale(canvas, ratio); + + _preserveHeaders = options.preserveHeaders; + + // rotate if required, according to orientation tag + if (!_preserveHeaders) { + var orientation = (this.meta && this.meta.tiff && this.meta.tiff.Orientation) || 1; + _canvas = _rotateToOrientaion(_canvas, orientation); + } + + this.width = _canvas.width; + this.height = _canvas.height; + + _modified = true; + + this.trigger('Resize'); + }, + + getAsCanvas: function() { + if (!_canvas) { + _canvas = _getCanvas(); + } + _canvas.id = this.uid + '_canvas'; + return _canvas; + }, + + getAsBlob: function(type, quality) { + if (type !== this.type) { + _modified = true; // reconsider the state + return new File(null, { + name: _blob.name || '', + type: type, + data: me.getAsDataURL(type, quality) + }); + } + return new File(null, { + name: _blob.name || '', + type: type, + data: me.getAsBinaryString(type, quality) + }); + }, + + getAsDataURL: function(type) { + var quality = arguments[1] || 90; + + // if image has not been modified, return the source right away + if (!_modified) { + return _img.src; + } + + // make sure we have a canvas to work with + _getCanvas(); + + if ('image/jpeg' !== type) { + return _canvas.toDataURL('image/png'); + } else { + try { + // older Geckos used to result in an exception on quality argument + return _canvas.toDataURL('image/jpeg', quality/100); + } catch (ex) { + return _canvas.toDataURL('image/jpeg'); + } + } + }, + + getAsBinaryString: function(type, quality) { + // if image has not been modified, return the source right away + if (!_modified) { + // if image was not loaded from binary string + if (!_binStr) { + _binStr = _toBinary(me.getAsDataURL(type, quality)); + } + return _binStr; + } + + if ('image/jpeg' !== type) { + _binStr = _toBinary(me.getAsDataURL(type, quality)); + } else { + var dataUrl; + + // if jpeg + if (!quality) { + quality = 90; + } + + // make sure we have a canvas to work with + _getCanvas(); + + try { + // older Geckos used to result in an exception on quality argument + dataUrl = _canvas.toDataURL('image/jpeg', quality/100); + } catch (ex) { + dataUrl = _canvas.toDataURL('image/jpeg'); + } + + _binStr = _toBinary(dataUrl); + + if (_imgInfo) { + _binStr = _imgInfo.stripHeaders(_binStr); + + if (_preserveHeaders) { + // update dimensions info in exif + if (_imgInfo.meta && _imgInfo.meta.exif) { + _imgInfo.setExif({ + PixelXDimension: this.width, + PixelYDimension: this.height + }); + } + + // re-inject the headers + _binStr = _imgInfo.writeHeaders(_binStr); + } + + // will be re-created from fresh on next getInfo call + _imgInfo.purge(); + _imgInfo = null; + } + } + + _modified = false; + + return _binStr; + }, + + destroy: function() { + me = null; + _purge.call(this); + this.getRuntime().getShim().removeInstance(this.uid); + } + }); + + + function _getImg() { + if (!_canvas && !_img) { + throw new x.ImageError(x.DOMException.INVALID_STATE_ERR); + } + return _canvas || _img; + } + + + function _getCanvas() { + var canvas = _getImg(); + if (canvas.nodeName.toLowerCase() == 'canvas') { + return canvas; + } + _canvas = document.createElement('canvas'); + _canvas.width = canvas.width; + _canvas.height = canvas.height; + _canvas.getContext("2d").drawImage(canvas, 0, 0); + return _canvas; + } + + + function _toBinary(str) { + return Encode.atob(str.substring(str.indexOf('base64,') + 7)); + } + + + function _toDataUrl(str, type) { + return 'data:' + (type || '') + ';base64,' + Encode.btoa(str); + } + + + function _preload(str) { + var comp = this; + + _img = new Image(); + _img.onerror = function() { + _purge.call(this); + comp.trigger('error', x.ImageError.WRONG_FORMAT); + }; + _img.onload = function() { + comp.trigger('load'); + }; + + _img.src = str.substr(0, 5) == 'data:' ? str : _toDataUrl(str, _blob.type); + } + + + function _readAsDataUrl(file, callback) { + var comp = this, fr; + + // use FileReader if it's available + if (window.FileReader) { + fr = new FileReader(); + fr.onload = function() { + callback.call(comp, this.result); + }; + fr.onerror = function() { + comp.trigger('error', x.ImageError.WRONG_FORMAT); + }; + fr.readAsDataURL(file); + } else { + return callback.call(this, file.getAsDataURL()); + } + } + + /** + * Transform canvas coordination according to specified frame size and orientation + * Orientation value is from EXIF tag + * @author Shinichi Tomita + */ + function _rotateToOrientaion(img, orientation) { + var RADIANS = Math.PI/180; + var canvas = document.createElement('canvas'); + var ctx = canvas.getContext('2d'); + var width = img.width; + var height = img.height; + + if (Basic.inArray(orientation, [5,6,7,8]) > -1) { + canvas.width = height; + canvas.height = width; + } else { + canvas.width = width; + canvas.height = height; + } + + /** + 1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side. + 2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side. + 3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side. + 4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side. + 5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top. + 6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top. + 7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom. + 8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom. + */ + switch (orientation) { + case 2: + // horizontal flip + ctx.translate(width, 0); + ctx.scale(-1, 1); + break; + case 3: + // 180 rotate left + ctx.translate(width, height); + ctx.rotate(180 * RADIANS); + break; + case 4: + // vertical flip + ctx.translate(0, height); + ctx.scale(1, -1); + break; + case 5: + // vertical flip + 90 rotate right + ctx.rotate(90 * RADIANS); + ctx.scale(1, -1); + break; + case 6: + // 90 rotate right + ctx.rotate(90 * RADIANS); + ctx.translate(0, -height); + break; + case 7: + // horizontal flip + 90 rotate right + ctx.rotate(90 * RADIANS); + ctx.translate(width, -height); + ctx.scale(-1, 1); + break; + case 8: + // 90 rotate left + ctx.rotate(-90 * RADIANS); + ctx.translate(-width, 0); + break; + } + + ctx.drawImage(img, 0, 0, width, height); + return canvas; + } + + + function _purge() { + if (_imgInfo) { + _imgInfo.purge(); + _imgInfo = null; + } + + _binStr = _img = _canvas = _blob = null; + _modified = false; + } + } + + return (extensions.Image = HTML5Image); +}); + +// Included from: src/javascript/runtime/flash/Runtime.js + +/** + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global ActiveXObject:true */ + +/** +Defines constructor for Flash runtime. + +@class moxie/runtime/flash/Runtime +@private +*/ +define("moxie/runtime/flash/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Env", + "moxie/core/utils/Dom", + "moxie/core/Exceptions", + "moxie/runtime/Runtime" +], function(Basic, Env, Dom, x, Runtime) { + + var type = 'flash', extensions = {}; + + /** + Get the version of the Flash Player + + @method getShimVersion + @private + @return {Number} Flash Player version + */ + function getShimVersion() { + var version; + + try { + version = navigator.plugins['Shockwave Flash']; + version = version.description; + } catch (e1) { + try { + version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + } catch (e2) { + version = '0.0'; + } + } + version = version.match(/\d+/g); + return parseFloat(version[0] + '.' + version[1]); + } + + + /** + Cross-browser SWF removal + - Especially needed to safely and completely remove a SWF in Internet Explorer + + Originated from SWFObject v2.2 + */ + function removeSWF(id) { + var obj = Dom.get(id); + if (obj && obj.nodeName == "OBJECT") { + if (Env.browser === 'IE') { + obj.style.display = "none"; + (function onInit(){ + // http://msdn.microsoft.com/en-us/library/ie/ms534360(v=vs.85).aspx + if (obj.readyState == 4) { + removeObjectInIE(id); + } + else { + setTimeout(onInit, 10); + } + })(); + } + else { + obj.parentNode.removeChild(obj); + } + } + } + + + function removeObjectInIE(id) { + var obj = Dom.get(id); + if (obj) { + for (var i in obj) { + if (typeof obj[i] == "function") { + obj[i] = null; + } + } + obj.parentNode.removeChild(obj); + } + } + + /** + Constructor for the Flash Runtime + + @class FlashRuntime + @extends Runtime + */ + function FlashRuntime(options) { + var I = this, initTimer; + + options = Basic.extend({ swf_url: Env.swf_url }, options); + + Runtime.call(this, options, type, { + access_binary: function(value) { + return value && I.mode === 'browser'; + }, + access_image_binary: function(value) { + return value && I.mode === 'browser'; + }, + display_media: Runtime.capTest(defined('moxie/image/Image')), + do_cors: Runtime.capTrue, + drag_and_drop: false, + report_upload_progress: function() { + return I.mode === 'client'; + }, + resize_image: Runtime.capTrue, + return_response_headers: false, + return_response_type: function(responseType) { + if (responseType === 'json' && !!window.JSON) { + return true; + } + return !Basic.arrayDiff(responseType, ['', 'text', 'document']) || I.mode === 'browser'; + }, + return_status_code: function(code) { + return I.mode === 'browser' || !Basic.arrayDiff(code, [200, 404]); + }, + select_file: Runtime.capTrue, + select_multiple: Runtime.capTrue, + send_binary_string: function(value) { + return value && I.mode === 'browser'; + }, + send_browser_cookies: function(value) { + return value && I.mode === 'browser'; + }, + send_custom_headers: function(value) { + return value && I.mode === 'browser'; + }, + send_multipart: Runtime.capTrue, + slice_blob: function(value) { + return value && I.mode === 'browser'; + }, + stream_upload: function(value) { + return value && I.mode === 'browser'; + }, + summon_file_dialog: false, + upload_filesize: function(size) { + return Basic.parseSizeStr(size) <= 2097152 || I.mode === 'client'; + }, + use_http_method: function(methods) { + return !Basic.arrayDiff(methods, ['GET', 'POST']); + } + }, { + // capabilities that require specific mode + access_binary: function(value) { + return value ? 'browser' : 'client'; + }, + access_image_binary: function(value) { + return value ? 'browser' : 'client'; + }, + report_upload_progress: function(value) { + return value ? 'browser' : 'client'; + }, + return_response_type: function(responseType) { + return Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) ? 'browser' : ['client', 'browser']; + }, + return_status_code: function(code) { + return Basic.arrayDiff(code, [200, 404]) ? 'browser' : ['client', 'browser']; + }, + send_binary_string: function(value) { + return value ? 'browser' : 'client'; + }, + send_browser_cookies: function(value) { + return value ? 'browser' : 'client'; + }, + send_custom_headers: function(value) { + return value ? 'browser' : 'client'; + }, + slice_blob: function(value) { + return value ? 'browser' : 'client'; + }, + stream_upload: function(value) { + return value ? 'client' : 'browser'; + }, + upload_filesize: function(size) { + return Basic.parseSizeStr(size) >= 2097152 ? 'client' : 'browser'; + } + }, 'client'); + + + // minimal requirement for Flash Player version + if (getShimVersion() < 11.3) { + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\tFlash didn't meet minimal version requirement (11.3)."); + } + + this.mode = false; // with falsy mode, runtime won't operable, no matter what the mode was before + } + + + Basic.extend(this, { + + getShim: function() { + return Dom.get(this.uid); + }, + + shimExec: function(component, action) { + var args = [].slice.call(arguments, 2); + return I.getShim().exec(this.uid, component, action, args); + }, + + init: function() { + var html, el, container; + + container = this.getShimContainer(); + + // if not the minimal height, shims are not initialized in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc) + Basic.extend(container.style, { + position: 'absolute', + top: '-8px', + left: '-8px', + width: '9px', + height: '9px', + overflow: 'hidden' + }); + + // insert flash object + html = '' + + '' + + '' + + '' + + ''; + + if (Env.browser === 'IE') { + el = document.createElement('div'); + container.appendChild(el); + el.outerHTML = html; + el = container = null; // just in case + } else { + container.innerHTML = html; + } + + // Init is dispatched by the shim + initTimer = setTimeout(function() { + if (I && !I.initialized) { // runtime might be already destroyed by this moment + I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR)); + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\tFlash failed to initialize within a specified period of time (typically 5s)."); + } + } + }, 5000); + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + removeSWF(I.uid); // SWF removal requires special care in IE + + destroy.call(I); + clearTimeout(initTimer); // initialization check might be still onwait + options = initTimer = destroy = I = null; + }; + }(this.destroy)) + + }, extensions); + } + + Runtime.addConstructor(type, FlashRuntime); + + return extensions; +}); + +// Included from: src/javascript/runtime/flash/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/Blob +@private +*/ +define("moxie/runtime/flash/file/Blob", [ + "moxie/runtime/flash/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + var FlashBlob = { + slice: function(blob, start, end, type) { + var self = this.getRuntime(); + + if (start < 0) { + start = Math.max(blob.size + start, 0); + } else if (start > 0) { + start = Math.min(start, blob.size); + } + + if (end < 0) { + end = Math.max(blob.size + end, 0); + } else if (end > 0) { + end = Math.min(end, blob.size); + } + + blob = self.shimExec.call(this, 'Blob', 'slice', start, end, type || ''); + + if (blob) { + blob = new Blob(self.uid, blob); + } + return blob; + } + }; + + return (extensions.Blob = FlashBlob); +}); + +// Included from: src/javascript/runtime/flash/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileInput +@private +*/ +define("moxie/runtime/flash/file/FileInput", [ + "moxie/runtime/flash/Runtime", + "moxie/file/File", + "moxie/core/utils/Basic" +], function(extensions, File, Basic) { + + var FileInput = { + init: function(options) { + var comp = this, I = this.getRuntime(); + + this.bind("Change", function() { + var files = I.shimExec.call(comp, 'FileInput', 'getFiles'); + comp.files = []; + Basic.each(files, function(file) { + comp.files.push(new File(I.uid, file)); + }); + }, 999); + + this.getRuntime().shimExec.call(this, 'FileInput', 'init', { + accept: options.accept, + multiple: options.multiple + }); + + this.trigger('ready'); + } + }; + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/flash/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileReader +@private +*/ +define("moxie/runtime/flash/file/FileReader", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Encode" +], function(extensions, Encode) { + + function _formatData(data, op) { + switch (op) { + case 'readAsText': + return Encode.atob(data, 'utf8'); + case 'readAsBinaryString': + return Encode.atob(data); + case 'readAsDataURL': + return data; + } + return null; + } + + var FileReader = { + read: function(op, blob) { + var comp = this; + + comp.result = ''; + + // special prefix for DataURL read mode + if (op === 'readAsDataURL') { + comp.result = 'data:' + (blob.type || '') + ';base64,'; + } + + comp.bind('Progress', function(e, data) { + if (data) { + comp.result += _formatData(data, op); + } + }, 999); + + return comp.getRuntime().shimExec.call(this, 'FileReader', 'readAsBase64', blob.uid); + } + }; + + return (extensions.FileReader = FileReader); +}); + +// Included from: src/javascript/runtime/flash/file/FileReaderSync.js + +/** + * FileReaderSync.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileReaderSync +@private +*/ +define("moxie/runtime/flash/file/FileReaderSync", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Encode" +], function(extensions, Encode) { + + function _formatData(data, op) { + switch (op) { + case 'readAsText': + return Encode.atob(data, 'utf8'); + case 'readAsBinaryString': + return Encode.atob(data); + case 'readAsDataURL': + return data; + } + return null; + } + + var FileReaderSync = { + read: function(op, blob) { + var result, self = this.getRuntime(); + + result = self.shimExec.call(this, 'FileReaderSync', 'readAsBase64', blob.uid); + if (!result) { + return null; // or throw ex + } + + // special prefix for DataURL read mode + if (op === 'readAsDataURL') { + result = 'data:' + (blob.type || '') + ';base64,' + result; + } + + return _formatData(result, op, blob.type); + } + }; + + return (extensions.FileReaderSync = FileReaderSync); +}); + +// Included from: src/javascript/runtime/flash/runtime/Transporter.js + +/** + * Transporter.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/runtime/Transporter +@private +*/ +define("moxie/runtime/flash/runtime/Transporter", [ + "moxie/runtime/flash/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + var Transporter = { + getAsBlob: function(type) { + var self = this.getRuntime() + , blob = self.shimExec.call(this, 'Transporter', 'getAsBlob', type) + ; + if (blob) { + return new Blob(self.uid, blob); + } + return null; + } + }; + + return (extensions.Transporter = Transporter); +}); + +// Included from: src/javascript/runtime/flash/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/flash/xhr/XMLHttpRequest", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Basic", + "moxie/file/Blob", + "moxie/file/File", + "moxie/file/FileReaderSync", + "moxie/runtime/flash/file/FileReaderSync", + "moxie/xhr/FormData", + "moxie/runtime/Transporter", + "moxie/runtime/flash/runtime/Transporter" +], function(extensions, Basic, Blob, File, FileReaderSync, FileReaderSyncFlash, FormData, Transporter, TransporterFlash) { + + var XMLHttpRequest = { + + send: function(meta, data) { + var target = this, self = target.getRuntime(); + + function send() { + meta.transport = self.mode; + self.shimExec.call(target, 'XMLHttpRequest', 'send', meta, data); + } + + + function appendBlob(name, blob) { + self.shimExec.call(target, 'XMLHttpRequest', 'appendBlob', name, blob.uid); + data = null; + send(); + } + + + function attachBlob(blob, cb) { + var tr = new Transporter(); + + tr.bind("TransportingComplete", function() { + cb(this.result); + }); + + tr.transport(blob.getSource(), blob.type, { + ruid: self.uid + }); + } + + // copy over the headers if any + if (!Basic.isEmptyObj(meta.headers)) { + Basic.each(meta.headers, function(value, header) { + self.shimExec.call(target, 'XMLHttpRequest', 'setRequestHeader', header, value.toString()); // Silverlight doesn't accept integers into the arguments of type object + }); + } + + // transfer over multipart params and blob itself + if (data instanceof FormData) { + var blobField; + data.each(function(value, name) { + if (value instanceof Blob) { + blobField = name; + } else { + self.shimExec.call(target, 'XMLHttpRequest', 'append', name, value); + } + }); + + if (!data.hasBlob()) { + data = null; + send(); + } else { + var blob = data.getBlob(); + if (blob.isDetached()) { + attachBlob(blob, function(attachedBlob) { + blob.destroy(); + appendBlob(blobField, attachedBlob); + }); + } else { + appendBlob(blobField, blob); + } + } + } else if (data instanceof Blob) { + if (data.isDetached()) { + attachBlob(data, function(attachedBlob) { + data.destroy(); + data = attachedBlob.uid; + send(); + }); + } else { + data = data.uid; + send(); + } + } else { + send(); + } + }, + + getResponse: function(responseType) { + var frs, blob, self = this.getRuntime(); + + blob = self.shimExec.call(this, 'XMLHttpRequest', 'getResponseAsBlob'); + + if (blob) { + blob = new File(self.uid, blob); + + if ('blob' === responseType) { + return blob; + } + + try { + frs = new FileReaderSync(); + + if (!!~Basic.inArray(responseType, ["", "text"])) { + return frs.readAsText(blob); + } else if ('json' === responseType && !!window.JSON) { + return JSON.parse(frs.readAsText(blob)); + } + } finally { + blob.destroy(); + } + } + return null; + }, + + abort: function(upload_complete_flag) { + var self = this.getRuntime(); + + self.shimExec.call(this, 'XMLHttpRequest', 'abort'); + + this.dispatchEvent('readystatechange'); + // this.dispatchEvent('progress'); + this.dispatchEvent('abort'); + + //if (!upload_complete_flag) { + // this.dispatchEvent('uploadprogress'); + //} + } + }; + + return (extensions.XMLHttpRequest = XMLHttpRequest); +}); + +// Included from: src/javascript/runtime/flash/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/image/Image +@private +*/ +define("moxie/runtime/flash/image/Image", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/Transporter", + "moxie/file/Blob", + "moxie/file/FileReaderSync" +], function(extensions, Basic, Transporter, Blob, FileReaderSync) { + + var Image = { + loadFromBlob: function(blob) { + var comp = this, self = comp.getRuntime(); + + function exec(srcBlob) { + self.shimExec.call(comp, 'Image', 'loadFromBlob', srcBlob.uid); + comp = self = null; + } + + if (blob.isDetached()) { // binary string + var tr = new Transporter(); + tr.bind("TransportingComplete", function() { + exec(tr.result.getSource()); + }); + tr.transport(blob.getSource(), blob.type, { ruid: self.uid }); + } else { + exec(blob.getSource()); + } + }, + + loadFromImage: function(img) { + var self = this.getRuntime(); + return self.shimExec.call(this, 'Image', 'loadFromImage', img.uid); + }, + + getInfo: function() { + var self = this.getRuntime() + , info = self.shimExec.call(this, 'Image', 'getInfo') + ; + + if (info.meta && info.meta.thumb && info.meta.thumb.data && !(self.meta.thumb.data instanceof Blob)) { + info.meta.thumb.data = new Blob(self.uid, info.meta.thumb.data); + } + return info; + }, + + getAsBlob: function(type, quality) { + var self = this.getRuntime() + , blob = self.shimExec.call(this, 'Image', 'getAsBlob', type, quality) + ; + if (blob) { + return new Blob(self.uid, blob); + } + return null; + }, + + getAsDataURL: function() { + var self = this.getRuntime() + , blob = self.Image.getAsBlob.apply(this, arguments) + , frs + ; + if (!blob) { + return null; + } + frs = new FileReaderSync(); + return frs.readAsDataURL(blob); + } + }; + + return (extensions.Image = Image); +}); + +// Included from: src/javascript/runtime/silverlight/Runtime.js + +/** + * RunTime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global ActiveXObject:true */ + +/** +Defines constructor for Silverlight runtime. + +@class moxie/runtime/silverlight/Runtime +@private +*/ +define("moxie/runtime/silverlight/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Env", + "moxie/core/utils/Dom", + "moxie/core/Exceptions", + "moxie/runtime/Runtime" +], function(Basic, Env, Dom, x, Runtime) { + + var type = "silverlight", extensions = {}; + + function isInstalled(version) { + var isVersionSupported = false, control = null, actualVer, + actualVerArray, reqVerArray, requiredVersionPart, actualVersionPart, index = 0; + + try { + try { + control = new ActiveXObject('AgControl.AgControl'); + + if (control.IsVersionSupported(version)) { + isVersionSupported = true; + } + + control = null; + } catch (e) { + var plugin = navigator.plugins["Silverlight Plug-In"]; + + if (plugin) { + actualVer = plugin.description; + + if (actualVer === "1.0.30226.2") { + actualVer = "2.0.30226.2"; + } + + actualVerArray = actualVer.split("."); + + while (actualVerArray.length > 3) { + actualVerArray.pop(); + } + + while ( actualVerArray.length < 4) { + actualVerArray.push(0); + } + + reqVerArray = version.split("."); + + while (reqVerArray.length > 4) { + reqVerArray.pop(); + } + + do { + requiredVersionPart = parseInt(reqVerArray[index], 10); + actualVersionPart = parseInt(actualVerArray[index], 10); + index++; + } while (index < reqVerArray.length && requiredVersionPart === actualVersionPart); + + if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) { + isVersionSupported = true; + } + } + } + } catch (e2) { + isVersionSupported = false; + } + + return isVersionSupported; + } + + /** + Constructor for the Silverlight Runtime + + @class SilverlightRuntime + @extends Runtime + */ + function SilverlightRuntime(options) { + var I = this, initTimer; + + options = Basic.extend({ xap_url: Env.xap_url }, options); + + Runtime.call(this, options, type, { + access_binary: Runtime.capTrue, + access_image_binary: Runtime.capTrue, + display_media: Runtime.capTest(defined('moxie/image/Image')), + do_cors: Runtime.capTrue, + drag_and_drop: false, + report_upload_progress: Runtime.capTrue, + resize_image: Runtime.capTrue, + return_response_headers: function(value) { + return value && I.mode === 'client'; + }, + return_response_type: function(responseType) { + if (responseType !== 'json') { + return true; + } else { + return !!window.JSON; + } + }, + return_status_code: function(code) { + return I.mode === 'client' || !Basic.arrayDiff(code, [200, 404]); + }, + select_file: Runtime.capTrue, + select_multiple: Runtime.capTrue, + send_binary_string: Runtime.capTrue, + send_browser_cookies: function(value) { + return value && I.mode === 'browser'; + }, + send_custom_headers: function(value) { + return value && I.mode === 'client'; + }, + send_multipart: Runtime.capTrue, + slice_blob: Runtime.capTrue, + stream_upload: true, + summon_file_dialog: false, + upload_filesize: Runtime.capTrue, + use_http_method: function(methods) { + return I.mode === 'client' || !Basic.arrayDiff(methods, ['GET', 'POST']); + } + }, { + // capabilities that require specific mode + return_response_headers: function(value) { + return value ? 'client' : 'browser'; + }, + return_status_code: function(code) { + return Basic.arrayDiff(code, [200, 404]) ? 'client' : ['client', 'browser']; + }, + send_browser_cookies: function(value) { + return value ? 'browser' : 'client'; + }, + send_custom_headers: function(value) { + return value ? 'client' : 'browser'; + }, + use_http_method: function(methods) { + return Basic.arrayDiff(methods, ['GET', 'POST']) ? 'client' : ['client', 'browser']; + } + }); + + + // minimal requirement + if (!isInstalled('2.0.31005.0') || Env.browser === 'Opera') { + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\tSilverlight is not installed or minimal version (2.0.31005.0) requirement not met (not likely)."); + } + + this.mode = false; + } + + + Basic.extend(this, { + getShim: function() { + return Dom.get(this.uid).content.Moxie; + }, + + shimExec: function(component, action) { + var args = [].slice.call(arguments, 2); + return I.getShim().exec(this.uid, component, action, args); + }, + + init : function() { + var container; + + container = this.getShimContainer(); + + container.innerHTML = '' + + '' + + '' + + '' + + '' + + '' + + ''; + + // Init is dispatched by the shim + initTimer = setTimeout(function() { + if (I && !I.initialized) { // runtime might be already destroyed by this moment + I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR)); + + if (MXI_DEBUG && Env.debug.runtime) { + Env.log("\Silverlight failed to initialize within a specified period of time (5-10s)."); + } + } + }, Env.OS !== 'Windows'? 10000 : 5000); // give it more time to initialize in non Windows OS (like Mac) + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + destroy.call(I); + clearTimeout(initTimer); // initialization check might be still onwait + options = initTimer = destroy = I = null; + }; + }(this.destroy)) + + }, extensions); + } + + Runtime.addConstructor(type, SilverlightRuntime); + + return extensions; +}); + +// Included from: src/javascript/runtime/silverlight/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/Blob +@private +*/ +define("moxie/runtime/silverlight/file/Blob", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/Blob" +], function(extensions, Basic, Blob) { + return (extensions.Blob = Basic.extend({}, Blob)); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileInput +@private +*/ +define("moxie/runtime/silverlight/file/FileInput", [ + "moxie/runtime/silverlight/Runtime", + "moxie/file/File", + "moxie/core/utils/Basic" +], function(extensions, File, Basic) { + + function toFilters(accept) { + var filter = ''; + for (var i = 0; i < accept.length; i++) { + filter += (filter !== '' ? '|' : '') + accept[i].title + " | *." + accept[i].extensions.replace(/,/g, ';*.'); + } + return filter; + } + + + var FileInput = { + init: function(options) { + var comp = this, I = this.getRuntime(); + + this.bind("Change", function() { + var files = I.shimExec.call(comp, 'FileInput', 'getFiles'); + comp.files = []; + Basic.each(files, function(file) { + comp.files.push(new File(I.uid, file)); + }); + }, 999); + + I.shimExec.call(this, 'FileInput', 'init', toFilters(options.accept), options.multiple); + this.trigger('ready'); + }, + + setOption: function(name, value) { + if (name == 'accept') { + value = toFilters(value); + } + this.getRuntime().shimExec.call(this, 'FileInput', 'setOption', name, value); + } + }; + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileDrop.js + +/** + * FileDrop.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileDrop +@private +*/ +define("moxie/runtime/silverlight/file/FileDrop", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Dom", + "moxie/core/utils/Events" +], function(extensions, Dom, Events) { + + // not exactly useful, since works only in safari (...crickets...) + var FileDrop = { + init: function() { + var comp = this, self = comp.getRuntime(), dropZone; + + dropZone = self.getShimContainer(); + + Events.addEvent(dropZone, 'dragover', function(e) { + e.preventDefault(); + e.stopPropagation(); + e.dataTransfer.dropEffect = 'copy'; + }, comp.uid); + + Events.addEvent(dropZone, 'dragenter', function(e) { + e.preventDefault(); + var flag = Dom.get(self.uid).dragEnter(e); + // If handled, then stop propagation of event in DOM + if (flag) { + e.stopPropagation(); + } + }, comp.uid); + + Events.addEvent(dropZone, 'drop', function(e) { + e.preventDefault(); + var flag = Dom.get(self.uid).dragDrop(e); + // If handled, then stop propagation of event in DOM + if (flag) { + e.stopPropagation(); + } + }, comp.uid); + + return self.shimExec.call(this, 'FileDrop', 'init'); + } + }; + + return (extensions.FileDrop = FileDrop); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileReader +@private +*/ +define("moxie/runtime/silverlight/file/FileReader", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/FileReader" +], function(extensions, Basic, FileReader) { + return (extensions.FileReader = Basic.extend({}, FileReader)); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileReaderSync.js + +/** + * FileReaderSync.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileReaderSync +@private +*/ +define("moxie/runtime/silverlight/file/FileReaderSync", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/FileReaderSync" +], function(extensions, Basic, FileReaderSync) { + return (extensions.FileReaderSync = Basic.extend({}, FileReaderSync)); +}); + +// Included from: src/javascript/runtime/silverlight/runtime/Transporter.js + +/** + * Transporter.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/runtime/Transporter +@private +*/ +define("moxie/runtime/silverlight/runtime/Transporter", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/runtime/Transporter" +], function(extensions, Basic, Transporter) { + return (extensions.Transporter = Basic.extend({}, Transporter)); +}); + +// Included from: src/javascript/runtime/silverlight/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/silverlight/xhr/XMLHttpRequest", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/xhr/XMLHttpRequest", + "moxie/runtime/silverlight/file/FileReaderSync", + "moxie/runtime/silverlight/runtime/Transporter" +], function(extensions, Basic, XMLHttpRequest, FileReaderSyncSilverlight, TransporterSilverlight) { + return (extensions.XMLHttpRequest = Basic.extend({}, XMLHttpRequest)); +}); + +// Included from: src/javascript/runtime/silverlight/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/image/Image +@private +*/ +define("moxie/runtime/silverlight/image/Image", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/file/Blob", + "moxie/runtime/flash/image/Image" +], function(extensions, Basic, Blob, Image) { + return (extensions.Image = Basic.extend({}, Image, { + + getInfo: function() { + var self = this.getRuntime() + , grps = ['tiff', 'exif', 'gps', 'thumb'] + , info = { meta: {} } + , rawInfo = self.shimExec.call(this, 'Image', 'getInfo') + ; + + if (rawInfo.meta) { + Basic.each(grps, function(grp) { + var meta = rawInfo.meta[grp] + , tag + , i + , length + , value + ; + if (meta && meta.keys) { + info.meta[grp] = {}; + for (i = 0, length = meta.keys.length; i < length; i++) { + tag = meta.keys[i]; + value = meta[tag]; + if (value) { + // convert numbers + if (/^(\d|[1-9]\d+)$/.test(value)) { // integer (make sure doesn't start with zero) + value = parseInt(value, 10); + } else if (/^\d*\.\d+$/.test(value)) { // double + value = parseFloat(value); + } + info.meta[grp][tag] = value; + } + } + } + }); + + // save thumb data as blob + if (info.meta && info.meta.thumb && info.meta.thumb.data && !(self.meta.thumb.data instanceof Blob)) { + info.meta.thumb.data = new Blob(self.uid, info.meta.thumb.data); + } + } + + info.width = parseInt(rawInfo.width, 10); + info.height = parseInt(rawInfo.height, 10); + info.size = parseInt(rawInfo.size, 10); + info.type = rawInfo.type; + info.name = rawInfo.name; + + return info; + }, + + resize: function(rect, ratio, opts) { + this.getRuntime().shimExec.call(this, 'Image', 'resize', rect.x, rect.y, rect.width, rect.height, ratio, opts.preserveHeaders, opts.resample); + } + })); +}); + +// Included from: src/javascript/runtime/html4/Runtime.js + +/** + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global File:true */ + +/** +Defines constructor for HTML4 runtime. + +@class moxie/runtime/html4/Runtime +@private +*/ +define("moxie/runtime/html4/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/runtime/Runtime", + "moxie/core/utils/Env" +], function(Basic, x, Runtime, Env) { + + var type = 'html4', extensions = {}; + + function Html4Runtime(options) { + var I = this + , Test = Runtime.capTest + , True = Runtime.capTrue + ; + + Runtime.call(this, options, type, { + access_binary: Test(window.FileReader || window.File && File.getAsDataURL), + access_image_binary: false, + display_media: Test( + (Env.can('create_canvas') || Env.can('use_data_uri_over32kb')) && + defined('moxie/image/Image') + ), + do_cors: false, + drag_and_drop: false, + filter_by_extension: Test(function() { // if you know how to feature-detect this, please suggest + return !( + (Env.browser === 'Chrome' && Env.verComp(Env.version, 28, '<')) || + (Env.browser === 'IE' && Env.verComp(Env.version, 10, '<')) || + (Env.browser === 'Safari' && Env.verComp(Env.version, 7, '<')) || + (Env.browser === 'Firefox' && Env.verComp(Env.version, 37, '<')) + ); + }()), + resize_image: function() { + return extensions.Image && I.can('access_binary') && Env.can('create_canvas'); + }, + report_upload_progress: false, + return_response_headers: false, + return_response_type: function(responseType) { + if (responseType === 'json' && !!window.JSON) { + return true; + } + return !!~Basic.inArray(responseType, ['text', 'document', '']); + }, + return_status_code: function(code) { + return !Basic.arrayDiff(code, [200, 404]); + }, + select_file: function() { + return Env.can('use_fileinput'); + }, + select_multiple: false, + send_binary_string: false, + send_custom_headers: false, + send_multipart: true, + slice_blob: false, + stream_upload: function() { + return I.can('select_file'); + }, + summon_file_dialog: function() { // yeah... some dirty sniffing here... + return I.can('select_file') && ( + (Env.browser === 'Firefox' && Env.verComp(Env.version, 4, '>=')) || + (Env.browser === 'Opera' && Env.verComp(Env.version, 12, '>=')) || + (Env.browser === 'IE' && Env.verComp(Env.version, 10, '>=')) || + !!~Basic.inArray(Env.browser, ['Chrome', 'Safari']) + ); + }, + upload_filesize: True, + use_http_method: function(methods) { + return !Basic.arrayDiff(methods, ['GET', 'POST']); + } + }); + + + Basic.extend(this, { + init : function() { + this.trigger("Init"); + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + destroy.call(I); + destroy = I = null; + }; + }(this.destroy)) + }); + + Basic.extend(this.getShim(), extensions); + } + + Runtime.addConstructor(type, Html4Runtime); + + return extensions; +}); + +// Included from: src/javascript/runtime/html4/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html4/file/FileInput +@private +*/ +define("moxie/runtime/html4/file/FileInput", [ + "moxie/runtime/html4/Runtime", + "moxie/file/File", + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/utils/Events", + "moxie/core/utils/Mime", + "moxie/core/utils/Env" +], function(extensions, File, Basic, Dom, Events, Mime, Env) { + + function FileInput() { + var _uid, _mimes = [], _options, _browseBtnZIndex; // save original z-index; + + function addInput() { + var comp = this, I = comp.getRuntime(), shimContainer, browseButton, currForm, form, input, uid; + + uid = Basic.guid('uid_'); + + shimContainer = I.getShimContainer(); // we get new ref every time to avoid memory leaks in IE + + if (_uid) { // move previous form out of the view + currForm = Dom.get(_uid + '_form'); + if (currForm) { + Basic.extend(currForm.style, { top: '100%' }); + } + } + + // build form in DOM, since innerHTML version not able to submit file for some reason + form = document.createElement('form'); + form.setAttribute('id', uid + '_form'); + form.setAttribute('method', 'post'); + form.setAttribute('enctype', 'multipart/form-data'); + form.setAttribute('encoding', 'multipart/form-data'); + + Basic.extend(form.style, { + overflow: 'hidden', + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%' + }); + + input = document.createElement('input'); + input.setAttribute('id', uid); + input.setAttribute('type', 'file'); + input.setAttribute('accept', _mimes.join(',')); + + Basic.extend(input.style, { + fontSize: '999px', + opacity: 0 + }); + + form.appendChild(input); + shimContainer.appendChild(form); + + // prepare file input to be placed underneath the browse_button element + Basic.extend(input.style, { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%' + }); + + if (Env.browser === 'IE' && Env.verComp(Env.version, 10, '<')) { + Basic.extend(input.style, { + filter : "progid:DXImageTransform.Microsoft.Alpha(opacity=0)" + }); + } + + input.onchange = function() { // there should be only one handler for this + var file; + + if (!this.value) { + return; + } + + if (this.files) { // check if browser is fresh enough + file = this.files[0]; + + // ignore empty files (IE10 for example hangs if you try to send them via XHR) + if (file.size === 0) { + form.parentNode.removeChild(form); + return; + } + } else { + file = { + name: this.value + }; + } + + file = new File(I.uid, file); + + // clear event handler + this.onchange = function() {}; + addInput.call(comp); + + comp.files = [file]; + + // substitute all ids with file uids (consider file.uid read-only - we cannot do it the other way around) + input.setAttribute('id', file.uid); + form.setAttribute('id', file.uid + '_form'); + + comp.trigger('change'); + + input = form = null; + }; + + + // route click event to the input + if (I.can('summon_file_dialog')) { + browseButton = Dom.get(_options.browse_button); + Events.removeEvent(browseButton, 'click', comp.uid); + Events.addEvent(browseButton, 'click', function(e) { + if (input && !input.disabled) { // for some reason FF (up to 8.0.1 so far) lets to click disabled input[type=file] + input.click(); + } + e.preventDefault(); + }, comp.uid); + } + + _uid = uid; + + shimContainer = currForm = browseButton = null; + } + + Basic.extend(this, { + init: function(options) { + var comp = this, I = comp.getRuntime(), shimContainer; + + // figure out accept string + _options = options; + _mimes = options.accept.mimes || Mime.extList2mimes(options.accept, I.can('filter_by_extension')); + + shimContainer = I.getShimContainer(); + + (function() { + var browseButton, zIndex, top; + + browseButton = Dom.get(options.browse_button); + _browseBtnZIndex = Dom.getStyle(browseButton, 'z-index') || 'auto'; + + // Route click event to the input[type=file] element for browsers that support such behavior + if (I.can('summon_file_dialog')) { + if (Dom.getStyle(browseButton, 'position') === 'static') { + browseButton.style.position = 'relative'; + } + + comp.bind('Refresh', function() { + zIndex = parseInt(_browseBtnZIndex, 10) || 1; + + Dom.get(_options.browse_button).style.zIndex = zIndex; + this.getRuntime().getShimContainer().style.zIndex = zIndex - 1; + }); + } + + /* Since we have to place input[type=file] on top of the browse_button for some browsers, + browse_button loses interactivity, so we restore it here */ + top = I.can('summon_file_dialog') ? browseButton : shimContainer; + + Events.addEvent(top, 'mouseover', function() { + comp.trigger('mouseenter'); + }, comp.uid); + + Events.addEvent(top, 'mouseout', function() { + comp.trigger('mouseleave'); + }, comp.uid); + + Events.addEvent(top, 'mousedown', function() { + comp.trigger('mousedown'); + }, comp.uid); + + Events.addEvent(Dom.get(options.container), 'mouseup', function() { + comp.trigger('mouseup'); + }, comp.uid); + + browseButton = null; + }()); + + addInput.call(this); + + shimContainer = null; + + // trigger ready event asynchronously + comp.trigger({ + type: 'ready', + async: true + }); + }, + + setOption: function(name, value) { + var I = this.getRuntime(); + var input; + + if (name == 'accept') { + _mimes = value.mimes || Mime.extList2mimes(value, I.can('filter_by_extension')); + } + + // update current input + input = Dom.get(_uid) + if (input) { + input.setAttribute('accept', _mimes.join(',')); + } + }, + + + disable: function(state) { + var input; + + if ((input = Dom.get(_uid))) { + input.disabled = !!state; + } + }, + + destroy: function() { + var I = this.getRuntime() + , shim = I.getShim() + , shimContainer = I.getShimContainer() + , container = _options && Dom.get(_options.container) + , browseButton = _options && Dom.get(_options.browse_button) + ; + + if (container) { + Events.removeAllEvents(container, this.uid); + } + + if (browseButton) { + Events.removeAllEvents(browseButton, this.uid); + browseButton.style.zIndex = _browseBtnZIndex; // reset to original value + } + + if (shimContainer) { + Events.removeAllEvents(shimContainer, this.uid); + shimContainer.innerHTML = ''; + } + + shim.removeInstance(this.uid); + + _uid = _mimes = _options = shimContainer = container = browseButton = shim = null; + } + }); + } + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/html4/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html4/file/FileReader +@private +*/ +define("moxie/runtime/html4/file/FileReader", [ + "moxie/runtime/html4/Runtime", + "moxie/runtime/html5/file/FileReader" +], function(extensions, FileReader) { + return (extensions.FileReader = FileReader); +}); + +// Included from: src/javascript/runtime/html4/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html4/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/html4/xhr/XMLHttpRequest", [ + "moxie/runtime/html4/Runtime", + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/utils/Url", + "moxie/core/Exceptions", + "moxie/core/utils/Events", + "moxie/file/Blob", + "moxie/xhr/FormData" +], function(extensions, Basic, Dom, Url, x, Events, Blob, FormData) { + + function XMLHttpRequest() { + var _status, _response, _iframe; + + function cleanup(cb) { + var target = this, uid, form, inputs, i, hasFile = false; + + if (!_iframe) { + return; + } + + uid = _iframe.id.replace(/_iframe$/, ''); + + form = Dom.get(uid + '_form'); + if (form) { + inputs = form.getElementsByTagName('input'); + i = inputs.length; + + while (i--) { + switch (inputs[i].getAttribute('type')) { + case 'hidden': + inputs[i].parentNode.removeChild(inputs[i]); + break; + case 'file': + hasFile = true; // flag the case for later + break; + } + } + inputs = []; + + if (!hasFile) { // we need to keep the form for sake of possible retries + form.parentNode.removeChild(form); + } + form = null; + } + + // without timeout, request is marked as canceled (in console) + setTimeout(function() { + Events.removeEvent(_iframe, 'load', target.uid); + if (_iframe.parentNode) { // #382 + _iframe.parentNode.removeChild(_iframe); + } + + // check if shim container has any other children, if - not, remove it as well + var shimContainer = target.getRuntime().getShimContainer(); + if (!shimContainer.children.length) { + shimContainer.parentNode.removeChild(shimContainer); + } + + shimContainer = _iframe = null; + cb(); + }, 1); + } + + Basic.extend(this, { + send: function(meta, data) { + var target = this, I = target.getRuntime(), uid, form, input, blob; + + _status = _response = null; + + function createIframe() { + var container = I.getShimContainer() || document.body + , temp = document.createElement('div') + ; + + // IE 6 won't be able to set the name using setAttribute or iframe.name + temp.innerHTML = ''; + _iframe = temp.firstChild; + container.appendChild(_iframe); + + /* _iframe.onreadystatechange = function() { + console.info(_iframe.readyState); + };*/ + + Events.addEvent(_iframe, 'load', function() { // _iframe.onload doesn't work in IE lte 8 + var el; + + try { + el = _iframe.contentWindow.document || _iframe.contentDocument || window.frames[_iframe.id].document; + + // try to detect some standard error pages + if (/^4(0[0-9]|1[0-7]|2[2346])\s/.test(el.title)) { // test if title starts with 4xx HTTP error + _status = el.title.replace(/^(\d+).*$/, '$1'); + } else { + _status = 200; + // get result + _response = Basic.trim(el.body.innerHTML); + + // we need to fire these at least once + target.trigger({ + type: 'progress', + loaded: _response.length, + total: _response.length + }); + + if (blob) { // if we were uploading a file + target.trigger({ + type: 'uploadprogress', + loaded: blob.size || 1025, + total: blob.size || 1025 + }); + } + } + } catch (ex) { + if (Url.hasSameOrigin(meta.url)) { + // if response is sent with error code, iframe in IE gets redirected to res://ieframe.dll/http_x.htm + // which obviously results to cross domain error (wtf?) + _status = 404; + } else { + cleanup.call(target, function() { + target.trigger('error'); + }); + return; + } + } + + cleanup.call(target, function() { + target.trigger('load'); + }); + }, target.uid); + } // end createIframe + + // prepare data to be sent and convert if required + if (data instanceof FormData && data.hasBlob()) { + blob = data.getBlob(); + uid = blob.uid; + input = Dom.get(uid); + form = Dom.get(uid + '_form'); + if (!form) { + throw new x.DOMException(x.DOMException.NOT_FOUND_ERR); + } + } else { + uid = Basic.guid('uid_'); + + form = document.createElement('form'); + form.setAttribute('id', uid + '_form'); + form.setAttribute('method', meta.method); + form.setAttribute('enctype', 'multipart/form-data'); + form.setAttribute('encoding', 'multipart/form-data'); + + I.getShimContainer().appendChild(form); + } + + // set upload target + form.setAttribute('target', uid + '_iframe'); + + if (data instanceof FormData) { + data.each(function(value, name) { + if (value instanceof Blob) { + if (input) { + input.setAttribute('name', name); + } + } else { + var hidden = document.createElement('input'); + + Basic.extend(hidden, { + type : 'hidden', + name : name, + value : value + }); + + // make sure that input[type="file"], if it's there, comes last + if (input) { + form.insertBefore(hidden, input); + } else { + form.appendChild(hidden); + } + } + }); + } + + // set destination url + form.setAttribute("action", meta.url); + + createIframe(); + form.submit(); + target.trigger('loadstart'); + }, + + getStatus: function() { + return _status; + }, + + getResponse: function(responseType) { + if ('json' === responseType) { + // strip off
..
tags that might be enclosing the response + if (Basic.typeOf(_response) === 'string' && !!window.JSON) { + try { + return JSON.parse(_response.replace(/^\s*]*>/, '').replace(/<\/pre>\s*$/, '')); + } catch (ex) { + return null; + } + } + } else if ('document' === responseType) { + + } + return _response; + }, + + abort: function() { + var target = this; + + if (_iframe && _iframe.contentWindow) { + if (_iframe.contentWindow.stop) { // FireFox/Safari/Chrome + _iframe.contentWindow.stop(); + } else if (_iframe.contentWindow.document.execCommand) { // IE + _iframe.contentWindow.document.execCommand('Stop'); + } else { + _iframe.src = "about:blank"; + } + } + + cleanup.call(this, function() { + // target.dispatchEvent('readystatechange'); + target.dispatchEvent('abort'); + }); + } + }); + } + + return (extensions.XMLHttpRequest = XMLHttpRequest); +}); + +// Included from: src/javascript/runtime/html4/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html4/image/Image +@private +*/ +define("moxie/runtime/html4/image/Image", [ + "moxie/runtime/html4/Runtime", + "moxie/runtime/html5/image/Image" +], function(extensions, Image) { + return (extensions.Image = Image); +}); + +expose(["moxie/core/utils/Basic","moxie/core/utils/Encode","moxie/core/utils/Env","moxie/core/Exceptions","moxie/core/utils/Dom","moxie/core/EventTarget","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/file/Blob","moxie/core/I18n","moxie/core/utils/Mime","moxie/file/FileInput","moxie/file/File","moxie/file/FileDrop","moxie/file/FileReader","moxie/core/utils/Url","moxie/runtime/RuntimeTarget","moxie/xhr/FormData","moxie/xhr/XMLHttpRequest","moxie/runtime/Transporter","moxie/image/Image","moxie/core/utils/Events","moxie/runtime/html5/image/ResizerCanvas"]); +})(this); +})); \ No newline at end of file diff --git a/static/js/uploader/plupload.dev.js b/static/js/uploader/plupload.dev.js new file mode 100644 index 00000000..24fc8565 --- /dev/null +++ b/static/js/uploader/plupload.dev.js @@ -0,0 +1,2476 @@ +/** + * Plupload - multi-runtime File Uploader + * v2.3.1 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2017-02-06 + */ +;(function (global, factory) { + var extract = function() { + var ctx = {}; + factory.apply(ctx, arguments); + return ctx.plupload; + }; + + if (typeof define === "function" && define.amd) { + define("plupload", ['./moxie'], extract); + } else if (typeof module === "object" && module.exports) { + module.exports = extract(require('../../../js-sdk-master 2/src/moxie')); + } else { + global.plupload = extract(global.moxie); + } +}(this || window, function(moxie) { +/** + * Plupload.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +;(function(exports, o, undef) { + +var delay = window.setTimeout; +var fileFilters = {}; +var u = o.core.utils; +var Runtime = o.runtime.Runtime; + +// convert plupload features to caps acceptable by mOxie +function normalizeCaps(settings) { + var features = settings.required_features, caps = {}; + + function resolve(feature, value, strict) { + // Feature notation is deprecated, use caps (this thing here is required for backward compatibility) + var map = { + chunks: 'slice_blob', + jpgresize: 'send_binary_string', + pngresize: 'send_binary_string', + progress: 'report_upload_progress', + multi_selection: 'select_multiple', + dragdrop: 'drag_and_drop', + drop_element: 'drag_and_drop', + headers: 'send_custom_headers', + urlstream_upload: 'send_binary_string', + canSendBinary: 'send_binary', + triggerDialog: 'summon_file_dialog' + }; + + if (map[feature]) { + caps[map[feature]] = value; + } else if (!strict) { + caps[feature] = value; + } + } + + if (typeof(features) === 'string') { + plupload.each(features.split(/\s*,\s*/), function(feature) { + resolve(feature, true); + }); + } else if (typeof(features) === 'object') { + plupload.each(features, function(value, feature) { + resolve(feature, value); + }); + } else if (features === true) { + // check settings for required features + if (settings.chunk_size && settings.chunk_size > 0) { + caps.slice_blob = true; + } + + if (!plupload.isEmptyObj(settings.resize) || settings.multipart === false) { + caps.send_binary_string = true; + } + + if (settings.http_method) { + caps.use_http_method = settings.http_method; + } + + plupload.each(settings, function(value, feature) { + resolve(feature, !!value, true); // strict check + }); + } + + return caps; +} + +/** + * @module plupload + * @static + */ +var plupload = { + /** + * Plupload version will be replaced on build. + * + * @property VERSION + * @for Plupload + * @static + * @final + */ + VERSION : '2.3.1', + + /** + * The state of the queue before it has started and after it has finished + * + * @property STOPPED + * @static + * @final + */ + STOPPED : 1, + + /** + * Upload process is running + * + * @property STARTED + * @static + * @final + */ + STARTED : 2, + + /** + * File is queued for upload + * + * @property QUEUED + * @static + * @final + */ + QUEUED : 1, + + /** + * File is being uploaded + * + * @property UPLOADING + * @static + * @final + */ + UPLOADING : 2, + + /** + * File has failed to be uploaded + * + * @property FAILED + * @static + * @final + */ + FAILED : 4, + + /** + * File has been uploaded successfully + * + * @property DONE + * @static + * @final + */ + DONE : 5, + + // Error constants used by the Error event + + /** + * Generic error for example if an exception is thrown inside Silverlight. + * + * @property GENERIC_ERROR + * @static + * @final + */ + GENERIC_ERROR : -100, + + /** + * HTTP transport error. For example if the server produces a HTTP status other than 200. + * + * @property HTTP_ERROR + * @static + * @final + */ + HTTP_ERROR : -200, + + /** + * Generic I/O error. For example if it wasn't possible to open the file stream on local machine. + * + * @property IO_ERROR + * @static + * @final + */ + IO_ERROR : -300, + + /** + * @property SECURITY_ERROR + * @static + * @final + */ + SECURITY_ERROR : -400, + + /** + * Initialization error. Will be triggered if no runtime was initialized. + * + * @property INIT_ERROR + * @static + * @final + */ + INIT_ERROR : -500, + + /** + * File size error. If the user selects a file that is too large it will be blocked and an error of this type will be triggered. + * + * @property FILE_SIZE_ERROR + * @static + * @final + */ + FILE_SIZE_ERROR : -600, + + /** + * File extension error. If the user selects a file that isn't valid according to the filters setting. + * + * @property FILE_EXTENSION_ERROR + * @static + * @final + */ + FILE_EXTENSION_ERROR : -601, + + /** + * Duplicate file error. If prevent_duplicates is set to true and user selects the same file again. + * + * @property FILE_DUPLICATE_ERROR + * @static + * @final + */ + FILE_DUPLICATE_ERROR : -602, + + /** + * Runtime will try to detect if image is proper one. Otherwise will throw this error. + * + * @property IMAGE_FORMAT_ERROR + * @static + * @final + */ + IMAGE_FORMAT_ERROR : -700, + + /** + * While working on files runtime may run out of memory and will throw this error. + * + * @since 2.1.2 + * @property MEMORY_ERROR + * @static + * @final + */ + MEMORY_ERROR : -701, + + /** + * Each runtime has an upper limit on a dimension of the image it can handle. If bigger, will throw this error. + * + * @property IMAGE_DIMENSIONS_ERROR + * @static + * @final + */ + IMAGE_DIMENSIONS_ERROR : -702, + + /** + * Mime type lookup table. + * + * @property mimeTypes + * @type Object + * @final + */ + mimeTypes : u.Mime.mimes, + + /** + * In some cases sniffing is the only way around :( + */ + ua: u.Env, + + /** + * Gets the true type of the built-in object (better version of typeof). + * @credits Angus Croll (http://javascriptweblog.wordpress.com/) + * + * @method typeOf + * @static + * @param {Object} o Object to check. + * @return {String} Object [[Class]] + */ + typeOf: u.Basic.typeOf, + + /** + * Extends the specified object with another object. + * + * @method extend + * @static + * @param {Object} target Object to extend. + * @param {Object..} obj Multiple objects to extend with. + * @return {Object} Same as target, the extended object. + */ + extend : u.Basic.extend, + + /** + * Generates an unique ID. This is 99.99% unique since it takes the current time and 5 random numbers. + * The only way a user would be able to get the same ID is if the two persons at the same exact millisecond manages + * to get 5 the same random numbers between 0-65535 it also uses a counter so each call will be guaranteed to be page unique. + * It's more probable for the earth to be hit with an asteriod. You can also if you want to be 100% sure set the plupload.guidPrefix property + * to an user unique key. + * + * @method guid + * @static + * @return {String} Virtually unique id. + */ + guid : u.Basic.guid, + + /** + * Get array of DOM Elements by their ids. + * + * @method get + * @param {String} id Identifier of the DOM Element + * @return {Array} + */ + getAll : function get(ids) { + var els = [], el; + + if (plupload.typeOf(ids) !== 'array') { + ids = [ids]; + } + + var i = ids.length; + while (i--) { + el = plupload.get(ids[i]); + if (el) { + els.push(el); + } + } + + return els.length ? els : null; + }, + + /** + Get DOM element by id + + @method get + @param {String} id Identifier of the DOM Element + @return {Node} + */ + get: u.Dom.get, + + /** + * Executes the callback function for each item in array/object. If you return false in the + * callback it will break the loop. + * + * @method each + * @static + * @param {Object} obj Object to iterate. + * @param {function} callback Callback function to execute for each item. + */ + each : u.Basic.each, + + /** + * Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields. + * + * @method getPos + * @static + * @param {Element} node HTML element or element id to get x, y position from. + * @param {Element} root Optional root element to stop calculations at. + * @return {object} Absolute position of the specified element object with x, y fields. + */ + getPos : u.Dom.getPos, + + /** + * Returns the size of the specified node in pixels. + * + * @method getSize + * @static + * @param {Node} node Node to get the size of. + * @return {Object} Object with a w and h property. + */ + getSize : u.Dom.getSize, + + /** + * Encodes the specified string. + * + * @method xmlEncode + * @static + * @param {String} s String to encode. + * @return {String} Encoded string. + */ + xmlEncode : function(str) { + var xmlEncodeChars = {'<' : 'lt', '>' : 'gt', '&' : 'amp', '"' : 'quot', '\'' : '#39'}, xmlEncodeRegExp = /[<>&\"\']/g; + + return str ? ('' + str).replace(xmlEncodeRegExp, function(chr) { + return xmlEncodeChars[chr] ? '&' + xmlEncodeChars[chr] + ';' : chr; + }) : str; + }, + + /** + * Forces anything into an array. + * + * @method toArray + * @static + * @param {Object} obj Object with length field. + * @return {Array} Array object containing all items. + */ + toArray : u.Basic.toArray, + + /** + * Find an element in array and return its index if present, otherwise return -1. + * + * @method inArray + * @static + * @param {mixed} needle Element to find + * @param {Array} array + * @return {Int} Index of the element, or -1 if not found + */ + inArray : u.Basic.inArray, + + /** + Recieve an array of functions (usually async) to call in sequence, each function + receives a callback as first argument that it should call, when it completes. Finally, + after everything is complete, main callback is called. Passing truthy value to the + callback as a first argument will interrupt the sequence and invoke main callback + immediately. + + @method inSeries + @static + @param {Array} queue Array of functions to call in sequence + @param {Function} cb Main callback that is called in the end, or in case of error + */ + inSeries: u.Basic.inSeries, + + /** + * Extends the language pack object with new items. + * + * @method addI18n + * @static + * @param {Object} pack Language pack items to add. + * @return {Object} Extended language pack object. + */ + addI18n : o.core.I18n.addI18n, + + /** + * Translates the specified string by checking for the english string in the language pack lookup. + * + * @method translate + * @static + * @param {String} str String to look for. + * @return {String} Translated string or the input string if it wasn't found. + */ + translate : o.core.I18n.translate, + + /** + * Pseudo sprintf implementation - simple way to replace tokens with specified values. + * + * @param {String} str String with tokens + * @return {String} String with replaced tokens + */ + sprintf : u.Basic.sprintf, + + /** + * Checks if object is empty. + * + * @method isEmptyObj + * @static + * @param {Object} obj Object to check. + * @return {Boolean} + */ + isEmptyObj : u.Basic.isEmptyObj, + + /** + * Checks if specified DOM element has specified class. + * + * @method hasClass + * @static + * @param {Object} obj DOM element like object to add handler to. + * @param {String} name Class name + */ + hasClass : u.Dom.hasClass, + + /** + * Adds specified className to specified DOM element. + * + * @method addClass + * @static + * @param {Object} obj DOM element like object to add handler to. + * @param {String} name Class name + */ + addClass : u.Dom.addClass, + + /** + * Removes specified className from specified DOM element. + * + * @method removeClass + * @static + * @param {Object} obj DOM element like object to add handler to. + * @param {String} name Class name + */ + removeClass : u.Dom.removeClass, + + /** + * Returns a given computed style of a DOM element. + * + * @method getStyle + * @static + * @param {Object} obj DOM element like object. + * @param {String} name Style you want to get from the DOM element + */ + getStyle : u.Dom.getStyle, + + /** + * Adds an event handler to the specified object and store reference to the handler + * in objects internal Plupload registry (@see removeEvent). + * + * @method addEvent + * @static + * @param {Object} obj DOM element like object to add handler to. + * @param {String} name Name to add event listener to. + * @param {Function} callback Function to call when event occurs. + * @param {String} (optional) key that might be used to add specifity to the event record. + */ + addEvent : u.Events.addEvent, + + /** + * Remove event handler from the specified object. If third argument (callback) + * is not specified remove all events with the specified name. + * + * @method removeEvent + * @static + * @param {Object} obj DOM element to remove event listener(s) from. + * @param {String} name Name of event listener to remove. + * @param {Function|String} (optional) might be a callback or unique key to match. + */ + removeEvent: u.Events.removeEvent, + + /** + * Remove all kind of events from the specified object + * + * @method removeAllEvents + * @static + * @param {Object} obj DOM element to remove event listeners from. + * @param {String} (optional) unique key to match, when removing events. + */ + removeAllEvents: u.Events.removeAllEvents, + + /** + * Cleans the specified name from national characters (diacritics). The result will be a name with only a-z, 0-9 and _. + * + * @method cleanName + * @static + * @param {String} s String to clean up. + * @return {String} Cleaned string. + */ + cleanName : function(name) { + var i, lookup; + + // Replace diacritics + lookup = [ + /[\300-\306]/g, 'A', /[\340-\346]/g, 'a', + /\307/g, 'C', /\347/g, 'c', + /[\310-\313]/g, 'E', /[\350-\353]/g, 'e', + /[\314-\317]/g, 'I', /[\354-\357]/g, 'i', + /\321/g, 'N', /\361/g, 'n', + /[\322-\330]/g, 'O', /[\362-\370]/g, 'o', + /[\331-\334]/g, 'U', /[\371-\374]/g, 'u' + ]; + + for (i = 0; i < lookup.length; i += 2) { + name = name.replace(lookup[i], lookup[i + 1]); + } + + // Replace whitespace + name = name.replace(/\s+/g, '_'); + + // Remove anything else + name = name.replace(/[^a-z0-9_\-\.]+/gi, ''); + + return name; + }, + + /** + * Builds a full url out of a base URL and an object with items to append as query string items. + * + * @method buildUrl + * @static + * @param {String} url Base URL to append query string items to. + * @param {Object} items Name/value object to serialize as a querystring. + * @return {String} String with url + serialized query string items. + */ + buildUrl: function(url, items) { + var query = ''; + + plupload.each(items, function(value, name) { + query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value); + }); + + if (query) { + url += (url.indexOf('?') > 0 ? '&' : '?') + query; + } + + return url; + }, + + /** + * Formats the specified number as a size string for example 1024 becomes 1 KB. + * + * @method formatSize + * @static + * @param {Number} size Size to format as string. + * @return {String} Formatted size string. + */ + formatSize : function(size) { + + if (size === undef || /\D/.test(size)) { + return plupload.translate('N/A'); + } + + function round(num, precision) { + return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision); + } + + var boundary = Math.pow(1024, 4); + + // TB + if (size > boundary) { + return round(size / boundary, 1) + " " + plupload.translate('tb'); + } + + // GB + if (size > (boundary/=1024)) { + return round(size / boundary, 1) + " " + plupload.translate('gb'); + } + + // MB + if (size > (boundary/=1024)) { + return round(size / boundary, 1) + " " + plupload.translate('mb'); + } + + // KB + if (size > 1024) { + return Math.round(size / 1024) + " " + plupload.translate('kb'); + } + + return size + " " + plupload.translate('b'); + }, + + + /** + * Parses the specified size string into a byte value. For example 10kb becomes 10240. + * + * @method parseSize + * @static + * @param {String|Number} size String to parse or number to just pass through. + * @return {Number} Size in bytes. + */ + parseSize : u.Basic.parseSizeStr, + + + /** + * A way to predict what runtime will be choosen in the current environment with the + * specified settings. + * + * @method predictRuntime + * @static + * @param {Object|String} config Plupload settings to check + * @param {String} [runtimes] Comma-separated list of runtimes to check against + * @return {String} Type of compatible runtime + */ + predictRuntime : function(config, runtimes) { + var up, runtime; + + up = new plupload.Uploader(config); + runtime = Runtime.thatCan(up.getOption().required_features, runtimes || config.runtimes); + up.destroy(); + return runtime; + }, + + /** + * Registers a filter that will be executed for each file added to the queue. + * If callback returns false, file will not be added. + * + * Callback receives two arguments: a value for the filter as it was specified in settings.filters + * and a file to be filtered. Callback is executed in the context of uploader instance. + * + * @method addFileFilter + * @static + * @param {String} name Name of the filter by which it can be referenced in settings.filters + * @param {String} cb Callback - the actual routine that every added file must pass + */ + addFileFilter: function(name, cb) { + fileFilters[name] = cb; + } +}; + + +plupload.addFileFilter('mime_types', function(filters, file, cb) { + if (filters.length && !filters.regexp.test(file.name)) { + this.trigger('Error', { + code : plupload.FILE_EXTENSION_ERROR, + message : plupload.translate('File extension error.'), + file : file + }); + cb(false); + } else { + cb(true); + } +}); + + +plupload.addFileFilter('max_file_size', function(maxSize, file, cb) { + var undef; + + maxSize = plupload.parseSize(maxSize); + + // Invalid file size + if (file.size !== undef && maxSize && file.size > maxSize) { + this.trigger('Error', { + code : plupload.FILE_SIZE_ERROR, + message : plupload.translate('File size error.'), + file : file + }); + cb(false); + } else { + cb(true); + } +}); + + +plupload.addFileFilter('prevent_duplicates', function(value, file, cb) { + if (value) { + var ii = this.files.length; + while (ii--) { + // Compare by name and size (size might be 0 or undefined, but still equivalent for both) + if (file.name === this.files[ii].name && file.size === this.files[ii].size) { + this.trigger('Error', { + code : plupload.FILE_DUPLICATE_ERROR, + message : plupload.translate('Duplicate file error.'), + file : file + }); + cb(false); + return; + } + } + } + cb(true); +}); + + +/** +@class Uploader +@constructor + +@param {Object} settings For detailed information about each option check documentation. + @param {String|DOMElement} settings.browse_button id of the DOM element or DOM element itself to use as file dialog trigger. + @param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled. + @param {String|DOMElement} [settings.container] id of the DOM element or DOM element itself that will be used to wrap uploader structures. Defaults to immediate parent of the `browse_button` element. + @param {String|DOMElement} [settings.drop_element] id of the DOM element or DOM element itself to use as a drop zone for Drag-n-Drop. + @param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message. + @param {Object} [settings.filters={}] Set of file type filters. + @param {String|Number} [settings.filters.max_file_size=0] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`. + @param {Array} [settings.filters.mime_types=[]] List of file types to accept, each one defined by title and list of extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR` + @param {Boolean} [settings.filters.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`. + @param {String} [settings.flash_swf_url] URL of the Flash swf. + @param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs. + @param {String} [settings.http_method="POST"] HTTP method to use during upload (only PUT or POST allowed). + @param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event. + @param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message. + @param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload. + @param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog. + @param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess. + @param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}` + @param {Number} [settings.resize.width] If image is bigger, it will be resized. + @param {Number} [settings.resize.height] If image is bigger, it will be resized. + @param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100). + @param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally. + @param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails. + @param {String} [settings.silverlight_xap_url] URL of the Silverlight xap. + @param {Boolean} [settings.send_chunk_number=true] Whether to send chunks and chunk numbers, or total and offset bytes. + @param {Boolean} [settings.send_file_name=true] Whether to send file name as additional argument - 'name' (required for chunked uploads and some other cases where file name cannot be sent via normal ways). + @param {String} settings.url URL of the server-side upload handler. + @param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files. + +*/ +plupload.Uploader = function(options) { + /** + Fires when the current RunTime has been initialized. + + @event Init + @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + Fires after the init event incase you need to perform actions there. + + @event PostInit + @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + Fires when the option is changed in via uploader.setOption(). + + @event OptionChanged + @since 2.1 + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {String} name Name of the option that was changed + @param {Mixed} value New value for the specified option + @param {Mixed} oldValue Previous value of the option + */ + + /** + Fires when the silverlight/flash or other shim needs to move. + + @event Refresh + @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + Fires when the overall state is being changed for the upload queue. + + @event StateChanged + @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + Fires when browse_button is clicked and browse dialog shows. + + @event Browse + @since 2.1.2 + @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + Fires for every filtered file before it is added to the queue. + + @event FileFiltered + @since 2.1 + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {plupload.File} file Another file that has to be added to the queue. + */ + + /** + Fires when the file queue is changed. In other words when files are added/removed to the files array of the uploader instance. + + @event QueueChanged + @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + Fires after files were filtered and added to the queue. + + @event FilesAdded + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {Array} files Array of file objects that were added to queue by the user. + */ + + /** + Fires when file is removed from the queue. + + @event FilesRemoved + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {Array} files Array of files that got removed. + */ + + /** + Fires just before a file is uploaded. Can be used to cancel the upload for the specified file + by returning false from the handler. + + @event BeforeUpload + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {plupload.File} file File to be uploaded. + */ + + /** + Fires when a file is to be uploaded by the runtime. + + @event UploadFile + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {plupload.File} file File to be uploaded. + */ + + /** + Fires while a file is being uploaded. Use this event to update the current file upload progress. + + @event UploadProgress + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {plupload.File} file File that is currently being uploaded. + */ + + /** + * Fires just before a chunk is uploaded. This event enables you to override settings + * on the uploader instance before the chunk is uploaded. + * + * @event BeforeChunkUpload + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {plupload.File} file File to be uploaded. + * @param {Object} args POST params to be sent. + * @param {Blob} chunkBlob Current blob. + * @param {offset} offset Current offset. + */ + + /** + Fires when file chunk is uploaded. + + @event ChunkUploaded + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {plupload.File} file File that the chunk was uploaded for. + @param {Object} result Object with response properties. + @param {Number} result.offset The amount of bytes the server has received so far, including this chunk. + @param {Number} result.total The size of the file. + @param {String} result.response The response body sent by the server. + @param {Number} result.status The HTTP status code sent by the server. + @param {String} result.responseHeaders All the response headers as a single string. + */ + + /** + Fires when a file is successfully uploaded. + + @event FileUploaded + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {plupload.File} file File that was uploaded. + @param {Object} result Object with response properties. + @param {String} result.response The response body sent by the server. + @param {Number} result.status The HTTP status code sent by the server. + @param {String} result.responseHeaders All the response headers as a single string. + */ + + /** + Fires when all files in a queue are uploaded. + + @event UploadComplete + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {Array} files Array of file objects that was added to queue/selected by the user. + */ + + /** + Fires when a error occurs. + + @event Error + @param {plupload.Uploader} uploader Uploader instance sending the event. + @param {Object} error Contains code, message and sometimes file and other details. + @param {Number} error.code The plupload error code. + @param {String} error.message Description of the error (uses i18n). + */ + + /** + Fires when destroy method is called. + + @event Destroy + @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + var uid = plupload.guid() + , settings + , files = [] + , preferred_caps = {} + , fileInputs = [] + , fileDrops = [] + , startTime + , total + , disabled = false + , xhr + ; + + + // Private methods + function uploadNext() { + var file, count = 0, i; + + if (this.state == plupload.STARTED) { + // Find first QUEUED file + for (i = 0; i < files.length; i++) { + if (!file && files[i].status == plupload.QUEUED) { + file = files[i]; + if (this.trigger("BeforeUpload", file)) { + file.status = plupload.UPLOADING; + this.trigger("UploadFile", file); + } + } else { + count++; + } + } + + // All files are DONE or FAILED + if (count == files.length) { + if (this.state !== plupload.STOPPED) { + this.state = plupload.STOPPED; + this.trigger("StateChanged"); + } + this.trigger("UploadComplete", files); + } + } + } + + + function calcFile(file) { + file.percent = file.size > 0 ? Math.ceil(file.loaded / file.size * 100) : 100; + calc(); + } + + + function calc() { + var i, file; + var loaded; + var loadedDuringCurrentSession = 0; + + // Reset stats + total.reset(); + + // Check status, size, loaded etc on all files + for (i = 0; i < files.length; i++) { + file = files[i]; + + if (file.size !== undef) { + // We calculate totals based on original file size + total.size += file.origSize; + + // Since we cannot predict file size after resize, we do opposite and + // interpolate loaded amount to match magnitude of total + loaded = file.loaded * file.origSize / file.size; + + if (!file.completeTimestamp || file.completeTimestamp > startTime) { + loadedDuringCurrentSession += loaded; + } + + total.loaded += loaded; + } else { + total.size = undef; + } + + if (file.status == plupload.DONE) { + total.uploaded++; + } else if (file.status == plupload.FAILED) { + total.failed++; + } else { + total.queued++; + } + } + + // If we couldn't calculate a total file size then use the number of files to calc percent + if (total.size === undef) { + total.percent = files.length > 0 ? Math.ceil(total.uploaded / files.length * 100) : 0; + } else { + total.bytesPerSec = Math.ceil(loadedDuringCurrentSession / ((+new Date() - startTime || 1) / 1000.0)); + total.percent = total.size > 0 ? Math.ceil(total.loaded / total.size * 100) : 0; + } + } + + + function getRUID() { + var ctrl = fileInputs[0] || fileDrops[0]; + if (ctrl) { + return ctrl.getRuntime().uid; + } + return false; + } + + + function runtimeCan(file, cap) { + if (file.ruid) { + var info = Runtime.getInfo(file.ruid); + if (info) { + return info.can(cap); + } + } + return false; + } + + + function bindEventListeners() { + this.bind('FilesAdded FilesRemoved', function(up) { + up.trigger('QueueChanged'); + up.refresh(); + }); + + this.bind('CancelUpload', onCancelUpload); + + this.bind('BeforeUpload', onBeforeUpload); + + this.bind('UploadFile', onUploadFile); + + this.bind('UploadProgress', onUploadProgress); + + this.bind('StateChanged', onStateChanged); + + this.bind('QueueChanged', calc); + + this.bind('Error', onError); + + this.bind('FileUploaded', onFileUploaded); + + this.bind('Destroy', onDestroy); + } + + + function initControls(settings, cb) { + var self = this, inited = 0, queue = []; + + // common settings + var options = { + runtime_order: settings.runtimes, + required_caps: settings.required_features, + preferred_caps: preferred_caps, + swf_url: settings.flash_swf_url, + xap_url: settings.silverlight_xap_url + }; + + // add runtime specific options if any + plupload.each(settings.runtimes.split(/\s*,\s*/), function(runtime) { + if (settings[runtime]) { + options[runtime] = settings[runtime]; + } + }); + + // initialize file pickers - there can be many + if (settings.browse_button) { + plupload.each(settings.browse_button, function(el) { + queue.push(function(cb) { + var fileInput = new o.file.FileInput(plupload.extend({}, options, { + accept: settings.filters.mime_types, + name: settings.file_data_name, + multiple: settings.multi_selection, + container: settings.container, + browse_button: el + })); + + fileInput.onready = function() { + var info = Runtime.getInfo(this.ruid); + + // for backward compatibility + plupload.extend(self.features, { + chunks: info.can('slice_blob'), + multipart: info.can('send_multipart'), + multi_selection: info.can('select_multiple') + }); + + inited++; + fileInputs.push(this); + cb(); + }; + + fileInput.onchange = function() { + self.addFile(this.files); + }; + + fileInput.bind('mouseenter mouseleave mousedown mouseup', function(e) { + if (!disabled) { + if (settings.browse_button_hover) { + if ('mouseenter' === e.type) { + plupload.addClass(el, settings.browse_button_hover); + } else if ('mouseleave' === e.type) { + plupload.removeClass(el, settings.browse_button_hover); + } + } + + if (settings.browse_button_active) { + if ('mousedown' === e.type) { + plupload.addClass(el, settings.browse_button_active); + } else if ('mouseup' === e.type) { + plupload.removeClass(el, settings.browse_button_active); + } + } + } + }); + + fileInput.bind('mousedown', function() { + self.trigger('Browse'); + }); + + fileInput.bind('error runtimeerror', function() { + fileInput = null; + cb(); + }); + + fileInput.init(); + }); + }); + } + + // initialize drop zones + if (settings.drop_element) { + plupload.each(settings.drop_element, function(el) { + queue.push(function(cb) { + var fileDrop = new o.file.FileDrop(plupload.extend({}, options, { + drop_zone: el + })); + + fileDrop.onready = function() { + var info = Runtime.getInfo(this.ruid); + + // for backward compatibility + plupload.extend(self.features, { + chunks: info.can('slice_blob'), + multipart: info.can('send_multipart'), + dragdrop: info.can('drag_and_drop') + }); + + inited++; + fileDrops.push(this); + cb(); + }; + + fileDrop.ondrop = function() { + self.addFile(this.files); + }; + + fileDrop.bind('error runtimeerror', function() { + fileDrop = null; + cb(); + }); + + fileDrop.init(); + }); + }); + } + + + plupload.inSeries(queue, function() { + if (typeof(cb) === 'function') { + cb(inited); + } + }); + } + + + function resizeImage(blob, params, cb) { + var img = new o.image.Image(); + + try { + img.onload = function() { + // no manipulation required if... + if (params.width > this.width && + params.height > this.height && + params.quality === undef && + params.preserve_headers && + !params.crop + ) { + this.destroy(); + return cb(blob); + } + // otherwise downsize + img.downsize(params.width, params.height, params.crop, params.preserve_headers); + }; + + img.onresize = function() { + cb(this.getAsBlob(blob.type, params.quality)); + this.destroy(); + }; + + img.onerror = function() { + cb(blob); + }; + + img.load(blob); + } catch(ex) { + cb(blob); + } + } + + + function setOption(option, value, init) { + var self = this, reinitRequired = false; + + function _setOption(option, value, init) { + var oldValue = settings[option]; + + switch (option) { + case 'max_file_size': + if (option === 'max_file_size') { + settings.max_file_size = settings.filters.max_file_size = value; + } + break; + + case 'chunk_size': + if (value = plupload.parseSize(value)) { + settings[option] = value; + settings.send_file_name = true; + } + break; + + case 'multipart': + settings[option] = value; + if (!value) { + settings.send_file_name = true; + } + break; + + case 'http_method': + settings[option] = value.toUpperCase() === 'PUT' ? 'PUT' : 'POST'; + break; + + case 'unique_names': + settings[option] = value; + if (value) { + settings.send_file_name = true; + } + break; + + case 'filters': + // for sake of backward compatibility + if (plupload.typeOf(value) === 'array') { + value = { + mime_types: value + }; + } + + if (init) { + plupload.extend(settings.filters, value); + } else { + settings.filters = value; + } + + // if file format filters are being updated, regenerate the matching expressions + if (value.mime_types) { + if (plupload.typeOf(value.mime_types) === 'string') { + value.mime_types = o.core.utils.Mime.mimes2extList(value.mime_types); + } + + value.mime_types.regexp = (function(filters) { + var extensionsRegExp = []; + + plupload.each(filters, function(filter) { + plupload.each(filter.extensions.split(/,/), function(ext) { + if (/^\s*\*\s*$/.test(ext)) { + extensionsRegExp.push('\\.*'); + } else { + extensionsRegExp.push('\\.' + ext.replace(new RegExp('[' + ('/^$.*+?|()[]{}\\'.replace(/./g, '\\$&')) + ']', 'g'), '\\$&')); + } + }); + }); + + return new RegExp('(' + extensionsRegExp.join('|') + ')$', 'i'); + }(value.mime_types)); + + settings.filters.mime_types = value.mime_types; + } + break; + + case 'resize': + if (value) { + settings.resize = plupload.extend({ + preserve_headers: true, + crop: false + }, value); + } else { + settings.resize = false; + } + break; + + case 'prevent_duplicates': + settings.prevent_duplicates = settings.filters.prevent_duplicates = !!value; + break; + + // options that require reinitialisation + case 'container': + case 'browse_button': + case 'drop_element': + value = 'container' === option + ? plupload.get(value) + : plupload.getAll(value) + ; + + case 'runtimes': + case 'multi_selection': + case 'flash_swf_url': + case 'silverlight_xap_url': + settings[option] = value; + if (!init) { + reinitRequired = true; + } + break; + + default: + settings[option] = value; + } + + if (!init) { + self.trigger('OptionChanged', option, value, oldValue); + } + } + + if (typeof(option) === 'object') { + plupload.each(option, function(value, option) { + _setOption(option, value, init); + }); + } else { + _setOption(option, value, init); + } + + if (init) { + // Normalize the list of required capabilities + settings.required_features = normalizeCaps(plupload.extend({}, settings)); + + // Come up with the list of capabilities that can affect default mode in a multi-mode runtimes + preferred_caps = normalizeCaps(plupload.extend({}, settings, { + required_features: true + })); + } else if (reinitRequired) { + self.trigger('Destroy'); + + initControls.call(self, settings, function(inited) { + if (inited) { + self.runtime = Runtime.getInfo(getRUID()).type; + self.trigger('Init', { runtime: self.runtime }); + self.trigger('PostInit'); + } else { + self.trigger('Error', { + code : plupload.INIT_ERROR, + message : plupload.translate('Init error.') + }); + } + }); + } + } + + + // Internal event handlers + function onBeforeUpload(up, file) { + // Generate unique target filenames + if (up.settings.unique_names) { + var matches = file.name.match(/\.([^.]+)$/), ext = "part"; + if (matches) { + ext = matches[1]; + } + file.target_name = file.id + '.' + ext; + } + } + + + function onUploadFile(up, file) { + var url = up.settings.url + , chunkSize = up.settings.chunk_size + , retries = up.settings.max_retries + , features = up.features + , offset = 0 + , blob + ; + + // make sure we start at a predictable offset + if (file.loaded) { + offset = file.loaded = chunkSize ? chunkSize * Math.floor(file.loaded / chunkSize) : 0; + } + + function handleError() { + if (retries-- > 0) { + delay(uploadNextChunk, 1000); + } else { + file.loaded = offset; // reset all progress + + up.trigger('Error', { + code : plupload.HTTP_ERROR, + message : plupload.translate('HTTP Error.'), + file : file, + response : xhr.responseText, + status : xhr.status, + responseHeaders: xhr.getAllResponseHeaders() + }); + } + } + + function uploadNextChunk() { + var chunkBlob, args = {}, curChunkSize; + + // make sure that file wasn't cancelled and upload is not stopped in general + if (file.status !== plupload.UPLOADING || up.state === plupload.STOPPED) { + return; + } + + // send additional 'name' parameter only if required + if (up.settings.send_file_name) { + args.name = file.target_name || file.name; + } + + if (chunkSize && features.chunks && blob.size > chunkSize) { // blob will be of type string if it was loaded in memory + curChunkSize = Math.min(chunkSize, blob.size - offset); + chunkBlob = blob.slice(offset, offset + curChunkSize); + } else { + curChunkSize = blob.size; + chunkBlob = blob; + } + + // If chunking is enabled add corresponding args, no matter if file is bigger than chunk or smaller + if (chunkSize && features.chunks) { + // Setup query string arguments + if (up.settings.send_chunk_number) { + args.chunk = Math.ceil(offset / chunkSize); + args.chunks = Math.ceil(blob.size / chunkSize); + } else { // keep support for experimental chunk format, just in case + args.offset = offset; + args.total = blob.size; + } + } + + if (up.trigger('BeforeChunkUpload', file, args, chunkBlob, offset)) { + uploadChunk(args, chunkBlob, curChunkSize); + } + } + + function uploadChunk(args, chunkBlob, curChunkSize) { + var formData; + + xhr = new o.xhr.XMLHttpRequest(); + + // Do we have upload progress support + if (xhr.upload) { + xhr.upload.onprogress = function(e) { + file.loaded = Math.min(file.size, offset + e.loaded); + up.trigger('UploadProgress', file); + }; + } + + xhr.onload = function() { + // check if upload made itself through + if (xhr.status >= 400) { + handleError(); + return; + } + + retries = up.settings.max_retries; // reset the counter + + // Handle chunk response + if (curChunkSize < blob.size) { + chunkBlob.destroy(); + + offset += curChunkSize; + file.loaded = Math.min(offset, blob.size); + + up.trigger('ChunkUploaded', file, { + offset : file.loaded, + total : blob.size, + response : xhr.responseText, + status : xhr.status, + responseHeaders: xhr.getAllResponseHeaders() + }); + + // stock Android browser doesn't fire upload progress events, but in chunking mode we can fake them + if (plupload.ua.browser === 'Android Browser') { + // doesn't harm in general, but is not required anywhere else + up.trigger('UploadProgress', file); + } + } else { + file.loaded = file.size; + } + + chunkBlob = formData = null; // Free memory + + // Check if file is uploaded + if (!offset || offset >= blob.size) { + // If file was modified, destory the copy + if (file.size != file.origSize) { + blob.destroy(); + blob = null; + } + + up.trigger('UploadProgress', file); + + file.status = plupload.DONE; + file.completeTimestamp = +new Date(); + + up.trigger('FileUploaded', file, { + response : xhr.responseText, + status : xhr.status, + responseHeaders: xhr.getAllResponseHeaders() + }); + } else { + // Still chunks left + delay(uploadNextChunk, 1); // run detached, otherwise event handlers interfere + } + }; + + xhr.onerror = function() { + handleError(); + }; + + xhr.onloadend = function() { + this.destroy(); + xhr = null; + }; + + // Build multipart request + if (up.settings.multipart && features.multipart) { + xhr.open(up.settings.http_method, url, true); + + // Set custom headers + plupload.each(up.settings.headers, function(value, name) { + xhr.setRequestHeader(name, value); + }); + + formData = new o.xhr.FormData(); + + // Add multipart params + plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) { + formData.append(name, value); + }); + + // Add file and send it + formData.append(up.settings.file_data_name, chunkBlob); + xhr.send(formData, { + runtime_order: up.settings.runtimes, + required_caps: up.settings.required_features, + preferred_caps: preferred_caps, + swf_url: up.settings.flash_swf_url, + xap_url: up.settings.silverlight_xap_url + }); + } else { + // if no multipart, send as binary stream + url = plupload.buildUrl(up.settings.url, plupload.extend(args, up.settings.multipart_params)); + + xhr.open(up.settings.http_method, url, true); + + // Set custom headers + plupload.each(up.settings.headers, function(value, name) { + xhr.setRequestHeader(name, value); + }); + + // do not set Content-Type, if it was defined previously (see #1203) + if (!xhr.hasRequestHeader('Content-Type')) { + xhr.setRequestHeader('Content-Type', 'application/octet-stream'); // Binary stream header + } + + xhr.send(chunkBlob, { + runtime_order: up.settings.runtimes, + required_caps: up.settings.required_features, + preferred_caps: preferred_caps, + swf_url: up.settings.flash_swf_url, + xap_url: up.settings.silverlight_xap_url + }); + } + } + + + blob = file.getSource(); + + // Start uploading chunks + if (!plupload.isEmptyObj(up.settings.resize) && runtimeCan(blob, 'send_binary_string') && plupload.inArray(blob.type, ['image/jpeg', 'image/png']) !== -1) { + // Resize if required + resizeImage.call(this, blob, up.settings.resize, function(resizedBlob) { + blob = resizedBlob; + file.size = resizedBlob.size; + uploadNextChunk(); + }); + } else { + uploadNextChunk(); + } + } + + + function onUploadProgress(up, file) { + calcFile(file); + } + + + function onStateChanged(up) { + if (up.state == plupload.STARTED) { + // Get start time to calculate bps + startTime = (+new Date()); + } else if (up.state == plupload.STOPPED) { + // Reset currently uploading files + for (var i = up.files.length - 1; i >= 0; i--) { + if (up.files[i].status == plupload.UPLOADING) { + up.files[i].status = plupload.QUEUED; + calc(); + } + } + } + } + + + function onCancelUpload() { + if (xhr) { + xhr.abort(); + } + } + + + function onFileUploaded(up) { + calc(); + + // Upload next file but detach it from the error event + // since other custom listeners might want to stop the queue + delay(function() { + uploadNext.call(up); + }, 1); + } + + + function onError(up, err) { + if (err.code === plupload.INIT_ERROR) { + up.destroy(); + } + // Set failed status if an error occured on a file + else if (err.code === plupload.HTTP_ERROR) { + err.file.status = plupload.FAILED; + err.file.completeTimestamp = +new Date(); + calcFile(err.file); + + // Upload next file but detach it from the error event + // since other custom listeners might want to stop the queue + if (up.state == plupload.STARTED) { // upload in progress + up.trigger('CancelUpload'); + delay(function() { + uploadNext.call(up); + }, 1); + } + } + } + + + function onDestroy(up) { + up.stop(); + + // Purge the queue + plupload.each(files, function(file) { + file.destroy(); + }); + files = []; + + if (fileInputs.length) { + plupload.each(fileInputs, function(fileInput) { + fileInput.destroy(); + }); + fileInputs = []; + } + + if (fileDrops.length) { + plupload.each(fileDrops, function(fileDrop) { + fileDrop.destroy(); + }); + fileDrops = []; + } + + preferred_caps = {}; + disabled = false; + startTime = xhr = null; + total.reset(); + } + + + // Default settings + settings = { + chunk_size: 0, + file_data_name: 'file', + filters: { + mime_types: [], + prevent_duplicates: false, + max_file_size: 0 + }, + flash_swf_url: 'js/Moxie.swf', + http_method: 'POST', + max_retries: 0, + multipart: true, + multi_selection: true, + resize: false, + runtimes: Runtime.order, + send_file_name: true, + send_chunk_number: true, + silverlight_xap_url: 'js/Moxie.xap' + }; + + + setOption.call(this, options, null, true); + + // Inital total state + total = new plupload.QueueProgress(); + + // Add public methods + plupload.extend(this, { + + /** + * Unique id for the Uploader instance. + * + * @property id + * @type String + */ + id : uid, + uid : uid, // mOxie uses this to differentiate between event targets + + /** + * Current state of the total uploading progress. This one can either be plupload.STARTED or plupload.STOPPED. + * These states are controlled by the stop/start methods. The default value is STOPPED. + * + * @property state + * @type Number + */ + state : plupload.STOPPED, + + /** + * Map of features that are available for the uploader runtime. Features will be filled + * before the init event is called, these features can then be used to alter the UI for the end user. + * Some of the current features that might be in this map is: dragdrop, chunks, jpgresize, pngresize. + * + * @property features + * @type Object + */ + features : {}, + + /** + * Current runtime name. + * + * @property runtime + * @type String + */ + runtime : null, + + /** + * Current upload queue, an array of File instances. + * + * @property files + * @type Array + * @see plupload.File + */ + files : files, + + /** + * Object with name/value settings. + * + * @property settings + * @type Object + */ + settings : settings, + + /** + * Total progess information. How many files has been uploaded, total percent etc. + * + * @property total + * @type plupload.QueueProgress + */ + total : total, + + + /** + * Initializes the Uploader instance and adds internal event listeners. + * + * @method init + */ + init : function() { + var self = this, opt, preinitOpt, err; + + preinitOpt = self.getOption('preinit'); + if (typeof(preinitOpt) == "function") { + preinitOpt(self); + } else { + plupload.each(preinitOpt, function(func, name) { + self.bind(name, func); + }); + } + + bindEventListeners.call(self); + + // Check for required options + plupload.each(['container', 'browse_button', 'drop_element'], function(el) { + if (self.getOption(el) === null) { + err = { + code : plupload.INIT_ERROR, + message : plupload.sprintf(plupload.translate("%s specified, but cannot be found."), el) + } + return false; + } + }); + + if (err) { + return self.trigger('Error', err); + } + + + if (!settings.browse_button && !settings.drop_element) { + return self.trigger('Error', { + code : plupload.INIT_ERROR, + message : plupload.translate("You must specify either browse_button or drop_element.") + }); + } + + + initControls.call(self, settings, function(inited) { + var initOpt = self.getOption('init'); + if (typeof(initOpt) == "function") { + initOpt(self); + } else { + plupload.each(initOpt, function(func, name) { + self.bind(name, func); + }); + } + + if (inited) { + self.runtime = Runtime.getInfo(getRUID()).type; + self.trigger('Init', { runtime: self.runtime }); + self.trigger('PostInit'); + } else { + self.trigger('Error', { + code : plupload.INIT_ERROR, + message : plupload.translate('Init error.') + }); + } + }); + }, + + /** + * Set the value for the specified option(s). + * + * @method setOption + * @since 2.1 + * @param {String|Object} option Name of the option to change or the set of key/value pairs + * @param {Mixed} [value] Value for the option (is ignored, if first argument is object) + */ + setOption: function(option, value) { + setOption.call(this, option, value, !this.runtime); // until runtime not set we do not need to reinitialize + }, + + /** + * Get the value for the specified option or the whole configuration, if not specified. + * + * @method getOption + * @since 2.1 + * @param {String} [option] Name of the option to get + * @return {Mixed} Value for the option or the whole set + */ + getOption: function(option) { + if (!option) { + return settings; + } + return settings[option]; + }, + + /** + * Refreshes the upload instance by dispatching out a refresh event to all runtimes. + * This would for example reposition flash/silverlight shims on the page. + * + * @method refresh + */ + refresh : function() { + if (fileInputs.length) { + plupload.each(fileInputs, function(fileInput) { + fileInput.trigger('Refresh'); + }); + } + this.trigger('Refresh'); + }, + + /** + * Starts uploading the queued files. + * + * @method start + */ + start : function() { + if (this.state != plupload.STARTED) { + this.state = plupload.STARTED; + this.trigger('StateChanged'); + + uploadNext.call(this); + } + }, + + /** + * Stops the upload of the queued files. + * + * @method stop + */ + stop : function() { + if (this.state != plupload.STOPPED) { + this.state = plupload.STOPPED; + this.trigger('StateChanged'); + this.trigger('CancelUpload'); + } + }, + + + /** + * Disables/enables browse button on request. + * + * @method disableBrowse + * @param {Boolean} disable Whether to disable or enable (default: true) + */ + disableBrowse : function() { + disabled = arguments[0] !== undef ? arguments[0] : true; + + if (fileInputs.length) { + plupload.each(fileInputs, function(fileInput) { + fileInput.disable(disabled); + }); + } + + this.trigger('DisableBrowse', disabled); + }, + + /** + * Returns the specified file object by id. + * + * @method getFile + * @param {String} id File id to look for. + * @return {plupload.File} File object or undefined if it wasn't found; + */ + getFile : function(id) { + var i; + for (i = files.length - 1; i >= 0; i--) { + if (files[i].id === id) { + return files[i]; + } + } + }, + + /** + * Adds file to the queue programmatically. Can be native file, instance of Plupload.File, + * instance of mOxie.File, input[type="file"] element, or array of these. Fires FilesAdded, + * if any files were added to the queue. Otherwise nothing happens. + * + * @method addFile + * @since 2.0 + * @param {plupload.File|mOxie.File|File|Node|Array} file File or files to add to the queue. + * @param {String} [fileName] If specified, will be used as a name for the file + */ + addFile : function(file, fileName) { + var self = this + , queue = [] + , filesAdded = [] + , ruid + ; + + function filterFile(file, cb) { + var queue = []; + plupload.each(self.settings.filters, function(rule, name) { + if (fileFilters[name]) { + queue.push(function(cb) { + fileFilters[name].call(self, rule, file, function(res) { + cb(!res); + }); + }); + } + }); + plupload.inSeries(queue, cb); + } + + /** + * @method resolveFile + * @private + * @param {moxie.file.File|moxie.file.Blob|plupload.File|File|Blob|input[type="file"]} file + */ + function resolveFile(file) { + var type = plupload.typeOf(file); + + // moxie.file.File + if (file instanceof o.file.File) { + if (!file.ruid && !file.isDetached()) { + if (!ruid) { // weird case + return false; + } + file.ruid = ruid; + file.connectRuntime(ruid); + } + resolveFile(new plupload.File(file)); + } + // moxie.file.Blob + else if (file instanceof o.file.Blob) { + resolveFile(file.getSource()); + file.destroy(); + } + // plupload.File - final step for other branches + else if (file instanceof plupload.File) { + if (fileName) { + file.name = fileName; + } + + queue.push(function(cb) { + // run through the internal and user-defined filters, if any + filterFile(file, function(err) { + if (!err) { + // make files available for the filters by updating the main queue directly + files.push(file); + // collect the files that will be passed to FilesAdded event + filesAdded.push(file); + + self.trigger("FileFiltered", file); + } + delay(cb, 1); // do not build up recursions or eventually we might hit the limits + }); + }); + } + // native File or blob + else if (plupload.inArray(type, ['file', 'blob']) !== -1) { + resolveFile(new o.file.File(null, file)); + } + // input[type="file"] + else if (type === 'node' && plupload.typeOf(file.files) === 'filelist') { + // if we are dealing with input[type="file"] + plupload.each(file.files, resolveFile); + } + // mixed array of any supported types (see above) + else if (type === 'array') { + fileName = null; // should never happen, but unset anyway to avoid funny situations + plupload.each(file, resolveFile); + } + } + + ruid = getRUID(); + + resolveFile(file); + + if (queue.length) { + plupload.inSeries(queue, function() { + // if any files left after filtration, trigger FilesAdded + if (filesAdded.length) { + self.trigger("FilesAdded", filesAdded); + } + }); + } + }, + + /** + * Removes a specific file. + * + * @method removeFile + * @param {plupload.File|String} file File to remove from queue. + */ + removeFile : function(file) { + var id = typeof(file) === 'string' ? file : file.id; + + for (var i = files.length - 1; i >= 0; i--) { + if (files[i].id === id) { + return this.splice(i, 1)[0]; + } + } + }, + + /** + * Removes part of the queue and returns the files removed. This will also trigger the FilesRemoved and QueueChanged events. + * + * @method splice + * @param {Number} start (Optional) Start index to remove from. + * @param {Number} length (Optional) Lengh of items to remove. + * @return {Array} Array of files that was removed. + */ + splice : function(start, length) { + // Splice and trigger events + var removed = files.splice(start === undef ? 0 : start, length === undef ? files.length : length); + + // if upload is in progress we need to stop it and restart after files are removed + var restartRequired = false; + if (this.state == plupload.STARTED) { // upload in progress + plupload.each(removed, function(file) { + if (file.status === plupload.UPLOADING) { + restartRequired = true; // do not restart, unless file that is being removed is uploading + return false; + } + }); + + if (restartRequired) { + this.stop(); + } + } + + this.trigger("FilesRemoved", removed); + + // Dispose any resources allocated by those files + plupload.each(removed, function(file) { + file.destroy(); + }); + + if (restartRequired) { + this.start(); + } + + return removed; + }, + + /** + Dispatches the specified event name and its arguments to all listeners. + + @method trigger + @param {String} name Event name to fire. + @param {Object..} Multiple arguments to pass along to the listener functions. + */ + + // override the parent method to match Plupload-like event logic + dispatchEvent: function(type) { + var list, args, result; + + type = type.toLowerCase(); + + list = this.hasEventListener(type); + + if (list) { + // sort event list by priority + list.sort(function(a, b) { return b.priority - a.priority; }); + + // first argument should be current plupload.Uploader instance + args = [].slice.call(arguments); + args.shift(); + args.unshift(this); + + for (var i = 0; i < list.length; i++) { + // Fire event, break chain if false is returned + if (list[i].fn.apply(list[i].scope, args) === false) { + return false; + } + } + } + return true; + }, + + /** + Check whether uploader has any listeners to the specified event. + + @method hasEventListener + @param {String} name Event name to check for. + */ + + + /** + Adds an event listener by name. + + @method bind + @param {String} name Event name to listen for. + @param {function} fn Function to call ones the event gets fired. + @param {Object} [scope] Optional scope to execute the specified function in. + @param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first + */ + bind: function(name, fn, scope, priority) { + // adapt moxie EventTarget style to Plupload-like + plupload.Uploader.prototype.bind.call(this, name, fn, priority, scope); + }, + + /** + Removes the specified event listener. + + @method unbind + @param {String} name Name of event to remove. + @param {function} fn Function to remove from listener. + */ + + /** + Removes all event listeners. + + @method unbindAll + */ + + + /** + * Destroys Plupload instance and cleans after itself. + * + * @method destroy + */ + destroy : function() { + this.trigger('Destroy'); + settings = total = null; // purge these exclusively + this.unbindAll(); + } + }); +}; + +plupload.Uploader.prototype = o.core.EventTarget.instance; + +/** + * Constructs a new file instance. + * + * @class File + * @constructor + * + * @param {Object} file Object containing file properties + * @param {String} file.name Name of the file. + * @param {Number} file.size File size. + */ +plupload.File = (function() { + var filepool = {}; + + function PluploadFile(file) { + + plupload.extend(this, { + + /** + * File id this is a globally unique id for the specific file. + * + * @property id + * @type String + */ + id: plupload.guid(), + + /** + * File name for example "myfile.gif". + * + * @property name + * @type String + */ + name: file.name || file.fileName, + + /** + * File type, `e.g image/jpeg` + * + * @property type + * @type String + */ + type: file.type || '', + + /** + * File size in bytes (may change after client-side manupilation). + * + * @property size + * @type Number + */ + size: file.size || file.fileSize, + + /** + * Original file size in bytes. + * + * @property origSize + * @type Number + */ + origSize: file.size || file.fileSize, + + /** + * Number of bytes uploaded of the files total size. + * + * @property loaded + * @type Number + */ + loaded: 0, + + /** + * Number of percentage uploaded of the file. + * + * @property percent + * @type Number + */ + percent: 0, + + /** + * Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE. + * + * @property status + * @type Number + * @see plupload + */ + status: plupload.QUEUED, + + /** + * Date of last modification. + * + * @property lastModifiedDate + * @type {String} + */ + lastModifiedDate: file.lastModifiedDate || (new Date()).toLocaleString(), // Thu Aug 23 2012 19:40:00 GMT+0400 (GET) + + + /** + * Set when file becomes plupload.DONE or plupload.FAILED. Is used to calculate proper plupload.QueueProgress.bytesPerSec. + * @private + * @property completeTimestamp + * @type {Number} + */ + completeTimestamp: 0, + + /** + * Returns native window.File object, when it's available. + * + * @method getNative + * @return {window.File} or null, if plupload.File is of different origin + */ + getNative: function() { + var file = this.getSource().getSource(); + return plupload.inArray(plupload.typeOf(file), ['blob', 'file']) !== -1 ? file : null; + }, + + /** + * Returns mOxie.File - unified wrapper object that can be used across runtimes. + * + * @method getSource + * @return {mOxie.File} or null + */ + getSource: function() { + if (!filepool[this.id]) { + return null; + } + return filepool[this.id]; + }, + + /** + * Destroys plupload.File object. + * + * @method destroy + */ + destroy: function() { + var src = this.getSource(); + if (src) { + src.destroy(); + delete filepool[this.id]; + } + } + }); + + filepool[this.id] = file; + } + + return PluploadFile; +}()); + + +/** + * Constructs a queue progress. + * + * @class QueueProgress + * @constructor + */ + plupload.QueueProgress = function() { + var self = this; // Setup alias for self to reduce code size when it's compressed + + /** + * Total queue file size. + * + * @property size + * @type Number + */ + self.size = 0; + + /** + * Total bytes uploaded. + * + * @property loaded + * @type Number + */ + self.loaded = 0; + + /** + * Number of files uploaded. + * + * @property uploaded + * @type Number + */ + self.uploaded = 0; + + /** + * Number of files failed to upload. + * + * @property failed + * @type Number + */ + self.failed = 0; + + /** + * Number of files yet to be uploaded. + * + * @property queued + * @type Number + */ + self.queued = 0; + + /** + * Total percent of the uploaded bytes. + * + * @property percent + * @type Number + */ + self.percent = 0; + + /** + * Bytes uploaded per second. + * + * @property bytesPerSec + * @type Number + */ + self.bytesPerSec = 0; + + /** + * Resets the progress to its initial values. + * + * @method reset + */ + self.reset = function() { + self.size = self.loaded = self.uploaded = self.failed = self.queued = self.percent = self.bytesPerSec = 0; + }; +}; + +exports.plupload = plupload; + +}(this, moxie)); + +})); \ No newline at end of file diff --git a/static/js/uploader/qiniu.js b/static/js/uploader/qiniu.js new file mode 100644 index 00000000..1f959b2f --- /dev/null +++ b/static/js/uploader/qiniu.js @@ -0,0 +1,1831 @@ +/*! + * qiniu-js-sdk v@VERSION + * + * Copyright 2015 by Qiniu + * Released under GPL V2 License. + * + * GitHub: http://github.com/qiniu/js-sdk + * + * Date: @DATE +*/ +/*! + * + * Rebuild By Aaron@2018 + * +*/ +/*global plupload ,mOxie*/ +/*global ActiveXObject */ +/*exported Qiniu */ +/*exported QiniuJsSDK */ + +function getCookieByString(cookieName){ + var start = document.cookie.indexOf(cookieName+'='); + if (start == -1) return false; + start = start+cookieName.length+1; + var end = document.cookie.indexOf(';', start); + if (end == -1) end=document.cookie.length; + return document.cookie.substring(start, end); +} +;(function( global ){ + +/** + * Creates new cookie or removes cookie with negative expiration + * @param key The key or identifier for the store + * @param value Contents of the store + * @param exp Expiration - creation defaults to 30 days + */ +function createCookie(key, value, exp) { + var date = new Date(); + date.setTime(date.getTime() + (exp * 24 * 60 * 60 * 1000)); + var expires = "; expires=" + date.toGMTString(); + document.cookie = key + "=" + value + expires + "; path=/"; +} + +/** + * Returns contents of cookie + * @param key The key or identifier for the store + */ +function readCookie(key) { + var nameEQ = key + "="; + var ca = document.cookie.split(';'); + for (var i = 0, max = ca.length; i < max; i++) { + var c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEQ) === 0) { + return c.substring(nameEQ.length, c.length); + } + } + return null; +} + +// if current browser is not support localStorage +// use cookie to make a polyfill +if ( !window.localStorage ) { + window.localStorage = { + setItem: function (key, value) { + createCookie(key, value, 30); + }, + getItem: function (key) { + return readCookie(key); + }, + removeItem: function (key) { + createCookie(key, '', -1); + } + }; +} + +function QiniuJsSDK() { + + var that = this; + + /** + * detect IE version + * if current browser is not IE + * it will return false + * else + * it will return version of current IE browser + * @return {Number|Boolean} IE version or false + */ + this.detectIEVersion = function() { + var v = 4, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( + div.innerHTML = '', + all[0] + ) { + v++; + } + return v > 4 ? v : false; + }; + + var logger = { + MUTE: 0, + FATA: 1, + ERROR: 2, + WARN: 3, + INFO: 4, + DEBUG: 5, + TRACE: 6, + level: 0 + }; + + function log(type, args){ + var header = "[Cloudreve-uploader]["+type+"]"; + var msg = header; + for (var i = 0; i < args.length; i++) { + if (typeof args[i] === "string") { + msg += " " + args[i]; + } else { + msg += " " + that.stringifyJSON(args[i]); + } + } + if (that.detectIEVersion()) { + // http://stackoverflow.com/questions/5538972/console-log-apply-not-working-in-ie9 + //var log = Function.prototype.bind.call(console.log, console); + //log.apply(console, args); + console.log(msg); + }else{ + args.unshift(header); + console.log.apply(console, args); + } + if (document.getElementById('qiniu-js-sdk-log')) { + document.getElementById('qiniu-js-sdk-log').innerHTML += '

'+msg+'

'; + } + } + + function makeLogFunc(code){ + var func = code.toLowerCase(); + logger[func] = function(){ + // logger[func].history = logger[func].history || []; + // logger[func].history.push(arguments); + if(window.console && window.console.log && logger.level>=logger[code]){ + var args = Array.prototype.slice.call(arguments); + log(func,args); + } + }; + } + + for (var property in logger){ + if (logger.hasOwnProperty(property) && (typeof logger[property]) === "number" && !logger.hasOwnProperty(property.toLowerCase())) { + makeLogFunc(property); + } + } + + + var qiniuUploadUrl; + + + /** + * qiniu upload urls + * 'qiniuUploadUrls' is used to change target when current url is not avaliable + * @type {Array} + */ + if(uploadConfig.saveType == "qiniu"){ + if (window.location.protocol === 'https:') { + qiniuUploadUrl = 'https://up.qbox.me'; + } else { + qiniuUploadUrl = 'http://upload.qiniu.com'; + } + var qiniuUploadUrls = [ + "http://upload.qiniu.com", + "http://up.qiniu.com" + ]; + + var qiniuUpHosts = { + "http": [ + "http://upload.qiniu.com", + "http://up.qiniu.com" + ], + "https": [ + "https://up.qbox.me" + ] + }; +}else if(uploadConfig.saveType == "local" || uploadConfig.saveType == "oss" ||uploadConfig.saveType == "upyun"||uploadConfig.saveType == "s3"|| uploadConfig.saveType == "remote"||uploadConfig.saveType == "onedrive"){ + qiniuUploadUrl = uploadConfig.upUrl; + var qiniuUploadUrls = [uploadConfig.upUrl,]; + var qiniuUpHosts = { + "http": [uploadConfig.upUrl,], + "https": [uploadConfig.upUrl,] + } +} + + var changeUrlTimes = 0; + + /** + * reset upload url + * if current page protocal is https + * it will always return 'https://up.qbox.me' + * else + * it will set 'qiniuUploadUrl' value with 'qiniuUploadUrls' looply + */ + this.resetUploadUrl = function(){ + var hosts = window.location.protocol === 'https:' ? qiniuUpHosts.https : qiniuUpHosts.http; + var i = changeUrlTimes % hosts.length; + qiniuUploadUrl = hosts[i]; + changeUrlTimes++; + logger.debug('resetUploadUrl: '+qiniuUploadUrl); + }; + + // this.resetUploadUrl(); + + + /** + * is image + * @param {String} url of a file + * @return {Boolean} file is a image or not + */ + this.isImage = function(url) { + url = url.split(/[?#]/)[0]; + return (/\.(png|jpg|jpeg|gif|bmp)$/i).test(url); + }; + + /** + * get file extension + * @param {String} filename + * @return {String} file extension + * @example + * input: test.txt + * output: txt + */ + this.getFileExtension = function(filename) { + var tempArr = filename.split("."); + var ext; + if (tempArr.length === 1 || (tempArr[0] === "" && tempArr.length === 2)) { + ext = ""; + } else { + ext = tempArr.pop().toLowerCase(); //get the extension and make it lower-case + } + return ext; + }; + + /** + * encode string by utf8 + * @param {String} string to encode + * @return {String} encoded string + */ + this.utf8_encode = function(argString) { + // http://kevin.vanzonneveld.net + // + original by: Webtoolkit.info (http://www.webtoolkit.info/) + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: sowberry + // + tweaked by: Jack + // + bugfixed by: Onno Marsman + // + improved by: Yves Sucaet + // + bugfixed by: Onno Marsman + // + bugfixed by: Ulrich + // + bugfixed by: Rafal Kukawski + // + improved by: kirilloid + // + bugfixed by: kirilloid + // * example 1: this.utf8_encode('Kevin van Zonneveld'); + // * returns 1: 'Kevin van Zonneveld' + + if (argString === null || typeof argString === 'undefined') { + return ''; + } + + var string = (argString + ''); // .replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + var utftext = '', + start, end, stringl = 0; + + start = end = 0; + stringl = string.length; + for (var n = 0; n < stringl; n++) { + var c1 = string.charCodeAt(n); + var enc = null; + + if (c1 < 128) { + end++; + } else if (c1 > 127 && c1 < 2048) { + enc = String.fromCharCode( + (c1 >> 6) | 192, (c1 & 63) | 128 + ); + } else if (c1 & 0xF800 ^ 0xD800 > 0) { + enc = String.fromCharCode( + (c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128 + ); + } else { // surrogate pairs + if (c1 & 0xFC00 ^ 0xD800 > 0) { + throw new RangeError('Unmatched trail surrogate at ' + n); + } + var c2 = string.charCodeAt(++n); + if (c2 & 0xFC00 ^ 0xDC00 > 0) { + throw new RangeError('Unmatched lead surrogate at ' + (n - 1)); + } + c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000; + enc = String.fromCharCode( + (c1 >> 18) | 240, ((c1 >> 12) & 63) | 128, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128 + ); + } + if (enc !== null) { + if (end > start) { + utftext += string.slice(start, end); + } + utftext += enc; + start = end = n + 1; + } + } + + if (end > start) { + utftext += string.slice(start, stringl); + } + + return utftext; + }; + + this.base64_decode = function (data) { + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Thunder.m + // + input by: Aman Gupta + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Onno Marsman + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Brett Zamir (http://brett-zamir.me) + // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); + // * returns 1: 'Kevin van Zonneveld' + // mozilla has this native + // - but breaks in 2.0.0.12! + //if (typeof this.window['atob'] == 'function') { + // return atob(data); + //} + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + dec = "", + tmp_arr = []; + + if (!data) { + return data; + } + + data += ''; + + do { // unpack four hexets into three octets using index points in b64 + h1 = b64.indexOf(data.charAt(i++)); + h2 = b64.indexOf(data.charAt(i++)); + h3 = b64.indexOf(data.charAt(i++)); + h4 = b64.indexOf(data.charAt(i++)); + + bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; + + o1 = bits >> 16 & 0xff; + o2 = bits >> 8 & 0xff; + o3 = bits & 0xff; + + if (h3 === 64) { + tmp_arr[ac++] = String.fromCharCode(o1); + } else if (h4 === 64) { + tmp_arr[ac++] = String.fromCharCode(o1, o2); + } else { + tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); + } + } while (i < data.length); + + dec = tmp_arr.join(''); + + return dec; + }; + + /** + * encode data by base64 + * @param {String} data to encode + * @return {String} encoded data + */ + this.base64_encode = function(data) { + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Bayron Guevara + // + improved by: Thunder.m + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // - depends on: this.utf8_encode + // * example 1: this.base64_encode('Kevin van Zonneveld'); + // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' + // mozilla has this native + // - but breaks in 2.0.0.12! + //if (typeof this.window['atob'] == 'function') { + // return atob(data); + //} + var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + enc = '', + tmp_arr = []; + + if (!data) { + return data; + } + + data = this.utf8_encode(data + ''); + + do { // pack three octets into four hexets + o1 = data.charCodeAt(i++); + o2 = data.charCodeAt(i++); + o3 = data.charCodeAt(i++); + + bits = o1 << 16 | o2 << 8 | o3; + + h1 = bits >> 18 & 0x3f; + h2 = bits >> 12 & 0x3f; + h3 = bits >> 6 & 0x3f; + h4 = bits & 0x3f; + + // use hexets to index into b64, and append result to encoded string + tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); + } while (i < data.length); + + enc = tmp_arr.join(''); + + switch (data.length % 3) { + case 1: + enc = enc.slice(0, -2) + '=='; + break; + case 2: + enc = enc.slice(0, -1) + '='; + break; + } + + return enc; + }; + + /** + * encode string in url by base64 + * @param {String} string in url + * @return {String} encoded string + */ + this.URLSafeBase64Encode = function(v) { + v = this.base64_encode(v); + return v.replace(/\//g, '_').replace(/\+/g, '-'); + }; + + this.URLSafeBase64Decode = function(v) { + v = v.replace(/_/g, '/').replace(/-/g, '+'); + return this.base64_decode(v); + }; + + // TODO: use mOxie + /** + * craete object used to AJAX + * @return {Object} + */ + this.createAjax = function(argument) { + var xmlhttp = {}; + if (window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + return xmlhttp; + }; + + // TODO: enhance IE compatibility + /** + * parse json string to javascript object + * @param {String} json string + * @return {Object} object + */ + this.parseJSON = function(data) { + // Attempt to parse using the native JSON parser first + if (window.JSON && window.JSON.parse) { + return window.JSON.parse(data); + } + + //var rx_one = /^[\],:{}\s]*$/, + // rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + // rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + // rx_four = /(?:^|:|,)(?:\s*\[)+/g, + var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + + //var json; + + var text = String(data); + rx_dangerous.lastIndex = 0; + if(rx_dangerous.test(text)){ + text = text.replace(rx_dangerous, function(a){ + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + + // todo 使用一下判断,增加安全性 + //if ( + // rx_one.test( + // text + // .replace(rx_two, '@') + // .replace(rx_three, ']') + // .replace(rx_four, '') + // ) + //) { + // return eval('(' + text + ')'); + //} + + return eval('('+text+')'); + }; + + /** + * parse javascript object to json string + * @param {Object} object + * @return {String} json string + */ + this.stringifyJSON = function(obj) { + // Attempt to parse using the native JSON parser first + if (window.JSON && window.JSON.stringify) { + return window.JSON.stringify(obj); + } + switch (typeof (obj)) { + case 'string': + return '"' + obj.replace(/(["\\])/g, '\\$1') + '"'; + case 'array': + return '[' + obj.map(that.stringifyJSON).join(',') + ']'; + case 'object': + if (obj instanceof Array) { + var strArr = []; + var len = obj.length; + for (var i = 0; i < len; i++) { + strArr.push(that.stringifyJSON(obj[i])); + } + return '[' + strArr.join(',') + ']'; + } else if (obj === null) { + return 'null'; + } else { + var string = []; + for (var property in obj) { + if (obj.hasOwnProperty(property)) { + string.push(that.stringifyJSON(property) + ':' + that.stringifyJSON(obj[property])); + } + } + return '{' + string.join(',') + '}'; + } + break; + case 'number': + return obj; + case false: + return obj; + case 'boolean': + return obj; + } + }; + + /** + * trim space beside text + * @param {String} untrimed string + * @return {String} trimed string + */ + this.trim = function(text) { + return text === null ? "" : text.replace(/^\s+|\s+$/g, ''); + }; + + /** + * create a uploader by QiniuJsSDK + * @param {object} options to create a new uploader + * @return {object} uploader + */ + this.uploader = function(op) { + + /********** inner function define start **********/ + + // according the different condition to reset chunk size + // and the upload strategy according with the chunk size + // when chunk size is zero will cause to direct upload + // see the statement binded on 'BeforeUpload' event + var reset_chunk_size = function() { + var ie = that.detectIEVersion(); + var BLOCK_BITS, MAX_CHUNK_SIZE, chunk_size; + // case Safari 5、Windows 7、iOS 7 set isSpecialSafari to true + var isSpecialSafari = (moxie.core.utils.Env.browser === "Safari" && moxie.core.utils.Env.version <= 5 && moxie.core.utils.Env.os === "Windows" && moxie.core.utils.Env.osVersion === "7") || (moxie.core.utils.Env.browser === "Safari" && moxie.core.utils.Env.os === "iOS" && moxie.core.utils.Env.osVersion === "7"); + // case IE 9-,chunk_size is not empty and flash is included in runtimes + // set op.chunk_size to zero + //if (ie && ie < 9 && op.chunk_size && op.runtimes.indexOf('flash') >= 0) { + if (ie && ie < 9 && op.chunk_size && op.runtimes.indexOf('flash') >= 0) { + // link: http://www.plupload.com/docs/Frequently-Asked-Questions#when-to-use-chunking-and-when-not + // when plupload chunk_size setting is't null ,it cause bug in ie8/9 which runs flash runtimes (not support html5) . + op.chunk_size = 0; + } else if (isSpecialSafari) { + // win7 safari / iOS7 safari have bug when in chunk upload mode + // reset chunk_size to 0 + // disable chunk in special version safari + op.chunk_size = 0; + } else { + BLOCK_BITS = 20; + MAX_CHUNK_SIZE = 4 << BLOCK_BITS; //4M + + chunk_size = plupload.parseSize(op.chunk_size); + if (chunk_size > MAX_CHUNK_SIZE) { + op.chunk_size = MAX_CHUNK_SIZE; + } + // qiniu service max_chunk_size is 4m + // reset chunk_size to max_chunk_size(4m) when chunk_size > 4m + } + // if op.chunk_size set 0 will be cause to direct upload + }; + + var getHosts = function(hosts) { + var result = []; + for (var i = 0; i < hosts.length; i++) { + var host = hosts[i]; + if (host.indexOf('-H') === 0) { + result.push(host.split(' ')[2]); + } else { + result.push(host); + } + } + return result; + }; + + var getPutPolicy = function (uptoken) { + if(uploadConfig.saveType =="oss" || uploadConfig.saveType =="upyun"||uploadConfig.saveType =="s3"||uploadConfig.saveType =="remote"){ + return "oss"; + }else{ + var segments = uptoken.split(":"); + var ak = segments[0]; + var putPolicy = that.parseJSON(that.URLSafeBase64Decode(segments[2])); + putPolicy.ak = ak; + if (putPolicy.scope.indexOf(":") >= 0) { + putPolicy.bucket = putPolicy.scope.split(":")[0]; + putPolicy.key = putPolicy.scope.split(":")[1]; + } else { + putPolicy.bucket = putPolicy.scope; + } + return putPolicy; + } + }; + + var getUpHosts = function(uptoken) { + var putPolicy = getPutPolicy(uptoken); + // var uphosts_url = "//uc.qbox.me/v1/query?ak="+ak+"&bucket="+putPolicy.scope; + // IE 9- is not support protocal relative url + var uphosts_url = window.location.protocol + "//uc.qbox.me/v1/query?ak=" + putPolicy.ak + "&bucket=" + putPolicy.bucket; + logger.debug("putPolicy: ", putPolicy); + logger.debug("get uphosts from: ", uphosts_url); + var ie = that.detectIEVersion(); + var ajax; + if (ie && ie <= 9) { + ajax = new moxie.XMLHttpRequest(); + moxie.core.utils.Env.swf_url = op.flash_swf_url; + }else{ + ajax = that.createAjax(); + } + if(uploadConfig.saveType != "qiniu"){ + qiniuUpHosts.http = [uploadConfig.upUrl]; + qiniuUpHosts.http = [uploadConfig.upUrl]; + that.resetUploadUrl(); + }else{ + ajax.open('GET', uphosts_url, false); + var onreadystatechange = function(){ + logger.debug("ajax.readyState: ", ajax.readyState); + if (ajax.readyState === 4) { + logger.debug("ajax.status: ", ajax.status); + if (ajax.status < 400) { + var res = that.parseJSON(ajax.responseText); + qiniuUpHosts.http = getHosts(res.http.up); + qiniuUpHosts.https = getHosts(res.https.up); + logger.debug("get new uphosts: ", qiniuUpHosts); + that.resetUploadUrl(); + } else { + logger.error("get uphosts error: ", ajax.responseText); + } + } + }; + if (ie && ie <= 9) { + ajax.bind('readystatechange', onreadystatechange); + }else{ + ajax.onreadystatechange = onreadystatechange; + } + ajax.send(); + // ajax.send(); + // if (ajax.status < 400) { + // var res = that.parseJSON(ajax.responseText); + // qiniuUpHosts.http = getHosts(res.http.up); + // qiniuUpHosts.https = getHosts(res.https.up); + // logger.debug("get new uphosts: ", qiniuUpHosts); + // that.resetUploadUrl(); + // } else { + // logger.error("get uphosts error: ", ajax.responseText); + // } + } + return; + }; + + var getUptoken = function(file) { + if(uploadConfig.saveType == "remote"){ + return that.token; + } + if (!that.token || (op.uptoken_url && that.tokenInfo.isExpired())) { + return getNewUpToken(file); + } else { + return that.token; + } + }; + + // getNewUptoken maybe called at Init Event or BeforeUpload Event + // case Init Event, the file param of getUptken will be set a null value + // if op.uptoken has value, set uptoken with op.uptoken + // else if op.uptoken_url has value, set uptoken from op.uptoken_url + // else if op.uptoken_func has value, set uptoken by result of op.uptoken_func + var getNewUpToken = function(file) { + if (op.uptoken) { + that.token = op.uptoken; + } else if (op.uptoken_url) { + logger.debug("get uptoken from: ", that.uptoken_url); + // TODO: use mOxie + var ajax = that.createAjax(); + ajax.open('GET', that.uptoken_url, false); + ajax.setRequestHeader("If-Modified-Since", "0"); + // ajax.onreadystatechange = function() { + // if (ajax.readyState === 4 && ajax.status === 200) { + // var res = that.parseJSON(ajax.responseText); + // that.token = res.uptoken; + // } + // }; + ajax.send(); + if (ajax.status === 200) { + var res = that.parseJSON(ajax.responseText); + that.token = res.uptoken; + if (uploadConfig.saveType == "oss"){ + var putPolicy = that.token; + that.sign = res.sign; + that.access = res.id; + that.file_name = res.key; + that.callback = res.callback; + }else if(uploadConfig.saveType == "s3"){ + var putPolicy = that.token; + that.sign = res.sign; + that.policy = res.policy; + that.file_name = res.key; + that.credential = res.credential; + that.x_amz_date = res.x_amz_date; + that.surl = res.siteUrl; + that.callbackKey = res.callBackKey; + }else if(uploadConfig.saveType == "upyun"){ + var putPolicy = that.token; + that.token = res.token; + that.policy = res.policy; + }else if(uploadConfig.saveType == "remote"){ + var putPolicy = that.token; + that.policy = res.uptoken; + }else{ + var segments = that.token.split(":"); + var putPolicy = that.parseJSON(that.URLSafeBase64Decode(segments[2])); + if (!that.tokenMap) { + that.tokenMap = {}; + } + var getTimestamp = function(time) { + return Math.ceil(time.getTime()/1000); + }; + var serverTime = getTimestamp(new Date(ajax.getResponseHeader("date"))); + var clientTime = getTimestamp(new Date()); + that.tokenInfo = { + serverDelay: clientTime - serverTime, + deadline: putPolicy.deadline, + isExpired: function() { + var leftTime = this.deadline - getTimestamp(new Date()) + this.serverDelay; + return leftTime < 600; + } + }; + logger.debug("get token info: ", that.tokenInfo); + } + + logger.debug("get new uptoken: ", that.token); + + } else { + logger.error("get uptoken error: ", ajax.responseText); + } + } else if (op.uptoken_func) { + logger.debug("get uptoken from uptoken_func"); + that.token = op.uptoken_func(file); + logger.debug("get new uptoken: ", that.token); + } else { + logger.error("one of [uptoken, uptoken_url, uptoken_func] settings in options is required!"); + } + if (that.token) { + getUpHosts(that.token); + } + return that.token; + }; + + // get file key according with the user passed options + var getFileKey = function(up, file, func) { + // WARNING + // When you set the key in putPolicy by "scope": "bucket:key" + // You should understand the risk of override a file in the bucket + // So the code below that automatically get key from uptoken has been commented + // var putPolicy = getPutPolicy(that.token) + // if (putPolicy.key) { + // logger.debug("key is defined in putPolicy.scope: ", putPolicy.key) + // return putPolicy.key + // } + var key = '', + unique_names = false; + if (!op.save_key) { + unique_names = up.getOption && up.getOption('unique_names'); + unique_names = unique_names || (up.settings && up.settings.unique_names); + if (unique_names) { + var ext = that.getFileExtension(file.name); + key = ext ? file.id + '.' + ext : file.id; + } else if (typeof func === 'function') { + key = func(up, file); + } else { + key = file.name; + } + } + if(uploadConfig.saveType == "qiniu"){ + return ""; + } + return key; + }; + + /********** inner function define end **********/ + + if (op.log_level) { + logger.level = op.log_level; + } + + if (!op.domain) { + throw 'domain setting in options is required!'; + } + + if (!op.browse_button) { + throw 'browse_button setting in options is required!'; + } + + if (!op.uptoken && !op.uptoken_url && !op.uptoken_func) { + throw 'one of [uptoken, uptoken_url, uptoken_func] settings in options is required!'; + } + + logger.debug("init uploader start"); + + logger.debug("environment: ", moxie.core.utils.Env); + + logger.debug("userAgent: ", navigator.userAgent); + + var option = {}; + + // hold the handler from user passed options + var _Error_Handler = op.init && op.init.Error; + var _FileUploaded_Handler = op.init && op.init.FileUploaded; + + // replace the handler for intercept + op.init.Error = function() {}; + op.init.FileUploaded = function() {}; + + that.uptoken_url = op.uptoken_url; + that.token = ''; + that.key_handler = typeof op.init.Key === 'function' ? op.init.Key : ''; + this.domain = op.domain; + // TODO: ctx is global in scope of a uploader instance + // this maybe cause error + var ctx = ''; + var speedCalInfo = { + isResumeUpload: false, + resumeFilesize: 0, + startTime: '', + currentTime: '' + }; + + reset_chunk_size(); + logger.debug("invoke reset_chunk_size()"); + logger.debug("op.chunk_size: ", op.chunk_size); + + var defaultSetting = { + url: qiniuUploadUrl, + multipart_params: { + token: '' + } + }; + var ie = that.detectIEVersion(); + // case IE 9- + // add accept in multipart params + if (ie && ie <= 9) { + defaultSetting.multipart_params.accept = 'text/plain; charset=utf-8'; + logger.debug("add accept text/plain in multipart params"); + } + + // compose options with user passed options and default setting + plupload.extend(option, op, defaultSetting); + + logger.debug("option: ", option); + + // create a new uploader with composed options + var uploader = new plupload.Uploader(option); + + logger.debug("new plupload.Uploader(option)"); + + // bind getNewUpToken to 'Init' event + uploader.bind('Init', function(up, params) { + logger.debug("Init event activated"); + // if op.get_new_uptoken is not true + // invoke getNewUptoken when uploader init + // else + // getNewUptoken everytime before a new file upload + if(!op.get_new_uptoken){ + getNewUpToken(null); + } + //getNewUpToken(null); + }); + + logger.debug("bind Init event"); + + // bind 'FilesAdded' event + // when file be added and auto_start has set value + // uploader will auto start upload the file + uploader.bind('FilesAdded', function(up, files) { + logger.debug("FilesAdded event activated"); + var auto_start = up.getOption && up.getOption('auto_start'); + auto_start = auto_start || (up.settings && up.settings.auto_start); + logger.debug("auto_start: ", auto_start); + logger.debug("files: ", files); + + + for (var i = 0; i < files.length; i++) { + var file = files[i]; + file.path = decodeURIComponent(getCookieByString("path_tmp")); + + } + + // detect is iOS + var is_ios = function (){ + if(moxie.core.utils.Env.OS.toLowerCase()==="ios") { + return true; + } else { + return false; + } + }; + + // if current env os is iOS change file name to [time].[ext] + if (is_ios()) { + for (var i = 0; i < files.length; i++) { + var file = files[i]; + var ext = that.getFileExtension(file.name); + file.name = file.id + "." + ext; + } + } + + if (auto_start) { + setTimeout(function(){ + up.start(); + logger.debug("invoke up.start()"); + }, 0); + // up.start(); + // plupload.each(files, function(i, file) { + // up.start(); + // logger.debug("invoke up.start()") + // logger.debug("file: ", file); + // }); + } + up.refresh(); // Reposition Flash/Silverlight + }); + + logger.debug("bind FilesAdded event"); + + // bind 'BeforeUpload' event + // intercept the process of upload + // - prepare uptoken + // - according the chunk size to make differnt upload strategy + // - resume upload with the last breakpoint of file + uploader.bind('BeforeUpload', function(up, file) { + logger.debug("BeforeUpload event activated"); + getNewUpToken(file); + // add a key named speed for file object + file.speed = file.speed || 0; + ctx = ''; + + var directUpload = function(up, file, func) { + speedCalInfo.startTime = new Date().getTime(); + + + + var multipart_params_obj; + if (op.save_key) { + multipart_params_obj = { + 'token': that.token + }; + } else { + multipart_params_obj = { + 'key': getFileKey(up, file, func), + 'token': that.token + }; + if(uploadConfig.saveType == "qiniu"){ + multipart_params_obj = { + 'token': that.token, + 'x:path': file.path + }; + }else if(uploadConfig.saveType == "local"||uploadConfig.saveType == "onedrive"){ + multipart_params_obj = { + 'path': file.path + }; + }else if(uploadConfig.saveType == "remote"){ + multipart_params_obj = { + 'path': file.path, + "token" :that.policy, + "MAX_FILE_SIZE":4194304, + }; + }else if(uploadConfig.saveType == "oss"){ + multipart_params_obj = { + 'policy': that.token, + 'x:path': file.path, + "signature":that.sign, + "OSSAccessKeyId":that.access, + 'x:fname':file.name, + "key" :that.file_name.replace("${filename}", file.name), + "callback":that.callback, + }; + }else if(uploadConfig.saveType == "s3"){ + multipart_params_obj = { + 'policy': that.policy, + "key" :that.file_name+"/"+(file.path.replace(",","/") == "" ? "" : file.path.replace(",","/")+"/")+file.name, + "success_action_redirect" :that.surl+"Callback/S3/key/"+that.callbackKey, + "x-amz-algorithm":"AWS4-HMAC-SHA256", + "x-amz-credential":that.credential, + "x-amz-date":that.x_amz_date, + "x-amz-signature":that.sign, + "Content-Type":file.type, + }; + }else if(uploadConfig.saveType == "upyun"){ + multipart_params_obj = { + 'authorization': that.token, + 'policy': that.policy, + }; + } + } + var ie = that.detectIEVersion(); + // case IE 9- + // add accept in multipart params + if (ie && ie <= 9) { + multipart_params_obj.accept = 'text/plain; charset=utf-8'; + logger.debug("add accept text/plain in multipart params"); + } + + logger.debug("directUpload multipart_params_obj: ", multipart_params_obj); + + var x_vars = op.x_vars; + if (x_vars !== undefined && typeof x_vars === 'object') { + for (var x_key in x_vars) { + if (x_vars.hasOwnProperty(x_key)) { + if (typeof x_vars[x_key] === 'function') { + multipart_params_obj['x:' + x_key] = x_vars[x_key](up, file); + } else if (typeof x_vars[x_key] !== 'object') { + multipart_params_obj['x:' + x_key] = x_vars[x_key]; + } + } + } + } + + up.setOption({ + 'url': qiniuUploadUrl, + 'multipart': true, + 'chunk_size': is_android_weixin_or_qq() ? op.max_file_size : undefined, + 'multipart_params': multipart_params_obj + }); + }; + + // detect is weixin or qq inner browser + var is_android_weixin_or_qq = function (){ + var ua = navigator.userAgent.toLowerCase(); + if((ua.match(/MicroMessenger/i) || moxie.core.utils.Env.browser === "QQBrowser" || ua.match(/V1_AND_SQ/i)) && moxie.core.utils.Env.OS.toLowerCase()==="android") { + return true; + } else { + return false; + } + }; + + var chunk_size = up.getOption && up.getOption('chunk_size'); + chunk_size = chunk_size || (up.settings && up.settings.chunk_size); + + logger.debug("uploader.runtime: ",uploader.runtime); + logger.debug("chunk_size: ",chunk_size); + + // TODO: flash support chunk upload + if ((uploader.runtime === 'html5' || uploader.runtime === 'flash') && chunk_size) { + if (file.size < chunk_size || is_android_weixin_or_qq()) { + logger.debug("directUpload because file.size < chunk_size || is_android_weixin_or_qq()"); + // direct upload if file size is less then the chunk size + directUpload(up, file, that.key_handler); + } else { + // TODO: need a polifill to make it work in IE 9- + // ISSUE: if file.name is existed in localStorage + // but not the same file maybe cause error + var localFileInfo = localStorage.getItem(file.name); + var blockSize = chunk_size; + if (localFileInfo) { + // TODO: although only the html5 runtime will enter this statement + // but need uniform way to make convertion between string and json + localFileInfo = that.parseJSON(localFileInfo); + var now = (new Date()).getTime(); + var before = localFileInfo.time || 0; + var aDay = 24 * 60 * 60 * 1000; // milliseconds of one day + // if the last upload time is within one day + // will upload continuously follow the last breakpoint + // else + // will reupload entire file + if (now - before < aDay) { + + if (localFileInfo.percent !== 100) { + if (file.size === localFileInfo.total) { + // TODO: if file.name and file.size is the same + // but not the same file will cause error + file.percent = localFileInfo.percent; + file.loaded = localFileInfo.offset; + ctx = localFileInfo.ctx; + + // set speed info + speedCalInfo.isResumeUpload = true; + speedCalInfo.resumeFilesize = localFileInfo.offset; + + // set block size + if (localFileInfo.offset + blockSize > file.size) { + blockSize = file.size - localFileInfo.offset; + } + } else { + // remove file info when file.size is conflict with file info + localStorage.removeItem(file.name); + } + + } else { + // remove file info when upload percent is 100% + // avoid 499 bug + localStorage.removeItem(file.name); + } + } else { + // remove file info when last upload time is over one day + localStorage.removeItem(file.name); + } + } + speedCalInfo.startTime = new Date().getTime(); + var multipart_params_obj = {}; + var ie = that.detectIEVersion(); + // case IE 9- + // add accept in multipart params + if (ie && ie <= 9) { + multipart_params_obj.accept = 'text/plain; charset=utf-8'; + logger.debug("add accept text/plain in multipart params"); + } + // TODO: to support bput + // http://developer.qiniu.com/docs/v6/api/reference/up/bput.html + if(uploadConfig.saveType == "remote"){ + up.setOption({ + 'url': qiniuUploadUrl + 'chunk.php', + 'multipart': false, + 'chunk_size': chunk_size, + 'required_features': "chunks", + 'headers': { + 'Authorization': getUptoken(file) + }, + 'multipart_params': multipart_params_obj + }); + }else{ + up.setOption({ + 'url': qiniuUploadUrl + '/mkblk/' + blockSize, + 'multipart': false, + 'chunk_size': chunk_size, + 'required_features': "chunks", + 'headers': { + 'Authorization': 'UpToken ' + getUptoken(file) + }, + 'multipart_params': multipart_params_obj + }); + } + } + } else { + logger.debug("directUpload because uploader.runtime !== 'html5' || uploader.runtime !== 'flash' || !chunk_size"); + // direct upload if runtime is not html5 + directUpload(up, file, that.key_handler); + } + }); + + logger.debug("bind BeforeUpload event"); + + // bind 'UploadProgress' event + // calculate upload speed + uploader.bind('UploadProgress', function(up, file) { + logger.trace("UploadProgress event activated"); + speedCalInfo.currentTime = new Date().getTime(); + var timeUsed = speedCalInfo.currentTime - speedCalInfo.startTime; // ms + var fileUploaded = file.loaded || 0; + if (speedCalInfo.isResumeUpload) { + fileUploaded = file.loaded - speedCalInfo.resumeFilesize; + } + file.speed = (fileUploaded / timeUsed * 1000).toFixed(0) || 0; // unit: byte/s + }); + + logger.debug("bind UploadProgress event"); + + // bind 'ChunkUploaded' event + // store the chunk upload info and set next chunk upload url + uploader.bind('ChunkUploaded', function(up, file, info) { + logger.debug("ChunkUploaded event activated"); + logger.debug("file: ", file); + logger.debug("info: ", info); + var res = that.parseJSON(info.response); + logger.debug("res: ", res); + // ctx should look like '[chunk01_ctx],[chunk02_ctx],[chunk03_ctx],...' + ctx = ctx ? ctx + ',' + res.ctx : res.ctx; + var leftSize = info.total - info.offset; + var chunk_size = up.getOption && up.getOption('chunk_size'); + chunk_size = chunk_size || (up.settings && up.settings.chunk_size); + if (leftSize < chunk_size) { + up.setOption({ + 'url': qiniuUploadUrl + '/mkblk/' + leftSize + }); + if(uploadConfig.saveType == "remote"){ + up.setOption({ + 'url': qiniuUploadUrl + 'chunk.php' + }); + } + logger.debug("up.setOption url: ", qiniuUploadUrl + '/mkblk/' + leftSize); + } + if(uploadConfig.saveType == "remote"){ + up.setOption({ + 'headers': { + 'Authorization': getUptoken(file) + } + }); + }else{ + up.setOption({ + 'headers': { + 'Authorization': 'UpToken ' + getUptoken(file) + } + }); + } + localStorage.setItem(file.name, that.stringifyJSON({ + ctx: ctx, + percent: file.percent, + total: info.total, + offset: info.offset, + time: (new Date()).getTime() + })); + }); + + logger.debug("bind ChunkUploaded event"); + + var retries = qiniuUploadUrls.length; + + // if error is unkown switch upload url and retry + var unknow_error_retry = function(file){ + if (retries-- > 0) { + setTimeout(function(){ + that.resetUploadUrl(); + file.status = plupload.QUEUED; + uploader.stop(); + uploader.start(); + }, 0); + return true; + }else{ + retries = qiniuUploadUrls.length; + return false; + } + }; + + // bind 'Error' event + // check the err.code and return the errTip + uploader.bind('Error', (function(_Error_Handler) { + return function(up, err) { + logger.error("Error event activated"); + logger.error("err: ", err); + var errTip = ''; + var file = err.file; + if (file) { + switch (err.code) { + case plupload.FAILED: + errTip = '上传失败。请稍后再试。'; + break; + case plupload.FILE_SIZE_ERROR: + var max_file_size = up.getOption && up.getOption('max_file_size'); + max_file_size = max_file_size || (up.settings && up.settings.max_file_size); + errTip = '文件过大,您当前用户组最多可上传' + max_file_size + '的文件'; + break; + case plupload.FILE_EXTENSION_ERROR: + errTip = '您当前的用户组不可上传此文件'; + break; + case plupload.HTTP_ERROR: + if (err.response === '') { + // Fix parseJSON error ,when http error is like net::ERR_ADDRESS_UNREACHABLE + errTip = err.message || '未知网络错误。'; + if (!unknow_error_retry(file)) { + return; + } + break; + } + if(uploadConfig.saveType == "oss"){ + var str = err.response + var a = $.parseXML(str); + $(a).find('Error').each(function () { + errTip = $(this).children('Message').text(); + var errorText = "Error"; + }); + if(err.status == 203){ + errTip = "上传失败,请检查空间容量、是否重名"; + } + }else if(uploadConfig.saveType == "s3" && err.status!=401){ + var str = err.response + var a = $.parseXML(str); + $(a).find('Error').each(function () { + errTip = $(this).children('Message').text(); + var errorText = "Error"; + }); + }else{ + var errorObj = that.parseJSON(err.response); + var errorText = errorObj.error; + if (err.status==579){ + var errorObj2 = that.parseJSON(errorText); + errorText=errorObj2.error; + } + switch (err.status) { + case 400: + errTip = "请求报文格式错误。"; + break; + case 401: + errTip = "客户端认证授权失败。请重试或提交反馈。"; + break; + case 405: + errTip = "客户端请求错误。请重试或提交反馈。"; + break; + case 579: + errTip = "资源上传成功,但回调失败。"; + break; + case 599: + errTip = "网络连接异常。请重试或提交反馈。"; + if (!unknow_error_retry(file)) { + return; + } + break; + case 614: + errTip = "文件已存在。"; + try { + errorObj = that.parseJSON(errorObj.error); + errorText = errorObj.error || 'file exists'; + } catch (e) { + errorText = errorObj.error || 'file exists'; + } + break; + case 631: + errTip = "指定空间不存在。"; + break; + case 701: + errTip = "上传数据块校验出错。请重试或提交反馈。"; + break; + default: + errTip = "未知错误。"; + if (!unknow_error_retry(file)) { + return; + } + break; + } + + } + errTip = errTip + '(' + err.status + ':' + errorText + ')'; + break; + case plupload.SECURITY_ERROR: + errTip = '安全配置错误。请联系网站管理员。'; + break; + case plupload.GENERIC_ERROR: + errTip = '上传失败。请稍后再试。'; + break; + case plupload.IO_ERROR: + errTip = '上传失败。请稍后再试。'; + break; + case plupload.INIT_ERROR: + errTip = '网站配置错误。请联系网站管理员。'; + uploader.destroy(); + break; + default: + errTip = err.message + err.details; + if (!unknow_error_retry(file)) { + return; + } + break; + } + if (_Error_Handler) { + _Error_Handler(up, err, errTip); + } + } + up.refresh(); // Reposition Flash/Silverlight + }; + })(_Error_Handler)); + + logger.debug("bind Error event"); + + // bind 'FileUploaded' event + // intercept the complete of upload + // - get downtoken from downtoken_url if bucket is private + // - invoke mkfile api to compose chunks if upload strategy is chunk upload + uploader.bind('FileUploaded', (function(_FileUploaded_Handler) { + return function(up, file, info) { + logger.debug("FileUploaded event activated"); + logger.debug("file: ", file); + logger.debug("info: ", info); + if(uploadConfig.saveType == "s3"){ + } + var last_step = function(up, file, info) { + if (op.downtoken_url) { + // if op.dowontoken_url is not empty + // need get downtoken before invoke the _FileUploaded_Handler + var ajax_downtoken = that.createAjax(); + ajax_downtoken.open('POST', op.downtoken_url, true); + ajax_downtoken.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + ajax_downtoken.onreadystatechange = function() { + if (ajax_downtoken.readyState === 4) { + + if (ajax_downtoken.status === 200 || ajax_downtoken.status === 204||ajax_downtoken.status === 303) { + + var res_downtoken; + try { + res_downtoken = that.parseJSON(ajax_downtoken.responseText); + } catch (e) { + throw ('invalid json format'); + } + var info_extended = {}; + plupload.extend(info_extended, that.parseJSON(info), res_downtoken); + if (_FileUploaded_Handler) { + _FileUploaded_Handler(up, file, that.stringifyJSON(info_extended)); + } + + } else { + uploader.trigger('Error', { + status: ajax_downtoken.status, + response: ajax_downtoken.responseText, + file: file, + code: plupload.HTTP_ERROR + }); + } + } + }; + ajax_downtoken.send('key=' + that.parseJSON(info).key + '&domain=' + op.domain); + } else if (_FileUploaded_Handler) { + _FileUploaded_Handler(up, file, info); + } + }; + if(uploadConfig.saveType == "oss" || uploadConfig.saveType == "upyun"){ + ctx = 0; + }else{ + var res = that.parseJSON(info.response); + ctx = ctx ? ctx : res.ctx; + } + // if ctx is not empty + // that means the upload strategy is chunk upload + // befroe the invoke the last_step + // we need request the mkfile to compose all uploaded chunks + // else + // invalke the last_step + logger.debug("ctx: ", ctx); + if (ctx) { + var key = ''; + logger.debug("save_key: ", op.save_key); + if (!op.save_key) { + key = getFileKey(up, file, that.key_handler); + key = key ? '/key/' + that.URLSafeBase64Encode(key) : ''; + } + + var fname = '/fname/' + that.URLSafeBase64Encode(file.name); + if(uploadConfig.saveType=="remote"){ + if (!op.save_key) { + key = getFileKey(up, file, that.key_handler); + key = key ? that.URLSafeBase64Encode(key) : ''; + } + fname = '' + that.URLSafeBase64Encode(file.name); + op.x_vars= { + 'path': file.path, + }; + } + logger.debug("op.x_vars: ", op.x_vars); + if(uploadConfig.saveType == "qiniu"){ + op.x_vars= { + 'path': file.path, + }; + } + var x_vars = op.x_vars, + x_val = '', + x_vars_url = ''; + if (x_vars !== undefined && typeof x_vars === 'object') { + for (var x_key in x_vars) { + if (x_vars.hasOwnProperty(x_key)) { + if (typeof x_vars[x_key] === 'function') { + x_val = that.URLSafeBase64Encode(x_vars[x_key](up, file)); + } else if (typeof x_vars[x_key] !== 'object') { + x_val = that.URLSafeBase64Encode(x_vars[x_key]); + } + x_vars_url += '/x:' + x_key + '/' + x_val; + } + } + } + local_path = ""; + if(uploadConfig.saveType == "local"||uploadConfig.saveType == "onedrive"){ + pathTmp = file.path; + if(file.path == ""){ + pathTmp = "ROOTDIR"; + } + local_path = '/path/'+that.URLSafeBase64Encode(pathTmp); + } + if(uploadConfig.saveType == "remote"){ + pathTmp = file.path; + local_path = that.URLSafeBase64Encode(pathTmp); + var url = qiniuUploadUrl + 'mkfile.php?size=' + file.size +"&key="+ key+"&fname="+ fname +"&path="+local_path; + }else{ + var url = qiniuUploadUrl + '/mkfile/' + file.size + key + fname + x_vars_url+local_path; + } + var ie = that.detectIEVersion(); + var ajax; + if (ie && ie <= 9) { + ajax = new moxie.xhr.XMLHttpRequest(); + moxie.core.utils.Env.swf_url = op.flash_swf_url; + }else{ + ajax = that.createAjax(); + } + ajax.open('POST', url, true); + ajax.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8'); + if(uploadConfig.saveType == "remote"){ + ajax.setRequestHeader('Authorization',that.token); + }else{ + ajax.setRequestHeader('Authorization', 'UpToken ' + that.token); + } + var onreadystatechange = function(){ + logger.debug("ajax.readyState: ", ajax.readyState); + if (ajax.readyState === 4) { + localStorage.removeItem(file.name); + var info; + if (ajax.status === 200) { + info = ajax.responseText; + logger.debug("mkfile is success: ", info); + last_step(up, file, info); + } else { + info = { + status: ajax.status, + response: ajax.responseText, + file: file, + code: -200, + responseHeaders: ajax.getAllResponseHeaders() + }; + logger.debug("mkfile is error: ", info); + uploader.trigger('Error', info); + } + } + }; + if (ie && ie <= 9) { + ajax.bind('readystatechange', onreadystatechange); + }else{ + ajax.onreadystatechange = onreadystatechange; + } + ajax.send(ctx); + logger.debug("mkfile: ", url); + } else { + last_step(up, file, info.response); + } + + }; + })(_FileUploaded_Handler)); + + logger.debug("bind FileUploaded event"); + + // init uploader + uploader.init(); + + logger.debug("invoke uploader.init()"); + + logger.debug("init uploader end"); + + return uploader; + }; + + /** + * get url by key + * @param {String} key of file + * @return {String} url of file + */ + this.getUrl = function(key) { + if (!key) { + return false; + } + key = encodeURI(key); + var domain = this.domain; + if (domain.slice(domain.length - 1) !== '/') { + domain = domain + '/'; + } + return domain + key; + }; + + /** + * invoke the imageView2 api of Qiniu + * @param {Object} api params + * @param {String} key of file + * @return {String} url of processed image + */ + this.imageView2 = function(op, key) { + + if (!/^\d$/.test(op.mode)) { + return false; + } + + var mode = op.mode, + w = op.w || '', + h = op.h || '', + q = op.q || '', + format = op.format || ''; + + if (!w && !h) { + return false; + } + + var imageUrl = 'imageView2/' + mode; + imageUrl += w ? '/w/' + w : ''; + imageUrl += h ? '/h/' + h : ''; + imageUrl += q ? '/q/' + q : ''; + imageUrl += format ? '/format/' + format : ''; + if (key) { + imageUrl = this.getUrl(key) + '?' + imageUrl; + } + return imageUrl; + }; + + /** + * invoke the imageMogr2 api of Qiniu + * @param {Object} api params + * @param {String} key of file + * @return {String} url of processed image + */ + this.imageMogr2 = function(op, key) { + var auto_orient = op['auto-orient'] || '', + thumbnail = op.thumbnail || '', + strip = op.strip || '', + gravity = op.gravity || '', + crop = op.crop || '', + quality = op.quality || '', + rotate = op.rotate || '', + format = op.format || '', + blur = op.blur || ''; + //Todo check option + + var imageUrl = 'imageMogr2'; + + imageUrl += auto_orient ? '/auto-orient' : ''; + imageUrl += thumbnail ? '/thumbnail/' + thumbnail : ''; + imageUrl += strip ? '/strip' : ''; + imageUrl += gravity ? '/gravity/' + gravity : ''; + imageUrl += quality ? '/quality/' + quality : ''; + imageUrl += crop ? '/crop/' + crop : ''; + imageUrl += rotate ? '/rotate/' + rotate : ''; + imageUrl += format ? '/format/' + format : ''; + imageUrl += blur ? '/blur/' + blur : ''; + + if (key) { + imageUrl = this.getUrl(key) + '?' + imageUrl; + } + return imageUrl; + }; + + /** + * invoke the watermark api of Qiniu + * @param {Object} api params + * @param {String} key of file + * @return {String} url of processed image + */ + this.watermark = function(op, key) { + var mode = op.mode; + if (!mode) { + return false; + } + + var imageUrl = 'watermark/' + mode; + + if (mode === 1) { + var image = op.image || ''; + if (!image) { + return false; + } + imageUrl += image ? '/image/' + this.URLSafeBase64Encode(image) : ''; + } else if (mode === 2) { + var text = op.text ? op.text : '', + font = op.font ? op.font : '', + fontsize = op.fontsize ? op.fontsize : '', + fill = op.fill ? op.fill : ''; + if (!text) { + return false; + } + imageUrl += text ? '/text/' + this.URLSafeBase64Encode(text) : ''; + imageUrl += font ? '/font/' + this.URLSafeBase64Encode(font) : ''; + imageUrl += fontsize ? '/fontsize/' + fontsize : ''; + imageUrl += fill ? '/fill/' + this.URLSafeBase64Encode(fill) : ''; + } else { + // Todo mode3 + return false; + } + + var dissolve = op.dissolve || '', + gravity = op.gravity || '', + dx = op.dx || '', + dy = op.dy || ''; + + imageUrl += dissolve ? '/dissolve/' + dissolve : ''; + imageUrl += gravity ? '/gravity/' + gravity : ''; + imageUrl += dx ? '/dx/' + dx : ''; + imageUrl += dy ? '/dy/' + dy : ''; + + if (key) { + imageUrl = this.getUrl(key) + '?' + imageUrl; + } + return imageUrl; + }; + + /** + * invoke the imageInfo api of Qiniu + * @param {String} key of file + * @return {Object} image info + */ + this.imageInfo = function(key) { + if (!key) { + return false; + } + var url = this.getUrl(key) + '?imageInfo'; + var xhr = this.createAjax(); + var info; + var that = this; + xhr.open('GET', url, false); + xhr.onreadystatechange = function() { + if (xhr.readyState === 4 && xhr.status === 200) { + info = that.parseJSON(xhr.responseText); + } + }; + xhr.send(); + return info; + }; + + /** + * invoke the exif api of Qiniu + * @param {String} key of file + * @return {Object} image exif + */ + this.exif = function(key) { + if (!key) { + return false; + } + var url = this.getUrl(key) + '?exif'; + var xhr = this.createAjax(); + var info; + var that = this; + xhr.open('GET', url, false); + xhr.onreadystatechange = function() { + if (xhr.readyState === 4 && xhr.status === 200) { + info = that.parseJSON(xhr.responseText); + } + }; + xhr.send(); + return info; + }; + + /** + * invoke the exif or imageInfo api of Qiniu + * according with type param + * @param {String} ['exif'|'imageInfo']type of info + * @param {String} key of file + * @return {Object} image exif or info + */ + this.get = function(type, key) { + if (!key || !type) { + return false; + } + if (type === 'exif') { + return this.exif(key); + } else if (type === 'imageInfo') { + return this.imageInfo(key); + } + return false; + }; + + /** + * invoke api of Qiniu like a pipeline + * @param {Array of Object} params of a series api call + * each object in array is options of api which name is set as 'fop' property + * each api's output will be next api's input + * @param {String} key of file + * @return {String|Boolean} url of processed image + */ + this.pipeline = function(arr, key) { + var isArray = Object.prototype.toString.call(arr) === '[object Array]'; + var option, errOp, imageUrl = ''; + if (isArray) { + for (var i = 0, len = arr.length; i < len; i++) { + option = arr[i]; + if (!option.fop) { + return false; + } + switch (option.fop) { + case 'watermark': + imageUrl += this.watermark(option) + '|'; + break; + case 'imageView2': + imageUrl += this.imageView2(option) + '|'; + break; + case 'imageMogr2': + imageUrl += this.imageMogr2(option) + '|'; + break; + default: + errOp = true; + break; + } + if (errOp) { + return false; + } + } + if (key) { + imageUrl = this.getUrl(key) + '?' + imageUrl; + var length = imageUrl.length; + if (imageUrl.slice(length - 1) === '|') { + imageUrl = imageUrl.slice(0, length - 1); + } + } + return imageUrl; + } + return false; + }; +} + +var Qiniu = new QiniuJsSDK(); + +global.Qiniu = Qiniu; + +global.QiniuJsSDK = QiniuJsSDK; + +})( window ); \ No newline at end of file diff --git a/static/js/uploader/ui.js b/static/js/uploader/ui.js new file mode 100644 index 00000000..9f78b446 --- /dev/null +++ b/static/js/uploader/ui.js @@ -0,0 +1,278 @@ +/*global plupload */ +/*global qiniu */ +function FileProgress(file, targetID) { + this.fileProgressID = file.id; + this.file = file; + + this.opacity = 100; + this.height = 0; + this.fileProgressWrapper = $('#' + this.fileProgressID); + if (!this.fileProgressWrapper.length) { + //
+ //
+ // 20% Complete + //
+ //
+ + this.fileProgressWrapper = $(''); + var Wrappeer = this.fileProgressWrapper; + Wrappeer.attr('id', this.fileProgressID).addClass('progressContainer'); + + var progressText = $(""); + progressText.addClass('progressName').text(file.name); + + + var fileSize = plupload.formatSize(file.size).toUpperCase(); + var progressSize = $(""); + progressSize.addClass("progressFileSize").text(fileSize); + + var progressBarTd = $(""); + var progressBarBox = $("
"); + progressBarBox.addClass('info'); + var progressBarWrapper = $("
"); + progressBarWrapper.addClass("progress progress-striped"); + + var progressBar = $("
"); + progressBar.addClass("progress-bar progress-bar-info") + .attr('role', 'progressbar') + .attr('aria-valuemax', 100) + .attr('aria-valuenow', 0) + .attr('aria-valuein', 0) + .width('0%'); + + var progressBarPercent = $(''); + progressBarPercent.text(fileSize); + + var progressCancel = $(''); + progressCancel.show().addClass('progressCancel').text('×'); + + progressBar.append(progressBarPercent); + progressBarWrapper.append(progressBar); + progressBarBox.append(progressBarWrapper); + progressText.append(progressCancel); + + var progressBarStatus = $('
'); + progressBarBox.append(progressBarStatus); + progressBarTd.append(progressBarBox); + + Wrappeer.append(progressText); + Wrappeer.append(progressSize); + Wrappeer.append(progressBarTd); + + $('#' + targetID).append(Wrappeer); + } else { + this.reset(); + } + + this.height = this.fileProgressWrapper.offset().top; + this.setTimer(null); +} + +FileProgress.prototype.setTimer = function(timer) { + this.fileProgressWrapper.FP_TIMER = timer; +}; + +FileProgress.prototype.getTimer = function(timer) { + return this.fileProgressWrapper.FP_TIMER || null; +}; + +FileProgress.prototype.reset = function() { + this.fileProgressWrapper.attr('class', "progressContainer"); + this.fileProgressWrapper.find('td .progress .progress-bar-info').attr('aria-valuenow', 0).width('0%').find('span').text(''); + this.appear(); +}; + +FileProgress.prototype.setChunkProgess = function(chunk_size) { + var chunk_amount = Math.ceil(this.file.size / chunk_size); + if (chunk_amount === 1) { + return false; + } + + var viewProgess = $(''); + + var progressBarChunkTr = $(''); + var progressBarChunk = $('
'); + for (var i = 1; i <= chunk_amount; i++) { + var col = $('
'); + var progressBarWrapper = $('
"); + progressBar.addClass("progress-bar progress-bar-info text-left") + .attr('role', 'progressbar') + .attr('aria-valuemax', 100) + .attr('aria-valuenow', 0) + .attr('aria-valuein', 0) + .width('0%') + .attr('id', this.file.id + '_' + i) + .text(''); + + var progressBarStatus = $(''); + progressBarStatus.addClass('chunk-status').text(); + + progressBarWrapper.append(progressBar); + progressBarWrapper.append(progressBarStatus); + + col.append(progressBarWrapper); + progressBarChunk.append(col); + } + + if(!this.fileProgressWrapper.find('td:eq(2) .btn-default').length){ + this.fileProgressWrapper.find('td>div').append(viewProgess); + } + progressBarChunkTr.hide().find('td').append(progressBarChunk); + progressBarChunkTr.insertAfter(this.fileProgressWrapper); + +}; + +FileProgress.prototype.setProgress = function(percentage, speed, chunk_size) { + this.fileProgressWrapper.attr('class', "progressContainer green"); + + var file = this.file; + var uploaded = file.loaded; + + var size = plupload.formatSize(uploaded).toUpperCase(); + var formatSpeed = plupload.formatSize(speed).toUpperCase(); + var progressbar = this.fileProgressWrapper.find('td .progress').find('.progress-bar-info'); + if (this.fileProgressWrapper.find('.status').text() === '取消上传'){ + return; + } + this.fileProgressWrapper.find('.status').text("已上传: " + size + " 上传速度: " + formatSpeed + "/s"); + percentage = parseInt(percentage, 10); + if (file.status !== plupload.DONE && percentage === 100) { + percentage = 99; + } + + progressbar.attr('aria-valuenow', percentage).css('width', percentage + '%'); + + if (chunk_size) { + var chunk_amount = Math.ceil(file.size / chunk_size); + if (chunk_amount === 1) { + return false; + } + var current_uploading_chunk = Math.ceil(uploaded / chunk_size); + var pre_chunk, text; + + for (var index = 0; index < current_uploading_chunk; index++) { + pre_chunk = $('#' + file.id + "_" + index); + pre_chunk.width('100%').removeClass().addClass('alert alert-success').attr('aria-valuenow', 100); + text = "块" + index + "上传进度100%"; + pre_chunk.next().html(text); + } + + var currentProgessBar = $('#' + file.id + "_" + current_uploading_chunk); + var current_chunk_percent; + if (current_uploading_chunk < chunk_amount) { + if (uploaded % chunk_size) { + current_chunk_percent = ((uploaded % chunk_size) / chunk_size * 100).toFixed(2); + } else { + current_chunk_percent = 100; + currentProgessBar.removeClass().addClass('alert alert-success'); + } + } else { + var last_chunk_size = file.size - chunk_size * (chunk_amount - 1); + var left_file_size = file.size - uploaded; + if (left_file_size % last_chunk_size) { + current_chunk_percent = ((uploaded % chunk_size) / last_chunk_size * 100).toFixed(2); + } else { + current_chunk_percent = 100; + currentProgessBar.removeClass().addClass('alert alert-success'); + } + } + currentProgessBar.width(current_chunk_percent + '%'); + currentProgessBar.attr('aria-valuenow', current_chunk_percent); + text = "块" + current_uploading_chunk + "上传进度" + current_chunk_percent + '%'; + currentProgessBar.next().html(text); + } + + this.appear(); +}; + +FileProgress.prototype.setComplete = function(up, info) { + var td = this.fileProgressWrapper.find('td:eq(2)'), + tdProgress = td.find('.progress'); + + var res; + var url; + if(uploadConfig.saveType == "oss"){ + url = "oss"; + str = "
上传成功
"; + }else{ + res = $.parseJSON(info); + if (res.url) { + url = res.url; + str = "
上传成功
"; + } else { + var domain = up.getOption('domain'); + url = domain + encodeURI(res.key); + var link = domain + res.key; + str = "
上传成功
"; + } + } + + tdProgress.html(str).removeClass().next().next('.status').hide(); + this.fileProgressWrapper.find('td:eq(0) .progressCancel').hide(); + td.find('.status').hide(); + angular.element(document.querySelector('angular-filemanager > div')).scope().fileNavigator.refresh(); +}; +FileProgress.prototype.setError = function() { + this.fileProgressWrapper.find('td:eq(2)').attr('class', 'text-warning'); + this.fileProgressWrapper.find('td:eq(2) .progress').css('width', 0).hide(); + this.fileProgressWrapper.find('button').hide(); + this.fileProgressWrapper.next('.chunk-status-tr').hide(); +}; + +FileProgress.prototype.setCancelled = function(manual) { + var progressContainer = 'progressContainer'; + if (!manual) { + progressContainer += ' red'; + } + this.fileProgressWrapper.attr('class', progressContainer); + this.fileProgressWrapper.find('td .progress').remove(); + this.fileProgressWrapper.find('td:eq(2) .btn-default').hide(); + this.fileProgressWrapper.find('td:eq(0) .progressCancel').hide(); +}; + +FileProgress.prototype.setStatus = function(status, isUploading) { + if (!isUploading) { + this.fileProgressWrapper.find('.status').text(status).attr('class', 'status text-left'); + } +}; + +// 绑定取消上传事件 +FileProgress.prototype.bindUploadCancel = function(up) { + var self = this; + if (up) { + self.fileProgressWrapper.find('td:eq(0) .progressCancel').on('click', function(){ + self.setCancelled(false); + self.setStatus("取消上传"); + self.fileProgressWrapper.find('.status').css('left', '0'); + up.removeFile(self.file); + }); + } + +}; + +FileProgress.prototype.appear = function() { + if (this.getTimer() !== null) { + clearTimeout(this.getTimer()); + this.setTimer(null); + } + + if (this.fileProgressWrapper[0].filters) { + try { + this.fileProgressWrapper[0].filters.item("DXImageTransform.Microsoft.Alpha").opacity = 100; + } catch (e) { + // If it is not set initially, the browser will throw an error. This will set it if it is not set yet. + this.fileProgressWrapper.css('filter', "progid:DXImageTransform.Microsoft.Alpha(opacity=100)"); + } + } else { + this.fileProgressWrapper.css('opacity', 1); + } + + this.fileProgressWrapper.css('height', ''); + + this.height = this.fileProgressWrapper.offset().top; + this.opacity = 100; + this.fileProgressWrapper.show(); + +}; diff --git a/thinkphp/.gitignore b/thinkphp/.gitignore new file mode 100644 index 00000000..7e31ef51 --- /dev/null +++ b/thinkphp/.gitignore @@ -0,0 +1,4 @@ +/composer.lock +/vendor +.idea +.DS_Store diff --git a/thinkphp/CONTRIBUTING.md b/thinkphp/CONTRIBUTING.md index 6cefcb38..dc8e91cd 100644 --- a/thinkphp/CONTRIBUTING.md +++ b/thinkphp/CONTRIBUTING.md @@ -7,7 +7,7 @@ ThinkPHP 目前使用 Git 来控制程序版本,如果你想为 ThinkPHP 贡献源代码,请先大致了解 Git 的使用方法。我们目前把项目托管在 GitHub 上,任何 GitHub 用户都可以向我们贡献代码。 -参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请并。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。 +参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。 我们希望你贡献的代码符合: @@ -60,7 +60,7 @@ GitHub 提供了 Issue 功能,该功能可以用于: 6. 变基(衍合 `rebase`)你的分支到上游 master 分支; 7. `push` 你的本地仓库到 GitHub; 8. 提交 `pull request`; -9. 等待 CI 验证(若不通过则重复 5~7,GitHub 会自动更新你的 `pull request`); +9. 等待 CI 验证(若不通过则重复 5~7,不需要重新提交 `pull request`,GitHub 会自动更新你的 `pull request`); 10. 等待管理员处理,并及时 `rebase` 你的分支到上游 master 分支(若上游 master 分支有修改)。 *若有必要,可以 `git push -f` 强行推送 rebase 后的分支到自己的 `fork`* diff --git a/thinkphp/LICENSE.txt b/thinkphp/LICENSE.txt index 574a39c4..2cb9a8a9 100644 --- a/thinkphp/LICENSE.txt +++ b/thinkphp/LICENSE.txt @@ -1,6 +1,6 @@ ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 -版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) +版权所有Copyright © 2006-2017 by ThinkPHP (http://thinkphp.cn) All rights reserved。 ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 diff --git a/thinkphp/README.md b/thinkphp/README.md new file mode 100644 index 00000000..f01fd2b9 --- /dev/null +++ b/thinkphp/README.md @@ -0,0 +1,114 @@ +ThinkPHP 5.0 +=============== + +[![StyleCI](https://styleci.io/repos/48530411/shield?style=flat&branch=master)](https://styleci.io/repos/48530411) +[![Build Status](https://travis-ci.org/top-think/framework.svg?branch=master)](https://travis-ci.org/top-think/framework) +[![codecov.io](http://codecov.io/github/top-think/framework/coverage.svg?branch=master)](http://codecov.io/github/github/top-think/framework?branch=master) +[![Total Downloads](https://poser.pugx.org/topthink/framework/downloads)](https://packagist.org/packages/topthink/framework) +[![Latest Stable Version](https://poser.pugx.org/topthink/framework/v/stable)](https://packagist.org/packages/topthink/framework) +[![Latest Unstable Version](https://poser.pugx.org/topthink/framework/v/unstable)](https://packagist.org/packages/topthink/framework) +[![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework) + +ThinkPHP5在保持快速开发和大道至简的核心理念不变的同时,PHP版本要求提升到5.4,优化核心,减少依赖,基于全新的架构思想和命名空间实现,是ThinkPHP突破原有框架思路的颠覆之作,其主要特性包括: + + + 基于命名空间和众多PHP新特性 + + 核心功能组件化 + + 强化路由功能 + + 更灵活的控制器 + + 重构的模型和数据库类 + + 配置文件可分离 + + 重写的自动验证和完成 + + 简化扩展机制 + + API支持完善 + + 改进的Log类 + + 命令行访问支持 + + REST支持 + + 引导文件支持 + + 方便的自动生成定义 + + 真正惰性加载 + + 分布式环境支持 + + 支持Composer + + 支持MongoDb + +> ThinkPHP5的运行环境要求PHP5.4以上。 + +详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5) 以及[ThinkPHP5入门系列教程](http://www.kancloud.cn/special/thinkphp5_quickstart) + +## 目录结构 + +初始的目录结构如下: + +~~~ +www WEB部署目录(或者子目录) +├─application 应用目录 +│ ├─common 公共模块目录(可以更改) +│ ├─module_name 模块目录 +│ │ ├─config.php 模块配置文件 +│ │ ├─common.php 模块函数文件 +│ │ ├─controller 控制器目录 +│ │ ├─model 模型目录 +│ │ ├─view 视图目录 +│ │ └─ ... 更多类库目录 +│ │ +│ ├─command.php 命令行工具配置文件 +│ ├─common.php 公共函数文件 +│ ├─config.php 公共配置文件 +│ ├─route.php 路由配置文件 +│ ├─tags.php 应用行为扩展定义文件 +│ └─database.php 数据库配置文件 +│ +├─public WEB目录(对外访问目录) +│ ├─index.php 入口文件 +│ ├─router.php 快速测试文件 +│ └─.htaccess 用于apache的重写 +│ +├─thinkphp 框架系统目录 +│ ├─lang 语言文件目录 +│ ├─library 框架类库目录 +│ │ ├─think Think类库包目录 +│ │ └─traits 系统Trait目录 +│ │ +│ ├─tpl 系统模板目录 +│ ├─base.php 基础定义文件 +│ ├─console.php 控制台入口文件 +│ ├─convention.php 框架惯例配置文件 +│ ├─helper.php 助手函数文件 +│ ├─phpunit.xml phpunit配置文件 +│ └─start.php 框架入口文件 +│ +├─extend 扩展类库目录 +├─runtime 应用的运行时目录(可写,可定制) +├─vendor 第三方类库目录(Composer依赖库) +├─build.php 自动生成定义文件(参考) +├─composer.json composer 定义文件 +├─LICENSE.txt 授权说明文件 +├─README.md README 文件 +├─think 命令行入口文件 +~~~ + +> router.php用于php自带webserver支持,可用于快速测试 +> 切换到public目录后,启动命令:php -S localhost:8888 router.php +> 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。 + +## 命名规范 + +ThinkPHP5的命名规范遵循`PSR-2`规范以及`PSR-4`自动加载规范。 + +## 参与开发 +注册并登录 Github 帐号, fork 本项目并进行改动。 + +更多细节参阅 [CONTRIBUTING.md](CONTRIBUTING.md) + +## 版权信息 + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 + +本项目包含的第三方源码和二进制文件之版权信息另行标注。 + +版权所有Copyright © 2006-2018 by ThinkPHP (http://thinkphp.cn) + +All rights reserved。 + +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +更多细节参阅 [LICENSE.txt](LICENSE.txt) diff --git a/thinkphp/base.php b/thinkphp/base.php index 9744f01d..92c4fa55 100644 --- a/thinkphp/base.php +++ b/thinkphp/base.php @@ -2,14 +2,14 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: liu21st // +---------------------------------------------------------------------- -define('THINK_VERSION', '5.0.9'); +define('THINK_VERSION', '5.0.24'); define('THINK_START_TIME', microtime(true)); define('THINK_START_MEM', memory_get_usage()); define('EXT', '.php'); @@ -40,8 +40,10 @@ require CORE_PATH . 'Loader.php'; // 加载环境变量配置文件 if (is_file(ROOT_PATH . '.env')) { $env = parse_ini_file(ROOT_PATH . '.env', true); + foreach ($env as $key => $val) { $name = ENV_PREFIX . strtoupper($key); + if (is_array($val)) { foreach ($val as $k => $v) { $item = $name . '_' . strtoupper($k); diff --git a/thinkphp/convention.php b/thinkphp/convention.php index 801c90a8..31a0a0c1 100644 --- a/thinkphp/convention.php +++ b/thinkphp/convention.php @@ -7,7 +7,7 @@ return [ // 默认Host地址 'app_host' => '', // 应用调试模式 - 'app_debug' => true, + 'app_debug' => false, // 应用Trace 'app_trace' => false, // 应用模式状态 @@ -74,6 +74,8 @@ return [ 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], // pathinfo分隔符 'pathinfo_depr' => '/', + // HTTPS代理标识 + 'https_agent_name' => '', // URL伪静态后缀 'url_html_suffix' => 'html', // URL普通方式参数 用于自动生成 @@ -114,6 +116,8 @@ return [ // +---------------------------------------------------------------------- 'template' => [ + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 + 'auto_rule' => 1, // 模板引擎类型 支持 php think 支持扩展 'type' => 'Think', // 视图基础目录,配置目录为所有模块的视图起始目录 @@ -153,6 +157,8 @@ return [ 'show_error_msg' => false, // 异常处理handle类 留空使用 \think\exception\Handle 'exception_handle' => '', + // 是否记录trace信息到日志 + 'record_trace' => false, // +---------------------------------------------------------------------- // | 日志设置 @@ -282,4 +288,11 @@ return [ 'list_rows' => 15, ], + //控制台配置 + 'console' => [ + 'name' => 'Think Console', + 'version' => '0.1', + 'user' => null, + ], + ]; diff --git a/thinkphp/helper.php b/thinkphp/helper.php index a23b6794..12683cfd 100644 --- a/thinkphp/helper.php +++ b/thinkphp/helper.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -127,7 +127,7 @@ if (!function_exists('input')) { if ($pos = strpos($key, '.')) { // 指定参数来源 list($method, $key) = explode('.', $key, 2); - if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) { + if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) { $key = $method . '.' . $key; $method = 'param'; } diff --git a/thinkphp/lang/zh-cn.php b/thinkphp/lang/zh-cn.php index c6c5a50f..eb7a9142 100644 --- a/thinkphp/lang/zh-cn.php +++ b/thinkphp/lang/zh-cn.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -12,57 +12,125 @@ // 核心中文语言包 return [ // 系统错误提示 - 'Undefined variable' => '未定义变量', - 'Undefined index' => '未定义数组索引', - 'Undefined offset' => '未定义数组下标', - 'Parse error' => '语法解析错误', - 'Type error' => '类型错误', - 'Fatal error' => '致命错误', - 'syntax error' => '语法错误', + 'Undefined variable' => '未定义变量', + 'Undefined index' => '未定义数组索引', + 'Undefined offset' => '未定义数组下标', + 'Parse error' => '语法解析错误', + 'Type error' => '类型错误', + 'Fatal error' => '致命错误', + 'syntax error' => '语法错误', // 框架核心错误提示 - 'dispatch type not support' => '不支持的调度类型', - 'method param miss' => '方法参数错误', - 'method not exists' => '方法不存在', - 'module not exists' => '模块不存在', - 'controller not exists' => '控制器不存在', - 'class not exists' => '类不存在', - 'property not exists' => '类的属性不存在', - 'template not exists' => '模板文件不存在', - 'illegal controller name' => '非法的控制器名称', - 'illegal action name' => '非法的操作名称', - 'url suffix deny' => '禁止的URL后缀访问', - 'Route Not Found' => '当前访问路由未定义', - 'Underfined db type' => '未定义数据库类型', - 'variable type error' => '变量类型错误', - 'PSR-4 error' => 'PSR-4 规范错误', - 'not support total' => '简洁模式下不能获取数据总数', - 'not support last' => '简洁模式下不能获取最后一页', - 'error session handler' => '错误的SESSION处理器类', - 'not allow php tag' => '模板不允许使用PHP语法', - 'not support' => '不支持', - 'redisd master' => 'Redisd 主服务器错误', - 'redisd slave' => 'Redisd 从服务器错误', - 'must run at sae' => '必须在SAE运行', - 'memcache init error' => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务', - 'KVDB init error' => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务', - 'fields not exists' => '数据表字段不存在', - 'where express error' => '查询表达式错误', - 'no data to update' => '没有任何数据需要更新', - 'miss data to insert' => '缺少需要写入的数据', - 'miss complex primary data' => '缺少复合主键数据', - 'miss update condition' => '缺少更新条件', - 'model data Not Found' => '模型数据不存在', - 'table data not Found' => '表数据不存在', - 'delete without condition' => '没有条件不会执行删除操作', - 'miss relation data' => '缺少关联表数据', - 'tag attr must' => '模板标签属性必须', - 'tag error' => '模板标签错误', - 'cache write error' => '缓存写入失败', - 'sae mc write error' => 'SAE mc 写入错误', - 'route name not exists' => '路由标识不存在(或参数不够)', - 'invalid request' => '非法请求', - 'bind attr has exists' => '模型的属性已经存在', - 'relation data not exists' => '关联数据不存在', - 'relation not support' => '关联不支持', + 'dispatch type not support' => '不支持的调度类型', + 'method param miss' => '方法参数错误', + 'method not exists' => '方法不存在', + 'module not exists' => '模块不存在', + 'controller not exists' => '控制器不存在', + 'class not exists' => '类不存在', + 'property not exists' => '类的属性不存在', + 'template not exists' => '模板文件不存在', + 'illegal controller name' => '非法的控制器名称', + 'illegal action name' => '非法的操作名称', + 'url suffix deny' => '禁止的URL后缀访问', + 'Route Not Found' => '当前访问路由未定义', + 'Undefined db type' => '未定义数据库类型', + 'variable type error' => '变量类型错误', + 'PSR-4 error' => 'PSR-4 规范错误', + 'not support total' => '简洁模式下不能获取数据总数', + 'not support last' => '简洁模式下不能获取最后一页', + 'error session handler' => '错误的SESSION处理器类', + 'not allow php tag' => '模板不允许使用PHP语法', + 'not support' => '不支持', + 'redisd master' => 'Redisd 主服务器错误', + 'redisd slave' => 'Redisd 从服务器错误', + 'must run at sae' => '必须在SAE运行', + 'memcache init error' => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务', + 'KVDB init error' => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务', + 'fields not exists' => '数据表字段不存在', + 'where express error' => '查询表达式错误', + 'not support data' => '不支持的数据表达式', + 'no data to update' => '没有任何数据需要更新', + 'miss data to insert' => '缺少需要写入的数据', + 'miss complex primary data' => '缺少复合主键数据', + 'miss update condition' => '缺少更新条件', + 'model data Not Found' => '模型数据不存在', + 'table data not Found' => '表数据不存在', + 'delete without condition' => '没有条件不会执行删除操作', + 'miss relation data' => '缺少关联表数据', + 'tag attr must' => '模板标签属性必须', + 'tag error' => '模板标签错误', + 'cache write error' => '缓存写入失败', + 'sae mc write error' => 'SAE mc 写入错误', + 'route name not exists' => '路由标识不存在(或参数不够)', + 'invalid request' => '非法请求', + 'bind attr has exists' => '模型的属性已经存在', + 'relation data not exists' => '关联数据不存在', + 'relation not support' => '关联不支持', + 'chunk not support order' => 'Chunk不支持调用order方法', + 'closure not support cache(true)' => '使用闭包查询不支持cache(true),请指定缓存Key', + + // 上传错误信息 + 'unknown upload error' => '未知上传错误!', + 'file write error' => '文件写入失败!', + 'upload temp dir not found' => '找不到临时文件夹!', + 'no file to uploaded' => '没有文件被上传!', + 'only the portion of file is uploaded' => '文件只有部分被上传!', + 'upload File size exceeds the maximum value' => '上传文件大小超过了最大值!', + 'upload write error' => '文件上传保存错误!', + 'has the same filename: {:filename}' => '存在同名文件:{:filename}', + 'upload illegal files' => '非法上传文件', + 'illegal image files' => '非法图片文件', + 'extensions to upload is not allowed' => '上传文件后缀不允许', + 'mimetype to upload is not allowed' => '上传文件MIME类型不允许!', + 'filesize not match' => '上传文件大小不符!', + 'directory {:path} creation failed' => '目录 {:path} 创建失败!', + + // Validate Error Message + ':attribute require' => ':attribute不能为空', + ':attribute must be numeric' => ':attribute必须是数字', + ':attribute must be integer' => ':attribute必须是整数', + ':attribute must be float' => ':attribute必须是浮点数', + ':attribute must be bool' => ':attribute必须是布尔值', + ':attribute not a valid email address' => ':attribute格式不符', + ':attribute not a valid mobile' => ':attribute格式不符', + ':attribute must be a array' => ':attribute必须是数组', + ':attribute must be yes,on or 1' => ':attribute必须是yes、on或者1', + ':attribute not a valid datetime' => ':attribute不是一个有效的日期或时间格式', + ':attribute not a valid file' => ':attribute不是有效的上传文件', + ':attribute not a valid image' => ':attribute不是有效的图像文件', + ':attribute must be alpha' => ':attribute只能是字母', + ':attribute must be alpha-numeric' => ':attribute只能是字母和数字', + ':attribute must be alpha-numeric, dash, underscore' => ':attribute只能是字母、数字和下划线_及破折号-', + ':attribute not a valid domain or ip' => ':attribute不是有效的域名或者IP', + ':attribute must be chinese' => ':attribute只能是汉字', + ':attribute must be chinese or alpha' => ':attribute只能是汉字、字母', + ':attribute must be chinese,alpha-numeric' => ':attribute只能是汉字、字母和数字', + ':attribute must be chinese,alpha-numeric,underscore, dash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', + ':attribute not a valid url' => ':attribute不是有效的URL地址', + ':attribute not a valid ip' => ':attribute不是有效的IP地址', + ':attribute must be dateFormat of :rule' => ':attribute必须使用日期格式 :rule', + ':attribute must be in :rule' => ':attribute必须在 :rule 范围内', + ':attribute be notin :rule' => ':attribute不能在 :rule 范围内', + ':attribute must between :1 - :2' => ':attribute只能在 :1 - :2 之间', + ':attribute not between :1 - :2' => ':attribute不能在 :1 - :2 之间', + 'size of :attribute must be :rule' => ':attribute长度不符合要求 :rule', + 'max size of :attribute must be :rule' => ':attribute长度不能超过 :rule', + 'min size of :attribute must be :rule' => ':attribute长度不能小于 :rule', + ':attribute cannot be less than :rule' => ':attribute日期不能小于 :rule', + ':attribute cannot exceed :rule' => ':attribute日期不能超过 :rule', + ':attribute not within :rule' => '不在有效期内 :rule', + 'access IP is not allowed' => '不允许的IP访问', + 'access IP denied' => '禁止的IP访问', + ':attribute out of accord with :2' => ':attribute和确认字段:2不一致', + ':attribute cannot be same with :2' => ':attribute和比较字段:2不能相同', + ':attribute must greater than or equal :rule' => ':attribute必须大于等于 :rule', + ':attribute must greater than :rule' => ':attribute必须大于 :rule', + ':attribute must less than or equal :rule' => ':attribute必须小于等于 :rule', + ':attribute must less than :rule' => ':attribute必须小于 :rule', + ':attribute must equal :rule' => ':attribute必须等于 :rule', + ':attribute has exists' => ':attribute已存在', + ':attribute not conform to the rules' => ':attribute不符合指定规则', + 'invalid Request method' => '无效的请求类型', + 'invalid token' => '令牌数据无效', + 'not conform to the rules' => '规则错误', ]; diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php index 7b27a15d..f572b907 100644 --- a/thinkphp/library/think/App.php +++ b/thinkphp/library/think/App.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -11,13 +11,14 @@ namespace think; +use think\exception\ClassNotFoundException; use think\exception\HttpException; use think\exception\HttpResponseException; use think\exception\RouteNotFoundException; /** * App 应用管理 - * @author liu21st + * @author liu21st */ class App { @@ -56,24 +57,32 @@ class App */ protected static $routeMust; + /** + * @var array 请求调度分发 + */ protected static $dispatch; + + /** + * @var array 额外加载文件 + */ protected static $file = []; /** * 执行应用程序 * @access public - * @param Request $request Request对象 + * @param Request $request 请求对象 * @return Response * @throws Exception */ public static function run(Request $request = null) { - is_null($request) && $request = Request::instance(); + $request = is_null($request) ? Request::instance() : $request; try { $config = self::initCommon(); + + // 模块/控制器绑定 if (defined('BIND_MODULE')) { - // 模块/控制器绑定 BIND_MODULE && Route::bind(BIND_MODULE); } elseif ($config['auto_bind_module']) { // 入口自动绑定 @@ -87,10 +96,8 @@ class App // 默认语言 Lang::range($config['default_lang']); - if ($config['lang_switch_on']) { - // 开启多语言机制 检测当前语言 - Lang::detect(); - } + // 开启多语言机制 检测当前语言 + $config['lang_switch_on'] && Lang::detect(); $request->langset(Lang::range()); // 加载系统语言包 @@ -99,12 +106,16 @@ class App APP_PATH . 'lang' . DS . $request->langset() . EXT, ]); + // 监听 app_dispatch + Hook::listen('app_dispatch', self::$dispatch); // 获取应用调度信息 $dispatch = self::$dispatch; + + // 未设置调度信息则进行 URL 路由检测 if (empty($dispatch)) { - // 进行URL路由检测 $dispatch = self::routeCheck($request, $config); } + // 记录当前调度信息 $request->dispatch($dispatch); @@ -115,10 +126,15 @@ class App Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info'); } - // 监听app_begin + // 监听 app_begin Hook::listen('app_begin', $dispatch); + // 请求缓存检查 - $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']); + $request->cache( + $config['request_cache'], + $config['request_cache_expire'], + $config['request_cache_except'] + ); $data = self::exec($dispatch, $config); } catch (HttpResponseException $exception) { @@ -133,24 +149,151 @@ class App $response = $data; } elseif (!is_null($data)) { // 默认自动识别响应输出类型 - $isAjax = $request->isAjax(); - $type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type'); + $type = $request->isAjax() ? + Config::get('default_ajax_return') : + Config::get('default_return_type'); + $response = Response::create($data, $type); } else { $response = Response::create(); } - // 监听app_end + // 监听 app_end Hook::listen('app_end', $response); return $response; } + /** + * 初始化应用,并返回配置信息 + * @access public + * @return array + */ + public static function initCommon() + { + if (empty(self::$init)) { + if (defined('APP_NAMESPACE')) { + self::$namespace = APP_NAMESPACE; + } + + Loader::addNamespace(self::$namespace, APP_PATH); + + // 初始化应用 + $config = self::init(); + self::$suffix = $config['class_suffix']; + + // 应用调试模式 + self::$debug = Env::get('app_debug', Config::get('app_debug')); + + if (!self::$debug) { + ini_set('display_errors', 'Off'); + } elseif (!IS_CLI) { + // 重新申请一块比较大的 buffer + if (ob_get_level() > 0) { + $output = ob_get_clean(); + } + + ob_start(); + + if (!empty($output)) { + echo $output; + } + + } + + if (!empty($config['root_namespace'])) { + Loader::addNamespace($config['root_namespace']); + } + + // 加载额外文件 + if (!empty($config['extra_file_list'])) { + foreach ($config['extra_file_list'] as $file) { + $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; + if (is_file($file) && !isset(self::$file[$file])) { + include $file; + self::$file[$file] = true; + } + } + } + + // 设置系统时区 + date_default_timezone_set($config['default_timezone']); + + // 监听 app_init + Hook::listen('app_init'); + + self::$init = true; + } + + return Config::get(); + } + + /** + * 初始化应用或模块 + * @access public + * @param string $module 模块名 + * @return array + */ + private static function init($module = '') + { + // 定位模块目录 + $module = $module ? $module . DS : ''; + + // 加载初始化文件 + if (is_file(APP_PATH . $module . 'init' . EXT)) { + include APP_PATH . $module . 'init' . EXT; + } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) { + include RUNTIME_PATH . $module . 'init' . EXT; + } else { + // 加载模块配置 + $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT); + + // 读取数据库配置文件 + $filename = CONF_PATH . $module . 'database' . CONF_EXT; + Config::load($filename, 'database'); + + // 读取扩展配置文件 + if (is_dir(CONF_PATH . $module . 'extra')) { + $dir = CONF_PATH . $module . 'extra'; + $files = scandir($dir); + foreach ($files as $file) { + if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) { + $filename = $dir . DS . $file; + Config::load($filename, pathinfo($file, PATHINFO_FILENAME)); + } + } + } + + // 加载应用状态配置 + if ($config['app_status']) { + Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT); + } + + // 加载行为扩展文件 + if (is_file(CONF_PATH . $module . 'tags' . EXT)) { + Hook::import(include CONF_PATH . $module . 'tags' . EXT); + } + + // 加载公共文件 + $path = APP_PATH . $module; + if (is_file($path . 'common' . EXT)) { + include $path . 'common' . EXT; + } + + // 加载当前模块语言包 + if ($module) { + Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT); + } + } + + return Config::get(); + } + /** * 设置当前请求的调度信息 * @access public * @param array|string $dispatch 调度信息 - * @param string $type 调度类型 + * @param string $type 调度类型 * @return void */ public static function dispatch($dispatch, $type = 'module') @@ -169,8 +312,10 @@ class App { $reflect = new \ReflectionFunction($function); $args = self::bindParams($reflect, $vars); + // 记录执行信息 self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info'); + return $reflect->invokeArgs($args); } @@ -190,28 +335,27 @@ class App // 静态方法 $reflect = new \ReflectionMethod($method); } + $args = self::bindParams($reflect, $vars); self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info'); + return $reflect->invokeArgs(isset($class) ? $class : null, $args); } /** * 调用反射执行类的实例化 支持依赖注入 * @access public - * @param string $class 类名 - * @param array $vars 变量 + * @param string $class 类名 + * @param array $vars 变量 * @return mixed */ public static function invokeClass($class, $vars = []) { $reflect = new \ReflectionClass($class); $constructor = $reflect->getConstructor(); - if ($constructor) { - $args = self::bindParams($constructor, $vars); - } else { - $args = []; - } + $args = $constructor ? self::bindParams($constructor, $vars) : []; + return $reflect->newInstanceArgs($args); } @@ -224,52 +368,58 @@ class App */ private static function bindParams($reflect, $vars = []) { + // 自动获取请求变量 if (empty($vars)) { - // 自动获取请求变量 - if (Config::get('url_param_type')) { - $vars = Request::instance()->route(); - } else { - $vars = Request::instance()->param(); - } + $vars = Config::get('url_param_type') ? + Request::instance()->route() : + Request::instance()->param(); } + $args = []; if ($reflect->getNumberOfParameters() > 0) { // 判断数组类型 数字数组时按顺序绑定参数 reset($vars); - $type = key($vars) === 0 ? 1 : 0; - $params = $reflect->getParameters(); - foreach ($params as $param) { + $type = key($vars) === 0 ? 1 : 0; + + foreach ($reflect->getParameters() as $param) { $args[] = self::getParamValue($param, $vars, $type); } } + return $args; } /** * 获取参数值 * @access private - * @param \ReflectionParameter $param - * @param array $vars 变量 - * @param string $type + * @param \ReflectionParameter $param 参数 + * @param array $vars 变量 + * @param string $type 类别 * @return array */ private static function getParamValue($param, &$vars, $type) { $name = $param->getName(); $class = $param->getClass(); + if ($class) { $className = $class->getName(); $bind = Request::instance()->$name; + if ($bind instanceof $className) { $result = $bind; } else { if (method_exists($className, 'invoke')) { $method = new \ReflectionMethod($className, 'invoke'); + if ($method->isPublic() && $method->isStatic()) { return $className::invoke(Request::instance()); } } - $result = method_exists($className, 'instance') ? $className::instance() : new $className; + + $result = method_exists($className, 'instance') ? + $className::instance() : + new $className; } } elseif (1 == $type && !empty($vars)) { $result = array_shift($vars); @@ -280,65 +430,85 @@ class App } else { throw new \InvalidArgumentException('method param miss:' . $name); } + return $result; } + /** + * 执行调用分发 + * @access protected + * @param array $dispatch 调用信息 + * @param array $config 配置信息 + * @return Response|mixed + * @throws \InvalidArgumentException + */ protected static function exec($dispatch, $config) { switch ($dispatch['type']) { - case 'redirect': - // 执行重定向跳转 - $data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']); + case 'redirect': // 重定向跳转 + $data = Response::create($dispatch['url'], 'redirect') + ->code($dispatch['status']); break; - case 'module': - // 模块/控制器/操作 - $data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null); + case 'module': // 模块/控制器/操作 + $data = self::module( + $dispatch['module'], + $config, + isset($dispatch['convert']) ? $dispatch['convert'] : null + ); break; - case 'controller': - // 执行控制器操作 + case 'controller': // 执行控制器操作 $vars = array_merge(Request::instance()->param(), $dispatch['var']); - $data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']); + $data = Loader::action( + $dispatch['controller'], + $vars, + $config['url_controller_layer'], + $config['controller_suffix'] + ); break; - case 'method': - // 执行回调方法 + case 'method': // 回调方法 $vars = array_merge(Request::instance()->param(), $dispatch['var']); $data = self::invokeMethod($dispatch['method'], $vars); break; - case 'function': - // 执行闭包 + case 'function': // 闭包 $data = self::invokeFunction($dispatch['function']); break; - case 'response': + case 'response': // Response 实例 $data = $dispatch['response']; break; default: throw new \InvalidArgumentException('dispatch type not support'); } + return $data; } /** * 执行模块 * @access public - * @param array $result 模块/控制器/操作 - * @param array $config 配置参数 + * @param array $result 模块/控制器/操作 + * @param array $config 配置参数 * @param bool $convert 是否自动转换控制器和操作名 * @return mixed + * @throws HttpException */ public static function module($result, $config, $convert = null) { if (is_string($result)) { $result = explode('/', $result); } + $request = Request::instance(); + if ($config['app_multi_module']) { // 多模块部署 $module = strip_tags(strtolower($result[0] ?: $config['default_module'])); $bind = Route::getBind('module'); $available = false; + if ($bind) { // 绑定模块 list($bindModule) = explode('/', $bind); + if (empty($result[0])) { $module = $bindModule; $available = true; @@ -354,8 +524,13 @@ class App // 初始化模块 $request->module($module); $config = self::init($module); + // 模块请求缓存检查 - $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']); + $request->cache( + $config['request_cache'], + $config['request_cache_expire'], + $config['request_cache_except'] + ); } else { throw new HttpException(404, 'module not exists:' . $module); } @@ -364,22 +539,32 @@ class App $module = ''; $request->module($module); } + + // 设置默认过滤机制 + $request->filter($config['default_filter']); + // 当前模块路径 App::$modulePath = APP_PATH . ($module ? $module . DS : ''); // 是否自动转换控制器和操作名 $convert = is_bool($convert) ? $convert : $config['url_convert']; + // 获取控制器名 $controller = strip_tags($result[1] ?: $config['default_controller']); - $controller = $convert ? strtolower($controller) : $controller; - + if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) { throw new HttpException(404, 'controller not exists:' . $controller); } - + + $controller = $convert ? strtolower($controller) : $controller; + // 获取操作名 $actionName = strip_tags($result[2] ?: $config['default_action']); - $actionName = $convert ? strtolower($actionName) : $actionName; + if (!empty($config['action_convert'])) { + $actionName = Loader::parseName($actionName, 1); + } else { + $actionName = $convert ? strtolower($actionName) : $actionName; + } // 设置当前请求的控制器、操作 $request->controller(Loader::parseName($controller, 1))->action($actionName); @@ -387,10 +572,17 @@ class App // 监听module_init Hook::listen('module_init', $request); - $instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']); - if (is_null($instance)) { - throw new HttpException(404, 'controller not exists:' . Loader::parseName($controller, 1)); + try { + $instance = Loader::controller( + $controller, + $config['url_controller_layer'], + $config['controller_suffix'], + $config['empty_controller'] + ); + } catch (ClassNotFoundException $e) { + throw new HttpException(404, 'controller not exists:' . $e->getClass()); } + // 获取当前操作名 $action = $actionName . $config['action_suffix']; @@ -398,6 +590,13 @@ class App if (is_callable([$instance, $action])) { // 执行操作方法 $call = [$instance, $action]; + // 严格获取当前操作方法名 + $reflect = new \ReflectionMethod($instance, $action); + $methodName = $reflect->getName(); + $suffix = $config['action_suffix']; + $actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName; + $request->action($actionName); + } elseif (is_callable([$instance, '_empty'])) { // 空操作 $call = [$instance, '_empty']; @@ -412,125 +611,11 @@ class App return self::invokeMethod($call, $vars); } - /** - * 初始化应用 - */ - public static function initCommon() - { - if (empty(self::$init)) { - if (defined('APP_NAMESPACE')) { - self::$namespace = APP_NAMESPACE; - } - Loader::addNamespace(self::$namespace, APP_PATH); - - // 初始化应用 - $config = self::init(); - self::$suffix = $config['class_suffix']; - - // 应用调试模式 - self::$debug = Env::get('app_debug', Config::get('app_debug')); - if (!self::$debug) { - ini_set('display_errors', 'Off'); - } elseif (!IS_CLI) { - //重新申请一块比较大的buffer - if (ob_get_level() > 0) { - $output = ob_get_clean(); - } - ob_start(); - if (!empty($output)) { - echo $output; - } - } - - if (!empty($config['root_namespace'])) { - Loader::addNamespace($config['root_namespace']); - } - - // 加载额外文件 - if (!empty($config['extra_file_list'])) { - foreach ($config['extra_file_list'] as $file) { - $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; - if (is_file($file) && !isset(self::$file[$file])) { - include $file; - self::$file[$file] = true; - } - } - } - - // 设置系统时区 - date_default_timezone_set($config['default_timezone']); - - // 监听app_init - Hook::listen('app_init'); - - self::$init = true; - } - return Config::get(); - } - - /** - * 初始化应用或模块 - * @access public - * @param string $module 模块名 - * @return array - */ - private static function init($module = '') - { - // 定位模块目录 - $module = $module ? $module . DS : ''; - - // 加载初始化文件 - if (is_file(APP_PATH . $module . 'init' . EXT)) { - include APP_PATH . $module . 'init' . EXT; - } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) { - include RUNTIME_PATH . $module . 'init' . EXT; - } else { - $path = APP_PATH . $module; - // 加载模块配置 - $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT); - // 读取数据库配置文件 - $filename = CONF_PATH . $module . 'database' . CONF_EXT; - Config::load($filename, 'database'); - // 读取扩展配置文件 - if (is_dir(CONF_PATH . $module . 'extra')) { - $dir = CONF_PATH . $module . 'extra'; - $files = scandir($dir); - foreach ($files as $file) { - if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) { - $filename = $dir . DS . $file; - Config::load($filename, pathinfo($file, PATHINFO_FILENAME)); - } - } - } - - // 加载应用状态配置 - if ($config['app_status']) { - $config = Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT); - } - - // 加载行为扩展文件 - if (is_file(CONF_PATH . $module . 'tags' . EXT)) { - Hook::import(include CONF_PATH . $module . 'tags' . EXT); - } - - // 加载公共文件 - if (is_file($path . 'common' . EXT)) { - include $path . 'common' . EXT; - } - - // 加载当前模块语言包 - if ($module) { - Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT); - } - } - return Config::get(); - } - /** * URL路由检测(根据PATH_INFO) * @access public - * @param \think\Request $request - * @param array $config + * @param \think\Request $request 请求实例 + * @param array $config 配置信息 * @return array * @throws \think\Exception */ @@ -539,6 +624,7 @@ class App $path = $request->path(); $depr = $config['pathinfo_depr']; $result = false; + // 路由检测 $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on']; if ($check) { @@ -546,18 +632,14 @@ class App if (is_file(RUNTIME_PATH . 'route.php')) { // 读取路由缓存 $rules = include RUNTIME_PATH . 'route.php'; - if (is_array($rules)) { - Route::rules($rules); - } + is_array($rules) && Route::rules($rules); } else { $files = $config['route_config_file']; foreach ($files as $file) { if (is_file(CONF_PATH . $file . CONF_EXT)) { // 导入路由配置 $rules = include CONF_PATH . $file . CONF_EXT; - if (is_array($rules)) { - Route::import($rules); - } + is_array($rules) && Route::import($rules); } } } @@ -565,15 +647,18 @@ class App // 路由检测(根据路由定义返回不同的URL调度) $result = Route::check($request, $path, $depr, $config['url_domain_deploy']); $must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must']; + if ($must && false === $result) { // 路由无效 throw new RouteNotFoundException(); } } + + // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 if (false === $result) { - // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); } + return $result; } diff --git a/thinkphp/library/think/Build.php b/thinkphp/library/think/Build.php index d08dc50b..de7c3275 100644 --- a/thinkphp/library/think/Build.php +++ b/thinkphp/library/think/Build.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -14,36 +14,44 @@ namespace think; class Build { /** - * 根据传入的build资料创建目录和文件 - * @access protected - * @param array $build build列表 + * 根据传入的 build 资料创建目录和文件 + * @access public + * @param array $build build 列表 * @param string $namespace 应用类库命名空间 - * @param bool $suffix 类库后缀 + * @param bool $suffix 类库后缀 * @return void + * @throws Exception */ public static function run(array $build = [], $namespace = 'app', $suffix = false) { // 锁定 - $lockfile = APP_PATH . 'build.lock'; - if (is_writable($lockfile)) { - return; - } elseif (!touch($lockfile)) { - throw new Exception('应用目录[' . APP_PATH . ']不可写,目录无法自动生成!
请手动生成项目目录~', 10006); - } - foreach ($build as $module => $list) { - if ('__dir__' == $module) { - // 创建目录列表 - self::buildDir($list); - } elseif ('__file__' == $module) { - // 创建文件列表 - self::buildFile($list); - } else { - // 创建模块 - self::module($module, $list, $namespace, $suffix); + $lock = APP_PATH . 'build.lock'; + + // 如果锁定文件不可写(不存在)则进行处理,否则表示已经有程序在处理了 + if (!is_writable($lock)) { + if (!touch($lock)) { + throw new Exception( + '应用目录[' . APP_PATH . ']不可写,目录无法自动生成!
请手动生成项目目录~', + 10006 + ); } + + foreach ($build as $module => $list) { + if ('__dir__' == $module) { + // 创建目录列表 + self::buildDir($list); + } elseif ('__file__' == $module) { + // 创建文件列表 + self::buildFile($list); + } else { + // 创建模块 + self::module($module, $list, $namespace, $suffix); + } + } + + // 解除锁定 + unlink($lock); } - // 解除锁定 - unlink($lockfile); } /** @@ -55,10 +63,8 @@ class Build protected static function buildDir($list) { foreach ($list as $dir) { - if (!is_dir(APP_PATH . $dir)) { - // 创建目录 - mkdir(APP_PATH . $dir, 0755, true); - } + // 目录不存在则创建目录 + !is_dir(APP_PATH . $dir) && mkdir(APP_PATH . $dir, 0755, true); } } @@ -71,12 +77,17 @@ class Build protected static function buildFile($list) { foreach ($list as $file) { + // 先创建目录 if (!is_dir(APP_PATH . dirname($file))) { - // 创建目录 mkdir(APP_PATH . dirname($file), 0755, true); } + + // 再创建文件 if (!is_file(APP_PATH . $file)) { - file_put_contents(APP_PATH . $file, 'php' == pathinfo($file, PATHINFO_EXTENSION) ? " ['config.php', 'common.php'], '__dir__' => ['controller', 'model', 'view'], ]; } + // 创建子目录和文件 foreach ($list as $path => $file) { $modulePath = APP_PATH . $module . DS; + if ('__dir__' == $path) { // 生成子目录 foreach ($file as $dir) { - if (!is_dir($modulePath . $dir)) { - // 创建目录 - mkdir($modulePath . $dir, 0755, true); - } + self::checkDirBuild($modulePath . $dir); } } elseif ('__file__' == $path) { // 生成(空白)文件 foreach ($file as $name) { if (!is_file($modulePath . $name)) { - file_put_contents($modulePath . $name, 'php' == pathinfo($name, PATHINFO_EXTENSION) ? "has($name); } /** * 读取缓存 * @access public - * @param string $name 缓存标识 - * @param mixed $default 默认值 + * @param string $name 缓存标识 + * @param mixed $default 默认值 * @return mixed */ public static function get($name, $default = false) { self::$readTimes++; + return self::init()->get($name, $default); } /** * 写入缓存 * @access public - * @param string $name 缓存标识 - * @param mixed $value 存储数据 - * @param int|null $expire 有效时间 0为永久 + * @param string $name 缓存标识 + * @param mixed $value 存储数据 + * @param int|null $expire 有效时间 0为永久 * @return boolean */ public static function set($name, $value, $expire = null) { self::$writeTimes++; + return self::init()->set($name, $value, $expire); } /** * 自增缓存(针对数值缓存) * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 + * @param string $name 缓存变量名 + * @param int $step 步长 * @return false|int */ public static function inc($name, $step = 1) { self::$writeTimes++; + return self::init()->inc($name, $step); } /** * 自减缓存(针对数值缓存) * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 + * @param string $name 缓存变量名 + * @param int $step 步长 * @return false|int */ public static function dec($name, $step = 1) { self::$writeTimes++; + return self::init()->dec($name, $step); } /** * 删除缓存 * @access public - * @param string $name 缓存标识 + * @param string $name 缓存标识 * @return boolean */ public static function rm($name) { self::$writeTimes++; + return self::init()->rm($name); } /** * 清除缓存 * @access public - * @param string $tag 标签名 + * @param string $tag 标签名 * @return boolean */ public static function clear($tag = null) { self::$writeTimes++; + return self::init()->clear($tag); } /** * 读取缓存并删除 * @access public - * @param string $name 缓存变量名 + * @param string $name 缓存变量名 * @return mixed */ public static function pull($name) { self::$readTimes++; self::$writeTimes++; + return self::init()->pull($name); } /** * 如果不存在则写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param int $expire 有效时间 0为永久 + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int $expire 有效时间 0为永久 * @return mixed */ public static function remember($name, $value, $expire = null) { self::$readTimes++; + return self::init()->remember($name, $value, $expire); } /** * 缓存标签 * @access public - * @param string $name 标签名 - * @param string|array $keys 缓存标识 - * @param bool $overlay 是否覆盖 + * @param string $name 标签名 + * @param string|array $keys 缓存标识 + * @param bool $overlay 是否覆盖 * @return Driver */ public static function tag($name, $keys = null, $overlay = false) diff --git a/thinkphp/library/think/Collection.php b/thinkphp/library/think/Collection.php index 41b42759..f872476f 100644 --- a/thinkphp/library/think/Collection.php +++ b/thinkphp/library/think/Collection.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -19,20 +19,35 @@ use JsonSerializable; class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable { + /** + * @var array 数据 + */ protected $items = []; + /** + * Collection constructor. + * @access public + * @param array $items 数据 + */ public function __construct($items = []) { $this->items = $this->convertToArray($items); } + /** + * 创建 Collection 实例 + * @access public + * @param array $items 数据 + * @return static + */ public static function make($items = []) { return new static($items); } /** - * 是否为空 + * 判断数据是否为空 + * @access public * @return bool */ public function isEmpty() @@ -40,74 +55,96 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria return empty($this->items); } + /** + * 将数据转成数组 + * @access public + * @return array + */ public function toArray() { return array_map(function ($value) { - return ($value instanceof Model || $value instanceof self) ? $value->toArray() : $value; + return ($value instanceof Model || $value instanceof self) ? + $value->toArray() : + $value; }, $this->items); } + /** + * 获取全部的数据 + * @access public + * @return array + */ public function all() { return $this->items; } /** - * 合并数组 - * - * @param mixed $items + * 交换数组中的键和值 + * @access public * @return static */ - public function merge($items) + public function flip() { - return new static(array_merge($this->items, $this->convertToArray($items))); + return new static(array_flip($this->items)); } /** - * 比较数组,返回差集 - * - * @param mixed $items + * 返回数组中所有的键名组成的新 Collection 实例 + * @access public * @return static */ - public function diff($items) + public function keys() { - return new static(array_diff($this->items, $this->convertToArray($items))); + return new static(array_keys($this->items)); } /** - * 交换数组中的键和值 - * + * 返回数组中所有的值组成的新 Collection 实例 + * @access public * @return static */ - public function flip() + public function values() { - return new static(array_flip($this->items)); + return new static(array_values($this->items)); } /** - * 比较数组,返回交集 - * - * @param mixed $items + * 合并数组并返回一个新的 Collection 实例 + * @access public + * @param mixed $items 新的数据 * @return static */ - public function intersect($items) + public function merge($items) { - return new static(array_intersect($this->items, $this->convertToArray($items))); + return new static(array_merge($this->items, $this->convertToArray($items))); } /** - * 返回数组中所有的键名 - * + * 比较数组,返回差集生成的新 Collection 实例 + * @access public + * @param mixed $items 做比较的数据 * @return static */ - public function keys() + public function diff($items) { - return new static(array_keys($this->items)); + return new static(array_diff($this->items, $this->convertToArray($items))); + } + + /** + * 比较数组,返回交集组成的 Collection 新实例 + * @access public + * @param mixed $items 比较数据 + * @return static + */ + public function intersect($items) + { + return new static(array_intersect($this->items, $this->convertToArray($items))); } /** - * 删除数组的最后一个元素(出栈) - * + * 返回并删除数据中的的最后一个元素(出栈) + * @access public * @return mixed */ public function pop() @@ -116,42 +153,74 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria } /** - * 通过使用用户自定义函数,以字符串返回数组 - * - * @param callable $callback - * @param mixed $initial + * 返回并删除数据中首个元素 + * @access public * @return mixed */ - public function reduce(callable $callback, $initial = null) + public function shift() { - return array_reduce($this->items, $callback, $initial); + return array_shift($this->items); } /** - * 以相反的顺序返回数组。 - * - * @return static + * 在数组开头插入一个元素 + * @access public + * @param mixed $value 值 + * @param mixed $key 键名 + * @return void */ - public function reverse() + public function unshift($value, $key = null) { - return new static(array_reverse($this->items)); + if (is_null($key)) { + array_unshift($this->items, $value); + } else { + $this->items = [$key => $value] + $this->items; + } + } + + /** + * 在数组结尾插入一个元素 + * @access public + * @param mixed $value 值 + * @param mixed $key 键名 + * @return void + */ + public function push($value, $key = null) + { + if (is_null($key)) { + $this->items[] = $value; + } else { + $this->items[$key] = $value; + } } /** - * 删除数组中首个元素,并返回被删除元素的值 - * + * 通过使用用户自定义函数,以字符串返回数组 + * @access public + * @param callable $callback 回调函数 + * @param mixed $initial 初始值 * @return mixed */ - public function shift() + public function reduce(callable $callback, $initial = null) { - return array_shift($this->items); + return array_reduce($this->items, $callback, $initial); + } + + /** + * 以相反的顺序创建一个新的 Collection 实例 + * @access public + * @return static + */ + public function reverse() + { + return new static(array_reverse($this->items)); } /** - * 把一个数组分割为新的数组块. - * - * @param int $size - * @param bool $preserveKeys + * 把数据分割为新的数组块 + * @access public + * @param int $size 分隔长度 + * @param bool $preserveKeys 是否保持原数据索引 * @return static */ public function chunk($size, $preserveKeys = false) @@ -166,78 +235,70 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria } /** - * 在数组开头插入一个元素 - * @param mixed $value - * @param null $key - * @return int - */ - public function unshift($value, $key = null) - { - if (is_null($key)) { - array_unshift($this->items, $value); - } else { - $this->items = [$key => $value] + $this->items; - } - } - - /** - * 给每个元素执行个回调 - * - * @param callable $callback + * 给数据中的每个元素执行回调 + * @access public + * @param callable $callback 回调函数 * @return $this */ public function each(callable $callback) { foreach ($this->items as $key => $item) { - if ($callback($item, $key) === false) { + $result = $callback($item, $key); + + if (false === $result) { break; } + + if (!is_object($item)) { + $this->items[$key] = $result; + } } return $this; } /** - * 用回调函数过滤数组中的元素 - * @param callable|null $callback + * 用回调函数过滤数据中的元素 + * @access public + * @param callable|null $callback 回调函数 * @return static */ public function filter(callable $callback = null) { - if ($callback) { - return new static(array_filter($this->items, $callback)); - } - - return new static(array_filter($this->items)); + return new static(array_filter($this->items, $callback ?: null)); } /** - * 返回数组中指定的一列 - * @param $column_key - * @param null $index_key + * 返回数据中指定的一列 + * @access public + * @param mixed $columnKey 键名 + * @param null $indexKey 作为索引值的列 * @return array */ - public function column($column_key, $index_key = null) + public function column($columnKey, $indexKey = null) { if (function_exists('array_column')) { - return array_column($this->items, $column_key, $index_key); + return array_column($this->items, $columnKey, $indexKey); } $result = []; foreach ($this->items as $row) { - $key = $value = null; + $key = $value = null; $keySet = $valueSet = false; - if (null !== $index_key && array_key_exists($index_key, $row)) { + + if (null !== $indexKey && array_key_exists($indexKey, $row)) { + $key = (string) $row[$indexKey]; $keySet = true; - $key = (string) $row[$index_key]; } - if (null === $column_key) { + + if (null === $columnKey) { $valueSet = true; $value = $row; - } elseif (is_array($row) && array_key_exists($column_key, $row)) { + } elseif (is_array($row) && array_key_exists($columnKey, $row)) { $valueSet = true; - $value = $row[$column_key]; + $value = $row[$columnKey]; } + if ($valueSet) { if ($keySet) { $result[$key] = $value; @@ -246,34 +307,30 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria } } } + return $result; } /** - * 对数组排序 - * - * @param callable|null $callback + * 对数据排序,并返回排序后的数据组成的新 Collection 实例 + * @access public + * @param callable|null $callback 回调函数 * @return static */ public function sort(callable $callback = null) { - $items = $this->items; - - $callback ? uasort($items, $callback) : uasort($items, function ($a, $b) { - - if ($a == $b) { - return 0; - } - - return ($a < $b) ? -1 : 1; - }); + $items = $this->items; + $callback = $callback ?: function ($a, $b) { + return $a == $b ? 0 : (($a < $b) ? -1 : 1); + }; + uasort($items, $callback); return new static($items); } /** - * 将数组打乱 - * + * 将数据打乱后组成新的 Collection 实例 + * @access public * @return static */ public function shuffle() @@ -281,16 +338,15 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria $items = $this->items; shuffle($items); - return new static($items); } /** - * 截取数组 - * - * @param int $offset - * @param int $length - * @param bool $preserveKeys + * 截取数据并返回新的 Collection 实例 + * @access public + * @param int $offset 起始位置 + * @param int $length 截取长度 + * @param bool $preserveKeys 是否保持原先的键名 * @return static */ public function slice($offset, $length = null, $preserveKeys = false) @@ -298,17 +354,35 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria return new static(array_slice($this->items, $offset, $length, $preserveKeys)); } - // ArrayAccess + /** + * 指定的键是否存在 + * @access public + * @param mixed $offset 键名 + * @return bool + */ public function offsetExists($offset) { return array_key_exists($offset, $this->items); } + /** + * 获取指定键对应的值 + * @access public + * @param mixed $offset 键名 + * @return mixed + */ public function offsetGet($offset) { return $this->items[$offset]; } + /** + * 设置键值 + * @access public + * @param mixed $offset 键名 + * @param mixed $value 值 + * @return void + */ public function offsetSet($offset, $value) { if (is_null($offset)) { @@ -318,33 +392,51 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria } } + /** + * 删除指定键值 + * @access public + * @param mixed $offset 键名 + * @return void + */ public function offsetUnset($offset) { unset($this->items[$offset]); } - //Countable + /** + * 统计数据的个数 + * @access public + * @return int + */ public function count() { return count($this->items); } - //IteratorAggregate + /** + * 获取数据的迭代器 + * @access public + * @return ArrayIterator + */ public function getIterator() { return new ArrayIterator($this->items); } - //JsonSerializable + /** + * 将数据反序列化成数组 + * @access public + * @return array + */ public function jsonSerialize() { return $this->toArray(); } /** - * 转换当前数据集为JSON字符串 + * 转换当前数据集为 JSON 字符串 * @access public - * @param integer $options json参数 + * @param integer $options json 参数 * @return string */ public function toJson($options = JSON_UNESCAPED_UNICODE) @@ -352,22 +444,24 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria return json_encode($this->toArray(), $options); } + /** + * 将数据转换成字符串 + * @access public + * @return string + */ public function __toString() { return $this->toJson(); } /** - * 转换成数组 - * - * @param mixed $items + * 将数据转换成数组 + * @access protected + * @param mixed $items 数据 * @return array */ protected function convertToArray($items) { - if ($items instanceof self) { - return $items->all(); - } - return (array) $items; + return $items instanceof self ? $items->all() : (array) $items; } } diff --git a/thinkphp/library/think/Config.php b/thinkphp/library/think/Config.php index 2b808434..8fa668d1 100644 --- a/thinkphp/library/think/Config.php +++ b/thinkphp/library/think/Config.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -13,70 +13,88 @@ namespace think; class Config { - // 配置参数 + /** + * @var array 配置参数 + */ private static $config = []; - // 参数作用域 + + /** + * @var string 参数作用域 + */ private static $range = '_sys_'; - // 设定配置参数的作用域 + /** + * 设定配置参数的作用域 + * @access public + * @param string $range 作用域 + * @return void + */ public static function range($range) { self::$range = $range; - if (!isset(self::$config[$range])) { - self::$config[$range] = []; - } + + if (!isset(self::$config[$range])) self::$config[$range] = []; } /** * 解析配置文件或内容 - * @param string $config 配置文件路径或内容 - * @param string $type 配置解析类型 - * @param string $name 配置名(如设置即表示二级配置) - * @param string $range 作用域 + * @access public + * @param string $config 配置文件路径或内容 + * @param string $type 配置解析类型 + * @param string $name 配置名(如设置即表示二级配置) + * @param string $range 作用域 * @return mixed */ public static function parse($config, $type = '', $name = '', $range = '') { $range = $range ?: self::$range; - if (empty($type)) { - $type = pathinfo($config, PATHINFO_EXTENSION); - } - $class = false !== strpos($type, '\\') ? $type : '\\think\\config\\driver\\' . ucwords($type); + + if (empty($type)) $type = pathinfo($config, PATHINFO_EXTENSION); + + $class = false !== strpos($type, '\\') ? + $type : + '\\think\\config\\driver\\' . ucwords($type); + return self::set((new $class())->parse($config), $name, $range); } /** * 加载配置文件(PHP格式) - * @param string $file 配置文件名 - * @param string $name 配置名(如设置即表示二级配置) - * @param string $range 作用域 + * @access public + * @param string $file 配置文件名 + * @param string $name 配置名(如设置即表示二级配置) + * @param string $range 作用域 * @return mixed */ public static function load($file, $name = '', $range = '') { $range = $range ?: self::$range; - if (!isset(self::$config[$range])) { - self::$config[$range] = []; - } + + if (!isset(self::$config[$range])) self::$config[$range] = []; + if (is_file($file)) { $name = strtolower($name); $type = pathinfo($file, PATHINFO_EXTENSION); + if ('php' == $type) { return self::set(include $file, $name, $range); - } elseif ('yaml' == $type && function_exists('yaml_parse_file')) { + } + + if ('yaml' == $type && function_exists('yaml_parse_file')) { return self::set(yaml_parse_file($file), $name, $range); - } else { - return self::parse($file, $type, $name, $range); } - } else { - return self::$config[$range]; + + return self::parse($file, $type, $name, $range); } + + return self::$config[$range]; } /** * 检测配置是否存在 - * @param string $name 配置参数名(支持二级配置 .号分割) - * @param string $range 作用域 + * @access public + * @param string $name 配置参数名(支持二级配置 . 号分割) + * @param string $range 作用域 * @return bool */ public static function has($name, $range = '') @@ -85,82 +103,108 @@ class Config if (!strpos($name, '.')) { return isset(self::$config[$range][strtolower($name)]); - } else { - // 二维数组设置和获取支持 - $name = explode('.', $name, 2); - return isset(self::$config[$range][strtolower($name[0])][$name[1]]); } + + // 二维数组设置和获取支持 + $name = explode('.', $name, 2); + return isset(self::$config[$range][strtolower($name[0])][$name[1]]); } /** * 获取配置参数 为空则获取所有配置 - * @param string $name 配置参数名(支持二级配置 .号分割) - * @param string $range 作用域 + * @access public + * @param string $name 配置参数名(支持二级配置 . 号分割) + * @param string $range 作用域 * @return mixed */ public static function get($name = null, $range = '') { $range = $range ?: self::$range; + // 无参数时获取所有 if (empty($name) && isset(self::$config[$range])) { return self::$config[$range]; } + // 非二级配置时直接返回 if (!strpos($name, '.')) { $name = strtolower($name); return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null; - } else { - // 二维数组设置和获取支持 - $name = explode('.', $name, 2); - $name[0] = strtolower($name[0]); - return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null; } + + // 二维数组设置和获取支持 + $name = explode('.', $name, 2); + $name[0] = strtolower($name[0]); + + if (!isset(self::$config[$range][$name[0]])) { + // 动态载入额外配置 + $module = Request::instance()->module(); + $file = CONF_PATH . ($module ? $module . DS : '') . 'extra' . DS . $name[0] . CONF_EXT; + + is_file($file) && self::load($file, $name[0]); + } + + return isset(self::$config[$range][$name[0]][$name[1]]) ? + self::$config[$range][$name[0]][$name[1]] : + null; } /** - * 设置配置参数 name为数组则为批量设置 - * @param string|array $name 配置参数名(支持二级配置 .号分割) - * @param mixed $value 配置值 - * @param string $range 作用域 + * 设置配置参数 name 为数组则为批量设置 + * @access public + * @param string|array $name 配置参数名(支持二级配置 . 号分割) + * @param mixed $value 配置值 + * @param string $range 作用域 * @return mixed */ public static function set($name, $value = null, $range = '') { $range = $range ?: self::$range; - if (!isset(self::$config[$range])) { - self::$config[$range] = []; - } + + if (!isset(self::$config[$range])) self::$config[$range] = []; + + // 字符串则表示单个配置设置 if (is_string($name)) { if (!strpos($name, '.')) { self::$config[$range][strtolower($name)] = $value; } else { - // 二维数组设置和获取支持 - $name = explode('.', $name, 2); + // 二维数组 + $name = explode('.', $name, 2); self::$config[$range][strtolower($name[0])][$name[1]] = $value; } - return; - } elseif (is_array($name)) { - // 批量设置 + + return $value; + } + + // 数组则表示批量设置 + if (is_array($name)) { if (!empty($value)) { self::$config[$range][$value] = isset(self::$config[$range][$value]) ? - array_merge(self::$config[$range][$value], $name) : - self::$config[$range][$value] = $name; + array_merge(self::$config[$range][$value], $name) : + $name; + return self::$config[$range][$value]; - } else { - return self::$config[$range] = array_merge(self::$config[$range], array_change_key_case($name)); } - } else { - // 为空直接返回 已有配置 - return self::$config[$range]; + + return self::$config[$range] = array_merge( + self::$config[$range], array_change_key_case($name) + ); } + + // 为空直接返回已有配置 + return self::$config[$range]; } /** * 重置配置参数 + * @access public + * @param string $range 作用域 + * @return void */ public static function reset($range = '') { $range = $range ?: self::$range; + if (true === $range) { self::$config = []; } else { diff --git a/thinkphp/library/think/Console.php b/thinkphp/library/think/Console.php index 1d97ab2b..32b25725 100644 --- a/thinkphp/library/think/Console.php +++ b/thinkphp/library/think/Console.php @@ -20,20 +20,49 @@ use think\console\output\driver\Buffer; class Console { - + /** + * @var string 命令名称 + */ private $name; + + /** + * @var string 命令版本 + */ private $version; - /** @var Command[] */ + /** + * @var Command[] 命令 + */ private $commands = []; + /** + * @var bool 是否需要帮助信息 + */ private $wantHelps = false; + /** + * @var bool 是否捕获异常 + */ private $catchExceptions = true; - private $autoExit = true; + + /** + * @var bool 是否自动退出执行 + */ + private $autoExit = true; + + /** + * @var InputDefinition 输入定义 + */ private $definition; + + /** + * @var string 默认执行的命令 + */ private $defaultCommand; + /** + * @var array 默认提供的命令 + */ private static $defaultCommands = [ "think\\console\\command\\Help", "think\\console\\command\\Lists", @@ -47,11 +76,22 @@ class Console "think\\console\\command\\optimize\\Schema", ]; - public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') + /** + * Console constructor. + * @access public + * @param string $name 名称 + * @param string $version 版本 + * @param null|string $user 执行用户 + */ + public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN', $user = null) { $this->name = $name; $this->version = $version; + if ($user) { + $this->setUser($user); + } + $this->defaultCommand = 'list'; $this->definition = $this->getDefaultInputDefinition(); @@ -60,38 +100,58 @@ class Console } } + /** + * 设置执行用户 + * @param $user + */ + public function setUser($user) + { + $user = posix_getpwnam($user); + if ($user) { + posix_setuid($user['uid']); + posix_setgid($user['gid']); + } + } + + /** + * 初始化 Console + * @access public + * @param bool $run 是否运行 Console + * @return int|Console + */ public static function init($run = true) { static $console; + if (!$console) { - // 实例化console - $console = new self('Think Console', '0.1'); + $config = Config::get('console'); + // 实例化 console + $console = new self($config['name'], $config['version'], $config['user']); + // 读取指令集 if (is_file(CONF_PATH . 'command' . EXT)) { $commands = include CONF_PATH . 'command' . EXT; + if (is_array($commands)) { foreach ($commands as $command) { - if (class_exists($command) && is_subclass_of($command, "\\think\\console\\Command")) { - // 注册指令 - $console->add(new $command()); - } + class_exists($command) && + is_subclass_of($command, "\\think\\console\\Command") && + $console->add(new $command()); // 注册指令 } } } } - if ($run) { - // 运行 - return $console->run(); - } else { - return $console; - } + + return $run ? $console->run() : $console; } /** - * @param $command - * @param array $parameters - * @param string $driver - * @return Output|Buffer + * 调用命令 + * @access public + * @param string $command + * @param array $parameters + * @param string $driver + * @return Output */ public static function call($command, array $parameters = [], $driver = 'buffer') { @@ -110,9 +170,9 @@ class Console /** * 执行当前的指令 + * @access public * @return int * @throws \Exception - * @api */ public function run() { @@ -124,27 +184,21 @@ class Console try { $exitCode = $this->doRun($input, $output); } catch (\Exception $e) { - if (!$this->catchExceptions) { - throw $e; - } + if (!$this->catchExceptions) throw $e; $output->renderException($e); $exitCode = $e->getCode(); + if (is_numeric($exitCode)) { - $exitCode = (int) $exitCode; - if (0 === $exitCode) { - $exitCode = 1; - } + $exitCode = ((int) $exitCode) ?: 1; } else { $exitCode = 1; } } if ($this->autoExit) { - if ($exitCode > 255) { - $exitCode = 255; - } + if ($exitCode > 255) $exitCode = 255; exit($exitCode); } @@ -154,12 +208,14 @@ class Console /** * 执行指令 - * @param Input $input - * @param Output $output + * @access public + * @param Input $input 输入 + * @param Output $output 输出 * @return int */ public function doRun(Input $input, Output $output) { + // 获取版本信息 if (true === $input->hasParameterOption(['--version', '-V'])) { $output->writeln($this->getLongVersion()); @@ -168,6 +224,7 @@ class Console $name = $this->getCommandName($input); + // 获取帮助信息 if (true === $input->hasParameterOption(['--help', '-h'])) { if (!$name) { $name = 'help'; @@ -182,25 +239,26 @@ class Console $input = new Input([$this->defaultCommand]); } - $command = $this->find($name); - - $exitCode = $this->doRunCommand($command, $input, $output); - - return $exitCode; + return $this->doRunCommand($this->find($name), $input, $output); } /** * 设置输入参数定义 - * @param InputDefinition $definition + * @access public + * @param InputDefinition $definition 输入定义 + * @return $this; */ public function setDefinition(InputDefinition $definition) { $this->definition = $definition; + + return $this; } /** * 获取输入参数定义 - * @return InputDefinition The InputDefinition instance + * @access public + * @return InputDefinition */ public function getDefinition() { @@ -208,8 +266,9 @@ class Console } /** - * Gets the help message. - * @return string A help message. + * 获取帮助信息 + * @access public + * @return string */ public function getHelp() { @@ -217,27 +276,34 @@ class Console } /** - * 是否捕获异常 - * @param bool $boolean - * @api + * 设置是否捕获异常 + * @access public + * @param bool $boolean 是否捕获 + * @return $this */ public function setCatchExceptions($boolean) { $this->catchExceptions = (bool) $boolean; + + return $this; } /** - * 是否自动退出 - * @param bool $boolean - * @api + * 设置是否自动退出 + * @access public + * @param bool $boolean 是否自动退出 + * @return $this */ public function setAutoExit($boolean) { $this->autoExit = (bool) $boolean; + + return $this; } /** * 获取名称 + * @access public * @return string */ public function getName() @@ -247,17 +313,21 @@ class Console /** * 设置名称 - * @param string $name + * @access public + * @param string $name 名称 + * @return $this */ public function setName($name) { $this->name = $name; + + return $this; } /** * 获取版本 + * @access public * @return string - * @api */ public function getVersion() { @@ -266,21 +336,30 @@ class Console /** * 设置版本 - * @param string $version + * @access public + * @param string $version 版本信息 + * @return $this */ public function setVersion($version) { $this->version = $version; + + return $this; } /** * 获取完整的版本号 + * @access public * @return string */ public function getLongVersion() { if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) { - return sprintf('%s version %s', $this->getName(), $this->getVersion()); + return sprintf( + '%s version %s', + $this->getName(), + $this->getVersion() + ); } return 'Console Tool'; @@ -288,7 +367,8 @@ class Console /** * 注册一个指令 - * @param string $name + * @access public + * @param string $name 指令名称 * @return Command */ public function register($name) @@ -297,32 +377,37 @@ class Console } /** - * 添加指令 - * @param Command[] $commands + * 批量添加指令 + * @access public + * @param Command[] $commands 指令实例 + * @return $this */ public function addCommands(array $commands) { - foreach ($commands as $command) { - $this->add($command); - } + foreach ($commands as $command) $this->add($command); + + return $this; } /** * 添加一个指令 - * @param Command $command - * @return Command + * @access public + * @param Command $command 命令实例 + * @return Command|bool */ public function add(Command $command) { - $command->setConsole($this); - if (!$command->isEnabled()) { $command->setConsole(null); - return; + return false; } + $command->setConsole($this); + if (null === $command->getDefinition()) { - throw new \LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command))); + throw new \LogicException( + sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)) + ); } $this->commands[$command->getName()] = $command; @@ -336,14 +421,17 @@ class Console /** * 获取指令 - * @param string $name 指令名称 + * @access public + * @param string $name 指令名称 * @return Command * @throws \InvalidArgumentException */ public function get($name) { if (!isset($this->commands[$name])) { - throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name)); + throw new \InvalidArgumentException( + sprintf('The command "%s" does not exist.', $name) + ); } $command = $this->commands[$name]; @@ -363,7 +451,8 @@ class Console /** * 某个指令是否存在 - * @param string $name 指令名称 + * @access public + * @param string $name 指令名称 * @return bool */ public function has($name) @@ -373,16 +462,22 @@ class Console /** * 获取所有的命名空间 + * @access public * @return array */ public function getNamespaces() { $namespaces = []; + foreach ($this->commands as $command) { - $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName())); + $namespaces = array_merge( + $namespaces, $this->extractAllNamespaces($command->getName()) + ); foreach ($command->getAliases() as $alias) { - $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias)); + $namespaces = array_merge( + $namespaces, $this->extractAllNamespaces($alias) + ); } } @@ -390,21 +485,25 @@ class Console } /** - * 查找注册命名空间中的名称或缩写。 + * 查找注册命名空间中的名称或缩写 + * @access public * @param string $namespace * @return string * @throws \InvalidArgumentException */ public function findNamespace($namespace) { - $allNamespaces = $this->getNamespaces(); - $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]) . '[^:]*'; }, $namespace); - $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); + + $allNamespaces = $this->getNamespaces(); + $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); if (empty($namespaces)) { - $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); + $message = sprintf( + 'There are no commands defined in the "%s" namespace.', $namespace + ); if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { if (1 == count($alternatives)) { @@ -420,8 +519,14 @@ class Console } $exact = in_array($namespace, $namespaces, true); + if (count($namespaces) > 1 && !$exact) { - throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces)))); + throw new \InvalidArgumentException( + sprintf( + 'The namespace "%s" is ambiguous (%s).', + $namespace, + $this->getAbbreviationSuggestions(array_values($namespaces))) + ); } return $exact ? $namespace : reset($namespaces); @@ -429,20 +534,22 @@ class Console /** * 查找指令 - * @param string $name 名称或者别名 + * @access public + * @param string $name 名称或者别名 * @return Command * @throws \InvalidArgumentException */ public function find($name) { - $allCommands = array_keys($this->commands); - $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]) . '[^:]*'; }, $name); - $commands = preg_grep('{^' . $expr . '}', $allCommands); + + $allCommands = array_keys($this->commands); + $commands = preg_grep('{^' . $expr . '}', $allCommands); if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) { - if (false !== $pos = strrpos($name, ':')) { + if (false !== ($pos = strrpos($name, ':'))) { $this->findNamespace(substr($name, 0, $pos)); } @@ -473,7 +580,9 @@ class Console if (count($commands) > 1 && !$exact) { $suggestions = $this->getAbbreviationSuggestions(array_values($commands)); - throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); + throw new \InvalidArgumentException( + sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions) + ); } return $this->get($exact ? $name : reset($commands)); @@ -481,21 +590,20 @@ class Console /** * 获取所有的指令 - * @param string $namespace 命名空间 + * @access public + * @param string $namespace 命名空间 * @return Command[] - * @api */ public function all($namespace = null) { - if (null === $namespace) { - return $this->commands; - } + if (null === $namespace) return $this->commands; $commands = []; + foreach ($this->commands as $name => $command) { - if ($this->extractNamespace($name, substr_count($namespace, ':') + 1) === $namespace) { - $commands[$name] = $command; - } + $ext = $this->extractNamespace($name, substr_count($namespace, ':') + 1); + + if ($ext === $namespace) $commands[$name] = $command; } return $commands; @@ -503,7 +611,8 @@ class Console /** * 获取可能的指令名 - * @param array $names + * @access public + * @param array $names 指令名 * @return array */ public static function getAbbreviations($names) @@ -520,9 +629,11 @@ class Console } /** - * 配置基于用户的参数和选项的输入和输出实例。 - * @param Input $input 输入实例 - * @param Output $output 输出实例 + * 配置基于用户的参数和选项的输入和输出实例 + * @access protected + * @param Input $input 输入实例 + * @param Output $output 输出实例 + * @return void */ protected function configureIO(Input $input, Output $output) { @@ -551,9 +662,10 @@ class Console /** * 执行指令 - * @param Command $command 指令实例 - * @param Input $input 输入实例 - * @param Output $output 输出实例 + * @access protected + * @param Command $command 指令实例 + * @param Input $input 输入实例 + * @param Output $output 输出实例 * @return int * @throws \Exception */ @@ -563,8 +675,9 @@ class Console } /** - * 获取指令的基础名称 - * @param Input $input + * 获取指令的名称 + * @access protected + * @param Input $input 输入实例 * @return string */ protected function getCommandName(Input $input) @@ -574,6 +687,7 @@ class Console /** * 获取默认输入定义 + * @access protected * @return InputDefinition */ protected function getDefaultInputDefinition() @@ -591,41 +705,55 @@ class Console } /** - * 设置默认命令 - * @return Command[] An array of default Command instances + * 获取默认命令 + * @access protected + * @return Command[] */ protected function getDefaultCommands() { $defaultCommands = []; - foreach (self::$defaultCommands as $classname) { - if (class_exists($classname) && is_subclass_of($classname, "think\\console\\Command")) { - $defaultCommands[] = new $classname(); + foreach (self::$defaultCommands as $class) { + if (class_exists($class) && is_subclass_of($class, "think\\console\\Command")) { + $defaultCommands[] = new $class(); } } return $defaultCommands; } - public static function addDefaultCommands(array $classnames) + /** + * 添加默认指令 + * @access public + * @param array $classes 指令 + * @return void + */ + public static function addDefaultCommands(array $classes) { - self::$defaultCommands = array_merge(self::$defaultCommands, $classnames); + self::$defaultCommands = array_merge(self::$defaultCommands, $classes); } /** * 获取可能的建议 - * @param array $abbrevs + * @access private + * @param array $abbrevs * @return string */ private function getAbbreviationSuggestions($abbrevs) { - return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : ''); + return sprintf( + '%s, %s%s', + $abbrevs[0], + $abbrevs[1], + count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '' + ); } /** - * 返回命名空间部分 - * @param string $name 指令 - * @param string $limit 部分的命名空间的最大数量 + * 返回指令的命名空间部分 + * @access public + * @param string $name 指令名称 + * @param string $limit 部分的命名空间的最大数量 * @return string */ public function extractNamespace($name, $limit = null) @@ -638,16 +766,17 @@ class Console /** * 查找可替代的建议 - * @param string $name - * @param array|\Traversable $collection + * @access private + * @param string $name 指令名称 + * @param array|\Traversable $collection 建议集合 * @return array */ private function findAlternatives($name, $collection) { - $threshold = 1e3; - $alternatives = []; - + $threshold = 1e3; + $alternatives = []; $collectionParts = []; + foreach ($collection as $item) { $collectionParts[$item] = explode(':', $item); } @@ -655,6 +784,7 @@ class Console foreach (explode(':', $name) as $i => $subname) { foreach ($collectionParts as $collectionName => $parts) { $exists = isset($alternatives[$collectionName]); + if (!isset($parts[$i]) && $exists) { $alternatives[$collectionName] += $threshold; continue; @@ -663,8 +793,14 @@ class Console } $lev = levenshtein($subname, $parts[$i]); - if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) { - $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; + + if ($lev <= strlen($subname) / 3 || + '' !== $subname && + false !== strpos($parts[$i], $subname) + ) { + $alternatives[$collectionName] = $exists ? + $alternatives[$collectionName] + $lev : + $lev; } elseif ($exists) { $alternatives[$collectionName] += $threshold; } @@ -673,14 +809,18 @@ class Console foreach ($collection as $item) { $lev = levenshtein($name, $item); + if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { - $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; + $alternatives[$item] = isset($alternatives[$item]) ? + $alternatives[$item] - $lev : + $lev; } } $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; }); + asort($alternatives); return array_keys($alternatives); @@ -688,24 +828,28 @@ class Console /** * 设置默认的指令 - * @param string $commandName The Command name + * @access public + * @param string $commandName 指令名称 + * @return $this */ public function setDefaultCommand($commandName) { $this->defaultCommand = $commandName; + + return $this; } /** * 返回所有的命名空间 - * @param string $name + * @access private + * @param string $name 指令名称 * @return array */ private function extractAllNamespaces($name) { - $parts = explode(':', $name, -1); $namespaces = []; - foreach ($parts as $part) { + foreach (explode(':', $name, -1) as $part) { if (count($namespaces)) { $namespaces[] = end($namespaces) . ':' . $part; } else { diff --git a/thinkphp/library/think/Controller.php b/thinkphp/library/think/Controller.php index 7aba39cd..77225b73 100644 --- a/thinkphp/library/think/Controller.php +++ b/thinkphp/library/think/Controller.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -11,46 +11,49 @@ namespace think; -\think\Loader::import('controller/Jump', TRAIT_PATH, EXT); - use think\exception\ValidateException; +use traits\controller\Jump; + +Loader::import('controller/Jump', TRAIT_PATH, EXT); class Controller { - use \traits\controller\Jump; + use Jump; /** * @var \think\View 视图类实例 */ protected $view; + /** - * @var \think\Request Request实例 + * @var \think\Request Request 实例 */ protected $request; - // 验证失败是否抛出异常 + + /** + * @var bool 验证失败是否抛出异常 + */ protected $failException = false; - // 是否批量验证 + + /** + * @var bool 是否批量验证 + */ protected $batchValidate = false; /** - * 前置操作方法列表 - * @var array $beforeActionList - * @access protected + * @var array 前置操作方法列表 */ protected $beforeActionList = []; /** * 构造方法 - * @param Request $request Request对象 * @access public + * @param Request $request Request 对象 */ public function __construct(Request $request = null) { - if (is_null($request)) { - $request = Request::instance(); - } $this->view = View::instance(Config::get('template'), Config::get('view_replace_str')); - $this->request = $request; + $this->request = is_null($request) ? Request::instance() : $request; // 控制器初始化 $this->_initialize(); @@ -65,7 +68,10 @@ class Controller } } - // 初始化 + /** + * 初始化操作 + * @access protected + */ protected function _initialize() { } @@ -73,8 +79,9 @@ class Controller /** * 前置操作 * @access protected - * @param string $method 前置操作方法名 - * @param array $options 调用参数 ['only'=>[...]] 或者['except'=>[...]] + * @param string $method 前置操作方法名 + * @param array $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]] + * @return void */ protected function beforeAction($method, $options = []) { @@ -82,6 +89,7 @@ class Controller if (is_string($options['only'])) { $options['only'] = explode(',', $options['only']); } + if (!in_array($this->request->action(), $options['only'])) { return; } @@ -89,6 +97,7 @@ class Controller if (is_string($options['except'])) { $options['except'] = explode(',', $options['except']); } + if (in_array($this->request->action(), $options['except'])) { return; } @@ -100,10 +109,10 @@ class Controller /** * 加载模板输出 * @access protected - * @param string $template 模板文件名 - * @param array $vars 模板输出变量 - * @param array $replace 模板替换 - * @param array $config 模板参数 + * @param string $template 模板文件名 + * @param array $vars 模板输出变量 + * @param array $replace 模板替换 + * @param array $config 模板参数 * @return mixed */ protected function fetch($template = '', $vars = [], $replace = [], $config = []) @@ -114,10 +123,10 @@ class Controller /** * 渲染内容输出 * @access protected - * @param string $content 模板内容 - * @param array $vars 模板输出变量 - * @param array $replace 替换内容 - * @param array $config 模板参数 + * @param string $content 模板内容 + * @param array $vars 模板输出变量 + * @param array $replace 替换内容 + * @param array $config 模板参数 * @return mixed */ protected function display($content = '', $vars = [], $replace = [], $config = []) @@ -128,24 +137,28 @@ class Controller /** * 模板变量赋值 * @access protected - * @param mixed $name 要显示的模板变量 - * @param mixed $value 变量的值 - * @return void + * @param mixed $name 要显示的模板变量 + * @param mixed $value 变量的值 + * @return $this */ protected function assign($name, $value = '') { $this->view->assign($name, $value); + + return $this; } /** * 初始化模板引擎 * @access protected * @param array|string $engine 引擎参数 - * @return void + * @return $this */ protected function engine($engine) { $this->view->engine($engine); + + return $this; } /** @@ -157,17 +170,18 @@ class Controller protected function validateFailException($fail = true) { $this->failException = $fail; + return $this; } /** * 验证数据 * @access protected - * @param array $data 数据 - * @param string|array $validate 验证器名或者验证规则数组 - * @param array $message 提示信息 - * @param bool $batch 是否批量验证 - * @param mixed $callback 回调方法(闭包) + * @param array $data 数据 + * @param string|array $validate 验证器名或者验证规则数组 + * @param array $message 提示信息 + * @param bool $batch 是否批量验证 + * @param mixed $callback 回调方法(闭包) * @return array|string|true * @throws ValidateException */ @@ -177,24 +191,27 @@ class Controller $v = Loader::validate(); $v->rule($validate); } else { + // 支持场景 if (strpos($validate, '.')) { - // 支持场景 list($validate, $scene) = explode('.', $validate); } + $v = Loader::validate($validate); - if (!empty($scene)) { - $v->scene($scene); - } + + !empty($scene) && $v->scene($scene); } - // 是否批量验证 + + // 批量验证 if ($batch || $this->batchValidate) { $v->batch(true); } + // 设置错误信息 if (is_array($message)) { $v->message($message); } + // 使用回调验证 if ($callback && is_callable($callback)) { call_user_func_array($callback, [$v, &$data]); } @@ -202,11 +219,11 @@ class Controller if (!$v->check($data)) { if ($this->failException) { throw new ValidateException($v->getError()); - } else { - return $v->getError(); } - } else { - return true; + + return $v->getError(); } + + return true; } } diff --git a/thinkphp/library/think/Cookie.php b/thinkphp/library/think/Cookie.php index 3205fcd9..61b47cce 100644 --- a/thinkphp/library/think/Cookie.php +++ b/thinkphp/library/think/Cookie.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -13,28 +13,28 @@ namespace think; class Cookie { + /** + * @var array cookie 设置参数 + */ protected static $config = [ - // cookie 名称前缀 - 'prefix' => '', - // cookie 保存时间 - 'expire' => 0, - // cookie 保存路径 - 'path' => '/', - // cookie 有效域名 - 'domain' => '', - // cookie 启用安全传输 - 'secure' => false, - // httponly设置 - 'httponly' => '', - // 是否使用 setcookie - 'setcookie' => true, + 'prefix' => '', // cookie 名称前缀 + 'expire' => 0, // cookie 保存时间 + 'path' => '/', // cookie 保存路径 + 'domain' => '', // cookie 有效域名 + 'secure' => false, // cookie 启用安全传输 + 'httponly' => false, // httponly 设置 + 'setcookie' => true, // 是否使用 setcookie ]; + /** + * @var bool 是否完成初始化了 + */ protected static $init; /** * Cookie初始化 - * @param array $config + * @access public + * @param array $config 配置参数 * @return void */ public static function init(array $config = []) @@ -42,39 +42,43 @@ class Cookie if (empty($config)) { $config = Config::get('cookie'); } + self::$config = array_merge(self::$config, array_change_key_case($config)); + if (!empty(self::$config['httponly'])) { ini_set('session.cookie_httponly', 1); } + self::$init = true; } /** - * 设置或者获取cookie作用域(前缀) - * @param string $prefix - * @return string|void + * 设置或者获取 cookie 作用域(前缀) + * @access public + * @param string $prefix 前缀 + * @return string| */ public static function prefix($prefix = '') { if (empty($prefix)) { return self::$config['prefix']; } - self::$config['prefix'] = $prefix; + + return self::$config['prefix'] = $prefix; } /** * Cookie 设置、获取、删除 - * - * @param string $name cookie名称 - * @param mixed $value cookie值 - * @param mixed $option 可选参数 可能会是 null|integer|string - * - * @return mixed - * @internal param mixed $options cookie参数 + * @access public + * @param string $name cookie 名称 + * @param mixed $value cookie 值 + * @param mixed $option 可选参数 可能会是 null|integer|string + * @return void */ public static function set($name, $value = '', $option = null) { !isset(self::$init) && self::init(); + // 参数设置(会覆盖黙认设置) if (!is_null($option)) { if (is_numeric($option)) { @@ -82,28 +86,40 @@ class Cookie } elseif (is_string($option)) { parse_str($option, $option); } + $config = array_merge(self::$config, array_change_key_case($option)); } else { $config = self::$config; } + $name = $config['prefix'] . $name; - // 设置cookie + + // 设置 cookie if (is_array($value)) { array_walk_recursive($value, 'self::jsonFormatProtect', 'encode'); $value = 'think:' . json_encode($value); } - $expire = !empty($config['expire']) ? $_SERVER['REQUEST_TIME'] + intval($config['expire']) : 0; + + $expire = !empty($config['expire']) ? + $_SERVER['REQUEST_TIME'] + intval($config['expire']) : + 0; + if ($config['setcookie']) { - setcookie($name, $value, $expire, $config['path'], $config['domain'], $config['secure'], $config['httponly']); + setcookie( + $name, $value, $expire, $config['path'], $config['domain'], + $config['secure'], $config['httponly'] + ); } + $_COOKIE[$name] = $value; } /** - * 永久保存Cookie数据 - * @param string $name cookie名称 - * @param mixed $value cookie值 - * @param mixed $option 可选参数 可能会是 null|integer|string + * 永久保存 Cookie 数据 + * @access public + * @param string $name cookie 名称 + * @param mixed $value cookie 值 + * @param mixed $option 可选参数 可能会是 null|integer|string * @return void */ public static function forever($name, $value = '', $option = null) @@ -111,33 +127,39 @@ class Cookie if (is_null($option) || is_numeric($option)) { $option = []; } + $option['expire'] = 315360000; + self::set($name, $value, $option); } /** - * 判断Cookie数据 - * @param string $name cookie名称 - * @param string|null $prefix cookie前缀 + * 判断是否有 Cookie 数据 + * @access public + * @param string $name cookie 名称 + * @param string|null $prefix cookie 前缀 * @return bool */ public static function has($name, $prefix = null) { !isset(self::$init) && self::init(); + $prefix = !is_null($prefix) ? $prefix : self::$config['prefix']; - $name = $prefix . $name; - return isset($_COOKIE[$name]); + + return isset($_COOKIE[$prefix . $name]); } /** - * Cookie获取 - * @param string $name cookie名称 - * @param string|null $prefix cookie前缀 + * 获取 Cookie 的值 + * @access public + * @param string $name cookie 名称 + * @param string|null $prefix cookie 前缀 * @return mixed */ public static function get($name = '', $prefix = null) { !isset(self::$init) && self::init(); + $prefix = !is_null($prefix) ? $prefix : self::$config['prefix']; $key = $prefix . $name; @@ -145,80 +167,102 @@ class Cookie // 获取全部 if ($prefix) { $value = []; + foreach ($_COOKIE as $k => $val) { if (0 === strpos($k, $prefix)) { $value[$k] = $val; } + } } else { $value = $_COOKIE; } } elseif (isset($_COOKIE[$key])) { $value = $_COOKIE[$key]; + if (0 === strpos($value, 'think:')) { - $value = substr($value, 6); - $value = json_decode($value, true); + $value = json_decode(substr($value, 6), true); array_walk_recursive($value, 'self::jsonFormatProtect', 'decode'); } } else { $value = null; } + return $value; } /** - * Cookie删除 - * @param string $name cookie名称 - * @param string|null $prefix cookie前缀 - * @return mixed + * 删除 Cookie + * @access public + * @param string $name cookie 名称 + * @param string|null $prefix cookie 前缀 + * @return void */ public static function delete($name, $prefix = null) { !isset(self::$init) && self::init(); + $config = self::$config; $prefix = !is_null($prefix) ? $prefix : $config['prefix']; $name = $prefix . $name; + if ($config['setcookie']) { - setcookie($name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); + setcookie( + $name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], + $config['domain'], $config['secure'], $config['httponly'] + ); } - // 删除指定cookie + + // 删除指定 cookie unset($_COOKIE[$name]); } /** - * Cookie清空 - * @param string|null $prefix cookie前缀 - * @return mixed + * 清除指定前缀的所有 cookie + * @access public + * @param string|null $prefix cookie 前缀 + * @return void */ public static function clear($prefix = null) { - // 清除指定前缀的所有cookie if (empty($_COOKIE)) { return; } + !isset(self::$init) && self::init(); - // 要删除的cookie前缀,不指定则删除config设置的指定前缀 + + // 要删除的 cookie 前缀,不指定则删除 config 设置的指定前缀 $config = self::$config; $prefix = !is_null($prefix) ? $prefix : $config['prefix']; + if ($prefix) { - // 如果前缀为空字符串将不作处理直接返回 foreach ($_COOKIE as $key => $val) { if (0 === strpos($key, $prefix)) { if ($config['setcookie']) { - setcookie($key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); + setcookie( + $key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], + $config['domain'], $config['secure'], $config['httponly'] + ); } + unset($_COOKIE[$key]); } } } - return; } - private static function jsonFormatProtect(&$val, $key, $type = 'encode') + /** + * json 转换时的格式保护 + * @access protected + * @param mixed $val 要转换的值 + * @param string $key 键名 + * @param string $type 转换类别 + * @return void + */ + protected static function jsonFormatProtect(&$val, $key, $type = 'encode') { if (!empty($val) && true !== $val) { $val = 'decode' == $type ? urldecode($val) : urlencode($val); } } - } diff --git a/thinkphp/library/think/Db.php b/thinkphp/library/think/Db.php index 3e613f7a..80f08d24 100644 --- a/thinkphp/library/think/Db.php +++ b/thinkphp/library/think/Db.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -49,19 +49,26 @@ use think\db\Query; */ class Db { - // 数据库连接实例 + /** + * @var Connection[] 数据库连接实例 + */ private static $instance = []; - // 查询次数 + + /** + * @var int 查询次数 + */ public static $queryTimes = 0; - // 执行次数 + + /** + * @var int 执行次数 + */ public static $executeTimes = 0; /** - * 数据库初始化 并取得数据库类实例 - * @static + * 数据库初始化,并取得数据库类实例 * @access public - * @param mixed $config 连接配置 - * @param bool|string $name 连接标识 true 强制重新连接 + * @param mixed $config 连接配置 + * @param bool|string $name 连接标识 true 强制重新连接 * @return Connection * @throws Exception */ @@ -70,31 +77,48 @@ class Db if (false === $name) { $name = md5(serialize($config)); } + if (true === $name || !isset(self::$instance[$name])) { // 解析连接参数 支持数组和字符串 $options = self::parseConfig($config); + if (empty($options['type'])) { - throw new \InvalidArgumentException('Underfined db type'); + throw new \InvalidArgumentException('Undefined db type'); } - $class = false !== strpos($options['type'], '\\') ? $options['type'] : '\\think\\db\\connector\\' . ucwords($options['type']); + + $class = false !== strpos($options['type'], '\\') ? + $options['type'] : + '\\think\\db\\connector\\' . ucwords($options['type']); + // 记录初始化信息 if (App::$debug) { Log::record('[ DB ] INIT ' . $options['type'], 'info'); } + if (true === $name) { - return new $class($options); - } else { - self::$instance[$name] = new $class($options); + $name = md5(serialize($config)); } + + self::$instance[$name] = new $class($options); } + return self::$instance[$name]; } + /** + * 清除连接实例 + * @access public + * @return void + */ + public static function clear() + { + self::$instance = []; + } + /** * 数据库连接参数解析 - * @static * @access private - * @param mixed $config + * @param mixed $config 连接参数 * @return array */ private static function parseConfig($config) @@ -102,30 +126,27 @@ class Db if (empty($config)) { $config = Config::get('database'); } elseif (is_string($config) && false === strpos($config, '/')) { - // 支持读取配置参数 - $config = Config::get($config); - } - if (is_string($config)) { - return self::parseDsn($config); - } else { - return $config; + $config = Config::get($config); // 支持读取配置参数 } + + return is_string($config) ? self::parseDsn($config) : $config; } /** - * DSN解析 + * DSN 解析 * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1¶m2=val2#utf8 - * @static * @access private - * @param string $dsnStr + * @param string $dsnStr 数据库 DSN 字符串解析 * @return array */ private static function parseDsn($dsnStr) { $info = parse_url($dsnStr); + if (!$info) { return []; } + $dsn = [ 'type' => $info['scheme'], 'username' => isset($info['user']) ? $info['user'] : '', @@ -141,13 +162,19 @@ class Db } else { $dsn['params'] = []; } + return $dsn; } - // 调用驱动类的方法 + /** + * 调用驱动类的方法 + * @access public + * @param string $method 方法名 + * @param array $params 参数 + * @return mixed + */ public static function __callStatic($method, $params) { - // 自动初始化数据库 return call_user_func_array([self::connect(), $method], $params); } } diff --git a/thinkphp/library/think/Debug.php b/thinkphp/library/think/Debug.php index 9994e20c..df487485 100644 --- a/thinkphp/library/think/Debug.php +++ b/thinkphp/library/think/Debug.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -16,21 +16,27 @@ use think\response\Redirect; class Debug { - // 区间时间信息 + /** + * @var array 区间时间信息 + */ protected static $info = []; - // 区间内存信息 + + /** + * @var array 区间内存信息 + */ protected static $mem = []; /** * 记录时间(微秒)和内存使用情况 - * @param string $name 标记位置 - * @param mixed $value 标记值 留空则取当前 time 表示仅记录时间 否则同时记录时间和内存 - * @return mixed + * @access public + * @param string $name 标记位置 + * @param mixed $value 标记值(留空则取当前 time 表示仅记录时间 否则同时记录时间和内存) + * @return void */ public static function remark($name, $value = '') { - // 记录时间和内存使用 self::$info[$name] = is_float($value) ? $value : microtime(true); + if ('time' != $value) { self::$mem['mem'][$name] = is_float($value) ? $value : memory_get_usage(); self::$mem['peak'][$name] = memory_get_peak_usage(); @@ -39,23 +45,26 @@ class Debug /** * 统计某个区间的时间(微秒)使用情况 返回值以秒为单位 - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer|string $dec 小数位 - * @return integer + * @access public + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer $dec 小数位 + * @return string */ public static function getRangeTime($start, $end, $dec = 6) { if (!isset(self::$info[$end])) { self::$info[$end] = microtime(true); } + return number_format((self::$info[$end] - self::$info[$start]), $dec); } /** * 统计从开始到统计时的时间(微秒)使用情况 返回值以秒为单位 - * @param integer|string $dec 小数位 - * @return integer + * @access public + * @param integer $dec 小数位 + * @return string */ public static function getUseTime($dec = 6) { @@ -64,6 +73,7 @@ class Debug /** * 获取当前访问的吞吐率情况 + * @access public * @return string */ public static function getThroughputRate() @@ -73,9 +83,10 @@ class Debug /** * 记录区间的内存使用情况 - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer|string $dec 小数位 + * @access public + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer $dec 小数位 * @return string */ public static function getRangeMem($start, $end, $dec = 2) @@ -83,19 +94,23 @@ class Debug if (!isset(self::$mem['mem'][$end])) { self::$mem['mem'][$end] = memory_get_usage(); } + $size = self::$mem['mem'][$end] - self::$mem['mem'][$start]; $a = ['B', 'KB', 'MB', 'GB', 'TB']; $pos = 0; + while ($size >= 1024) { $size /= 1024; $pos++; } + return round($size, $dec) . " " . $a[$pos]; } /** * 统计从开始到统计时的内存使用情况 - * @param integer|string $dec 小数位 + * @access public + * @param integer $dec 小数位 * @return string */ public static function getUseMem($dec = 2) @@ -103,103 +118,128 @@ class Debug $size = memory_get_usage() - THINK_START_MEM; $a = ['B', 'KB', 'MB', 'GB', 'TB']; $pos = 0; + while ($size >= 1024) { $size /= 1024; $pos++; } + return round($size, $dec) . " " . $a[$pos]; } /** * 统计区间的内存峰值情况 - * @param string $start 开始标签 - * @param string $end 结束标签 - * @param integer|string $dec 小数位 - * @return mixed + * @access public + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer $dec 小数位 + * @return string */ public static function getMemPeak($start, $end, $dec = 2) { if (!isset(self::$mem['peak'][$end])) { self::$mem['peak'][$end] = memory_get_peak_usage(); } + $size = self::$mem['peak'][$end] - self::$mem['peak'][$start]; $a = ['B', 'KB', 'MB', 'GB', 'TB']; $pos = 0; + while ($size >= 1024) { $size /= 1024; $pos++; } + return round($size, $dec) . " " . $a[$pos]; } /** * 获取文件加载信息 - * @param bool $detail 是否显示详细 + * @access public + * @param bool $detail 是否显示详细 * @return integer|array */ public static function getFile($detail = false) { + $files = get_included_files(); + if ($detail) { - $files = get_included_files(); - $info = []; - foreach ($files as $key => $file) { + $info = []; + + foreach ($files as $file) { $info[] = $file . ' ( ' . number_format(filesize($file) / 1024, 2) . ' KB )'; } + return $info; } - return count(get_included_files()); + + return count($files); } /** * 浏览器友好的变量输出 - * @param mixed $var 变量 - * @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串 - * @param string $label 标签 默认为空 - * @param integer $flags htmlspecialchars flags - * @return void|string + * @access public + * @param mixed $var 变量 + * @param boolean $echo 是否输出(默认为 true,为 false 则返回输出字符串) + * @param string|null $label 标签(默认为空) + * @param integer $flags htmlspecialchars 的标志 + * @return null|string */ public static function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE) { $label = (null === $label) ? '' : rtrim($label) . ':'; + ob_start(); var_dump($var); - $output = ob_get_clean(); - $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output); + $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', ob_get_clean()); + if (IS_CLI) { $output = PHP_EOL . $label . $output . PHP_EOL; } else { if (!extension_loaded('xdebug')) { $output = htmlspecialchars($output, $flags); } + $output = '
' . $label . $output . '
'; } + if ($echo) { echo($output); return; - } else { - return $output; } + + return $output; } + /** + * 调试信息注入到响应中 + * @access public + * @param Response $response 响应实例 + * @param string $content 返回的字符串 + * @return void + */ public static function inject(Response $response, &$content) { - $config = Config::get('trace'); - $type = isset($config['type']) ? $config['type'] : 'Html'; - $request = Request::instance(); - $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); + $config = Config::get('trace'); + $type = isset($config['type']) ? $config['type'] : 'Html'; + $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); + unset($config['type']); - if (class_exists($class)) { - $trace = new $class($config); - } else { + + if (!class_exists($class)) { throw new ClassNotFoundException('class not exists:' . $class, $class); } + /** @var \think\debug\Console|\think\debug\Html $trace */ + $trace = new $class($config); + if ($response instanceof Redirect) { - //TODO 记录 + // TODO 记录 } else { $output = $trace->output($response, Log::getLog()); + if (is_string($output)) { - // trace调试信息注入 + // trace 调试信息注入 $pos = strripos($content, ''); if (false !== $pos) { $content = substr($content, 0, $pos) . $output . substr($content, $pos); diff --git a/thinkphp/library/think/Env.php b/thinkphp/library/think/Env.php index fa87897c..0a8b2509 100644 --- a/thinkphp/library/think/Env.php +++ b/thinkphp/library/think/Env.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -15,22 +15,25 @@ class Env { /** * 获取环境变量值 - * @param string $name 环境变量名(支持二级 .号分割) - * @param string $default 默认值 + * @access public + * @param string $name 环境变量名(支持二级 . 号分割) + * @param string $default 默认值 * @return mixed */ public static function get($name, $default = null) { $result = getenv(ENV_PREFIX . strtoupper(str_replace('.', '_', $name))); + if (false !== $result) { if ('false' === $result) { $result = false; } elseif ('true' === $result) { $result = true; } + return $result; - } else { - return $default; } + + return $default; } } diff --git a/thinkphp/library/think/Error.php b/thinkphp/library/think/Error.php index c17292bf..5f361d58 100644 --- a/thinkphp/library/think/Error.php +++ b/thinkphp/library/think/Error.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -20,6 +20,7 @@ class Error { /** * 注册异常处理 + * @access public * @return void */ public static function register() @@ -31,8 +32,10 @@ class Error } /** - * Exception Handler - * @param \Exception|\Throwable $e + * 异常处理 + * @access public + * @param \Exception|\Throwable $e 异常 + * @return void */ public static function appException($e) { @@ -40,44 +43,50 @@ class Error $e = new ThrowableError($e); } - self::getExceptionHandler()->report($e); + $handler = self::getExceptionHandler(); + $handler->report($e); + if (IS_CLI) { - self::getExceptionHandler()->renderForConsole(new ConsoleOutput, $e); + $handler->renderForConsole(new ConsoleOutput, $e); } else { - self::getExceptionHandler()->render($e)->send(); + $handler->render($e)->send(); } } /** - * Error Handler - * @param integer $errno 错误编号 - * @param integer $errstr 详细错误信息 - * @param string $errfile 出错的文件 - * @param integer $errline 出错行号 - * @param array $errcontext + * 错误处理 + * @access public + * @param integer $errno 错误编号 + * @param integer $errstr 详细错误信息 + * @param string $errfile 出错的文件 + * @param integer $errline 出错行号 + * @return void * @throws ErrorException */ - public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = []) + public static function appError($errno, $errstr, $errfile = '', $errline = 0) { - $exception = new ErrorException($errno, $errstr, $errfile, $errline, $errcontext); + $exception = new ErrorException($errno, $errstr, $errfile, $errline); + + // 符合异常处理的则将错误信息托管至 think\exception\ErrorException if (error_reporting() & $errno) { - // 将错误信息托管至 think\exception\ErrorException throw $exception; - } else { - self::getExceptionHandler()->report($exception); } + + self::getExceptionHandler()->report($exception); } /** - * Shutdown Handler + * 异常中止处理 + * @access public + * @return void */ public static function appShutdown() { + // 将错误信息托管至 think\ErrorException if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) { - // 将错误信息托管至think\ErrorException - $exception = new ErrorException($error['type'], $error['message'], $error['file'], $error['line']); - - self::appException($exception); + self::appException(new ErrorException( + $error['type'], $error['message'], $error['file'], $error['line'] + )); } // 写入日志 @@ -86,8 +95,8 @@ class Error /** * 确定错误类型是否致命 - * - * @param int $type + * @access protected + * @param int $type 错误类型 * @return bool */ protected static function isFatal($type) @@ -96,22 +105,32 @@ class Error } /** - * Get an instance of the exception handler. - * + * 获取异常处理的实例 + * @access public * @return Handle */ public static function getExceptionHandler() { static $handle; + if (!$handle) { - // 异常处理handle + // 异常处理 handle $class = Config::get('exception_handle'); - if ($class && class_exists($class) && is_subclass_of($class, "\\think\\exception\\Handle")) { + + if ($class && is_string($class) && class_exists($class) && + is_subclass_of($class, "\\think\\exception\\Handle") + ) { $handle = new $class; } else { $handle = new Handle; + + if ($class instanceof \Closure) { + $handle->setRender($class); + } + } } + return $handle; } } diff --git a/thinkphp/library/think/Exception.php b/thinkphp/library/think/Exception.php index 034c85b6..1ef06bdb 100644 --- a/thinkphp/library/think/Exception.php +++ b/thinkphp/library/think/Exception.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -13,15 +13,13 @@ namespace think; class Exception extends \Exception { - /** - * 保存异常页面显示的额外Debug数据 - * @var array + * @var array 保存异常页面显示的额外 Debug 数据 */ protected $data = []; /** - * 设置异常额外的Debug数据 + * 设置异常额外的 Debug 数据 * 数据将会显示为下面的格式 * * Exception Data @@ -33,8 +31,10 @@ class Exception extends \Exception * key1 value1 * key2 value2 * - * @param string $label 数据分类,用于异常页面显示 - * @param array $data 需要显示的数据,必须为关联数组 + * @access protected + * @param string $label 数据分类,用于异常页面显示 + * @param array $data 需要显示的数据,必须为关联数组 + * @return void */ final protected function setData($label, array $data) { @@ -42,13 +42,14 @@ class Exception extends \Exception } /** - * 获取异常额外Debug数据 + * 获取异常额外 Debug 数据 * 主要用于输出到异常页面便于调试 - * @return array 由setData设置的Debug数据 + * @access public + * @return array */ final public function getData() { return $this->data; } - + } diff --git a/thinkphp/library/think/File.php b/thinkphp/library/think/File.php index 90eac4e2..d2ed2208 100644 --- a/thinkphp/library/think/File.php +++ b/thinkphp/library/think/File.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -16,25 +16,51 @@ use SplFileObject; class File extends SplFileObject { /** - * 错误信息 - * @var string + * @var string 错误信息 */ private $error = ''; - // 当前完整文件名 + + /** + * @var string 当前完整文件名 + */ protected $filename; - // 上传文件名 + + /** + * @var string 上传文件名 + */ protected $saveName; - // 文件上传命名规则 + + /** + * @var string 文件上传命名规则 + */ protected $rule = 'date'; - // 文件上传验证规则 + + /** + * @var array 文件上传验证规则 + */ protected $validate = []; - // 单元测试 + + /** + * @var bool 单元测试 + */ protected $isTest; - // 上传文件信息 + + /** + * @var array 上传文件信息 + */ protected $info; - // 文件hash信息 + + /** + * @var array 文件 hash 信息 + */ protected $hash = []; + /** + * File constructor. + * @access public + * @param string $filename 文件名称 + * @param string $mode 访问模式 + */ public function __construct($filename, $mode = 'r') { parent::__construct($filename, $mode); @@ -42,30 +68,35 @@ class File extends SplFileObject } /** - * 是否测试 - * @param bool $test 是否测试 + * 设置是否是单元测试 + * @access public + * @param bool $test 是否是测试 * @return $this */ public function isTest($test = false) { $this->isTest = $test; + return $this; } /** * 设置上传信息 - * @param array $info 上传文件信息 + * @access public + * @param array $info 上传文件信息 * @return $this */ public function setUploadInfo($info) { $this->info = $info; + return $this; } /** * 获取上传文件的信息 - * @param string $name + * @access public + * @param string $name 信息名称 * @return array|string */ public function getInfo($name = '') @@ -75,106 +106,111 @@ class File extends SplFileObject /** * 获取上传文件的文件名 + * @access public * @return string */ public function getSaveName() { return $this->saveName; } - public function getFileName() - { - return $this->filename; - } /** * 设置上传文件的保存文件名 - * @param string $saveName + * @access public + * @param string $saveName 保存名称 * @return $this */ public function setSaveName($saveName) { $this->saveName = $saveName; + return $this; } /** * 获取文件的哈希散列值 - * @return $string + * @access public + * @param string $type 类型 + * @return string */ public function hash($type = 'sha1') { if (!isset($this->hash[$type])) { $this->hash[$type] = hash_file($type, $this->filename); } + return $this->hash[$type]; } /** * 检查目录是否可写 - * @param string $path 目录 + * @access protected + * @param string $path 目录 * @return boolean */ protected function checkPath($path) { - if (is_dir($path)) { + if (is_dir($path) || mkdir($path, 0755, true)) { return true; } - if (mkdir($path, 0755, true)) { - return true; - } else { - $this->error = "目录 {$path} 创建失败!"; - return false; - } + $this->error = ['directory {:path} creation failed', ['path' => $path]]; + + return false; } /** * 获取文件类型信息 + * @access public * @return string */ public function getMime() { $finfo = finfo_open(FILEINFO_MIME_TYPE); + return finfo_file($finfo, $this->filename); } /** * 设置文件的命名规则 - * @param string $rule 文件命名规则 + * @access public + * @param string $rule 文件命名规则 * @return $this */ public function rule($rule) { $this->rule = $rule; + return $this; } /** * 设置上传文件的验证规则 - * @param array $rule 验证规则 + * @access public + * @param array $rule 验证规则 * @return $this */ - public function validate($rule = []) + public function validate(array $rule = []) { $this->validate = $rule; + return $this; } /** * 检测是否合法的上传文件 + * @access public * @return bool */ public function isValid() { - if ($this->isTest) { - return is_file($this->filename); - } - return is_uploaded_file($this->filename); + return $this->isTest ? is_file($this->filename) : is_uploaded_file($this->filename); } /** * 检测上传文件 - * @param array $rule 验证规则 + * @access public + * @param array $rule 验证规则 * @return bool */ public function check($rule = []) @@ -183,25 +219,25 @@ class File extends SplFileObject /* 检查文件大小 */ if (isset($rule['size']) && !$this->checkSize($rule['size'])) { - $this->error = '上传文件大小不符!'; + $this->error = 'filesize not match'; return false; } - /* 检查文件Mime类型 */ + /* 检查文件 Mime 类型 */ if (isset($rule['type']) && !$this->checkMime($rule['type'])) { - $this->error = '上传文件MIME类型不允许!'; + $this->error = 'mimetype to upload is not allowed'; return false; } /* 检查文件后缀 */ if (isset($rule['ext']) && !$this->checkExt($rule['ext'])) { - $this->error = '上传文件后缀不允许'; + $this->error = 'extensions to upload is not allowed'; return false; } /* 检查图像文件 */ if (!$this->checkImg()) { - $this->error = '非法图像文件!'; + $this->error = 'illegal image files'; return false; } @@ -210,7 +246,8 @@ class File extends SplFileObject /** * 检测上传文件后缀 - * @param array|string $ext 允许后缀 + * @access public + * @param array|string $ext 允许后缀 * @return bool */ public function checkExt($ext) @@ -218,73 +255,76 @@ class File extends SplFileObject if (is_string($ext)) { $ext = explode(',', $ext); } + $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); - if (!in_array($extension, $ext)) { - return false; - } - return true; + + return in_array($extension, $ext); } /** * 检测图像文件 + * @access public * @return bool */ public function checkImg() { $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); - /* 对图像文件进行严格检测 */ - if (in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) && !in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6])) { - return false; - } - return true; + + // 如果上传的不是图片,或者是图片而且后缀确实符合图片类型则返回 true + return !in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) || in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6, 13]); } - // 判断图像类型 + /** + * 判断图像类型 + * @access protected + * @param string $image 图片名称 + * @return bool|int + */ protected function getImageType($image) { if (function_exists('exif_imagetype')) { return exif_imagetype($image); - } else { + } + + try { $info = getimagesize($image); - return $info[2]; + return $info ? $info[2] : false; + } catch (\Exception $e) { + return false; } } /** * 检测上传文件大小 - * @param integer $size 最大大小 + * @access public + * @param integer $size 最大大小 * @return bool */ public function checkSize($size) { - if ($this->getSize() > $size) { - return false; - } - return true; + return $this->getSize() <= $size; } /** * 检测上传文件类型 - * @param array|string $mime 允许类型 + * @access public + * @param array|string $mime 允许类型 * @return bool */ public function checkMime($mime) { - if (is_string($mime)) { - $mime = explode(',', $mime); - } - if (!in_array(strtolower($this->getMime()), $mime)) { - return false; - } - return true; + $mime = is_string($mime) ? explode(',', $mime) : $mime; + + return in_array(strtolower($this->getMime()), $mime); } /** * 移动文件 - * @param string $path 保存路径 - * @param string|bool $savename 保存的文件名 默认自动生成 - * @param boolean $replace 同名文件是否覆盖 - * @return false|File false-失败 否则返回File实例 + * @access public + * @param string $path 保存路径 + * @param string|bool $savename 保存的文件名 默认自动生成 + * @param boolean $replace 同名文件是否覆盖 + * @return false|File */ public function move($path, $savename = true, $replace = true) { @@ -296,7 +336,7 @@ class File extends SplFileObject // 检测合法性 if (!$this->isValid()) { - $this->error = '非法上传文件'; + $this->error = 'upload illegal files'; return false; } @@ -304,6 +344,7 @@ class File extends SplFileObject if (!$this->check()) { return false; } + $path = rtrim($path, DS) . DS; // 文件保存命名规则 $saveName = $this->buildSaveName($savename); @@ -314,9 +355,9 @@ class File extends SplFileObject return false; } - /* 不覆盖同名文件 */ + // 不覆盖同名文件 if (!$replace && is_file($filename)) { - $this->error = '存在同名文件'; + $this->error = ['has the same filename: {:filename}', ['filename' => $filename]]; return false; } @@ -324,25 +365,27 @@ class File extends SplFileObject if ($this->isTest) { rename($this->filename, $filename); } elseif (!move_uploaded_file($this->filename, $filename)) { - $this->error = '文件上传保存错误!'; + $this->error = 'upload write error'; return false; } - // 返回 File对象实例 + + // 返回 File 对象实例 $file = new self($filename); - $file->setSaveName($saveName); - $file->setUploadInfo($this->info); + $file->setSaveName($saveName)->setUploadInfo($this->info); + return $file; } /** * 获取保存文件名 - * @param string|bool $savename 保存的文件名 默认自动生成 + * @access protected + * @param string|bool $savename 保存的文件名 默认自动生成 * @return string */ protected function buildSaveName($savename) { + // 自动生成文件名 if (true === $savename) { - // 自动生成文件名 if ($this->rule instanceof \Closure) { $savename = call_user_func_array($this->rule, [$this]); } else { @@ -361,52 +404,73 @@ class File extends SplFileObject } } } - } elseif ('' === $savename) { + } elseif ('' === $savename || false === $savename) { $savename = $this->getInfo('name'); } + if (!strpos($savename, '.')) { $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION); } + return $savename; } /** * 获取错误代码信息 - * @param int $errorNo 错误号 + * @access private + * @param int $errorNo 错误号 + * @return $this */ private function error($errorNo) { switch ($errorNo) { case 1: case 2: - $this->error = '上传文件大小超过了最大值!'; + $this->error = 'upload File size exceeds the maximum value'; break; case 3: - $this->error = '文件只有部分被上传!'; + $this->error = 'only the portion of file is uploaded'; break; case 4: - $this->error = '没有文件被上传!'; + $this->error = 'no file to uploaded'; break; case 6: - $this->error = '找不到临时文件夹!'; + $this->error = 'upload temp dir not found'; break; case 7: - $this->error = '文件写入失败!'; + $this->error = 'file write error'; break; default: - $this->error = '未知上传错误!'; + $this->error = 'unknown upload error'; } + + return $this; } /** - * 获取错误信息 - * @return mixed + * 获取错误信息(支持多语言) + * @access public + * @return string */ public function getError() { - return $this->error; + if (is_array($this->error)) { + list($msg, $vars) = $this->error; + } else { + $msg = $this->error; + $vars = []; + } + + return Lang::has($msg) ? Lang::get($msg, $vars) : $msg; } + /** + * 魔法方法,获取文件的 hash 值 + * @access public + * @param string $method 方法名 + * @param mixed $args 调用参数 + * @return string + */ public function __call($method, $args) { return $this->hash($method); diff --git a/thinkphp/library/think/Hook.php b/thinkphp/library/think/Hook.php index f06196e4..a69ce546 100644 --- a/thinkphp/library/think/Hook.php +++ b/thinkphp/library/think/Hook.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -13,19 +13,23 @@ namespace think; class Hook { - + /** + * @var array 标签 + */ private static $tags = []; /** * 动态添加行为扩展到某个标签 - * @param string $tag 标签名称 - * @param mixed $behavior 行为名称 - * @param bool $first 是否放到开头执行 + * @access public + * @param string $tag 标签名称 + * @param mixed $behavior 行为名称 + * @param bool $first 是否放到开头执行 * @return void */ public static function add($tag, $behavior, $first = false) { isset(self::$tags[$tag]) || self::$tags[$tag] = []; + if (is_array($behavior) && !is_callable($behavior)) { if (!array_key_exists('_overlay', $behavior) || !$behavior['_overlay']) { unset($behavior['_overlay']); @@ -43,8 +47,10 @@ class Hook /** * 批量导入插件 - * @param array $tags 插件信息 - * @param boolean $recursive 是否递归合并 + * @access public + * @param array $tags 插件信息 + * @param boolean $recursive 是否递归合并 + * @return void */ public static function import(array $tags, $recursive = true) { @@ -59,55 +65,59 @@ class Hook /** * 获取插件信息 - * @param string $tag 插件位置 留空获取全部 + * @access public + * @param string $tag 插件位置(留空获取全部) * @return array */ public static function get($tag = '') { if (empty($tag)) { - //获取全部的插件信息 return self::$tags; - } else { - return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : []; } + + return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : []; } /** * 监听标签的行为 - * @param string $tag 标签名称 - * @param mixed $params 传入参数 - * @param mixed $extra 额外参数 - * @param bool $once 只获取一个有效返回值 + * @access public + * @param string $tag 标签名称 + * @param mixed $params 传入参数 + * @param mixed $extra 额外参数 + * @param bool $once 只获取一个有效返回值 * @return mixed */ public static function listen($tag, &$params = null, $extra = null, $once = false) { $results = []; - $tags = static::get($tag); - foreach ($tags as $key => $name) { + + foreach (static::get($tag) as $key => $name) { $results[$key] = self::exec($name, $tag, $params, $extra); - if (false === $results[$key]) { - // 如果返回false 则中断行为执行 - break; - } elseif (!is_null($results[$key]) && $once) { + + // 如果返回 false,或者仅获取一个有效返回则中断行为执行 + if (false === $results[$key] || (!is_null($results[$key]) && $once)) { break; } } + return $once ? end($results) : $results; } /** * 执行某个行为 - * @param mixed $class 要执行的行为 - * @param string $tag 方法名(标签名) - * @param Mixed $params 传人的参数 - * @param mixed $extra 额外参数 + * @access public + * @param mixed $class 要执行的行为 + * @param string $tag 方法名(标签名) + * @param mixed $params 传人的参数 + * @param mixed $extra 额外参数 * @return mixed */ public static function exec($class, $tag = '', &$params = null, $extra = null) { App::$debug && Debug::remark('behavior_start', 'time'); + $method = Loader::parseName($tag, 1, false); + if ($class instanceof \Closure) { $result = call_user_func_array($class, [ & $params, $extra]); $class = 'Closure'; @@ -126,10 +136,12 @@ class Hook $method = ($tag && is_callable([$obj, $method])) ? $method : 'run'; $result = $obj->$method($params, $extra); } + if (App::$debug) { Debug::remark('behavior_end', 'time'); Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info'); } + return $result; } diff --git a/thinkphp/library/think/Lang.php b/thinkphp/library/think/Lang.php index 2df3767c..a50d838d 100644 --- a/thinkphp/library/think/Lang.php +++ b/thinkphp/library/think/Lang.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -13,114 +13,148 @@ namespace think; class Lang { - // 语言数据 + /** + * @var array 语言数据 + */ private static $lang = []; - // 语言作用域 + + /** + * @var string 语言作用域 + */ private static $range = 'zh-cn'; - // 语言自动侦测的变量 + + /** + * @var string 语言自动侦测的变量 + */ protected static $langDetectVar = 'lang'; - // 语言Cookie变量 + + /** + * @var string 语言 Cookie 变量 + */ protected static $langCookieVar = 'think_var'; - // 语言Cookie的过期时间 + + /** + * @var int 语言 Cookie 的过期时间 + */ protected static $langCookieExpire = 3600; - // 允许语言列表 + + /** + * @var array 允许语言列表 + */ protected static $allowLangList = []; - // Accept-Language转义为对应语言包名称 系统默认配置 - protected static $acceptLanguage = [ - 'zh-hans-cn' => 'zh-cn', - ]; - // 设定当前的语言 + /** + * @var array Accept-Language 转义为对应语言包名称 系统默认配置 + */ + protected static $acceptLanguage = ['zh-hans-cn' => 'zh-cn']; + + /** + * 设定当前的语言 + * @access public + * @param string $range 语言作用域 + * @return string + */ public static function range($range = '') { - if ('' == $range) { - return self::$range; - } else { + if ($range) { self::$range = $range; } + return self::$range; } /** * 设置语言定义(不区分大小写) - * @param string|array $name 语言变量 - * @param string $value 语言值 - * @param string $range 语言作用域 + * @access public + * @param string|array $name 语言变量 + * @param string $value 语言值 + * @param string $range 语言作用域 * @return mixed */ public static function set($name, $value = null, $range = '') { $range = $range ?: self::$range; - // 批量定义 + if (!isset(self::$lang[$range])) { self::$lang[$range] = []; } + if (is_array($name)) { return self::$lang[$range] = array_change_key_case($name) + self::$lang[$range]; - } else { - return self::$lang[$range][strtolower($name)] = $value; } + + return self::$lang[$range][strtolower($name)] = $value; } /** * 加载语言定义(不区分大小写) - * @param string $file 语言文件 - * @param string $range 语言作用域 + * @access public + * @param array|string $file 语言文件 + * @param string $range 语言作用域 * @return mixed */ public static function load($file, $range = '') { $range = $range ?: self::$range; + $file = is_string($file) ? [$file] : $file; + if (!isset(self::$lang[$range])) { self::$lang[$range] = []; } - // 批量定义 - if (is_string($file)) { - $file = [$file]; - } + $lang = []; + foreach ($file as $_file) { if (is_file($_file)) { // 记录加载信息 App::$debug && Log::record('[ LANG ] ' . $_file, 'info'); + $_lang = include $_file; + if (is_array($_lang)) { $lang = array_change_key_case($_lang) + $lang; } } } + if (!empty($lang)) { self::$lang[$range] = $lang + self::$lang[$range]; } + return self::$lang[$range]; } /** * 获取语言定义(不区分大小写) - * @param string|null $name 语言变量 - * @param string $range 语言作用域 + * @access public + * @param string|null $name 语言变量 + * @param string $range 语言作用域 * @return mixed */ public static function has($name, $range = '') { $range = $range ?: self::$range; + return isset(self::$lang[$range][strtolower($name)]); } /** * 获取语言定义(不区分大小写) - * @param string|null $name 语言变量 - * @param array $vars 变量替换 - * @param string $range 语言作用域 + * @access public + * @param string|null $name 语言变量 + * @param array $vars 变量替换 + * @param string $range 语言作用域 * @return mixed */ public static function get($name = null, $vars = [], $range = '') { $range = $range ?: self::$range; + // 空参数返回所有定义 if (empty($name)) { return self::$lang[$range]; } + $key = strtolower($name); $value = isset(self::$lang[$range][$key]) ? self::$lang[$range][$key] : $name; @@ -145,42 +179,50 @@ class Lang } } + return $value; } /** * 自动侦测设置获取语言选择 + * @access public * @return string */ public static function detect() { - // 自动侦测设置获取语言选择 $langSet = ''; if (isset($_GET[self::$langDetectVar])) { - // url中设置了语言变量 + // url 中设置了语言变量 $langSet = strtolower($_GET[self::$langDetectVar]); + } elseif (isset($_COOKIE[self::$langCookieVar])) { + // Cookie 中设置了语言变量 + $langSet = strtolower($_COOKIE[self::$langCookieVar]); } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { // 自动侦测浏览器语言 preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches); $langSet = strtolower($matches[1]); $acceptLangs = Config::get('header_accept_lang'); + if (isset($acceptLangs[$langSet])) { $langSet = $acceptLangs[$langSet]; } elseif (isset(self::$acceptLanguage[$langSet])) { $langSet = self::$acceptLanguage[$langSet]; } } + + // 合法的语言 if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) { - // 合法的语言 self::$range = $langSet ?: self::$range; } + return self::$range; } /** * 设置语言自动侦测的变量 - * @param string $var 变量名称 + * @access public + * @param string $var 变量名称 * @return void */ public static function setLangDetectVar($var) @@ -189,8 +231,9 @@ class Lang } /** - * 设置语言的cookie保存变量 - * @param string $var 变量名称 + * 设置语言的 cookie 保存变量 + * @access public + * @param string $var 变量名称 * @return void */ public static function setLangCookieVar($var) @@ -199,8 +242,9 @@ class Lang } /** - * 设置语言的cookie的过期时间 - * @param string $expire 过期时间 + * 设置语言的 cookie 的过期时间 + * @access public + * @param string $expire 过期时间 * @return void */ public static function setLangCookieExpire($expire) @@ -210,7 +254,8 @@ class Lang /** * 设置允许的语言列表 - * @param array $list 语言列表 + * @access public + * @param array $list 语言列表 * @return void */ public static function setAllowLangList($list) diff --git a/thinkphp/library/think/Loader.php b/thinkphp/library/think/Loader.php index a0727fef..d813a5d7 100644 --- a/thinkphp/library/think/Loader.php +++ b/thinkphp/library/think/Loader.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -15,26 +15,57 @@ use think\exception\ClassNotFoundException; class Loader { + /** + * @var array 实例数组 + */ protected static $instance = []; - // 类名映射 - protected static $map = []; - // 命名空间别名 + /** + * @var array 类名映射 + */ + protected static $classMap = []; + + /** + * @var array 命名空间别名 + */ protected static $namespaceAlias = []; - // PSR-4 + /** + * @var array PSR-4 命名空间前缀长度映射 + */ private static $prefixLengthsPsr4 = []; - private static $prefixDirsPsr4 = []; - private static $fallbackDirsPsr4 = []; - // PSR-0 - private static $prefixesPsr0 = []; + /** + * @var array PSR-4 的加载目录 + */ + private static $prefixDirsPsr4 = []; + + /** + * @var array PSR-4 加载失败的回退目录 + */ + private static $fallbackDirsPsr4 = []; + + /** + * @var array PSR-0 命名空间前缀映射 + */ + private static $prefixesPsr0 = []; + + /** + * @var array PSR-0 加载失败的回退目录 + */ private static $fallbackDirsPsr0 = []; - // 自动加载的文件 - private static $autoloadFiles = []; + /** + * @var array 需要加载的文件 + */ + private static $files = []; - // 自动加载 + /** + * 自动加载 + * @access public + * @param string $class 类名 + * @return bool + */ public static function autoload($class) { // 检测命名空间别名 @@ -49,33 +80,33 @@ class Loader } if ($file = self::findFile($class)) { - - // Win环境严格区分大小写 - if (IS_WIN && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) { - return false; + // 非 Win 环境不严格区分大小写 + if (!IS_WIN || pathinfo($file, PATHINFO_FILENAME) == pathinfo(realpath($file), PATHINFO_FILENAME)) { + __include_file($file); + return true; } - - __include_file($file); - return true; } + + return false; } /** * 查找文件 - * @param $class - * @return bool + * @access private + * @param string $class 类名 + * @return bool|string */ private static function findFile($class) { - if (!empty(self::$map[$class])) { - // 类库映射 - return self::$map[$class]; + // 类库映射 + if (!empty(self::$classMap[$class])) { + return self::$classMap[$class]; } // 查找 PSR-4 $logicalPathPsr4 = strtr($class, '\\', DS) . EXT; + $first = $class[0]; - $first = $class[0]; if (isset(self::$prefixLengthsPsr4[$first])) { foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) { if (0 === strpos($class, $prefix)) { @@ -97,7 +128,7 @@ class Loader // 查找 PSR-0 if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name + // namespace class name $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) . strtr(substr($logicalPathPsr4, $pos + 1), '_', DS); } else { @@ -124,20 +155,33 @@ class Loader } } - return self::$map[$class] = false; + // 找不到则设置映射为 false 并返回 + return self::$classMap[$class] = false; } - // 注册classmap + /** + * 注册 classmap + * @access public + * @param string|array $class 类名 + * @param string $map 映射 + * @return void + */ public static function addClassMap($class, $map = '') { if (is_array($class)) { - self::$map = array_merge(self::$map, $class); + self::$classMap = array_merge(self::$classMap, $class); } else { - self::$map[$class] = $map; + self::$classMap[$class] = $map; } } - // 注册命名空间 + /** + * 注册命名空间 + * @access public + * @param string|array $namespace 命名空间 + * @param string $path 路径 + * @return void + */ public static function addNamespace($namespace, $path = '') { if (is_array($namespace)) { @@ -149,84 +193,77 @@ class Loader } } - // 添加Ps0空间 + /** + * 添加 PSR-0 命名空间 + * @access private + * @param array|string $prefix 空间前缀 + * @param array $paths 路径 + * @param bool $prepend 预先设置的优先级更高 + * @return void + */ private static function addPsr0($prefix, $paths, $prepend = false) { if (!$prefix) { - if ($prepend) { - self::$fallbackDirsPsr0 = array_merge( - (array) $paths, - self::$fallbackDirsPsr0 - ); + self::$fallbackDirsPsr0 = $prepend ? + array_merge((array) $paths, self::$fallbackDirsPsr0) : + array_merge(self::$fallbackDirsPsr0, (array) $paths); + } else { + $first = $prefix[0]; + + if (!isset(self::$prefixesPsr0[$first][$prefix])) { + self::$prefixesPsr0[$first][$prefix] = (array) $paths; } else { - self::$fallbackDirsPsr0 = array_merge( - self::$fallbackDirsPsr0, - (array) $paths - ); + self::$prefixesPsr0[$first][$prefix] = $prepend ? + array_merge((array) $paths, self::$prefixesPsr0[$first][$prefix]) : + array_merge(self::$prefixesPsr0[$first][$prefix], (array) $paths); } - - return; - } - - $first = $prefix[0]; - if (!isset(self::$prefixesPsr0[$first][$prefix])) { - self::$prefixesPsr0[$first][$prefix] = (array) $paths; - - return; - } - if ($prepend) { - self::$prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, - self::$prefixesPsr0[$first][$prefix] - ); - } else { - self::$prefixesPsr0[$first][$prefix] = array_merge( - self::$prefixesPsr0[$first][$prefix], - (array) $paths - ); } } - // 添加Psr4空间 + /** + * 添加 PSR-4 空间 + * @access private + * @param array|string $prefix 空间前缀 + * @param string $paths 路径 + * @param bool $prepend 预先设置的优先级更高 + * @return void + */ private static function addPsr4($prefix, $paths, $prepend = false) { if (!$prefix) { // Register directories for the root namespace. - if ($prepend) { - self::$fallbackDirsPsr4 = array_merge( - (array) $paths, - self::$fallbackDirsPsr4 - ); - } else { - self::$fallbackDirsPsr4 = array_merge( - self::$fallbackDirsPsr4, - (array) $paths - ); - } + self::$fallbackDirsPsr4 = $prepend ? + array_merge((array) $paths, self::$fallbackDirsPsr4) : + array_merge(self::$fallbackDirsPsr4, (array) $paths); + } elseif (!isset(self::$prefixDirsPsr4[$prefix])) { // Register directories for a new namespace. $length = strlen($prefix); if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + throw new \InvalidArgumentException( + "A non-empty PSR-4 prefix must end with a namespace separator." + ); } + self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length; self::$prefixDirsPsr4[$prefix] = (array) $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - self::$prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, - self::$prefixDirsPsr4[$prefix] - ); + } else { + self::$prefixDirsPsr4[$prefix] = $prepend ? + // Prepend directories for an already registered namespace. + array_merge((array) $paths, self::$prefixDirsPsr4[$prefix]) : // Append directories for an already registered namespace. - self::$prefixDirsPsr4[$prefix] = array_merge( - self::$prefixDirsPsr4[$prefix], - (array) $paths - ); + array_merge(self::$prefixDirsPsr4[$prefix], (array) $paths); } } - // 注册命名空间别名 + /** + * 注册命名空间别名 + * @access public + * @param array|string $namespace 命名空间 + * @param string $original 源文件 + * @return void + */ public static function addNamespaceAlias($namespace, $original = '') { if (is_array($namespace)) { @@ -236,32 +273,58 @@ class Loader } } - // 注册自动加载机制 - public static function register($autoload = '') + /** + * 注册自动加载机制 + * @access public + * @param callable $autoload 自动加载处理方法 + * @return void + */ + public static function register($autoload = null) { // 注册系统自动加载 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); + + // Composer 自动加载支持 + if (is_dir(VENDOR_PATH . 'composer')) { + if (PHP_VERSION_ID >= 50600 && is_file(VENDOR_PATH . 'composer' . DS . 'autoload_static.php')) { + require VENDOR_PATH . 'composer' . DS . 'autoload_static.php'; + + $declaredClass = get_declared_classes(); + $composerClass = array_pop($declaredClass); + + foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) { + if (property_exists($composerClass, $attr)) { + self::${$attr} = $composerClass::${$attr}; + } + } + } else { + self::registerComposerLoader(); + } + } + // 注册命名空间定义 self::addNamespace([ 'think' => LIB_PATH . 'think' . DS, 'behavior' => LIB_PATH . 'behavior' . DS, 'traits' => LIB_PATH . 'traits' . DS, ]); + // 加载类库映射文件 if (is_file(RUNTIME_PATH . 'classmap' . EXT)) { self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT)); } - // Composer自动加载支持 - if (is_dir(VENDOR_PATH . 'composer')) { - self::registerComposerLoader(); - } + self::loadComposerAutoloadFiles(); - // 自动加载extend目录 + // 自动加载 extend 目录 self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS); } - // 注册composer自动加载 + /** + * 注册 composer 自动加载 + * @access private + * @return void + */ private static function registerComposerLoader() { if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) { @@ -286,28 +349,36 @@ class Loader } if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) { - $includeFiles = require VENDOR_PATH . 'composer/autoload_files.php'; - foreach ($includeFiles as $fileIdentifier => $file) { - if (empty(self::$autoloadFiles[$fileIdentifier])) { - __require_file($file); - self::$autoloadFiles[$fileIdentifier] = true; - } + self::$files = require VENDOR_PATH . 'composer/autoload_files.php'; + } + } + + // 加载composer autofile文件 + public static function loadComposerAutoloadFiles() + { + foreach (self::$files as $fileIdentifier => $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + __require_file($file); + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; } } } /** - * 导入所需的类库 同java的Import 本函数有缓存功能 - * @param string $class 类库命名空间字符串 - * @param string $baseUrl 起始路径 - * @param string $ext 导入的文件扩展名 - * @return boolean + * 导入所需的类库 同 Java 的 Import 本函数有缓存功能 + * @access public + * @param string $class 类库命名空间字符串 + * @param string $baseUrl 起始路径 + * @param string $ext 导入的文件扩展名 + * @return bool */ public static function import($class, $baseUrl = '', $ext = EXT) { static $_file = []; $key = $class . $baseUrl; $class = str_replace(['.', '#'], [DS, '.'], $class); + if (isset($_file[$key])) { return true; } @@ -319,7 +390,7 @@ class Loader // 注册的命名空间 $baseUrl = self::$prefixDirsPsr4[$name . '\\']; } elseif ('@' == $name) { - //加载当前模块应用类库 + // 加载当前模块应用类库 $baseUrl = App::$modulePath; } elseif (is_dir(EXTEND_PATH . $name)) { $baseUrl = EXTEND_PATH . $name . DS; @@ -330,11 +401,11 @@ class Loader } elseif (substr($baseUrl, -1) != DS) { $baseUrl .= DS; } - // 如果类存在 则导入类库文件 + + // 如果类存在则导入类库文件 if (is_array($baseUrl)) { foreach ($baseUrl as $path) { - $filename = $path . DS . $class . $ext; - if (is_file($filename)) { + if (is_file($filename = $path . DS . $class . $ext)) { break; } } @@ -342,135 +413,154 @@ class Loader $filename = $baseUrl . $class . $ext; } - if (!empty($filename) && is_file($filename)) { - // 开启调试模式Win环境严格区分大小写 - if (IS_WIN && pathinfo($filename, PATHINFO_FILENAME) != pathinfo(realpath($filename), PATHINFO_FILENAME)) { - return false; - } + if (!empty($filename) && + is_file($filename) && + (!IS_WIN || pathinfo($filename, PATHINFO_FILENAME) == pathinfo(realpath($filename), PATHINFO_FILENAME)) + ) { __include_file($filename); $_file[$key] = true; + return true; } + return false; } /** * 实例化(分层)模型 - * @param string $name Model名称 - * @param string $layer 业务层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $common 公共模块名 - * @return Object + * @access public + * @param string $name Model名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 + * @return object * @throws ClassNotFoundException */ public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common') { - $guid = $name . $layer; - if (isset(self::$instance[$guid])) { - return self::$instance[$guid]; - } - if (false !== strpos($name, '\\')) { - $class = $name; - $module = Request::instance()->module(); - } else { - if (strpos($name, '/')) { - list($module, $name) = explode('/', $name, 2); - } else { - $module = Request::instance()->module(); - } - $class = self::parseClass($module, $layer, $name, $appendSuffix); + $uid = $name . $layer; + + if (isset(self::$instance[$uid])) { + return self::$instance[$uid]; } + + list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix); + if (class_exists($class)) { $model = new $class(); } else { $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class); + if (class_exists($class)) { $model = new $class(); } else { throw new ClassNotFoundException('class not exists:' . $class, $class); } } - self::$instance[$guid] = $model; - return $model; + + return self::$instance[$uid] = $model; } /** * 实例化(分层)控制器 格式:[模块名/]控制器名 - * @param string $name 资源地址 - * @param string $layer 控制层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $empty 空控制器名称 - * @return Object|false + * @access public + * @param string $name 资源地址 + * @param string $layer 控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $empty 空控制器名称 + * @return object * @throws ClassNotFoundException */ public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '') { - if (false !== strpos($name, '\\')) { - $class = $name; - $module = Request::instance()->module(); - } else { - if (strpos($name, '/')) { - list($module, $name) = explode('/', $name); - } else { - $module = Request::instance()->module(); - } - $class = self::parseClass($module, $layer, $name, $appendSuffix); - } + list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix); + if (class_exists($class)) { return App::invokeClass($class); - } elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) { - return new $emptyClass(Request::instance()); } + + if ($empty) { + $emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix); + + if (class_exists($emptyClass)) { + return new $emptyClass(Request::instance()); + } + } + + throw new ClassNotFoundException('class not exists:' . $class, $class); } /** * 实例化验证类 格式:[模块名/]验证器名 - * @param string $name 资源地址 - * @param string $layer 验证层名称 - * @param bool $appendSuffix 是否添加类名后缀 - * @param string $common 公共模块名 - * @return Object|false + * @access public + * @param string $name 资源地址 + * @param string $layer 验证层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 + * @return object|false * @throws ClassNotFoundException */ public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common') { $name = $name ?: Config::get('default_validate'); + if (empty($name)) { return new Validate; } - $guid = $name . $layer; - if (isset(self::$instance[$guid])) { - return self::$instance[$guid]; - } - if (false !== strpos($name, '\\')) { - $class = $name; - $module = Request::instance()->module(); - } else { - if (strpos($name, '/')) { - list($module, $name) = explode('/', $name); - } else { - $module = Request::instance()->module(); - } - $class = self::parseClass($module, $layer, $name, $appendSuffix); + + $uid = $name . $layer; + if (isset(self::$instance[$uid])) { + return self::$instance[$uid]; } + + list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix); + if (class_exists($class)) { $validate = new $class; } else { $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class); + if (class_exists($class)) { $validate = new $class; } else { throw new ClassNotFoundException('class not exists:' . $class, $class); } } - self::$instance[$guid] = $validate; - return $validate; + + return self::$instance[$uid] = $validate; + } + + /** + * 解析模块和类名 + * @access protected + * @param string $name 资源地址 + * @param string $layer 验证层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return array + */ + protected static function getModuleAndClass($name, $layer, $appendSuffix) + { + if (false !== strpos($name, '\\')) { + $module = Request::instance()->module(); + $class = $name; + } else { + if (strpos($name, '/')) { + list($module, $name) = explode('/', $name, 2); + } else { + $module = Request::instance()->module(); + } + + $class = self::parseClass($module, $layer, $name, $appendSuffix); + } + + return [$module, $class]; } /** * 数据库初始化 并取得数据库类实例 - * @param mixed $config 数据库配置 - * @param bool|string $name 连接标识 true 强制重新连接 + * @access public + * @param mixed $config 数据库配置 + * @param bool|string $name 连接标识 true 强制重新连接 * @return \think\db\Connection */ public static function db($config = [], $name = false) @@ -480,10 +570,11 @@ class Loader /** * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作 - * @param string $url 调用地址 - * @param string|array $vars 调用参数 支持字符串和数组 - * @param string $layer 要调用的控制层名称 - * @param bool $appendSuffix 是否添加类名后缀 + * @access public + * @param string $url 调用地址 + * @param string|array $vars 调用参数 支持字符串和数组 + * @param string $layer 要调用的控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 * @return mixed */ public static function action($url, $vars = [], $layer = 'controller', $appendSuffix = false) @@ -492,6 +583,7 @@ class Loader $action = $info['basename']; $module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller(); $class = self::controller($module, $layer, $appendSuffix); + if ($class) { if (is_scalar($vars)) { if (strpos($vars, '=')) { @@ -500,16 +592,20 @@ class Loader $vars = [$vars]; } } + return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars); } + + return false; } /** * 字符串命名风格转换 - * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格 - * @param string $name 字符串 - * @param integer $type 转换类型 - * @param bool $ucfirst 首字母是否大写(驼峰规则) + * type 0 将 Java 风格转换为 C 的风格 1 将 C 风格转换为 Java 的风格 + * @access public + * @param string $name 字符串 + * @param integer $type 转换类型 + * @param bool $ucfirst 首字母是否大写(驼峰规则) * @return string */ public static function parseName($name, $type = 0, $ucfirst = true) @@ -518,31 +614,38 @@ class Loader $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) { return strtoupper($match[1]); }, $name); + return $ucfirst ? ucfirst($name) : lcfirst($name); - } else { - return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); } + + return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); } /** * 解析应用类的类名 - * @param string $module 模块名 - * @param string $layer 层名 controller model ... - * @param string $name 类名 - * @param bool $appendSuffix + * @access public + * @param string $module 模块名 + * @param string $layer 层名 controller model ... + * @param string $name 类名 + * @param bool $appendSuffix 是否添加类名后缀 * @return string */ public static function parseClass($module, $layer, $name, $appendSuffix = false) { - $name = str_replace(['/', '.'], '\\', $name); - $array = explode('\\', $name); - $class = self::parseName(array_pop($array), 1) . (App::$suffix || $appendSuffix ? ucfirst($layer) : ''); + + $array = explode('\\', str_replace(['/', '.'], '\\', $name)); + $class = self::parseName(array_pop($array), 1); + $class = $class . (App::$suffix || $appendSuffix ? ucfirst($layer) : ''); $path = $array ? implode('\\', $array) . '\\' : ''; - return App::$namespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class; + + return App::$namespace . '\\' . + ($module ? $module . '\\' : '') . + $layer . '\\' . $path . $class; } /** * 初始化类的实例 + * @access public * @return void */ public static function clearInstance() @@ -551,10 +654,11 @@ class Loader } } +// 作用范围隔离 + /** - * 作用范围隔离 - * - * @param $file + * include + * @param string $file 文件路径 * @return mixed */ function __include_file($file) @@ -562,6 +666,11 @@ function __include_file($file) return include $file; } +/** + * require + * @param string $file 文件路径 + * @return mixed + */ function __require_file($file) { return require $file; diff --git a/thinkphp/library/think/Log.php b/thinkphp/library/think/Log.php index a20ab262..c064306c 100644 --- a/thinkphp/library/think/Log.php +++ b/thinkphp/library/think/Log.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -17,12 +17,12 @@ use think\exception\ClassNotFoundException; * Class Log * @package think * - * @method void log($msg) static - * @method void error($msg) static - * @method void info($msg) static - * @method void sql($msg) static - * @method void notice($msg) static - * @method void alert($msg) static + * @method void log($msg) static 记录一般日志 + * @method void error($msg) static 记录错误日志 + * @method void info($msg) static 记录一般信息日志 + * @method void sql($msg) static 记录 SQL 查询日志 + * @method void notice($msg) static 记录提示日志 + * @method void alert($msg) static 记录报警日志 */ class Log { @@ -34,41 +34,60 @@ class Log const ALERT = 'alert'; const DEBUG = 'debug'; - // 日志信息 + /** + * @var array 日志信息 + */ protected static $log = []; - // 配置参数 + + /** + * @var array 配置参数 + */ protected static $config = []; - // 日志类型 + + /** + * @var array 日志类型 + */ protected static $type = ['log', 'error', 'info', 'sql', 'notice', 'alert', 'debug']; - // 日志写入驱动 + + /** + * @var log\driver\File|log\driver\Test|log\driver\Socket 日志写入驱动 + */ protected static $driver; - // 当前日志授权key + /** + * @var string 当前日志授权 key + */ protected static $key; /** * 日志初始化 - * @param array $config + * @access public + * @param array $config 配置参数 + * @return void */ public static function init($config = []) { - $type = isset($config['type']) ? $config['type'] : 'File'; - $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type); + $type = isset($config['type']) ? $config['type'] : 'File'; + $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type); + self::$config = $config; unset($config['type']); + if (class_exists($class)) { self::$driver = new $class($config); } else { throw new ClassNotFoundException('class not exists:' . $class, $class); } + // 记录初始化信息 App::$debug && Log::record('[ LOG ] INIT ' . $type, 'info'); } /** * 获取日志信息 - * @param string $type 信息类型 - * @return array + * @access public + * @param string $type 信息类型 + * @return array|string */ public static function getLog($type = '') { @@ -77,21 +96,22 @@ class Log /** * 记录调试信息 - * @param mixed $msg 调试信息 - * @param string $type 信息类型 + * @access public + * @param mixed $msg 调试信息 + * @param string $type 信息类型 * @return void */ public static function record($msg, $type = 'log') { self::$log[$type][] = $msg; - if (IS_CLI) { - // 命令行下面日志写入改进 - self::save(); - } + + // 命令行下面日志写入改进 + IS_CLI && self::save(); } /** * 清空日志信息 + * @access public * @return void */ public static function clear() @@ -100,8 +120,9 @@ class Log } /** - * 当前日志记录的授权key - * @param string $key 授权key + * 设置当前日志记录的授权 key + * @access public + * @param string $key 授权 key * @return void */ public static function key($key) @@ -111,102 +132,105 @@ class Log /** * 检查日志写入权限 - * @param array $config 当前日志配置参数 + * @access public + * @param array $config 当前日志配置参数 * @return bool */ public static function check($config) { - if (self::$key && !empty($config['allow_key']) && !in_array(self::$key, $config['allow_key'])) { - return false; - } - return true; + return !self::$key || empty($config['allow_key']) || in_array(self::$key, $config['allow_key']); } /** * 保存调试信息 + * @access public * @return bool */ public static function save() { - if (!empty(self::$log)) { - if (is_null(self::$driver)) { - self::init(Config::get('log')); - } + // 没有需要保存的记录则直接返回 + if (empty(self::$log)) { + return true; + } - if (!self::check(self::$config)) { - // 检测日志写入权限 - return false; - } + is_null(self::$driver) && self::init(Config::get('log')); - if (empty(self::$config['level'])) { - // 获取全部日志 - $log = self::$log; - if (!App::$debug && isset($log['debug'])) { - unset($log['debug']); - } - } else { - // 记录允许级别 - $log = []; - foreach (self::$config['level'] as $level) { - if (isset(self::$log[$level])) { - $log[$level] = self::$log[$level]; - } + // 检测日志写入权限 + if (!self::check(self::$config)) { + return false; + } + + if (empty(self::$config['level'])) { + // 获取全部日志 + $log = self::$log; + if (!App::$debug && isset($log['debug'])) { + unset($log['debug']); + } + } else { + // 记录允许级别 + $log = []; + foreach (self::$config['level'] as $level) { + if (isset(self::$log[$level])) { + $log[$level] = self::$log[$level]; } } + } - $result = self::$driver->save($log); - if ($result) { - self::$log = []; - } - Hook::listen('log_write_done', $log); - return $result; + if ($result = self::$driver->save($log, true)) { + self::$log = []; } - return true; + + Hook::listen('log_write_done', $log); + + return $result; } /** * 实时写入日志信息 并支持行为 - * @param mixed $msg 调试信息 - * @param string $type 信息类型 - * @param bool $force 是否强制写入 + * @access public + * @param mixed $msg 调试信息 + * @param string $type 信息类型 + * @param bool $force 是否强制写入 * @return bool */ public static function write($msg, $type = 'log', $force = false) { $log = self::$log; - // 封装日志信息 - if (true === $force || empty(self::$config['level'])) { - $log[$type][] = $msg; - } elseif (in_array($type, self::$config['level'])) { - $log[$type][] = $msg; - } else { + + // 如果不是强制写入,而且信息类型不在可记录的类别中则直接返回 false 不做记录 + if (true !== $force && !empty(self::$config['level']) && !in_array($type, self::$config['level'])) { return false; } - // 监听log_write + // 封装日志信息 + $log[$type][] = $msg; + + // 监听 log_write Hook::listen('log_write', $log); - if (is_null(self::$driver)) { - self::init(Config::get('log')); - } + + is_null(self::$driver) && self::init(Config::get('log')); + // 写入日志 - $result = self::$driver->save($log); - if ($result) { + if ($result = self::$driver->save($log, false)) { self::$log = []; } + return $result; } /** - * 静态调用 - * @param $method - * @param $args - * @return mixed + * 静态方法调用 + * @access public + * @param string $method 调用方法 + * @param mixed $args 参数 + * @return void */ public static function __callStatic($method, $args) { if (in_array($method, self::$type)) { array_push($args, $method); - return call_user_func_array('\\think\\Log::record', $args); + + call_user_func_array('\\think\\Log::record', $args); } } diff --git a/thinkphp/library/think/Model.php b/thinkphp/library/think/Model.php index 6fc8cabe..2dc27b48 100644 --- a/thinkphp/library/think/Model.php +++ b/thinkphp/library/think/Model.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -11,6 +11,7 @@ namespace think; +use BadMethodCallException; use InvalidArgumentException; use think\db\Query; use think\exception\ValidateException; @@ -56,6 +57,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess protected $pk; // 数据表字段信息 留空则自动获取 protected $field = []; + // 数据排除字段 + protected $except = []; + // 数据废弃字段 + protected $disuse = []; // 只读字段 protected $readonly = []; // 显示属性 @@ -89,6 +94,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess protected $type = []; // 是否为更新数据 protected $isUpdate = false; + // 是否使用Replace + protected $replace = false; + // 是否强制更新所有数据 + protected $force = false; // 更新条件 protected $updateWhere; // 验证失败是否抛出异常 @@ -109,6 +118,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ protected static $initialized = []; + /** + * 是否从主库读取(主从分布式有效) + * @var array + */ + protected static $readMaster; + /** * 构造方法 * @access public @@ -121,6 +136,16 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } else { $this->data = $data; } + + if ($this->disuse) { + // 废弃字段 + foreach ((array) $this->disuse as $key) { + if (array_key_exists($key, $this->data)) { + unset($this->data[$key]); + } + } + } + // 记录原始数据 $this->origin = $this->data; @@ -154,6 +179,20 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $this->initialize(); } + /** + * 是否从主库读取数据(主从分布有效) + * @access public + * @param bool $all 是否所有模型生效 + * @return $this + */ + public function readMaster($all = false) + { + $model = $all ? '*' : $this->class; + + static::$readMaster[$model] = true; + return $this; + } + /** * 创建模型的查询对象 * @access protected @@ -175,7 +214,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $con = Db::connect($connection); // 设置当前模型 确保查询返回模型对象 $queryClass = $this->query ?: $con->getConfig('query'); - $query = new $queryClass($con, $this->class); + $query = new $queryClass($con, $this); + + if (isset(static::$readMaster['*']) || isset(static::$readMaster[$this->class])) { + $query->master(true); + } // 设置当前数据表和模型名 if (!empty($this->table)) { @@ -191,6 +234,19 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $query; } + /** + * 创建新的模型实例 + * @access public + * @param array|object $data 数据 + * @param bool $isUpdate 是否为更新 + * @param mixed $where 更新条件 + * @return Model + */ + public function newInstance($data = [], $isUpdate = false, $where = null) + { + return (new static($data))->isUpdate($isUpdate, $where); + } + /** * 获取当前模型的查询对象 * @access public @@ -261,7 +317,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess public function setParent($model) { $this->parent = $model; - return $this; } @@ -336,6 +391,18 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $this; } + /** + * 更新是否强制写入数据 而不做比较 + * @access public + * @param bool $force + * @return $this + */ + public function force($force = true) + { + $this->force = $force; + return $this; + } + /** * 修改器 设置数据对象值 * @access public @@ -353,7 +420,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess // 检测修改器 $method = 'set' . Loader::parseName($name, 1) . 'Attr'; if (method_exists($this, $method)) { - $value = $this->$method($value, array_merge($this->data, $data)); + $value = $this->$method($value, array_merge($this->data, $data), $this->relation); } elseif (isset($this->type[$name])) { // 类型转换 $value = $this->writeTransform($value, $this->type[$name]); @@ -532,7 +599,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess // 检测属性获取器 $method = 'get' . Loader::parseName($name, 1) . 'Attr'; if (method_exists($this, $method)) { - $value = $this->$method($value, $this->data); + $value = $this->$method($value, $this->data, $this->relation); } elseif (isset($this->type[$name])) { // 类型转换 $value = $this->readTransform($value, $this->type[$name]); @@ -567,14 +634,19 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * @access public * @param Relation $modelRelation 模型关联对象 * @return mixed + * @throws BadMethodCallException */ protected function getRelationData(Relation $modelRelation) { - if ($this->parent && get_class($this->parent) == $modelRelation->getModel()) { + if ($this->parent && !$modelRelation->isSelfRelation() && get_class($modelRelation->getModel()) == get_class($this->parent)) { $value = $this->parent; } else { // 首先获取关联数据 - $value = $modelRelation->getRelation(); + if (method_exists($modelRelation, 'getRelation')) { + $value = $modelRelation->getRelation(); + } else { + throw new BadMethodCallException('method not exists:' . get_class($modelRelation) . '-> getRelation'); + } } return $value; } @@ -633,7 +705,11 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $value = empty($value) ? new \stdClass() : json_decode($value); break; case 'serialize': - $value = unserialize($value); + try { + $value = unserialize($value); + } catch (\Exception $e) { + $value = null; + } break; default: if (false !== strpos($type, '\\')) { @@ -686,7 +762,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess if (isset($this->data[$key])) { throw new Exception('bind attr has exists:' . $key); } else { - $this->data[$key] = $model->$attr; + $this->data[$key] = $model->getAttr($attr); } } } @@ -820,7 +896,29 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $relation = $this->getAttr($key); $item[$key] = $relation->append([$attr])->toArray(); } else { - $item[$name] = $this->getAttr($name); + $relation = Loader::parseName($name, 1, false); + if (method_exists($this, $relation)) { + $modelRelation = $this->$relation(); + $value = $this->getRelationData($modelRelation); + + if (method_exists($modelRelation, 'getBindAttr')) { + $bindAttr = $modelRelation->getBindAttr(); + if ($bindAttr) { + foreach ($bindAttr as $key => $attr) { + $key = is_numeric($key) ? $attr : $key; + if (isset($this->data[$key])) { + throw new Exception('bind attr has exists:' . $key); + } else { + $item[$key] = $value ? $value->getAttr($attr) : null; + } + } + continue; + } + } + $item[$name] = $value; + } else { + $item[$name] = $this->getAttr($name); + } } } } @@ -838,6 +936,17 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return json_encode($this->toArray(), $options); } + /** + * 移除当前模型的关联属性 + * @access public + * @return $this + */ + public function removeRelation() + { + $this->relation = []; + return $this; + } + /** * 转换当前模型数据集为数据集对象 * @access public @@ -906,6 +1015,18 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return false; } + /** + * 新增数据是否使用Replace + * @access public + * @param bool $replace + * @return $this + */ + public function replace($replace = true) + { + $this->replace = $replace; + return $this; + } + /** * 保存当前数据对象 * @access public @@ -916,18 +1037,26 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public function save($data = [], $where = [], $sequence = null) { + if (is_string($data)) { + $sequence = $data; + $data = []; + } + + // 数据自动验证 if (!empty($data)) { - // 数据自动验证 if (!$this->validateData($data)) { return false; } + // 数据对象赋值 foreach ($data as $key => $value) { $this->setAttr($key, $value, $data); } - if (!empty($where)) { - $this->isUpdate = true; - } + } + + if (!empty($where)) { + $this->isUpdate = true; + $this->updateWhere = $where; } // 自动关联写入 @@ -964,9 +1093,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } $pk = $this->getPk(); if ($this->isUpdate) { - // 检测字段 - $this->checkAllowField($this->data, array_merge($this->auto, $this->update)); - // 自动更新 $this->autoCompleteData($this->update); @@ -986,7 +1112,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return 0; } elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) { // 自动写入更新时间 - $data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime); + $data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime); + $this->data[$this->updateTime] = $data[$this->updateTime]; } if (empty($where) && !empty($this->updateWhere)) { @@ -1000,16 +1127,28 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } } - if (is_string($pk) && isset($data[$pk])) { - if (!isset($where[$pk])) { - unset($where); - $where[$pk] = $data[$pk]; + $array = []; + + foreach ((array) $pk as $key) { + if (isset($data[$key])) { + $array[$key] = $data[$key]; + unset($data[$key]); } - unset($data[$pk]); } + if (!empty($array)) { + $where = $array; + } + + // 检测字段 + $allowFields = $this->checkAllowField(array_merge($this->auto, $this->update)); + // 模型更新 - $result = $this->getQuery()->where($where)->update($data); + if (!empty($allowFields)) { + $result = $this->getQuery()->where($where)->strict(false)->field($allowFields)->update($data); + } else { + $result = $this->getQuery()->where($where)->update($data); + } // 关联更新 if (isset($relation)) { @@ -1020,9 +1159,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $this->trigger('after_update', $this); } else { - // 检测字段 - $this->checkAllowField($this->data, array_merge($this->auto, $this->insert)); - // 自动写入 $this->autoCompleteData($this->insert); @@ -1040,13 +1176,20 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return false; } - $result = $this->getQuery()->insert($this->data); + // 检测字段 + $allowFields = $this->checkAllowField(array_merge($this->auto, $this->insert)); + if (!empty($allowFields)) { + $result = $this->getQuery()->strict(false)->field($allowFields)->insert($this->data, $this->replace, false, $sequence); + } else { + $result = $this->getQuery()->insert($this->data, $this->replace, false, $sequence); + } // 获取自动增长主键 - if ($result && is_string($pk) && (!isset($this->data[$pk]) || '' == $this->data[$pk])) { - $insertId = $this->getQuery()->getLastInsID($sequence); - if ($insertId) { - $this->data[$pk] = $insertId; + if ($result && $insertId = $this->getQuery()->getLastInsID($sequence)) { + foreach ((array) $pk as $key) { + if (!isset($this->data[$key]) || '' == $this->data[$key]) { + $this->data[$key] = $insertId; + } } } @@ -1073,22 +1216,29 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $result; } - protected function checkAllowField(&$data, $auto = []) + protected function checkAllowField($auto = []) { - if (!empty($this->field)) { - if (true === $this->field) { - $this->field = $this->getQuery()->getTableInfo('', 'fields'); - $field = $this->field; - } else { - $field = array_merge($this->field, $auto); + if (true === $this->field) { + $this->field = $this->getQuery()->getTableInfo('', 'fields'); + $field = $this->field; + } elseif (!empty($this->field)) { + $field = array_merge($this->field, $auto); + if ($this->autoWriteTimestamp) { + array_push($field, $this->createTime, $this->updateTime); } + } elseif (!empty($this->except)) { + $fields = $this->getQuery()->getTableInfo('', 'fields'); + $field = array_diff($fields, (array) $this->except); + $this->field = $field; + } else { + $field = []; + } - foreach ($data as $key => $val) { - if (!in_array($key, $field)) { - unset($data[$key]); - } - } + if ($this->disuse) { + // 废弃字段 + $field = array_diff($field, (array) $this->disuse); } + return $field; } protected function autoRelationUpdate($relation) @@ -1113,12 +1263,16 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public function getChangedData() { - $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) { - if ((empty($b) || empty($b)) && $a !== $b) { - return 1; - } - return is_object($a) || $a != $b ? 1 : 0; - }); + if ($this->force) { + $data = $this->data; + } else { + $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) { + if ((empty($a) || empty($b)) && $a !== $b) { + return 1; + } + return is_object($a) || $a != $b ? 1 : 0; + }); + } if (!empty($this->readonly)) { // 只读字段不允许更新 @@ -1143,16 +1297,8 @@ abstract class Model implements \JsonSerializable, \ArrayAccess */ public function setInc($field, $step = 1, $lazyTime = 0) { - // 删除条件 - $pk = $this->getPk(); - - if (is_string($pk) && isset($this->data[$pk])) { - $where = [$pk => $this->data[$pk]]; - } elseif (!empty($this->updateWhere)) { - $where = $this->updateWhere; - } else { - $where = null; - } + // 更新条件 + $where = $this->getWhere(); $result = $this->getQuery()->where($where)->setInc($field, $step, $lazyTime); if (true !== $result) { @@ -1172,6 +1318,23 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * @throws Exception */ public function setDec($field, $step = 1, $lazyTime = 0) + { + // 更新条件 + $where = $this->getWhere(); + $result = $this->getQuery()->where($where)->setDec($field, $step, $lazyTime); + if (true !== $result) { + $this->data[$field] -= $step; + } + + return $result; + } + + /** + * 获取更新条件 + * @access protected + * @return mixed + */ + protected function getWhere() { // 删除条件 $pk = $this->getPk(); @@ -1183,13 +1346,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } else { $where = null; } - - $result = $this->getQuery()->where($where)->setDec($field, $step, $lazyTime); - if (true !== $result) { - $this->data[$field] -= $step; - } - - return $result; + return $where; } /** @@ -1221,14 +1378,14 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $auto = true; } foreach ($dataSet as $key => $data) { - if (!empty($auto) && isset($data[$pk])) { + if ($this->isUpdate || (!empty($auto) && isset($data[$pk]))) { $result[$key] = self::update($data, [], $this->field); } else { $result[$key] = self::create($data, $this->field); } } $db->commit(); - return $result; + return $this->toCollection($result); } catch (\Exception $e) { $db->rollback(); throw $e; @@ -1238,7 +1395,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess /** * 设置允许写入的字段 * @access public - * @param mixed $field 允许写入的字段 如果为true只允许写入数据表字段 + * @param string|array $field 允许写入的字段 如果为true只允许写入数据表字段 * @return $this */ public function allowField($field) @@ -1250,6 +1407,21 @@ abstract class Model implements \JsonSerializable, \ArrayAccess return $this; } + /** + * 设置排除写入的字段 + * @access public + * @param string|array $field 排除允许写入的字段 + * @return $this + */ + public function except($field) + { + if (is_string($field)) { + $field = explode(',', $field); + } + $this->except = $field; + return $this; + } + /** * 设置只读字段 * @access public @@ -1317,14 +1489,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess } // 删除条件 - $pk = $this->getPk(); - if (is_string($pk) && isset($this->data[$pk])) { - $where = [$pk => $this->data[$pk]]; - } elseif (!empty($this->updateWhere)) { - $where = $this->updateWhere; - } else { - $where = null; - } + $where = $this->getWhere(); // 删除当前模型数据 $result = $this->getQuery()->where($where)->delete(); @@ -1595,14 +1760,14 @@ abstract class Model implements \JsonSerializable, \ArrayAccess { $model = new static(); $query = $model->db(); - if (is_array($data) && key($data) !== 0) { + if (empty($data) && 0 !== $data) { + return 0; + } elseif (is_array($data) && key($data) !== 0) { $query->where($data); $data = null; } elseif ($data instanceof \Closure) { call_user_func_array($data, [ & $query]); $data = null; - } elseif (empty($data) && 0 !== $data) { - return 0; } $resultSet = $query->select($data); $count = 0; @@ -1627,6 +1792,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $model = new static(); $query = $model->db(); $params = func_get_args(); + array_shift($params); array_unshift($params, $query); if ($name instanceof \Closure) { call_user_func_array($name, $params); @@ -1648,7 +1814,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * 设置是否使用全局查询范围 * @param bool $use 是否启用全局查询范围 * @access public - * @return Model + * @return Query */ public static function useGlobalScope($use) { @@ -1677,13 +1843,14 @@ abstract class Model implements \JsonSerializable, \ArrayAccess /** * 根据关联条件查询当前模型 * @access public - * @param string $relation 关联方法名 - * @param mixed $where 查询条件(数组或者闭包) + * @param string $relation 关联方法名 + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Relation|Query */ - public static function hasWhere($relation, $where = []) + public static function hasWhere($relation, $where = [], $fields = null) { - return (new static())->$relation()->hasWhere($where); + return (new static())->$relation()->hasWhere($where, $fields); } /** @@ -1840,7 +2007,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * @access public * @param string $model 模型名 * @param string $foreignKey 关联外键 - * @param string $localKey 关联主键 + * @param string $localKey 当前模型主键 * @param array $alias 别名定义(已经废弃) * @param string $joinType JOIN类型 * @return HasOne @@ -1880,7 +2047,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * @access public * @param string $model 模型名 * @param string $foreignKey 关联外键 - * @param string $localKey 关联主键 + * @param string $localKey 当前模型主键 * @return HasMany */ public function hasMany($model, $foreignKey = '', $localKey = '') @@ -1899,7 +2066,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess * @param string $through 中间模型名 * @param string $foreignKey 关联外键 * @param string $throughKey 关联外键 - * @param string $localKey 关联主键 + * @param string $localKey 当前模型主键 * @return HasManyThrough */ public function hasManyThrough($model, $through, $foreignKey = '', $throughKey = '', $localKey = '') @@ -1927,7 +2094,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess // 记录当前关联信息 $model = $this->parseModel($model); $name = Loader::parseName(basename(str_replace('\\', '/', $model))); - $table = $table ?: $this->getQuery()->getTable(Loader::parseName($this->name) . '_' . $name); + $table = $table ?: Loader::parseName($this->name) . '_' . $name; $foreignKey = $foreignKey ?: $name . '_id'; $localKey = $localKey ?: $this->getForeignKey($this->name); return new BelongsToMany($this, $model, $table, $foreignKey, $localKey); @@ -1949,7 +2116,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $trace = debug_backtrace(false, 2); $morph = Loader::parseName($trace[1]['function']); } - $type = $type ?: Loader::parseName($this->name); + $type = $type ?: get_class($this); if (is_array($morph)) { list($morphType, $foreignKey) = $morph; } else { @@ -1975,7 +2142,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess $trace = debug_backtrace(false, 2); $morph = Loader::parseName($trace[1]['function']); } - $type = $type ?: Loader::parseName($this->name); + $type = $type ?: get_class($this); if (is_array($morph)) { list($morphType, $foreignKey) = $morph; } else { @@ -2013,7 +2180,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess public function __call($method, $args) { $query = $this->db(true, false); - if (method_exists($this, 'scope' . $method)) { // 动态调用命名范围 $method = 'scope' . $method; @@ -2029,7 +2195,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess { $model = new static(); $query = $model->db(); - if (method_exists($model, 'scope' . $method)) { // 动态调用命名范围 $method = 'scope' . $method; diff --git a/thinkphp/library/think/Paginator.php b/thinkphp/library/think/Paginator.php index 5a8fa20e..36555678 100644 --- a/thinkphp/library/think/Paginator.php +++ b/thinkphp/library/think/Paginator.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -49,6 +49,9 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J 'fragment' => '', ]; + /** @var mixed simple模式下的下个元素 */ + protected $nextItem; + public function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = []) { $this->options = array_merge($this->options, $options); @@ -65,7 +68,10 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J if ($simple) { $this->currentPage = $this->setCurrentPage($currentPage); $this->hasMore = count($items) > ($this->listRows); - $items = $items->slice(0, $this->listRows); + if ($this->hasMore) { + $this->nextItem = $items->slice($this->listRows, 1); + } + $items = $items->slice(0, $this->listRows); } else { $this->total = $total; $this->lastPage = (int) ceil($total / $listRows); @@ -122,7 +128,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J } $url = $path; if (!empty($parameters)) { - $url .= '?' . urldecode(http_build_query($parameters, null, '&')); + $url .= '?' . http_build_query($parameters, null, '&'); } return $url . $this->buildFragment(); } @@ -135,9 +141,9 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J */ public static function getCurrentPage($varPage = 'page', $default = 1) { - $page = Request::instance()->request($varPage); + $page = (int) Request::instance()->param($varPage); - if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) { + if (filter_var($page, FILTER_VALIDATE_INT) !== false && $page >= 1) { return $page; } @@ -282,8 +288,11 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J public function each(callable $callback) { foreach ($this->items as $key => $item) { - if ($callback($item, $key) === false) { + $result = $callback($item, $key); + if (false === $result) { break; + } elseif (!is_object($item)) { + $this->items[$key] = $result; } } @@ -356,19 +365,24 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J public function toArray() { - try { - $total = $this->total(); - } catch (\DomainException $e) { - $total = null; + if ($this->simple) { + return [ + 'per_page' => $this->listRows, + 'current_page' => $this->currentPage, + 'has_more' => $this->hasMore, + 'next_item' => $this->nextItem, + 'data' => $this->items->toArray(), + ]; + } else { + return [ + 'total' => $this->total, + 'per_page' => $this->listRows, + 'current_page' => $this->currentPage, + 'last_page' => $this->lastPage, + 'data' => $this->items->toArray(), + ]; } - return [ - 'total' => $total, - 'per_page' => $this->listRows(), - 'current_page' => $this->currentPage(), - 'last_page' => $this->lastPage, - 'data' => $this->items->toArray(), - ]; } /** @@ -381,7 +395,15 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J public function __call($name, $arguments) { - return call_user_func_array([$this->getCollection(), $name], $arguments); + $collection = $this->getCollection(); + + $result = call_user_func_array([$collection, $name], $arguments); + + if ($result === $collection) { + return $this; + } + + return $result; } } diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php index e3fa3a4f..5997a763 100644 --- a/thinkphp/library/think/Request.php +++ b/thinkphp/library/think/Request.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -59,6 +59,11 @@ class Request */ protected $routeInfo = []; + /** + * @var array 环境变量 + */ + protected $env; + /** * @var array 当前调度信息 */ @@ -116,6 +121,11 @@ class Request protected $cache; // 缓存是否检查 protected $isCheckCache; + /** + * 是否合并Param + * @var bool + */ + protected $mergeParam = false; /** * 构造函数 @@ -150,8 +160,8 @@ class Request /** * Hook 方法注入 * @access public - * @param string|array $method 方法名 - * @param mixed $callback callable + * @param string|array $method 方法名 + * @param mixed $callback callable * @return void */ public static function hook($method, $callback = null) @@ -177,16 +187,28 @@ class Request return self::$instance; } + /** + * 销毁当前请求对象 + * @access public + * @return void + */ + public static function destroy() + { + if (!is_null(self::$instance)) { + self::$instance = null; + } + } + /** * 创建一个URL请求 * @access public - * @param string $uri URL地址 - * @param string $method 请求类型 - * @param array $params 请求参数 - * @param array $cookie - * @param array $files - * @param array $server - * @param string $content + * @param string $uri URL地址 + * @param string $method 请求类型 + * @param array $params 请求参数 + * @param array $cookie + * @param array $files + * @param array $server + * @param string $content * @return \think\Request */ public static function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [], $content = null) @@ -227,7 +249,7 @@ class Request parse_str(html_entity_decode($info['query']), $query); if (!empty($params)) { $params = array_replace($query, $params); - $queryString = http_build_query($query, '', '&'); + $queryString = http_build_query($params, '', '&'); } else { $params = $query; $queryString = $info['query']; @@ -474,8 +496,8 @@ class Request /** * 设置资源类型 * @access public - * @param string|array $type 资源类型名 - * @param string $val 资源类型 + * @param string|array $type 资源类型名 + * @param string $val 资源类型 * @return void */ public function mimeType($type, $val = '') @@ -490,22 +512,28 @@ class Request /** * 当前的请求类型 * @access public - * @param bool $method true 获取原始请求类型 + * @param bool $method true 获取原始请求类型 * @return string */ public function method($method = false) { if (true === $method) { // 获取原始请求类型 - return IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']); + return $this->server('REQUEST_METHOD') ?: 'GET'; } elseif (!$this->method) { if (isset($_POST[Config::get('var_method')])) { - $this->method = strtoupper($_POST[Config::get('var_method')]); - $this->{$this->method}($_POST); + $method = strtoupper($_POST[Config::get('var_method')]); + if (in_array($method, ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'])) { + $this->method = $method; + $this->{$this->method}($_POST); + } else { + $this->method = 'POST'; + } + unset($_POST[Config::get('var_method')]); } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); } else { - $this->method = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']); + $this->method = $this->server('REQUEST_METHOD') ?: 'GET'; } } return $this->method; @@ -604,14 +632,14 @@ class Request /** * 获取当前请求的参数 * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function param($name = '', $default = null, $filter = '') { - if (empty($this->param)) { + if (empty($this->mergeParam)) { $method = $this->method(true); // 自动获取请求变量 switch ($method) { @@ -627,7 +655,8 @@ class Request $vars = []; } // 当前请求参数和URL地址中的参数合并 - $this->param = array_merge($this->get(false), $vars, $this->route(false)); + $this->param = array_merge($this->param, $this->get(false), $vars, $this->route(false)); + $this->mergeParam = true; } if (true === $name) { // 获取包含文件上传信息的数组 @@ -641,15 +670,16 @@ class Request /** * 设置获取路由参数 * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function route($name = '', $default = null, $filter = '') { if (is_array($name)) { $this->param = []; + $this->mergeParam = false; return $this->route = array_merge($this->route, $name); } return $this->input($this->route, $name, $default, $filter); @@ -658,9 +688,9 @@ class Request /** * 设置获取GET参数 * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function get($name = '', $default = null, $filter = '') @@ -670,6 +700,7 @@ class Request } if (is_array($name)) { $this->param = []; + $this->mergeParam = false; return $this->get = array_merge($this->get, $name); } return $this->input($this->get, $name, $default, $filter); @@ -678,9 +709,9 @@ class Request /** * 设置获取POST参数 * @access public - * @param string $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 + * @param string $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function post($name = '', $default = null, $filter = '') @@ -695,6 +726,7 @@ class Request } if (is_array($name)) { $this->param = []; + $this->mergeParam = false; return $this->post = array_merge($this->post, $name); } return $this->input($this->post, $name, $default, $filter); @@ -703,9 +735,9 @@ class Request /** * 设置获取PUT参数 * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function put($name = '', $default = null, $filter = '') @@ -720,6 +752,7 @@ class Request } if (is_array($name)) { $this->param = []; + $this->mergeParam = false; return $this->put = is_null($this->put) ? $name : array_merge($this->put, $name); } @@ -729,9 +762,9 @@ class Request /** * 设置获取DELETE参数 * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function delete($name = '', $default = null, $filter = '') @@ -742,9 +775,9 @@ class Request /** * 设置获取PATCH参数 * @access public - * @param string|array $name 变量名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function patch($name = '', $default = null, $filter = '') @@ -754,9 +787,9 @@ class Request /** * 获取request变量 - * @param string $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 + * @param string $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function request($name = '', $default = null, $filter = '') @@ -766,6 +799,7 @@ class Request } if (is_array($name)) { $this->param = []; + $this->mergeParam = false; return $this->request = array_merge($this->request, $name); } return $this->input($this->request, $name, $default, $filter); @@ -774,9 +808,9 @@ class Request /** * 获取session数据 * @access public - * @param string|array $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function session($name = '', $default = null, $filter = '') @@ -793,9 +827,9 @@ class Request /** * 获取cookie参数 * @access public - * @param string|array $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function cookie($name = '', $default = null, $filter = '') @@ -826,9 +860,9 @@ class Request /** * 获取server参数 * @access public - * @param string|array $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function server($name = '', $default = null, $filter = '') @@ -904,9 +938,9 @@ class Request /** * 获取环境变量 - * @param string|array $name 数据名称 - * @param string $default 默认值 - * @param string|array $filter 过滤方法 + * @param string|array $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 * @return mixed */ public function env($name = '', $default = null, $filter = '') @@ -923,8 +957,8 @@ class Request /** * 设置或者获取当前的Header * @access public - * @param string|array $name header名称 - * @param string $default 默认值 + * @param string|array $name header名称 + * @param string $default 默认值 * @return string */ public function header($name = '', $default = null) @@ -962,10 +996,10 @@ class Request /** * 获取变量 支持过滤和默认值 - * @param array $data 数据源 - * @param string|false $name 字段名 - * @param mixed $default 默认值 - * @param string|array $filter 过滤函数 + * @param array $data 数据源 + * @param string|false $name 字段名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤函数 * @return mixed */ public function input($data = [], $name = '', $default = null, $filter = '') @@ -1046,9 +1080,9 @@ class Request /** * 递归过滤给定的值 - * @param mixed $value 键值 - * @param mixed $key 键名 - * @param array $filters 过滤方法+默认值 + * @param mixed $value 键值 + * @param mixed $key 键名 + * @param array $filters 过滤方法+默认值 * @return mixed */ private function filterValue(&$value, $key, $filters) @@ -1088,7 +1122,7 @@ class Request public function filterExp(&$value) { // 过滤查询特殊字符 - if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) { + if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOT EXISTS|NOTEXISTS|EXISTS|NOT NULL|NOTNULL|NULL|BETWEEN TIME|NOT BETWEEN TIME|NOTBETWEEN TIME|NOTIN|NOT IN|IN)$/i', $value)) { $value .= ' '; } // TODO 其他安全过滤 @@ -1133,9 +1167,9 @@ class Request /** * 是否存在某个请求参数 * @access public - * @param string $name 变量名 - * @param string $type 变量类型 - * @param bool $checkEmpty 是否检测空值 + * @param string $name 变量名 + * @param string $type 变量类型 + * @param bool $checkEmpty 是否检测空值 * @return mixed */ public function has($name, $type = 'param', $checkEmpty = false) @@ -1159,8 +1193,8 @@ class Request /** * 获取指定的参数 * @access public - * @param string|array $name 变量名 - * @param string $type 变量类型 + * @param string|array $name 变量名 + * @param string $type 变量类型 * @return mixed */ public function only($name, $type = 'param') @@ -1181,8 +1215,8 @@ class Request /** * 排除指定参数获取 * @access public - * @param string|array $name 变量名 - * @param string $type 变量类型 + * @param string|array $name 变量名 + * @param string $type 变量类型 * @return mixed */ public function except($name, $type = 'param') @@ -1215,6 +1249,8 @@ class Request return true; } elseif (isset($server['HTTP_X_FORWARDED_PROTO']) && 'https' == $server['HTTP_X_FORWARDED_PROTO']) { return true; + } elseif (Config::get('https_agent_name') && isset($server[Config::get('https_agent_name')])) { + return true; } return false; } @@ -1222,7 +1258,7 @@ class Request /** * 当前是否Ajax请求 * @access public - * @param bool $ajax true 获取原始ajax请求 + * @param bool $ajax true 获取原始ajax请求 * @return bool */ public function isAjax($ajax = false) @@ -1232,14 +1268,16 @@ class Request if (true === $ajax) { return $result; } else { - return $this->param(Config::get('var_ajax')) ? true : $result; + $result = $this->param(Config::get('var_ajax')) ? true : $result; + $this->mergeParam = false; + return $result; } } /** * 当前是否Pjax请求 * @access public - * @param bool $pjax true 获取原始pjax请求 + * @param bool $pjax true 获取原始pjax请求 * @return bool */ public function isPjax($pjax = false) @@ -1248,17 +1286,19 @@ class Request if (true === $pjax) { return $result; } else { - return $this->param(Config::get('var_pjax')) ? true : $result; + $result = $this->param(Config::get('var_pjax')) ? true : $result; + $this->mergeParam = false; + return $result; } } /** * 获取客户端IP地址 - * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 - * @param boolean $adv 是否进行高级模式获取(有可能被伪装) + * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 + * @param boolean $adv 是否进行高级模式获取(有可能被伪装) * @return mixed */ - public function ip($type = 0, $adv = false) + public function ip($type = 0, $adv = true) { $type = $type ? 1 : 0; static $ip = null; @@ -1266,7 +1306,11 @@ class Request return $ip[$type]; } - if ($adv) { + $httpAgentIp = Config::get('http_agent_ip'); + + if ($httpAgentIp && isset($_SERVER[$httpAgentIp])) { + $ip = $_SERVER[$httpAgentIp]; + } elseif ($adv) { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $pos = array_search('unknown', $arr); @@ -1331,11 +1375,18 @@ class Request /** * 当前请求的host * @access public + * @param bool $strict true 仅仅获取HOST * @return string */ - public function host() + public function host($strict = false) { - return $this->server('HTTP_HOST'); + if (isset($_SERVER['HTTP_X_REAL_HOST'])) { + $host = $_SERVER['HTTP_X_REAL_HOST']; + } else { + $host = $this->server('HTTP_HOST'); + } + + return true === $strict && strpos($host, ':') ? strstr($host, ':', true) : $host; } /** @@ -1405,7 +1456,7 @@ class Request /** * 设置或者获取当前请求的调度信息 * @access public - * @param array $dispatch 调度信息 + * @param array $dispatch 调度信息 * @return array */ public function dispatch($dispatch = null) @@ -1456,11 +1507,12 @@ class Request */ public function action($action = null) { - if (!is_null($action)) { + if (!is_null($action) && !is_bool($action)) { $this->action = $action; return $this; } else { - return $this->action ?: ''; + $name = $this->action ?: ''; + return true === $action ? $name : strtolower($name); } } @@ -1524,13 +1576,19 @@ class Request /** * 设置当前地址的请求缓存 * @access public - * @param string $key 缓存标识,支持变量规则 ,例如 item/:name/:id + * @param string $key 缓存标识,支持变量规则 ,例如 item/:name/:id * @param mixed $expire 缓存有效期 * @param array $except 缓存排除 + * @param string $tag 缓存标签 * @return void */ - public function cache($key, $expire = null, $except = []) + public function cache($key, $expire = null, $except = [], $tag = null) { + if (!is_array($except)) { + $tag = $except; + $except = []; + } + if (false !== $key && $this->isGet() && !$this->isCheckCache) { // 标记请求缓存检查 $this->isCheckCache = true; @@ -1542,7 +1600,7 @@ class Request $key = call_user_func_array($key, [$this]); } elseif (true === $key) { foreach ($except as $rule) { - if (0 === strpos($this->url(), $rule)) { + if (0 === stripos($this->url(), $rule)) { return; } } @@ -1584,7 +1642,7 @@ class Request $response = Response::create($content)->header($header); throw new \think\exception\HttpResponseException($response); } else { - $this->cache = [$key, $expire]; + $this->cache = [$key, $expire, $tag]; } } } @@ -1602,8 +1660,8 @@ class Request /** * 设置当前请求绑定的对象实例 * @access public - * @param string $name 绑定的对象标识 - * @param mixed $obj 绑定的对象实例 + * @param string|array $name 绑定的对象标识 + * @param mixed $obj 绑定的对象实例 * @return mixed */ public function bind($name, $obj = null) diff --git a/thinkphp/library/think/Response.php b/thinkphp/library/think/Response.php index 96737dcd..c5c15209 100644 --- a/thinkphp/library/think/Response.php +++ b/thinkphp/library/think/Response.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -69,9 +69,7 @@ class Response */ public static function create($data = '', $type = '', $code = 200, array $header = [], $options = []) { - $type = empty($type) ? 'null' : strtolower($type); - - $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst($type); + $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type)); if (class_exists($class)) { $response = new $class($data, $code, $header, $options); } else { @@ -89,6 +87,9 @@ class Response */ public function send() { + // 监听response_send + Hook::listen('response_send', $this); + // 处理输出数据 $data = $this->getContent(); @@ -103,7 +104,7 @@ class Response $this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate'; $this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT'; $this->header['Expires'] = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT'; - Cache::set($cache[0], [$data, $this->header], $cache[1]); + Cache::tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]); } } diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php index a5b19327..ab53aa20 100644 --- a/thinkphp/library/think/Route.php +++ b/thinkphp/library/think/Route.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -68,8 +68,8 @@ class Route /** * 注册变量规则 * @access public - * @param string|array $name 变量名 - * @param string $rule 变量规则 + * @param string|array $name 变量名 + * @param string $rule 变量规则 * @return void */ public static function pattern($name = null, $rule = '') @@ -84,10 +84,10 @@ class Route /** * 注册子域名部署规则 * @access public - * @param string|array $domain 子域名 - * @param mixed $rule 路由规则 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $domain 子域名 + * @param mixed $rule 路由规则 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function domain($domain, $rule = '', $option = [], $pattern = []) @@ -121,8 +121,8 @@ class Route /** * 设置路由绑定 * @access public - * @param mixed $bind 绑定信息 - * @param string $type 绑定类型 默认为module 支持 namespace class controller + * @param mixed $bind 绑定信息 + * @param string $type 绑定类型 默认为module 支持 namespace class controller * @return mixed */ public static function bind($bind, $type = 'module') @@ -133,8 +133,8 @@ class Route /** * 设置或者获取路由标识 * @access public - * @param string|array $name 路由命名标识 数组表示批量设置 - * @param array $value 路由地址及变量信息 + * @param string|array $name 路由命名标识 数组表示批量设置 + * @param array $value 路由地址及变量信息 * @return array */ public static function name($name = '', $value = null) @@ -154,7 +154,7 @@ class Route /** * 读取路由绑定 * @access public - * @param string $type 绑定类型 + * @param string $type 绑定类型 * @return mixed */ public static function getBind($type) @@ -165,8 +165,8 @@ class Route /** * 导入配置文件的路由规则 * @access public - * @param array $rule 路由规则 - * @param string $type 请求类型 + * @param array $rule 路由规则 + * @param string $type 请求类型 * @return void */ public static function import(array $rule, $type = '*') @@ -222,11 +222,11 @@ class Route /** * 注册路由规则 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param string $type 请求类型 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param string $type 请求类型 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = []) @@ -255,9 +255,11 @@ class Route $option1 = array_merge($option, $val[1]); $pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []); } else { - $route = $val; + $option1 = null; + $pattern1 = null; + $route = $val; } - self::setRule($key, $route, $type, isset($option1) ? $option1 : $option, isset($pattern1) ? $pattern1 : $pattern, $group); + self::setRule($key, $route, $type, !is_null($option1) ? $option1 : $option, !is_null($pattern1) ? $pattern1 : $pattern, $group); } } else { self::setRule($rule, $route, $type, $option, $pattern, $group); @@ -268,12 +270,12 @@ class Route /** * 设置路由规则 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param string $type 请求类型 - * @param array $option 路由参数 - * @param array $pattern 变量规则 - * @param string $group 所属分组 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param string $type 请求类型 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @param string $group 所属分组 * @return void */ protected static function setRule($rule, $route, $type = '*', $option = [], $pattern = [], $group = '') @@ -333,9 +335,9 @@ class Route if ('*' == $type) { // 注册路由快捷方式 foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) { - if (self::$domain) { + if (self::$domain && !isset(self::$rules['domain'][self::$domain][$method][$rule])) { self::$rules['domain'][self::$domain][$method][$rule] = true; - } else { + } elseif (!self::$domain && !isset(self::$rules[$method][$rule])) { self::$rules[$method][$rule] = true; } } @@ -346,7 +348,7 @@ class Route /** * 设置当前执行的参数信息 * @access public - * @param array $options 参数信息 + * @param array $options 参数信息 * @return mixed */ protected static function setOption($options = []) @@ -367,7 +369,7 @@ class Route /** * 获取当前的分组信息 * @access public - * @param string $type 分组信息名称 name option pattern + * @param string $type 分组信息名称 name option pattern * @return mixed */ public static function getGroup($type) @@ -382,9 +384,9 @@ class Route /** * 设置当前的路由分组 * @access public - * @param string $name 分组名称 - * @param array $option 分组路由参数 - * @param array $pattern 分组变量规则 + * @param string $name 分组名称 + * @param array $option 分组路由参数 + * @param array $pattern 分组变量规则 * @return void */ public static function setGroup($name, $option = [], $pattern = []) @@ -397,10 +399,10 @@ class Route /** * 注册路由分组 * @access public - * @param string|array $name 分组名称或者参数 - * @param array|\Closure $routes 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $name 分组名称或者参数 + * @param array|\Closure $routes 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function group($name, $routes, $option = [], $pattern = []) @@ -428,7 +430,8 @@ class Route self::$rules['*'][$name]['pattern'] = $pattern; } } else { - $item = []; + $item = []; + $completeMatch = Config::get('route_complete_match'); foreach ($routes as $key => $val) { if (is_numeric($key)) { $key = array_shift($val); @@ -447,6 +450,8 @@ class Route // 是否完整匹配 $options['complete_match'] = true; $key = substr($key, 0, -1); + } elseif ($completeMatch) { + $options['complete_match'] = true; } $key = trim($key, '/'); $vars = self::parseVar($key); @@ -482,10 +487,10 @@ class Route /** * 注册路由 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function any($rule, $route = '', $option = [], $pattern = []) @@ -496,10 +501,10 @@ class Route /** * 注册GET路由 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function get($rule, $route = '', $option = [], $pattern = []) @@ -510,10 +515,10 @@ class Route /** * 注册POST路由 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function post($rule, $route = '', $option = [], $pattern = []) @@ -524,10 +529,10 @@ class Route /** * 注册PUT路由 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function put($rule, $route = '', $option = [], $pattern = []) @@ -538,10 +543,10 @@ class Route /** * 注册DELETE路由 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function delete($rule, $route = '', $option = [], $pattern = []) @@ -552,10 +557,10 @@ class Route /** * 注册PATCH路由 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function patch($rule, $route = '', $option = [], $pattern = []) @@ -566,10 +571,10 @@ class Route /** * 注册资源路由 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string|array $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function resource($rule, $route = '', $option = [], $pattern = []) @@ -613,10 +618,10 @@ class Route /** * 注册控制器路由 操作方法对应不同的请求后缀 * @access public - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param array $option 路由参数 - * @param array $pattern 变量规则 + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 * @return void */ public static function controller($rule, $route = '', $option = [], $pattern = []) @@ -629,9 +634,9 @@ class Route /** * 注册别名路由 * @access public - * @param string|array $rule 路由别名 - * @param string $route 路由地址 - * @param array $option 路由参数 + * @param string|array $rule 路由别名 + * @param string $route 路由地址 + * @param array $option 路由参数 * @return void */ public static function alias($rule = null, $route = '', $option = []) @@ -646,8 +651,8 @@ class Route /** * 设置不同请求类型下面的方法前缀 * @access public - * @param string $method 请求类型 - * @param string $prefix 类型前缀 + * @param string $method 请求类型 + * @param string $prefix 类型前缀 * @return void */ public static function setMethodPrefix($method, $prefix = '') @@ -662,8 +667,8 @@ class Route /** * rest方法定义和修改 * @access public - * @param string $name 方法名称 - * @param array|bool $resource 资源 + * @param string|array $name 方法名称 + * @param array|bool $resource 资源 * @return void */ public static function rest($name, $resource = []) @@ -678,9 +683,9 @@ class Route /** * 注册未匹配路由规则后的处理 * @access public - * @param string $route 路由地址 - * @param string $method 请求类型 - * @param array $option 路由参数 + * @param string $route 路由地址 + * @param string $method 请求类型 + * @param array $option 路由参数 * @return void */ public static function miss($route, $method = '*', $option = []) @@ -691,7 +696,7 @@ class Route /** * 注册一个自动解析的URL路由 * @access public - * @param string $route 路由地址 + * @param string $route 路由地址 * @return void */ public static function auto($route) @@ -721,9 +726,9 @@ class Route /** * 检测子域名部署 * @access public - * @param Request $request Request请求对象 - * @param array $currentRules 当前路由规则 - * @param string $method 请求类型 + * @param Request $request Request请求对象 + * @param array $currentRules 当前路由规则 + * @param string $method 请求类型 * @return void */ public static function checkDomain($request, &$currentRules, $method = 'get') @@ -732,7 +737,7 @@ class Route $rules = self::$rules['domain']; // 开启子域名部署 支持二级和三级域名 if (!empty($rules)) { - $host = $request->host(); + $host = $request->host(true); if (isset($rules[$host])) { // 完整域名或者IP配置 $item = $rules[$host]; @@ -822,14 +827,23 @@ class Route /** * 检测URL路由 * @access public - * @param Request $request Request请求对象 - * @param string $url URL地址 - * @param string $depr URL分隔符 - * @param bool $checkDomain 是否检测域名规则 + * @param Request $request Request请求对象 + * @param string $url URL地址 + * @param string $depr URL分隔符 + * @param bool $checkDomain 是否检测域名规则 * @return false|array */ public static function check($request, $url, $depr = '/', $checkDomain = false) { + //检查解析缓存 + if (!App::$debug && Config::get('route_check_cache')) { + $key = self::getCheckCacheKey($request); + if (Cache::has($key)) { + list($rule, $route, $pathinfo, $option, $matches) = Cache::get($key); + return self::parseRule($rule, $route, $pathinfo, $option, $matches, true); + } + } + // 分隔符替换 确保路由定义使用统一的分隔符 $url = str_replace($depr, '|', $url); @@ -883,12 +897,12 @@ class Route /** * 检测路由规则 * @access private - * @param Request $request - * @param array $rules 路由规则 - * @param string $url URL地址 - * @param string $depr URL分割符 - * @param string $group 路由分组名 - * @param array $options 路由参数(分组) + * @param Request $request + * @param array $rules 路由规则 + * @param string $url URL地址 + * @param string $depr URL分割符 + * @param string $group 路由分组名 + * @param array $options 路由参数(分组) * @return mixed */ private static function checkRoute($request, $rules, $url, $depr = '/', $group = '', $options = []) @@ -966,9 +980,9 @@ class Route /** * 检测路由别名 * @access private - * @param Request $request - * @param string $url URL地址 - * @param string $depr URL分隔符 + * @param Request $request + * @param string $url URL地址 + * @param string $depr URL分隔符 * @return mixed */ private static function checkRouteAlias($request, $url, $depr) @@ -1013,9 +1027,9 @@ class Route /** * 检测URL绑定 * @access private - * @param string $url URL地址 - * @param array $rules 路由规则 - * @param string $depr URL分隔符 + * @param string $url URL地址 + * @param array $rules 路由规则 + * @param string $depr URL分隔符 * @return mixed */ private static function checkUrlBind(&$url, &$rules, $depr = '/') @@ -1044,9 +1058,9 @@ class Route /** * 绑定到类 * @access public - * @param string $url URL地址 - * @param string $class 类名(带命名空间) - * @param string $depr URL分隔符 + * @param string $url URL地址 + * @param string $class 类名(带命名空间) + * @param string $depr URL分隔符 * @return array */ public static function bindToClass($url, $class, $depr = '/') @@ -1063,9 +1077,9 @@ class Route /** * 绑定到命名空间 * @access public - * @param string $url URL地址 - * @param string $namespace 命名空间 - * @param string $depr URL分隔符 + * @param string $url URL地址 + * @param string $namespace 命名空间 + * @param string $depr URL分隔符 * @return array */ public static function bindToNamespace($url, $namespace, $depr = '/') @@ -1083,9 +1097,9 @@ class Route /** * 绑定到控制器类 * @access public - * @param string $url URL地址 - * @param string $controller 控制器名 (支持带模块名 index/user ) - * @param string $depr URL分隔符 + * @param string $url URL地址 + * @param string $controller 控制器名 (支持带模块名 index/user ) + * @param string $depr URL分隔符 * @return array */ public static function bindToController($url, $controller, $depr = '/') @@ -1102,9 +1116,9 @@ class Route /** * 绑定到模块/控制器 * @access public - * @param string $url URL地址 - * @param string $controller 控制器类名(带命名空间) - * @param string $depr URL分隔符 + * @param string $url URL地址 + * @param string $controller 控制器类名(带命名空间) + * @param string $depr URL分隔符 * @return array */ public static function bindToModule($url, $controller, $depr = '/') @@ -1121,8 +1135,8 @@ class Route /** * 路由参数有效性检查 * @access private - * @param array $option 路由参数 - * @param Request $request Request对象 + * @param array $option 路由参数 + * @param Request $request Request对象 * @return bool */ private static function checkOption($option, $request) @@ -1148,18 +1162,18 @@ class Route /** * 检测路由规则 * @access private - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param string $url URL地址 - * @param array $pattern 变量规则 - * @param array $option 路由参数 - * @param string $depr URL分隔符(全局) + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param string $url URL地址 + * @param array $pattern 变量规则 + * @param array $option 路由参数 + * @param string $depr URL分隔符(全局) * @return array|false */ private static function checkRule($rule, $route, $url, $pattern, $option, $depr) { // 检查完整规则定义 - if (isset($pattern['__url__']) && !preg_match('/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) { + if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) { return false; } // 检查路由的参数分隔符 @@ -1195,9 +1209,9 @@ class Route /** * 解析模块的URL地址 [模块/控制器/操作?]参数1=值1&参数2=值2... * @access public - * @param string $url URL地址 - * @param string $depr URL分隔符 - * @param bool $autoSearch 是否自动深度搜索控制器 + * @param string $url URL地址 + * @param string $depr URL分隔符 + * @param bool $autoSearch 是否自动深度搜索控制器 * @return array */ public static function parseUrl($url, $depr = '/', $autoSearch = false) @@ -1264,7 +1278,7 @@ class Route /** * 解析URL的pathinfo参数和变量 * @access private - * @param string $url URL地址 + * @param string $url URL地址 * @return array */ private static function parseUrlPath($url) @@ -1290,9 +1304,9 @@ class Route /** * 检测URL和规则路由是否匹配 * @access private - * @param string $url URL地址 - * @param string $rule 路由规则 - * @param array $pattern 变量规则 + * @param string $url URL地址 + * @param string $rule 路由规则 + * @param array $pattern 变量规则 * @return array|false */ private static function match($url, $rule, $pattern) @@ -1349,7 +1363,7 @@ class Route if (false === $result) { return false; } - } elseif (!preg_match('/^' . $pattern[$name] . '$/', $m1[$key])) { + } elseif (!preg_match(0 === strpos($pattern[$name], '/') ? $pattern[$name] : '/^' . $pattern[$name] . '$/', $m1[$key])) { return false; } } @@ -1365,16 +1379,28 @@ class Route /** * 解析规则路由 * @access private - * @param string $rule 路由规则 - * @param string $route 路由地址 - * @param string $pathinfo URL地址 - * @param array $option 路由参数 - * @param array $matches 匹配的变量 + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param string $pathinfo URL地址 + * @param array $option 路由参数 + * @param array $matches 匹配的变量 + * @param bool $fromCache 通过缓存解析 * @return array */ - private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = []) + private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = [], $fromCache = false) { $request = Request::instance(); + + //保存解析缓存 + if (Config::get('route_check_cache') && !$fromCache) { + try { + $key = self::getCheckCacheKey($request); + Cache::tag('route_check')->set($key, [$rule, $route, $pathinfo, $option, $matches]); + } catch (\Exception $e) { + + } + } + // 解析路由规则 if ($rule) { $rule = explode('/', $rule); @@ -1449,6 +1475,10 @@ class Route $request->bind($bind); } + if (!empty($option['response'])) { + Hook::add('response_send', $option['response']); + } + // 解析额外参数 self::parseUrlParams(empty($paths) ? '' : implode('|', $paths), $matches); // 记录匹配的路由信息 @@ -1497,18 +1527,19 @@ class Route App::$modulePath = APP_PATH . (Config::get('app_multi_module') ? $request->module() . DS : ''); } else { // 路由到模块/控制器/操作 - $result = self::parseModule($route); + $result = self::parseModule($route, isset($option['convert']) ? $option['convert'] : false); } // 开启请求缓存 if ($request->isGet() && isset($option['cache'])) { $cache = $option['cache']; if (is_array($cache)) { - list($key, $expire) = $cache; + list($key, $expire, $tag) = array_pad($cache, 3, null); } else { $key = str_replace('|', '/', $pathinfo); $expire = $cache; + $tag = null; } - $request->cache($key, $expire); + $request->cache($key, $expire, $tag); } return $result; } @@ -1516,10 +1547,11 @@ class Route /** * 解析URL地址为 模块/控制器/操作 * @access private - * @param string $url URL地址 + * @param string $url URL地址 + * @param bool $convert 是否自动转换URL地址 * @return array */ - private static function parseModule($url) + private static function parseModule($url, $convert = false) { list($path, $var) = self::parseUrlPath($url); $action = array_pop($path); @@ -1533,14 +1565,14 @@ class Route // 设置当前请求的路由变量 Request::instance()->route($var); // 路由到模块/控制器/操作 - return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false]; + return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => $convert]; } /** * 解析URL地址中的参数Request对象 * @access private - * @param string $rule 路由规则 - * @param array $var 变量 + * @param string $url 路由规则 + * @param array $var 变量 * @return void */ private static function parseUrlParams($url, &$var = []) @@ -1590,4 +1622,24 @@ class Route } return $var; } + + /** + * 获取路由解析缓存的key + * @param Request $request + * @return string + */ + private static function getCheckCacheKey(Request $request) + { + static $key; + + if (empty($key)) { + if ($callback = Config::get('route_check_cache_key')) { + $key = call_user_func($callback, $request); + } else { + $key = "{$request->host(true)}|{$request->method()}|{$request->path()}"; + } + } + + return $key; + } } diff --git a/thinkphp/library/think/Session.php b/thinkphp/library/think/Session.php index d5a6a5a5..61150bca 100644 --- a/thinkphp/library/think/Session.php +++ b/thinkphp/library/think/Session.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -25,6 +25,7 @@ class Session */ public static function prefix($prefix = '') { + empty(self::$init) && self::boot(); if (empty($prefix) && null !== $prefix) { return self::$prefix; } else { @@ -56,7 +57,7 @@ class Session $isDoStart = true; } - if (isset($config['prefix']) && (self::$prefix === '' || self::$prefix === null)) { + if (isset($config['prefix']) && ('' === self::$prefix || null === self::$prefix)) { self::$prefix = $config['prefix']; } if (isset($config['var_session_id']) && isset($_REQUEST[$config['var_session_id']])) { @@ -347,7 +348,7 @@ class Session * @param bool $delete 是否删除关联会话文件 * @return void */ - private static function regenerate($delete = false) + public static function regenerate($delete = false) { session_regenerate_id($delete); } diff --git a/thinkphp/library/think/Template.php b/thinkphp/library/think/Template.php index 4abf21ce..9ba0ff35 100644 --- a/thinkphp/library/think/Template.php +++ b/thinkphp/library/think/Template.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -12,6 +12,7 @@ namespace think; use think\exception\TemplateNotFoundException; +use think\template\TagLib; /** * ThinkPHP分离出来的模板引擎 @@ -59,15 +60,20 @@ class Template /** * 构造函数 * @access public + * @param array $config */ public function __construct(array $config = []) { - $this->config['cache_path'] = TEMP_PATH; - $this->config = array_merge($this->config, $config); - $this->config['taglib_begin'] = $this->stripPreg($this->config['taglib_begin']); - $this->config['taglib_end'] = $this->stripPreg($this->config['taglib_end']); - $this->config['tpl_begin'] = $this->stripPreg($this->config['tpl_begin']); - $this->config['tpl_end'] = $this->stripPreg($this->config['tpl_end']); + $this->config['cache_path'] = TEMP_PATH; + $this->config = array_merge($this->config, $config); + + $this->config['taglib_begin_origin'] = $this->config['taglib_begin']; + $this->config['taglib_end_origin'] = $this->config['taglib_end']; + + $this->config['taglib_begin'] = preg_quote($this->config['taglib_begin'], '/'); + $this->config['taglib_end'] = preg_quote($this->config['taglib_end'], '/'); + $this->config['tpl_begin'] = preg_quote($this->config['tpl_begin'], '/'); + $this->config['tpl_end'] = preg_quote($this->config['tpl_end'], '/'); // 初始化模板编译存储器 $type = $this->config['compile_type'] ? $this->config['compile_type'] : 'File'; @@ -75,20 +81,6 @@ class Template $this->storage = new $class(); } - /** - * 字符串替换 避免正则混淆 - * @access private - * @param string $str - * @return string - */ - private function stripPreg($str) - { - return str_replace( - ['{', '}', '(', ')', '|', '[', ']', '-', '+', '*', '.', '^', '?'], - ['\{', '\}', '\(', '\)', '\|', '\[', '\]', '\-', '\+', '\*', '\.', '\^', '\?'], - $str); - } - /** * 模板变量赋值 * @access public @@ -120,7 +112,7 @@ class Template * 模板引擎配置项 * @access public * @param array|string $config - * @return void|array + * @return string|void|array */ public function config($config) { @@ -183,7 +175,7 @@ class Template } $template = $this->parseTemplateFile($template); if ($template) { - $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($template) . '.' . ltrim($this->config['cache_suffix'], '.'); + $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($this->config['layout_name'] . $template) . '.' . ltrim($this->config['cache_suffix'], '.'); if (!$this->checkCache($cacheFile)) { // 缓存无效 重新模板编译 $content = file_get_contents($template); @@ -234,7 +226,7 @@ class Template * @access public * @param mixed $name 布局模板名称 false 则关闭布局 * @param string $replace 布局模板内容替换标识 - * @return object + * @return Template */ public function layout($name, $replace = '') { @@ -688,6 +680,7 @@ class Template } else { $className = '\\think\\template\\taglib\\' . ucwords($tagLib); } + /** @var Taglib $tLib */ $tLib = new $className($this); $tLib->parseTag($content, $hide ? '' : $tagLib); return; @@ -763,31 +756,26 @@ class Template } else { if (isset($array[1])) { $this->parseVar($array[2]); - $_name = ' && ' . $name . $array[1] . $array[2]; + $express = $name . $array[1] . $array[2]; } else { - $_name = ''; + $express = false; } // $name为数组 switch ($first) { case '?': // {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx - $str = ''; + $str = ''; break; case '=': // {$varname?='xxx'} $varname为真时才输出xxx - $str = ''; + $str = ''; break; case ':': // {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx - $str = ''; + $str = ''; break; default: - if (strpos($str, ':')) { - // {$varname ? 'a' : 'b'} $varname为真时输出a,否则输出b - $str = ''; - } else { - $str = ''; - } + $str = ''; } } } else { @@ -1075,7 +1063,7 @@ class Template } else { $path = isset($module) ? APP_PATH . $module . DS . basename($this->config['view_path']) . DS : $this->config['view_path']; } - $template = $path . $template . '.' . ltrim($this->config['view_suffix'], '.'); + $template = realpath($path . $template . '.' . ltrim($this->config['view_suffix'], '.')); } if (is_file($template)) { diff --git a/thinkphp/library/think/Url.php b/thinkphp/library/think/Url.php index 9f725e2c..53a545f9 100644 --- a/thinkphp/library/think/Url.php +++ b/thinkphp/library/think/Url.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -118,7 +118,7 @@ class Url $type = Route::getBind('type'); if ($type) { $bind = Route::getBind($type); - if (0 === strpos($url, $bind)) { + if ($bind && 0 === strpos($url, $bind)) { $url = substr($url, strlen($bind) + 1); } } @@ -135,7 +135,7 @@ class Url if (!empty($vars)) { // 添加参数 if (Config::get('url_common_param')) { - $vars = urldecode(http_build_query($vars)); + $vars = http_build_query($vars); $url .= $suffix . '?' . $vars . $anchor; } else { $paramType = Config::get('url_param_type'); @@ -210,17 +210,21 @@ class Url } $module = $module ? $module . '/' : ''; - $controller = Loader::parseName($request->controller()); + $controller = $request->controller(); if ('' == $url) { // 空字符串输出当前的 模块/控制器/操作 - $url = $module . $controller . '/' . $request->action(); + $action = $request->action(); } else { $path = explode('/', $url); - $action = Config::get('url_convert') ? strtolower(array_pop($path)) : array_pop($path); - $controller = empty($path) ? $controller : (Config::get('url_convert') ? Loader::parseName(array_pop($path)) : array_pop($path)); + $action = array_pop($path); + $controller = empty($path) ? $controller : array_pop($path); $module = empty($path) ? $module : array_pop($path) . '/'; - $url = $module . $controller . '/' . $action; } + if (Config::get('url_convert')) { + $action = strtolower($action); + $controller = Loader::parseName($controller); + } + $url = $module . $controller . '/' . $action; } return $url; } @@ -272,7 +276,7 @@ class Url $domain .= '.' . $rootDomain; } } - if (false !== strpos($domain, ':')) { + if (false !== strpos($domain, '://')) { $scheme = ''; } else { $scheme = $request->isSsl() || Config::get('is_https') ? 'https://' : 'http://'; @@ -298,11 +302,12 @@ class Url foreach ($rule as $item) { list($url, $pattern, $domain, $suffix) = $item; if (empty($pattern)) { - return [$url, $domain, $suffix]; + return [rtrim($url, '$'), $domain, $suffix]; } + $type = Config::get('url_common_param'); foreach ($pattern as $key => $val) { if (isset($vars[$key])) { - $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], urlencode($vars[$key]), $url); + $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $type ? $vars[$key] : urlencode($vars[$key]), $url); unset($vars[$key]); $result = [$url, $domain, $suffix]; } elseif (2 == $val) { diff --git a/thinkphp/library/think/Validate.php b/thinkphp/library/think/Validate.php index 8d1cb3b5..608e1e4a 100644 --- a/thinkphp/library/think/Validate.php +++ b/thinkphp/library/think/Validate.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -36,54 +36,56 @@ class Validate // 验证规则默认提示信息 protected static $typeMsg = [ - 'require' => ':attribute不能为空', - 'number' => ':attribute必须是数字', - 'float' => ':attribute必须是浮点数', - 'boolean' => ':attribute必须是布尔值', - 'email' => ':attribute格式不符', - 'array' => ':attribute必须是数组', - 'accepted' => ':attribute必须是yes、on或者1', - 'date' => ':attribute格式不符合', - 'file' => ':attribute不是有效的上传文件', - 'image' => ':attribute不是有效的图像文件', - 'alpha' => ':attribute只能是字母', - 'alphaNum' => ':attribute只能是字母和数字', - 'alphaDash' => ':attribute只能是字母、数字和下划线_及破折号-', - 'activeUrl' => ':attribute不是有效的域名或者IP', - 'chs' => ':attribute只能是汉字', - 'chsAlpha' => ':attribute只能是汉字、字母', - 'chsAlphaNum' => ':attribute只能是汉字、字母和数字', - 'chsDash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', - 'url' => ':attribute不是有效的URL地址', - 'ip' => ':attribute不是有效的IP地址', - 'dateFormat' => ':attribute必须使用日期格式 :rule', - 'in' => ':attribute必须在 :rule 范围内', - 'notIn' => ':attribute不能在 :rule 范围内', - 'between' => ':attribute只能在 :1 - :2 之间', - 'notBetween' => ':attribute不能在 :1 - :2 之间', - 'length' => ':attribute长度不符合要求 :rule', - 'max' => ':attribute长度不能超过 :rule', - 'min' => ':attribute长度不能小于 :rule', - 'after' => ':attribute日期不能小于 :rule', - 'before' => ':attribute日期不能超过 :rule', - 'expire' => '不在有效期内 :rule', - 'allowIp' => '不允许的IP访问', - 'denyIp' => '禁止的IP访问', - 'confirm' => ':attribute和确认字段:2不一致', - 'different' => ':attribute和比较字段:2不能相同', - 'egt' => ':attribute必须大于等于 :rule', - 'gt' => ':attribute必须大于 :rule', - 'elt' => ':attribute必须小于等于 :rule', - 'lt' => ':attribute必须小于 :rule', - 'eq' => ':attribute必须等于 :rule', - 'unique' => ':attribute已存在', - 'regex' => ':attribute不符合指定规则', - 'method' => '无效的请求类型', - 'token' => '令牌数据无效', - 'fileSize' => '上传文件大小不符', - 'fileExt' => '上传文件后缀不符', - 'fileMime' => '上传文件类型不符', - + 'require' => ':attribute require', + 'number' => ':attribute must be numeric', + 'integer' => ':attribute must be integer', + 'float' => ':attribute must be float', + 'boolean' => ':attribute must be bool', + 'email' => ':attribute not a valid email address', + 'array' => ':attribute must be a array', + 'accepted' => ':attribute must be yes,on or 1', + 'date' => ':attribute not a valid datetime', + 'file' => ':attribute not a valid file', + 'image' => ':attribute not a valid image', + 'alpha' => ':attribute must be alpha', + 'alphaNum' => ':attribute must be alpha-numeric', + 'alphaDash' => ':attribute must be alpha-numeric, dash, underscore', + 'activeUrl' => ':attribute not a valid domain or ip', + 'chs' => ':attribute must be chinese', + 'chsAlpha' => ':attribute must be chinese or alpha', + 'chsAlphaNum' => ':attribute must be chinese,alpha-numeric', + 'chsDash' => ':attribute must be chinese,alpha-numeric,underscore, dash', + 'url' => ':attribute not a valid url', + 'ip' => ':attribute not a valid ip', + 'dateFormat' => ':attribute must be dateFormat of :rule', + 'in' => ':attribute must be in :rule', + 'notIn' => ':attribute be notin :rule', + 'between' => ':attribute must between :1 - :2', + 'notBetween' => ':attribute not between :1 - :2', + 'length' => 'size of :attribute must be :rule', + 'max' => 'max size of :attribute must be :rule', + 'min' => 'min size of :attribute must be :rule', + 'after' => ':attribute cannot be less than :rule', + 'before' => ':attribute cannot exceed :rule', + 'afterWith' => ':attribute cannot be less than :rule', + 'beforeWith' => ':attribute cannot exceed :rule', + 'expire' => ':attribute not within :rule', + 'allowIp' => 'access IP is not allowed', + 'denyIp' => 'access IP denied', + 'confirm' => ':attribute out of accord with :2', + 'different' => ':attribute cannot be same with :2', + 'egt' => ':attribute must greater than or equal :rule', + 'gt' => ':attribute must greater than :rule', + 'elt' => ':attribute must less than or equal :rule', + 'lt' => ':attribute must less than :rule', + 'eq' => ':attribute must equal :rule', + 'unique' => ':attribute has exists', + 'regex' => ':attribute not conform to the rules', + 'method' => 'invalid Request method', + 'token' => 'invalid token', + 'fileSize' => 'filesize not match', + 'fileExt' => 'extensions to upload is not allowed', + 'fileMime' => 'mimetype to upload is not allowed', ]; // 当前验证场景 @@ -339,6 +341,41 @@ class Validate return !empty($this->error) ? false : true; } + /** + * 根据验证规则验证数据 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rules 验证规则 + * @return bool + */ + protected function checkRule($value, $rules) + { + if ($rules instanceof \Closure) { + return call_user_func_array($rules, [$value]); + } elseif (is_string($rules)) { + $rules = explode('|', $rules); + } + + foreach ($rules as $key => $rule) { + if ($rule instanceof \Closure) { + $result = call_user_func_array($rule, [$value]); + } else { + // 判断验证类型 + list($type, $rule) = $this->getValidateType($key, $rule); + + $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type]; + + $result = call_user_func_array($callback, [$value, $rule]); + } + + if (true !== $result) { + return $result; + } + } + + return true; + } + /** * 验证单个字段规则 * @access protected @@ -363,25 +400,7 @@ class Validate $info = is_numeric($key) ? '' : $key; } else { // 判断验证类型 - if (is_numeric($key)) { - if (strpos($rule, ':')) { - list($type, $rule) = explode(':', $rule, 2); - if (isset($this->alias[$type])) { - // 判断别名 - $type = $this->alias[$type]; - } - $info = $type; - } elseif (method_exists($this, $rule)) { - $type = $rule; - $info = $rule; - $rule = ''; - } else { - $type = 'is'; - $info = $rule; - } - } else { - $info = $type = $key; - } + list($type, $rule, $info) = $this->getValidateType($key, $rule); // 如果不是require 有数据才会行验证 if (0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) { @@ -417,6 +436,39 @@ class Validate return $result; } + /** + * 获取当前验证类型及规则 + * @access public + * @param mixed $key + * @param mixed $rule + * @return array + */ + protected function getValidateType($key, $rule) + { + // 判断验证类型 + if (!is_numeric($key)) { + return [$key, $rule, $key]; + } + + if (strpos($rule, ':')) { + list($type, $rule) = explode(':', $rule, 2); + if (isset($this->alias[$type])) { + // 判断别名 + $type = $this->alias[$type]; + } + $info = $type; + } elseif (method_exists($this, $rule)) { + $type = $rule; + $info = $rule; + $rule = ''; + } else { + $type = 'is'; + $info = $rule; + } + + return [$type, $rule, $info]; + } + /** * 验证是否和某个字段的值一致 * @access protected @@ -568,7 +620,7 @@ class Validate break; case 'chsDash': // 只允许汉字、字母、数字和下划线_及破折号- - $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-\.]+$/u'); + $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-]+$/u'); break; case 'activeUrl': // 是否为有效的网址 @@ -632,8 +684,12 @@ class Validate if (function_exists('exif_imagetype')) { return exif_imagetype($image); } else { - $info = getimagesize($image); - return $info[2]; + try { + $info = getimagesize($image); + return $info ? $info[2] : false; + } catch (\Exception $e) { + return false; + } } } @@ -676,21 +732,17 @@ class Validate */ protected function fileExt($file, $rule) { - if (!($file instanceof File)) { - return false; - } - if (is_string($rule)) { - $rule = explode(',', $rule); - } if (is_array($file)) { foreach ($file as $item) { - if (!$item->checkExt($rule)) { + if (!($item instanceof File) || !$item->checkExt($rule)) { return false; } } return true; - } else { + } elseif ($file instanceof File) { return $file->checkExt($rule); + } else { + return false; } } @@ -703,21 +755,17 @@ class Validate */ protected function fileMime($file, $rule) { - if (!($file instanceof File)) { - return false; - } - if (is_string($rule)) { - $rule = explode(',', $rule); - } if (is_array($file)) { foreach ($file as $item) { - if (!$item->checkMime($rule)) { + if (!($item instanceof File) || !$item->checkMime($rule)) { return false; } } return true; - } else { + } elseif ($file instanceof File) { return $file->checkMime($rule); + } else { + return false; } } @@ -730,18 +778,17 @@ class Validate */ protected function fileSize($file, $rule) { - if (!($file instanceof File)) { - return false; - } if (is_array($file)) { foreach ($file as $item) { - if (!$item->checkSize($rule)) { + if (!($item instanceof File) || !$item->checkSize($rule)) { return false; } } return true; - } else { + } elseif ($file instanceof File) { return $file->checkSize($rule); + } else { + return false; } } @@ -833,21 +880,26 @@ class Validate // 支持多个字段验证 $fields = explode('^', $key); foreach ($fields as $key) { - $map[$key] = $data[$key]; + if (isset($data[$key])) { + $map[$key] = $data[$key]; + } } } elseif (strpos($key, '=')) { parse_str($key, $map); - } else { + } elseif (isset($data[$field])) { $map[$key] = $data[$field]; + } else { + $map = []; } - $pk = strval(isset($rule[3]) ? $rule[3] : $db->getPk()); - if (isset($rule[2])) { - $map[$pk] = ['neq', $rule[2]]; - } elseif (isset($data[$pk])) { - $map[$pk] = ['neq', $data[$pk]]; + $pk = isset($rule[3]) ? $rule[3] : $db->getPk(); + if (is_string($pk)) { + if (isset($rule[2])) { + $map[$pk] = ['neq', $rule[2]]; + } elseif (isset($data[$pk])) { + $map[$pk] = ['neq', $data[$pk]]; + } } - if ($db->where($map)->field($pk)->find()) { return false; } @@ -899,7 +951,7 @@ class Validate { list($field, $val) = explode(',', $rule); if ($this->getDataValue($data, $field) == $val) { - return !empty($value); + return !empty($value) || '0' == $value; } else { return true; } @@ -917,7 +969,7 @@ class Validate { $result = call_user_func_array($rule, [$value, $data]); if ($result) { - return !empty($value); + return !empty($value) || '0' == $value; } else { return true; } @@ -935,7 +987,7 @@ class Validate { $val = $this->getDataValue($data, $rule); if (!empty($val)) { - return !empty($value); + return !empty($value) || '0' == $value; } else { return true; } @@ -1067,9 +1119,10 @@ class Validate * @access protected * @param mixed $value 字段值 * @param mixed $rule 验证规则 + * @param array $data 数据 * @return bool */ - protected function after($value, $rule) + protected function after($value, $rule, $data) { return strtotime($value) >= strtotime($rule); } @@ -1079,13 +1132,42 @@ class Validate * @access protected * @param mixed $value 字段值 * @param mixed $rule 验证规则 + * @param array $data 数据 * @return bool */ - protected function before($value, $rule) + protected function before($value, $rule, $data) { return strtotime($value) <= strtotime($rule); } + /** + * 验证日期字段 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function afterWith($value, $rule, $data) + { + $rule = $this->getDataValue($data, $rule); + return !is_null($rule) && strtotime($value) >= strtotime($rule); + } + + /** + * 验证日期字段 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function beforeWith($value, $rule, $data) + { + $rule = $this->getDataValue($data, $rule); + return !is_null($rule) && strtotime($value) <= strtotime($rule); + } + /** * 验证有效期 * @access protected @@ -1149,7 +1231,7 @@ class Validate // 不是正则表达式则两端补上/ $rule = '/^' . $rule . '$/'; } - return 1 === preg_match($rule, (string) $value); + return is_scalar($value) && 1 === preg_match($rule, (string) $value); } /** @@ -1225,12 +1307,16 @@ class Validate $msg = $this->message[$attribute]; } elseif (isset(self::$typeMsg[$type])) { $msg = self::$typeMsg[$type]; + } elseif (0 === strpos($type, 'require')) { + $msg = self::$typeMsg['require']; } else { - $msg = $title . '规则错误'; + $msg = $title . Lang::get('not conform to the rules'); } if (is_string($msg) && 0 === strpos($msg, '{%')) { $msg = Lang::get(substr($msg, 2, -1)); + } elseif (Lang::has($msg)) { + $msg = Lang::get($msg); } if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) { diff --git a/thinkphp/library/think/View.php b/thinkphp/library/think/View.php index 96ae56c9..ca2dadbb 100644 --- a/thinkphp/library/think/View.php +++ b/thinkphp/library/think/View.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -33,7 +33,7 @@ class View public function __construct($engine = [], $replace = []) { // 初始化模板引擎 - $this->engine((array) $engine); + $this->engine($engine); // 基础替换字符串 $request = Request::instance(); $base = $request->root(); @@ -127,7 +127,7 @@ class View * @access private * @param string|array $name 参数名 * @param mixed $value 参数值 - * @return void + * @return $this */ public function config($name, $value = null) { @@ -155,18 +155,21 @@ class View ob_implicit_flush(0); // 渲染输出 - $method = $renderContent ? 'display' : 'fetch'; - $this->engine->$method($template, $vars, $config); + try { + $method = $renderContent ? 'display' : 'fetch'; + // 允许用户自定义模板的字符串替换 + $replace = array_merge($this->replace, $replace, (array) $this->engine->config('tpl_replace_string')); + $this->engine->config('tpl_replace_string', $replace); + $this->engine->$method($template, $vars, $config); + } catch (\Exception $e) { + ob_end_clean(); + throw $e; + } // 获取并清空缓存 $content = ob_get_clean(); // 内容过滤标签 Hook::listen('view_filter', $content); - // 允许用户自定义模板的字符串替换 - $replace = array_merge($this->replace, $replace); - if (!empty($replace)) { - $content = strtr($content, $replace); - } return $content; } diff --git a/thinkphp/library/think/cache/Driver.php b/thinkphp/library/think/cache/Driver.php index 688507a8..07805e48 100644 --- a/thinkphp/library/think/cache/Driver.php +++ b/thinkphp/library/think/cache/Driver.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -120,10 +120,29 @@ abstract class Driver public function remember($name, $value, $expire = null) { if (!$this->has($name)) { - if ($value instanceof \Closure) { - $value = call_user_func($value); + $time = time(); + while ($time + 5 > time() && $this->has($name . '_lock')) { + // 存在锁定则等待 + usleep(200000); + } + + try { + // 锁定 + $this->set($name . '_lock', true); + if ($value instanceof \Closure) { + $value = call_user_func($value); + } + $this->set($name, $value, $expire); + // 解锁 + $this->rm($name . '_lock'); + } catch (\Exception $e) { + // 解锁 + $this->rm($name . '_lock'); + throw $e; + } catch (\throwable $e) { + $this->rm($name . '_lock'); + throw $e; } - $this->set($name, $value, $expire); } else { $value = $this->get($name); } @@ -140,7 +159,9 @@ abstract class Driver */ public function tag($name, $keys = null, $overlay = false) { - if (is_null($keys)) { + if (is_null($name)) { + + } elseif (is_null($keys)) { $this->tag = $name; } else { $key = 'tag_' . md5($name); @@ -153,7 +174,7 @@ abstract class Driver } else { $value = array_unique(array_merge($this->getTagItem($name), $keys)); } - $this->set($key, implode(',', $value)); + $this->set($key, implode(',', $value), 0); } return $this; } @@ -170,12 +191,13 @@ abstract class Driver $key = 'tag_' . md5($this->tag); $this->tag = null; if ($this->has($key)) { - $value = $this->get($key); - $value .= ',' . $name; + $value = explode(',', $this->get($key)); + $value[] = $name; + $value = implode(',', array_unique($value)); } else { $value = $name; } - $this->set($key, $value); + $this->set($key, $value, 0); } } @@ -190,7 +212,7 @@ abstract class Driver $key = 'tag_' . md5($tag); $value = $this->get($key); if ($value) { - return explode(',', $value); + return array_filter(explode(',', $value)); } else { return []; } diff --git a/thinkphp/library/think/cache/driver/File.php b/thinkphp/library/think/cache/driver/File.php index 5aadb2b1..fee64894 100644 --- a/thinkphp/library/think/cache/driver/File.php +++ b/thinkphp/library/think/cache/driver/File.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -27,6 +27,8 @@ class File extends Driver 'data_compress' => false, ]; + protected $expire; + /** * 构造函数 * @param array $options @@ -61,10 +63,11 @@ class File extends Driver /** * 取得变量的存储文件名 * @access protected - * @param string $name 缓存变量名 + * @param string $name 缓存变量名 + * @param bool $auto 是否自动创建目录 * @return string */ - protected function getCacheKey($name) + protected function getCacheKey($name, $auto = false) { $name = md5($name); if ($this->options['cache_subdir']) { @@ -76,7 +79,8 @@ class File extends Driver } $filename = $this->options['path'] . $name . '.php'; $dir = dirname($filename); - if (!is_dir($dir)) { + + if ($auto && !is_dir($dir)) { mkdir($dir, 0755, true); } return $filename; @@ -106,15 +110,15 @@ class File extends Driver if (!is_file($filename)) { return $default; } - $content = file_get_contents($filename); + $content = file_get_contents($filename); + $this->expire = null; if (false !== $content) { $expire = (int) substr($content, 8, 12); - if (0 != $expire && $_SERVER['REQUEST_TIME'] > filemtime($filename) + $expire) { - //缓存过期删除缓存文件 - $this->unlink($filename); + if (0 != $expire && time() > filemtime($filename) + $expire) { return $default; } - $content = substr($content, 20, -3); + $this->expire = $expire; + $content = substr($content, 32); if ($this->options['data_compress'] && function_exists('gzcompress')) { //启用数据压缩 $content = gzuncompress($content); @@ -129,9 +133,9 @@ class File extends Driver /** * 写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param int $expire 有效时间 0为永久 + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) * @return boolean */ public function set($name, $value, $expire = null) @@ -139,7 +143,10 @@ class File extends Driver if (is_null($expire)) { $expire = $this->options['expire']; } - $filename = $this->getCacheKey($name); + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } + $filename = $this->getCacheKey($name, true); if ($this->tag && !is_file($filename)) { $first = true; } @@ -148,7 +155,7 @@ class File extends Driver //数据压缩 $data = gzcompress($data, 3); } - $data = ""; + $data = "\n" . $data; $result = file_put_contents($filename, $data); if ($result) { isset($first) && $this->setTagItem($filename); @@ -169,11 +176,14 @@ class File extends Driver public function inc($name, $step = 1) { if ($this->has($name)) { - $value = $this->get($name) + $step; + $value = $this->get($name) + $step; + $expire = $this->expire; } else { - $value = $step; + $value = $step; + $expire = 0; } - return $this->set($name, $value, 0) ? $value : false; + + return $this->set($name, $value, $expire) ? $value : false; } /** @@ -186,11 +196,14 @@ class File extends Driver public function dec($name, $step = 1) { if ($this->has($name)) { - $value = $this->get($name) - $step; + $value = $this->get($name) - $step; + $expire = $this->expire; } else { - $value = $step; + $value = -$step; + $expire = 0; } - return $this->set($name, $value, 0) ? $value : false; + + return $this->set($name, $value, $expire) ? $value : false; } /** @@ -201,7 +214,11 @@ class File extends Driver */ public function rm($name) { - return $this->unlink($this->getCacheKey($name)); + $filename = $this->getCacheKey($name); + try { + return $this->unlink($filename); + } catch (\Exception $e) { + } } /** @@ -224,7 +241,10 @@ class File extends Driver $files = (array) glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*'); foreach ($files as $path) { if (is_dir($path)) { - array_map('unlink', glob($path . '/*.php')); + $matches = glob($path . '/*.php'); + if (is_array($matches)) { + array_map('unlink', $matches); + } rmdir($path); } else { unlink($path); diff --git a/thinkphp/library/think/cache/driver/Lite.php b/thinkphp/library/think/cache/driver/Lite.php index eeb96a19..8cbf08f9 100644 --- a/thinkphp/library/think/cache/driver/Lite.php +++ b/thinkphp/library/think/cache/driver/Lite.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -77,7 +77,7 @@ class Lite extends Driver if (is_file($filename)) { // 判断是否过期 $mtime = filemtime($filename); - if ($mtime < $_SERVER['REQUEST_TIME']) { + if ($mtime < time()) { // 清除已经过期的文件 unlink($filename); return $default; @@ -91,9 +91,9 @@ class Lite extends Driver /** * 写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param int $expire 有效时间 0为永久 + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) * @return bool */ public function set($name, $value, $expire = null) @@ -101,9 +101,11 @@ class Lite extends Driver if (is_null($expire)) { $expire = $this->options['expire']; } - // 模拟永久 - if (0 === $expire) { - $expire = 10 * 365 * 24 * 3600; + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp(); + } else { + $expire = 0 === $expire ? 10 * 365 * 24 * 3600 : $expire; + $expire = time() + $expire; } $filename = $this->getCacheKey($name); if ($this->tag && !is_file($filename)) { @@ -113,7 +115,7 @@ class Lite extends Driver // 通过设置修改时间实现有效期 if ($ret) { isset($first) && $this->setTagItem($filename); - touch($filename, $_SERVER['REQUEST_TIME'] + $expire); + touch($filename, $expire); } return $ret; } @@ -147,7 +149,7 @@ class Lite extends Driver if ($this->has($name)) { $value = $this->get($name) - $step; } else { - $value = $step; + $value = -$step; } return $this->set($name, $value, 0) ? $value : false; } diff --git a/thinkphp/library/think/cache/driver/Memcache.php b/thinkphp/library/think/cache/driver/Memcache.php index e464f38c..58703ea3 100644 --- a/thinkphp/library/think/cache/driver/Memcache.php +++ b/thinkphp/library/think/cache/driver/Memcache.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -63,7 +63,7 @@ class Memcache extends Driver public function has($name) { $key = $this->getCacheKey($name); - return $this->handler->get($key) ? true : false; + return false !== $this->handler->get($key); } /** @@ -82,9 +82,9 @@ class Memcache extends Driver /** * 写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer $expire 有效时间(秒) + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) * @return bool */ public function set($name, $value, $expire = null) @@ -92,6 +92,9 @@ class Memcache extends Driver if (is_null($expire)) { $expire = $this->options['expire']; } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } if ($this->tag && !$this->has($name)) { $first = true; } diff --git a/thinkphp/library/think/cache/driver/Memcached.php b/thinkphp/library/think/cache/driver/Memcached.php index 4a9d898c..5aab5a30 100644 --- a/thinkphp/library/think/cache/driver/Memcached.php +++ b/thinkphp/library/think/cache/driver/Memcached.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -93,9 +93,9 @@ class Memcached extends Driver /** * 写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer $expire 有效时间(秒) + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) * @return bool */ public function set($name, $value, $expire = null) @@ -103,6 +103,9 @@ class Memcached extends Driver if (is_null($expire)) { $expire = $this->options['expire']; } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } if ($this->tag && !$this->has($name)) { $first = true; } diff --git a/thinkphp/library/think/cache/driver/Redis.php b/thinkphp/library/think/cache/driver/Redis.php index 4f618785..027b3ea2 100644 --- a/thinkphp/library/think/cache/driver/Redis.php +++ b/thinkphp/library/think/cache/driver/Redis.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -46,9 +46,12 @@ class Redis extends Driver if (!empty($options)) { $this->options = array_merge($this->options, $options); } - $func = $this->options['persistent'] ? 'pconnect' : 'connect'; $this->handler = new \Redis; - $this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout']); + if ($this->options['persistent']) { + $this->handler->pconnect($this->options['host'], $this->options['port'], $this->options['timeout'], 'persistent_id_' . $this->options['select']); + } else { + $this->handler->connect($this->options['host'], $this->options['port'], $this->options['timeout']); + } if ('' != $this->options['password']) { $this->handler->auth($this->options['password']); @@ -67,7 +70,7 @@ class Redis extends Driver */ public function has($name) { - return $this->handler->get($this->getCacheKey($name)) ? true : false; + return $this->handler->exists($this->getCacheKey($name)); } /** @@ -80,20 +83,25 @@ class Redis extends Driver public function get($name, $default = false) { $value = $this->handler->get($this->getCacheKey($name)); - if (is_null($value)) { + if (is_null($value) || false === $value) { return $default; } - $jsonData = json_decode($value, true); - // 检测是否为JSON数据 true 返回JSON解析数组, false返回源数据 byron sampson - return (null === $jsonData) ? $value : $jsonData; + + try { + $result = 0 === strpos($value, 'think_serialize:') ? unserialize(substr($value, 16)) : $value; + } catch (\Exception $e) { + $result = $default; + } + + return $result; } /** * 写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer $expire 有效时间(秒) + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) * @return boolean */ public function set($name, $value, $expire = null) @@ -101,13 +109,15 @@ class Redis extends Driver if (is_null($expire)) { $expire = $this->options['expire']; } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } if ($this->tag && !$this->has($name)) { $first = true; } - $key = $this->getCacheKey($name); - //对数组/对象数据进行缓存处理,保证数据完整性 byron sampson - $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value; - if (is_int($expire) && $expire) { + $key = $this->getCacheKey($name); + $value = is_scalar($value) ? $value : 'think_serialize:' . serialize($value); + if ($expire) { $result = $this->handler->setex($key, $expire, $value); } else { $result = $this->handler->set($key, $value); @@ -119,26 +129,28 @@ class Redis extends Driver /** * 自增缓存(针对数值缓存) * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 + * @param string $name 缓存变量名 + * @param int $step 步长 * @return false|int */ public function inc($name, $step = 1) { $key = $this->getCacheKey($name); + return $this->handler->incrby($key, $step); } /** * 自减缓存(针对数值缓存) * @access public - * @param string $name 缓存变量名 - * @param int $step 步长 + * @param string $name 缓存变量名 + * @param int $step 步长 * @return false|int */ public function dec($name, $step = 1) { $key = $this->getCacheKey($name); + return $this->handler->decrby($key, $step); } diff --git a/thinkphp/library/think/cache/driver/Sqlite.php b/thinkphp/library/think/cache/driver/Sqlite.php index 305fd9e8..dc2ee055 100644 --- a/thinkphp/library/think/cache/driver/Sqlite.php +++ b/thinkphp/library/think/cache/driver/Sqlite.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -96,9 +96,9 @@ class Sqlite extends Driver /** * 写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer $expire 有效时间(秒) + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) * @return boolean */ public function set($name, $value, $expire = null) @@ -108,7 +108,11 @@ class Sqlite extends Driver if (is_null($expire)) { $expire = $this->options['expire']; } - $expire = (0 == $expire) ? 0 : ($_SERVER['REQUEST_TIME'] + $expire); //缓存有效期为0表示永久缓存 + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp(); + } else { + $expire = (0 == $expire) ? 0 : (time() + $expire); //缓存有效期为0表示永久缓存 + } if (function_exists('gzcompress')) { //数据压缩 $value = gzcompress($value, 3); @@ -155,7 +159,7 @@ class Sqlite extends Driver if ($this->has($name)) { $value = $this->get($name) - $step; } else { - $value = $step; + $value = -$step; } return $this->set($name, $value, 0) ? $value : false; } diff --git a/thinkphp/library/think/cache/driver/Wincache.php b/thinkphp/library/think/cache/driver/Wincache.php index 3076fc14..03f8d357 100644 --- a/thinkphp/library/think/cache/driver/Wincache.php +++ b/thinkphp/library/think/cache/driver/Wincache.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -68,9 +68,9 @@ class Wincache extends Driver /** * 写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer $expire 有效时间(秒) + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) * @return boolean */ public function set($name, $value, $expire = null) @@ -78,6 +78,9 @@ class Wincache extends Driver if (is_null($expire)) { $expire = $this->options['expire']; } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } $key = $this->getCacheKey($name); if ($this->tag && !$this->has($name)) { $first = true; diff --git a/thinkphp/library/think/cache/driver/Xcache.php b/thinkphp/library/think/cache/driver/Xcache.php index 2a0e07ad..4d94c033 100644 --- a/thinkphp/library/think/cache/driver/Xcache.php +++ b/thinkphp/library/think/cache/driver/Xcache.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -68,9 +68,9 @@ class Xcache extends Driver /** * 写入缓存 * @access public - * @param string $name 缓存变量名 - * @param mixed $value 存储数据 - * @param integer $expire 有效时间(秒) + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) * @return boolean */ public function set($name, $value, $expire = null) @@ -78,6 +78,9 @@ class Xcache extends Driver if (is_null($expire)) { $expire = $this->options['expire']; } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } if ($this->tag && !$this->has($name)) { $first = true; } diff --git a/thinkphp/library/think/config/driver/Ini.php b/thinkphp/library/think/config/driver/Ini.php index a223a578..bcd12b69 100644 --- a/thinkphp/library/think/config/driver/Ini.php +++ b/thinkphp/library/think/config/driver/Ini.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/config/driver/Json.php b/thinkphp/library/think/config/driver/Json.php index 557f75fe..479dcc89 100644 --- a/thinkphp/library/think/config/driver/Json.php +++ b/thinkphp/library/think/config/driver/Json.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/config/driver/Xml.php b/thinkphp/library/think/config/driver/Xml.php index b573a562..1158519f 100644 --- a/thinkphp/library/think/config/driver/Xml.php +++ b/thinkphp/library/think/config/driver/Xml.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/console/command/Clear.php b/thinkphp/library/think/console/command/Clear.php index 41019cea..1b5102ec 100644 --- a/thinkphp/library/think/console/command/Clear.php +++ b/thinkphp/library/think/console/command/Clear.php @@ -10,8 +10,10 @@ // +---------------------------------------------------------------------- namespace think\console\command; +use think\Cache; use think\console\Command; use think\console\Input; +use think\console\input\Argument; use think\console\input\Option; use think\console\Output; @@ -22,6 +24,7 @@ class Clear extends Command // 指令配置 $this ->setName('clear') + ->addArgument('type', Argument::OPTIONAL, 'type to clear', null) ->addOption('path', 'd', Option::VALUE_OPTIONAL, 'path to clear', null) ->setDescription('Clear runtime file'); } @@ -30,8 +33,14 @@ class Clear extends Command { $path = $input->getOption('path') ?: RUNTIME_PATH; - if (is_dir($path)) { - $this->clearPath($path); + $type = $input->getArgument('type'); + + if ($type == 'route') { + Cache::clear('route_check'); + } else { + if (is_dir($path)) { + $this->clearPath($path); + } } $output->writeln("Clear Successed"); diff --git a/thinkphp/library/think/console/command/optimize/Config.php b/thinkphp/library/think/console/command/optimize/Config.php index cadfe5ee..59c69a8e 100644 --- a/thinkphp/library/think/console/command/optimize/Config.php +++ b/thinkphp/library/think/console/command/optimize/Config.php @@ -30,7 +30,7 @@ class Config extends Command protected function execute(Input $input, Output $output) { - if ($input->hasArgument('module')) { + if ($input->getArgument('module')) { $module = $input->getArgument('module') . DS; } else { $module = ''; diff --git a/thinkphp/library/think/console/command/optimize/Route.php b/thinkphp/library/think/console/command/optimize/Route.php index 911e4c14..6da1d9a6 100644 --- a/thinkphp/library/think/console/command/optimize/Route.php +++ b/thinkphp/library/think/console/command/optimize/Route.php @@ -27,6 +27,11 @@ class Route extends Command protected function execute(Input $input, Output $output) { + + if (!is_dir(RUNTIME_PATH)) { + @mkdir(RUNTIME_PATH, 0755, true); + } + file_put_contents(RUNTIME_PATH . 'route.php', $this->buildRouteCache()); $output->writeln('Succeed!'); } diff --git a/thinkphp/library/think/console/command/optimize/Schema.php b/thinkphp/library/think/console/command/optimize/Schema.php index 27eb9dbb..33534240 100644 --- a/thinkphp/library/think/console/command/optimize/Schema.php +++ b/thinkphp/library/think/console/command/optimize/Schema.php @@ -44,7 +44,8 @@ class Schema extends Command if ($input->hasOption('module')) { $module = $input->getOption('module'); // 读取模型 - $list = scandir(APP_PATH . $module . DS . 'model'); + $path = APP_PATH . $module . DS . 'model'; + $list = is_dir($path) ? scandir($path) : []; $app = App::$namespace; foreach ($list as $file) { if (0 === strpos($file, '.')) { @@ -66,7 +67,8 @@ class Schema extends Command $tables = Db::connect($config)->getTables($dbName); } elseif (!\think\Config::get('app_multi_module')) { $app = App::$namespace; - $list = scandir(APP_PATH . 'model'); + $path = APP_PATH . 'model'; + $list = is_dir($path) ? scandir($path) : []; foreach ($list as $file) { if (0 === strpos($file, '.')) { continue; diff --git a/thinkphp/library/think/console/output/Descriptor.php b/thinkphp/library/think/console/output/Descriptor.php index 6d98d53c..23dc6481 100644 --- a/thinkphp/library/think/console/output/Descriptor.php +++ b/thinkphp/library/think/console/output/Descriptor.php @@ -69,7 +69,7 @@ class Descriptor * 描述参数 * @param InputArgument $argument * @param array $options - * @return string|mixed + * @return void */ protected function describeInputArgument(InputArgument $argument, array $options = []) { @@ -93,7 +93,7 @@ class Descriptor * 描述选项 * @param InputOption $option * @param array $options - * @return string|mixed + * @return void */ protected function describeInputOption(InputOption $option, array $options = []) { @@ -128,7 +128,7 @@ class Descriptor * 描述输入 * @param InputDefinition $definition * @param array $options - * @return string|mixed + * @return void */ protected function describeInputDefinition(InputDefinition $definition, array $options = []) { @@ -173,7 +173,7 @@ class Descriptor * 描述指令 * @param Command $command * @param array $options - * @return string|mixed + * @return void */ protected function describeCommand(Command $command, array $options = []) { @@ -208,7 +208,7 @@ class Descriptor * 描述控制台 * @param Console $console * @param array $options - * @return string|mixed + * @return void */ protected function describeConsole(Console $console, array $options = []) { diff --git a/thinkphp/library/think/controller/Rest.php b/thinkphp/library/think/controller/Rest.php index 8c5911df..43ab2f62 100644 --- a/thinkphp/library/think/controller/Rest.php +++ b/thinkphp/library/think/controller/Rest.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -43,7 +43,7 @@ abstract class Rest if ('' == $ext) { // 自动检测资源类型 $this->type = $request->type(); - } elseif (!preg_match('/\(' . $this->restTypeList . '\)$/i', $ext)) { + } elseif (!preg_match('/(' . $this->restTypeList . ')$/i', $ext)) { // 资源类型非法 则用默认资源类型访问 $this->type = $this->restDefaultType; } else { @@ -51,7 +51,7 @@ abstract class Rest } // 请求方式检测 $method = strtolower($request->method()); - if (false === stripos($this->restMethodList, $method)) { + if (!preg_match('/(' . $this->restMethodList . ')$/i', $method)) { // 请求方式非法 则用默认请求方法 $method = $this->restDefaultMethod; } diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php index 23f88836..58b45aa8 100644 --- a/thinkphp/library/think/db/Builder.php +++ b/thinkphp/library/think/db/Builder.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -22,10 +22,10 @@ abstract class Builder protected $query; // 数据库表达式 - protected $exp = ['eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'exp' => 'EXP', 'notin' => 'NOT IN', 'not in' => 'NOT IN', 'between' => 'BETWEEN', 'not between' => 'NOT BETWEEN', 'notbetween' => 'NOT BETWEEN', 'exists' => 'EXISTS', 'notexists' => 'NOT EXISTS', 'not exists' => 'NOT EXISTS', 'null' => 'NULL', 'notnull' => 'NOT NULL', 'not null' => 'NOT NULL', '> time' => '> TIME', '< time' => '< TIME', '>= time' => '>= TIME', '<= time' => '<= TIME', 'between time' => 'BETWEEN TIME', 'not between time' => 'NOT BETWEEN TIME', 'notbetween time' => 'NOT BETWEEN TIME']; + protected $exp = ['eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'not like' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'exp' => 'EXP', 'notin' => 'NOT IN', 'not in' => 'NOT IN', 'between' => 'BETWEEN', 'not between' => 'NOT BETWEEN', 'notbetween' => 'NOT BETWEEN', 'exists' => 'EXISTS', 'notexists' => 'NOT EXISTS', 'not exists' => 'NOT EXISTS', 'null' => 'NULL', 'notnull' => 'NOT NULL', 'not null' => 'NOT NULL', '> time' => '> TIME', '< time' => '< TIME', '>= time' => '>= TIME', '<= time' => '<= TIME', 'between time' => 'BETWEEN TIME', 'not between time' => 'NOT BETWEEN TIME', 'notbetween time' => 'NOT BETWEEN TIME']; // SQL表达式 - protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%'; + protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%UNION%%ORDER%%LIMIT%%LOCK%%COMMENT%'; protected $insertSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; protected $updateSql = 'UPDATE %TABLE% SET %SET% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; @@ -46,7 +46,7 @@ abstract class Builder /** * 获取当前的连接对象实例 * @access public - * @return void + * @return Connection */ public function getConnection() { @@ -56,7 +56,7 @@ abstract class Builder /** * 获取当前的Query对象实例 * @access public - * @return void + * @return Query */ public function getQuery() { @@ -80,6 +80,7 @@ abstract class Builder * @param array $data 数据 * @param array $options 查询参数 * @return array + * @throws Exception */ protected function parseData($data, $options) { @@ -97,8 +98,15 @@ abstract class Builder $result = []; foreach ($data as $key => $val) { - $item = $this->parseKey($key, $options); - if (is_object($val) && method_exists($val, '__toString')) { + if ('*' != $options['field'] && !in_array($key, $fields, true)) { + continue; + } + + $item = $this->parseKey($key, $options, true); + if ($val instanceof Expression) { + $result[$item] = $val->getValue(); + continue; + } elseif (is_object($val) && method_exists($val, '__toString')) { // 对象数据写入 $val = $val->__toString(); } @@ -108,16 +116,25 @@ abstract class Builder } } elseif (is_null($val)) { $result[$item] = 'NULL'; - } elseif (isset($val[0]) && 'exp' == $val[0]) { - $result[$item] = $val[1]; + } elseif (is_array($val) && !empty($val)) { + switch (strtolower($val[0])) { + case 'inc': + $result[$item] = $item . '+' . floatval($val[1]); + break; + case 'dec': + $result[$item] = $item . '-' . floatval($val[1]); + break; + case 'exp': + throw new Exception('not support data:[' . $val[0] . ']'); + } } elseif (is_scalar($val)) { // 过滤非标量数据 if (0 === strpos($val, ':') && $this->query->isBind(substr($val, 1))) { $result[$item] = $val; } else { $key = str_replace('.', '_', $key); - $this->query->bind('__data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR); - $result[$item] = ':__data__' . $key; + $this->query->bind('data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR); + $result[$item] = ':data__' . $key; } } } @@ -131,7 +148,7 @@ abstract class Builder * @param array $options * @return string */ - protected function parseKey($key, $options = []) + protected function parseKey($key, $options = [], $strict = false) { return $key; } @@ -172,8 +189,10 @@ abstract class Builder // 支持 'field1'=>'field2' 这样的字段别名定义 $array = []; foreach ($fields as $key => $field) { - if (!is_numeric($key)) { - $array[] = $this->parseKey($key, $options) . ' AS ' . $this->parseKey($field, $options); + if ($field instanceof Expression) { + $array[] = $field->getValue(); + } elseif (!is_numeric($key)) { + $array[] = $this->parseKey($key, $options) . ' AS ' . $this->parseKey($field, $options, true); } else { $array[] = $this->parseKey($field, $options); } @@ -195,11 +214,8 @@ abstract class Builder $item = []; foreach ((array) $tables as $key => $table) { if (!is_numeric($key)) { - if (strpos($key, '@think')) { - $key = strstr($key, '@think', true); - } $key = $this->parseSqlTable($key); - $item[] = $this->parseKey($key) . ' ' . $this->parseKey($table); + $item[] = $this->parseKey($key) . ' ' . (isset($options['alias'][$table]) ? $this->parseKey($options['alias'][$table]) : $this->parseKey($table)); } else { $table = $this->parseSqlTable($table); if (isset($options['alias'][$table])) { @@ -255,7 +271,9 @@ abstract class Builder foreach ($where as $key => $val) { $str = []; foreach ($val as $field => $value) { - if ($value instanceof \Closure) { + if ($value instanceof Expression) { + $str[] = ' ' . $key . ' ( ' . $value->getValue() . ' )'; + } elseif ($value instanceof \Closure) { // 使用闭包查询 $query = new Query($this->connection); call_user_func_array($value, [ & $query]); @@ -296,11 +314,11 @@ abstract class Builder protected function parseWhereItem($field, $val, $rule = '', $options = [], $binds = [], $bindName = null) { // 字段分析 - $key = $field ? $this->parseKey($field, $options) : ''; + $key = $field ? $this->parseKey($field, $options, true) : ''; // 查询规则和条件 if (!is_array($val)) { - $val = ['=', $val]; + $val = is_null($val) ? ['null', ''] : ['=', $val]; } list($exp, $value) = $val; @@ -329,12 +347,19 @@ abstract class Builder throw new Exception('where express error:' . $exp); } } - $bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field); + $bindName = $bindName ?: 'where_' . $rule . '_' . str_replace(['.', '-'], '_', $field); if (preg_match('/\W/', $bindName)) { // 处理带非单词字符的字段名 $bindName = md5($bindName); } + if ($value instanceof Expression) { + + } elseif (is_object($value) && method_exists($value, '__toString')) { + // 对象数据写入 + $value = $value->__toString(); + } + $bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR; if (is_scalar($value) && array_key_exists($field, $binds) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) { if (strpos($value, ':') !== 0 || !$this->query->isBind(substr($value, 1))) { @@ -367,7 +392,11 @@ abstract class Builder } } elseif ('EXP' == $exp) { // 表达式查询 - $whereStr .= '( ' . $key . ' ' . $value . ' )'; + if ($value instanceof Expression) { + $whereStr .= '( ' . $key . ' ' . $value->getValue() . ' )'; + } else { + throw new Exception('where express error:' . $exp); + } } elseif (in_array($exp, ['NOT NULL', 'NULL'])) { // NULL 查询 $whereStr .= $key . ' IS ' . $exp; @@ -380,11 +409,13 @@ abstract class Builder if (array_key_exists($field, $binds)) { $bind = []; $array = []; - foreach ($value as $k => $v) { - if ($this->query->isBind($bindName . '_in_' . $k)) { - $bindKey = $bindName . '_in_' . uniqid() . '_' . $k; + $i = 0; + foreach ($value as $v) { + $i++; + if ($this->query->isBind($bindName . '_in_' . $i)) { + $bindKey = $bindName . '_in_' . uniqid() . '_' . $i; } else { - $bindKey = $bindName . '_in_' . $k; + $bindKey = $bindName . '_in_' . $i; } $bind[$bindKey] = [$v, $bindType]; $array[] = ':' . $bindKey; @@ -483,6 +514,11 @@ abstract class Builder } } $bindName = $bindName ?: $key; + + if ($this->query->isBind($bindName)) { + $bindName .= '_' . str_replace('.', '_', uniqid('', true)); + } + $this->query->bind($bindName, $value, $bindType); return ':' . $bindName; } @@ -490,7 +526,7 @@ abstract class Builder /** * limit分析 * @access protected - * @param mixed $lmit + * @param mixed $limit * @return string */ protected function parseLimit($limit) @@ -513,7 +549,9 @@ abstract class Builder list($table, $type, $on) = $item; $condition = []; foreach ((array) $on as $val) { - if (strpos($val, '=')) { + if ($val instanceof Expression) { + $condition[] = $val->getValue(); + } elseif (strpos($val, '=')) { list($val1, $val2) = explode('=', $val, 2); $condition[] = $this->parseKey($val1, $options) . '=' . $this->parseKey($val2, $options); } else { @@ -537,24 +575,29 @@ abstract class Builder */ protected function parseOrder($order, $options = []) { - if (is_array($order)) { - $array = []; - foreach ($order as $key => $val) { + if (empty($order)) { + return ''; + } + + $array = []; + foreach ($order as $key => $val) { + if ($val instanceof Expression) { + $array[] = $val->getValue(); + } elseif ('[rand]' == $val) { + $array[] = $this->parseRand(); + } else { if (is_numeric($key)) { - if ('[rand]' == $val) { - $array[] = $this->parseRand(); - } elseif (false === strpos($val, '(')) { - $array[] = $this->parseKey($val, $options); - } else { - $array[] = $val; - } + list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' '); } else { - $sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : ''; - $array[] = $this->parseKey($key, $options) . ' ' . $sort; + $sort = $val; } + $sort = strtoupper($sort); + $sort = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : ''; + $array[] = $this->parseKey($key, $options, true) . $sort; } - $order = implode(',', $array); } + $order = implode(',', $array); + return !empty($order) ? ' ORDER BY ' . $order : ''; } @@ -566,7 +609,7 @@ abstract class Builder */ protected function parseGroup($group) { - return !empty($group) ? ' GROUP BY ' . $group : ''; + return !empty($group) ? ' GROUP BY ' . $this->parseKey($group) : ''; } /** @@ -588,6 +631,9 @@ abstract class Builder */ protected function parseComment($comment) { + if (false !== strpos($comment, '*/')) { + $comment = strstr($comment, '*/', true); + } return !empty($comment) ? ' /* ' . $comment . ' */' : ''; } @@ -617,12 +663,12 @@ abstract class Builder unset($union['type']); foreach ($union as $u) { if ($u instanceof \Closure) { - $sql[] = $type . ' ' . $this->parseClosure($u, false); + $sql[] = $type . ' ' . $this->parseClosure($u); } elseif (is_string($u)) { - $sql[] = $type . ' ' . $this->parseSqlTable($u); + $sql[] = $type . ' ( ' . $this->parseSqlTable($u) . ' )'; } } - return implode(' ', $sql); + return ' ' . implode(' ', $sql); } /** @@ -637,22 +683,22 @@ abstract class Builder return ''; } - if (is_array($index)) { - $index = join(",", $index); - } - - return sprintf(" FORCE INDEX ( %s ) ", $index); + return sprintf(" FORCE INDEX ( %s ) ", is_array($index) ? implode(',', $index) : $index); } /** * 设置锁机制 * @access protected - * @param bool $locl + * @param bool|string $lock * @return string */ protected function parseLock($lock = false) { - return $lock ? ' FOR UPDATE ' : ''; + if (is_bool($lock)) { + return $lock ? ' FOR UPDATE ' : ''; + } elseif (is_string($lock)) { + return ' ' . trim($lock) . ' '; + } } /** @@ -721,8 +767,9 @@ abstract class Builder * @param array $options 表达式 * @param bool $replace 是否replace * @return string + * @throws Exception */ - public function insertAll($dataSet, $options, $replace = false) + public function insertAll($dataSet, $options = [], $replace = false) { // 获取合法的字段 if ('*' == $options['field']) { @@ -731,7 +778,7 @@ abstract class Builder $fields = $options['field']; } - foreach ($dataSet as &$data) { + foreach ($dataSet as $data) { foreach ($data as $key => $val) { if (!in_array($key, $fields, true)) { if ($options['strict']) { @@ -752,23 +799,29 @@ abstract class Builder } $value = array_values($data); $values[] = 'SELECT ' . implode(',', $value); + + if (!isset($insertFields)) { + $insertFields = array_keys($data); + } } - $fields = array_map([$this, 'parseKey'], array_keys(reset($dataSet))); - $sql = str_replace( + + foreach ($insertFields as $field) { + $fields[] = $this->parseKey($field, $options, true); + } + + return str_replace( ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'], [ $replace ? 'REPLACE' : 'INSERT', $this->parseTable($options['table'], $options), - implode(' , ', $fields), + implode(' , ', $insertFields), implode(' UNION ALL ', $values), $this->parseComment($options['comment']), ], $this->insertAllSql); - - return $sql; } /** - * 生成slectinsert SQL + * 生成select insert SQL * @access public * @param array $fields 数据 * @param string $table 数据表 @@ -789,7 +842,7 @@ abstract class Builder /** * 生成update SQL * @access public - * @param array $fields 数据 + * @param array $data 数据 * @param array $options 表达式 * @return string */ diff --git a/thinkphp/library/think/db/Connection.php b/thinkphp/library/think/db/Connection.php index fa773e51..578cc8f9 100644 --- a/thinkphp/library/think/db/Connection.php +++ b/thinkphp/library/think/db/Connection.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -90,6 +90,8 @@ abstract class Connection 'master_num' => 1, // 指定从服务器序号 'slave_no' => '', + // 模型写入后自动读取主服务器 + 'read_master' => false, // 是否严格检查字段是否存在 'fields_strict' => true, // 数据返回类型 @@ -338,8 +340,8 @@ abstract class Connection * @param bool $master 是否在主服务器读操作 * @param bool $pdo 是否返回PDO对象 * @return mixed - * @throws BindParamException * @throws PDOException + * @throws \Exception */ public function query($sql, $bind = [], $master = false, $pdo = false) { @@ -354,19 +356,14 @@ abstract class Connection $this->bind = $bind; } - // 释放前次的查询结果 - if (!empty($this->PDOStatement)) { - $this->free(); - } - Db::$queryTimes++; try { // 调试开始 $this->debug(true); + // 预处理 - if (empty($this->PDOStatement)) { - $this->PDOStatement = $this->linkID->prepare($sql); - } + $this->PDOStatement = $this->linkID->prepare($sql); + // 是否为存储过程调用 $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']); // 参数绑定 @@ -378,7 +375,7 @@ abstract class Connection // 执行查询 $this->PDOStatement->execute(); // 调试结束 - $this->debug(false); + $this->debug(false, '', $master); // 返回结果集 return $this->getResult($pdo, $procedure); } catch (\PDOException $e) { @@ -386,7 +383,12 @@ abstract class Connection return $this->close()->query($sql, $bind, $master, $pdo); } throw new PDOException($e, $this->config, $this->getLastsql()); - } catch (\ErrorException $e) { + } catch (\Throwable $e) { + if ($this->isBreak($e)) { + return $this->close()->query($sql, $bind, $master, $pdo); + } + throw $e; + } catch (\Exception $e) { if ($this->isBreak($e)) { return $this->close()->query($sql, $bind, $master, $pdo); } @@ -397,13 +399,14 @@ abstract class Connection /** * 执行语句 * @access public - * @param string $sql sql指令 - * @param array $bind 参数绑定 + * @param string $sql sql指令 + * @param array $bind 参数绑定 + * @param Query $query 查询对象 * @return int - * @throws BindParamException * @throws PDOException + * @throws \Exception */ - public function execute($sql, $bind = []) + public function execute($sql, $bind = [], Query $query = null) { $this->initConnect(true); if (!$this->linkID) { @@ -416,19 +419,14 @@ abstract class Connection $this->bind = $bind; } - //释放前次的查询结果 - if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) { - $this->free(); - } - Db::$executeTimes++; try { // 调试开始 $this->debug(true); + // 预处理 - if (empty($this->PDOStatement)) { - $this->PDOStatement = $this->linkID->prepare($sql); - } + $this->PDOStatement = $this->linkID->prepare($sql); + // 是否为存储过程调用 $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']); // 参数绑定 @@ -440,18 +438,27 @@ abstract class Connection // 执行语句 $this->PDOStatement->execute(); // 调试结束 - $this->debug(false); + $this->debug(false, '', true); + + if ($query && !empty($this->config['deploy']) && !empty($this->config['read_master'])) { + $query->readMaster(); + } $this->numRows = $this->PDOStatement->rowCount(); return $this->numRows; } catch (\PDOException $e) { if ($this->isBreak($e)) { - return $this->close()->execute($sql, $bind); + return $this->close()->execute($sql, $bind, $query); } throw new PDOException($e, $this->config, $this->getLastsql()); - } catch (\ErrorException $e) { + } catch (\Throwable $e) { if ($this->isBreak($e)) { - return $this->close()->execute($sql, $bind); + return $this->close()->execute($sql, $bind, $query); + } + throw $e; + } catch (\Exception $e) { + if ($this->isBreak($e)) { + return $this->close()->execute($sql, $bind, $query); } throw $e; } @@ -466,6 +473,10 @@ abstract class Connection */ public function getRealSql($sql, array $bind = []) { + if (is_array($sql)) { + $sql = implode(';', $sql); + } + foreach ($bind as $key => $val) { $value = is_array($val) ? $val[0] : $val; $type = is_array($val) ? $val[1] : PDO::PARAM_STR; @@ -478,8 +489,8 @@ abstract class Connection $sql = is_numeric($key) ? substr_replace($sql, $value, strpos($sql, '?'), 1) : str_replace( - [':' . $key . ')', ':' . $key . ',', ':' . $key . ' '], - [$value . ')', $value . ',', $value . ' '], + [':' . $key . ')', ':' . $key . ',', ':' . $key . ' ', ':' . $key . PHP_EOL], + [$value . ')', $value . ',', $value . ' ', $value . PHP_EOL], $sql . ' '); } return rtrim($sql); @@ -552,7 +563,7 @@ abstract class Connection * @access protected * @param bool $pdo 是否返回PDOStatement * @param bool $procedure 是否存储过程 - * @return array + * @return PDOStatement|array */ protected function getResult($pdo = false, $procedure = false) { @@ -618,7 +629,8 @@ abstract class Connection /** * 启动事务 * @access public - * @return void + * @return bool|mixed + * @throws \Exception */ public function startTrans() { @@ -637,13 +649,15 @@ abstract class Connection ); } - } catch (\PDOException $e) { + } catch (\Exception $e) { if ($this->isBreak($e)) { + --$this->transTimes; return $this->close()->startTrans(); } throw $e; - } catch (\ErrorException $e) { + } catch (\Error $e) { if ($this->isBreak($e)) { + --$this->transTimes; return $this->close()->startTrans(); } throw $e; @@ -724,7 +738,7 @@ abstract class Connection * @param array $sqlArray SQL批处理指令 * @return boolean */ - public function batchQuery($sqlArray = []) + public function batchQuery($sqlArray = [], $bind = [], Query $query = null) { if (!is_array($sqlArray)) { return false; @@ -733,7 +747,7 @@ abstract class Connection $this->startTrans(); try { foreach ($sqlArray as $sql) { - $this->execute($sql); + $this->execute($sql, $bind, $query); } // 提交事务 $this->commit(); @@ -741,6 +755,7 @@ abstract class Connection $this->rollback(); throw $e; } + return true; } @@ -776,13 +791,15 @@ abstract class Connection $this->linkWrite = null; $this->linkRead = null; $this->links = []; + // 释放查询 + $this->free(); return $this; } /** * 是否断线 * @access protected - * @param \PDOException $e 异常对象 + * @param \PDOException|\Exception $e 异常对象 * @return bool */ protected function isBreak($e) @@ -802,6 +819,7 @@ abstract class Connection 'SSL connection has been closed unexpectedly', 'Error writing data to the connection', 'Resource deadlock avoided', + 'failed with errno', ]; $error = $e->getMessage(); @@ -882,9 +900,10 @@ abstract class Connection * @access protected * @param boolean $start 调试开始标记 true 开始 false 结束 * @param string $sql 执行的SQL语句 留空自动获取 + * @param boolean $master 主从标记 * @return void */ - protected function debug($start, $sql = '') + protected function debug($start, $sql = '', $master = false) { if (!empty($this->config['debug'])) { // 开启数据库调试模式 @@ -901,7 +920,7 @@ abstract class Connection $result = $this->getExplain($sql); } // SQL监听 - $this->trigger($sql, $runtime, $result); + $this->trigger($sql, $runtime, $result, $master); } } } @@ -923,19 +942,27 @@ abstract class Connection * @param string $sql SQL语句 * @param float $runtime SQL运行时间 * @param mixed $explain SQL分析 - * @return bool + * @param bool $master 主从标记 + * @return void */ - protected function trigger($sql, $runtime, $explain = []) + protected function trigger($sql, $runtime, $explain = [], $master = false) { if (!empty(self::$event)) { foreach (self::$event as $callback) { if (is_callable($callback)) { - call_user_func_array($callback, [$sql, $runtime, $explain]); + call_user_func_array($callback, [$sql, $runtime, $explain, $master]); } } } else { // 未注册监听则记录到日志中 - Log::record('[ SQL ] ' . $sql . ' [ RunTime:' . $runtime . 's ]', 'sql'); + if ($this->config['deploy']) { + // 分布式记录当前操作的主从 + $master = $master ? 'master|' : 'slave|'; + } else { + $master = ''; + } + + Log::record('[ SQL ] ' . $sql . ' [ ' . $master . 'RunTime:' . $runtime . 's ]', 'sql'); if (!empty($explain)) { Log::record('[ EXPLAIN : ' . var_export($explain, true) . ' ]', 'sql'); } diff --git a/thinkphp/library/think/db/Expression.php b/thinkphp/library/think/db/Expression.php new file mode 100644 index 00000000..f1b92abd --- /dev/null +++ b/thinkphp/library/think/db/Expression.php @@ -0,0 +1,48 @@ + +// +---------------------------------------------------------------------- + +namespace think\db; + +class Expression +{ + /** + * 查询表达式 + * + * @var string + */ + protected $value; + + /** + * 创建一个查询表达式 + * + * @param string $value + * @return void + */ + public function __construct($value) + { + $this->value = $value; + } + + /** + * 获取表达式 + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + public function __toString() + { + return (string) $this->value; + } +} diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php index a8722a1a..ac4adea1 100644 --- a/thinkphp/library/think/db/Query.php +++ b/thinkphp/library/think/db/Query.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -12,6 +12,7 @@ namespace think\db; use PDO; +use think\App; use think\Cache; use think\Collection; use think\Config; @@ -52,14 +53,16 @@ class Query protected static $info = []; // 回调事件 private static $event = []; + // 读取主库 + protected static $readMaster = []; /** * 构造函数 * @access public * @param Connection $connection 数据库对象实例 - * @param string $model 模型名 + * @param Model $model 模型对象 */ - public function __construct(Connection $connection = null, $model = '') + public function __construct(Connection $connection = null, $model = null) { $this->connection = $connection ?: Db::connect([], true); $this->prefix = $this->connection->getConfig('prefix'); @@ -89,6 +92,13 @@ class Query $name = Loader::parseName(substr($method, 10)); $where[$name] = $args[0]; return $this->where($where)->value($args[1]); + } elseif ($this->model && method_exists($this->model, 'scope' . $method)) { + // 动态调用命名范围 + $method = 'scope' . $method; + array_unshift($args, $this); + + call_user_func_array([$this->model, $method], $args); + return $this; } else { throw new Exception('method not exist:' . __CLASS__ . '->' . $method); } @@ -114,6 +124,7 @@ class Query { $this->connection = Db::connect($config); $this->setBuilder(); + $this->prefix = $this->connection->getConfig('prefix'); return $this; } @@ -129,15 +140,34 @@ class Query } /** - * 获取当前的模型对象名 + * 获取当前的模型对象实例 * @access public - * @return string + * @return Model|null */ public function getModel() { return $this->model; } + /** + * 设置后续从主库读取数据 + * @access public + * @param bool $allTable + * @return void + */ + public function readMaster($allTable = false) + { + if ($allTable) { + $table = '*'; + } else { + $table = isset($this->options['table']) ? $this->options['table'] : $this->getTable(); + } + + static::$readMaster[$table] = true; + + return $this; + } + /** * 获取当前的builder实例对象 * @access public @@ -236,7 +266,7 @@ class Query */ public function execute($sql, $bind = []) { - return $this->connection->execute($sql, $bind); + return $this->connection->execute($sql, $bind, $this); } /** @@ -310,9 +340,9 @@ class Query * @param array $sql SQL批处理指令 * @return boolean */ - public function batchQuery($sql = []) + public function batchQuery($sql = [], $bind = []) { - return $this->connection->batchQuery($sql); + return $this->connection->batchQuery($sql, $bind); } /** @@ -401,7 +431,7 @@ class Query if (empty($this->options['table'])) { $this->options['table'] = $this->getTable(); } - $key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); + $key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind)); $result = Cache::get($key); } if (false === $result) { @@ -413,11 +443,13 @@ class Query // 返回SQL语句 return $pdo; } + $result = $pdo->fetchColumn(); if ($force) { - $result = is_numeric($result) ? $result + 0 : $result; + $result = (float) $result; } - if (isset($cache)) { + + if (isset($cache) && false !== $result) { // 缓存数据 $this->cacheData($key, $result, $cache); } @@ -444,7 +476,7 @@ class Query if (empty($this->options['table'])) { $this->options['table'] = $this->getTable(); } - $guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); + $guid = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . $field . serialize($this->options) . serialize($this->bind)); $result = Cache::get($guid); } if (false === $result) { @@ -507,13 +539,43 @@ class Query public function count($field = '*') { if (isset($this->options['group'])) { + if (!preg_match('/^[\w\.\*]+$/', $field)) { + throw new Exception('not support data:' . $field); + } // 支持GROUP $options = $this->getOptions(); $subSql = $this->options($options)->field('count(' . $field . ')')->bind($this->bind)->buildSql(); - return $this->table([$subSql => '_group_count_'])->value('COUNT(*) AS tp_count', 0, true); + + $count = $this->table([$subSql => '_group_count_'])->value('COUNT(*) AS tp_count', 0, true); + } else { + $count = $this->aggregate('COUNT', $field, true); + } + + return is_string($count) ? $count : (int) $count; + + } + + /** + * 聚合查询 + * @access public + * @param string $aggregate 聚合方法 + * @param string $field 字段名 + * @param bool $force 强制转为数字类型 + * @return mixed + */ + public function aggregate($aggregate, $field, $force = false) + { + if (0 === stripos($field, 'DISTINCT ')) { + list($distinct, $field) = explode(' ', $field); + } + + if (!preg_match('/^[\w\.\+\-\*]+$/', $field)) { + throw new Exception('not support data:' . $field); } - return $this->value('COUNT(' . $field . ') AS tp_count', 0, true); + $result = $this->value($aggregate . '(' . (!empty($distinct) ? 'DISTINCT ' : '') . $field . ') AS tp_' . strtolower($aggregate), 0, $force); + + return $result; } /** @@ -524,29 +586,31 @@ class Query */ public function sum($field) { - return $this->value('SUM(' . $field . ') AS tp_sum', 0, true); + return $this->aggregate('SUM', $field, true); } /** * MIN查询 * @access public * @param string $field 字段名 + * @param bool $force 强制转为数字类型 * @return mixed */ - public function min($field) + public function min($field, $force = true) { - return $this->value('MIN(' . $field . ') AS tp_min', 0, true); + return $this->aggregate('MIN', $field, $force); } /** * MAX查询 * @access public * @param string $field 字段名 + * @param bool $force 强制转为数字类型 * @return mixed */ - public function max($field) + public function max($field, $force = true) { - return $this->value('MAX(' . $field . ') AS tp_max', 0, true); + return $this->aggregate('MAX', $field, $force); } /** @@ -557,7 +621,7 @@ class Query */ public function avg($field) { - return $this->value('AVG(' . $field . ') AS tp_avg', 0, true); + return $this->aggregate('AVG', $field, true); } /** @@ -604,7 +668,7 @@ class Query return true; } } - return $this->setField($field, ['exp', $field . '+' . $step]); + return $this->setField($field, ['inc', $step]); } /** @@ -632,8 +696,9 @@ class Query $this->options = []; return true; } + return $this->setField($field, ['inc', $step]); } - return $this->setField($field, ['exp', $field . '-' . $step]); + return $this->setField($field, ['dec', $step]); } /** @@ -701,7 +766,8 @@ class Query { // 传入的表名为数组 if (is_array($join)) { - list($table, $alias) = each($join); + $table = $join; + $alias = array_shift($join); } else { $join = trim($join); if (false !== strpos($join, '(')) { @@ -722,13 +788,9 @@ class Query $table = $this->getTable($table); } } - } - if (isset($alias)) { - if (isset($this->options['alias'][$table])) { - $table = $table . '@think' . uniqid(); + if (isset($alias) && $table != $alias) { + $table = [$table => $alias]; } - $table = [$table => $alias]; - $this->alias($table); } return $table; } @@ -766,8 +828,15 @@ class Query { if (empty($field)) { return $this; + } elseif ($field instanceof Expression) { + $this->options['field'][] = $field; + return $this; } + if (is_string($field)) { + if (preg_match('/[\<\'\"\(]/', $field)) { + return $this->fieldRaw($field); + } $field = array_map('trim', explode(',', $field)); } if (true === $field) { @@ -791,12 +860,30 @@ class Query } if (isset($this->options['field'])) { - $field = array_merge($this->options['field'], $field); + $field = array_merge((array) $this->options['field'], $field); } $this->options['field'] = array_unique($field); return $this; } + /** + * 表达式方式指定查询字段 + * @access public + * @param string $field 字段名 + * @param array $bind 参数绑定 + * @return $this + */ + public function fieldRaw($field, array $bind = []) + { + $this->options['field'][] = $this->raw($field); + + if ($bind) { + $this->bind($bind); + } + + return $this; + } + /** * 设置数据 * @access public @@ -825,7 +912,7 @@ class Query { $fields = is_string($field) ? explode(',', $field) : $field; foreach ($fields as $field) { - $this->data($field, ['exp', $field . '+' . $step]); + $this->data($field, ['inc', $step]); } return $this; } @@ -841,7 +928,7 @@ class Query { $fields = is_string($field) ? explode(',', $field) : $field; foreach ($fields as $field) { - $this->data($field, ['exp', $field . '-' . $step]); + $this->data($field, ['dec', $step]); } return $this; } @@ -855,25 +942,36 @@ class Query */ public function exp($field, $value) { - $this->data($field, ['exp', $value]); + $this->data($field, $this->raw($value)); return $this; } + /** + * 使用表达式设置数据 + * @access public + * @param mixed $value 表达式 + * @return Expression + */ + public function raw($value) + { + return new Expression($value); + } + /** * 指定JOIN查询字段 * @access public * @param string|array $table 数据表 * @param string|array $field 查询字段 - * @param string|array $on JOIN条件 + * @param mixed $on JOIN条件 * @param string $type JOIN类型 * @return $this */ public function view($join, $field = true, $on = null, $type = 'INNER') { $this->options['view'] = true; - if (is_array($join) && key($join) !== 0) { + if (is_array($join) && key($join) === 0) { foreach ($join as $key => $val) { - $this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER'); + $this->view($val[0], $val[1], isset($val[2]) ? $val[2] : null, isset($val[3]) ? $val[3] : 'INNER'); } } else { $fields = []; @@ -972,6 +1070,37 @@ class Query return $this; } + /** + * 指定表达式查询条件 + * @access public + * @param string $where 查询条件 + * @param array $bind 参数绑定 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereRaw($where, $bind = [], $logic = 'AND') + { + $this->options['where'][$logic][] = $this->raw($where); + + if ($bind) { + $this->bind($bind); + } + + return $this; + } + + /** + * 指定表达式查询条件 OR + * @access public + * @param string $where 查询条件 + * @param array $bind 参数绑定 + * @return $this + */ + public function whereOrRaw($where, $bind = []) + { + return $this->whereRaw($where, $bind, 'OR'); + } + /** * 指定Null查询条件 * @access public @@ -981,7 +1110,7 @@ class Query */ public function whereNull($field, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'null', null); + $this->parseWhereExp($logic, $field, 'null', null, [], true); return $this; } @@ -994,7 +1123,7 @@ class Query */ public function whereNotNull($field, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'notnull', null); + $this->parseWhereExp($logic, $field, 'notnull', null, [], true); return $this; } @@ -1034,7 +1163,7 @@ class Query */ public function whereIn($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'in', $condition); + $this->parseWhereExp($logic, $field, 'in', $condition, [], true); return $this; } @@ -1048,7 +1177,7 @@ class Query */ public function whereNotIn($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'not in', $condition); + $this->parseWhereExp($logic, $field, 'not in', $condition, [], true); return $this; } @@ -1062,7 +1191,7 @@ class Query */ public function whereLike($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'like', $condition); + $this->parseWhereExp($logic, $field, 'like', $condition, [], true); return $this; } @@ -1076,7 +1205,7 @@ class Query */ public function whereNotLike($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'not like', $condition); + $this->parseWhereExp($logic, $field, 'not like', $condition, [], true); return $this; } @@ -1090,7 +1219,7 @@ class Query */ public function whereBetween($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'between', $condition); + $this->parseWhereExp($logic, $field, 'between', $condition, [], true); return $this; } @@ -1104,7 +1233,7 @@ class Query */ public function whereNotBetween($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'not between', $condition); + $this->parseWhereExp($logic, $field, 'not between', $condition, [], true); return $this; } @@ -1118,7 +1247,7 @@ class Query */ public function whereExp($field, $condition, $logic = 'AND') { - $this->parseWhereExp($logic, $field, 'exp', $condition); + $this->parseWhereExp($logic, $field, 'exp', $this->raw($condition), [], true); return $this; } @@ -1145,9 +1274,10 @@ class Query * @param mixed $op 查询表达式 * @param mixed $condition 查询条件 * @param array $param 查询参数 + * @param bool $strict 严格模式 * @return void */ - protected function parseWhereExp($logic, $field, $op, $condition, $param = []) + protected function parseWhereExp($logic, $field, $op, $condition, $param = [], $strict = false) { $logic = strtoupper($logic); if ($field instanceof \Closure) { @@ -1158,8 +1288,17 @@ class Query if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) { $field = $this->options['via'] . '.' . $field; } - if (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) { - $where[] = ['exp', $field]; + + if ($field instanceof Expression) { + return $this->whereRaw($field, is_array($op) ? $op : []); + } elseif ($strict) { + // 使用严格模式查询 + $where[$field] = [$op, $condition]; + + // 记录一个字段多次查询条件 + $this->options['multi'][$logic][$field][] = $where[$field]; + } elseif (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) { + $where[] = ['exp', $this->raw($field)]; if (is_array($op)) { // 参数绑定 $this->bind($op); @@ -1180,23 +1319,28 @@ class Query $where[$field] = $param; } elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) { // null查询 - $where[$field] = [$op, '']; + $where[$field] = [$op, '']; + $this->options['multi'][$logic][$field][] = $where[$field]; } elseif (is_null($condition)) { // 字段相等查询 $where[$field] = ['eq', $op]; - if ('AND' != $logic) { - $this->options['multi'][$logic][$field][] = $where[$field]; - } + + $this->options['multi'][$logic][$field][] = $where[$field]; } else { - $where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null]; - if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) { + if ('exp' == strtolower($op)) { + $where[$field] = ['exp', $this->raw($condition)]; // 参数绑定 - $this->bind($param[2]); + if (isset($param[2]) && is_array($param[2])) { + $this->bind($param[2]); + } + } else { + $where[$field] = [$op, $condition]; } // 记录一个字段多次查询条件 $this->options['multi'][$logic][$field][] = $where[$field]; } + if (!empty($where)) { if (!isset($this->options['where'][$logic])) { $this->options['where'][$logic] = []; @@ -1238,6 +1382,7 @@ class Query $logic = strtoupper($logic); if (isset($this->options['where'][$logic][$field])) { unset($this->options['where'][$logic][$field]); + unset($this->options['multi'][$logic][$field]); } return $this; } @@ -1413,49 +1558,78 @@ class Query */ public function order($field, $order = null) { - if (!empty($field)) { - if (is_string($field)) { - if (!empty($this->options['via'])) { - $field = $this->options['via'] . '.' . $field; - } - $field = empty($order) ? $field : [$field => $order]; - } elseif (!empty($this->options['via'])) { - foreach ($field as $key => $val) { - if (is_numeric($key)) { - $field[$key] = $this->options['via'] . '.' . $val; - } else { - $field[$this->options['via'] . '.' . $key] = $val; - unset($field[$key]); - } - } - } - if (!isset($this->options['order'])) { - $this->options['order'] = []; + if (empty($field)) { + return $this; + } elseif ($field instanceof Expression) { + $this->options['order'][] = $field; + return $this; + } + + if (is_string($field)) { + if (!empty($this->options['via'])) { + $field = $this->options['via'] . '.' . $field; } - if (is_array($field)) { - $this->options['order'] = array_merge($this->options['order'], $field); + if (strpos($field, ',')) { + $field = array_map('trim', explode(',', $field)); } else { - $this->options['order'][] = $field; + $field = empty($order) ? $field : [$field => $order]; } + } elseif (!empty($this->options['via'])) { + foreach ($field as $key => $val) { + if (is_numeric($key)) { + $field[$key] = $this->options['via'] . '.' . $val; + } else { + $field[$this->options['via'] . '.' . $key] = $val; + unset($field[$key]); + } + } + } + if (!isset($this->options['order'])) { + $this->options['order'] = []; + } + if (is_array($field)) { + $this->options['order'] = array_merge($this->options['order'], $field); + } else { + $this->options['order'][] = $field; } + + return $this; + } + + /** + * 表达式方式指定Field排序 + * @access public + * @param string $field 排序字段 + * @param array $bind 参数绑定 + * @return $this + */ + public function orderRaw($field, array $bind = []) + { + $this->options['order'][] = $this->raw($field); + + if ($bind) { + $this->bind($bind); + } + return $this; } /** * 查询缓存 * @access public - * @param mixed $key 缓存key - * @param integer $expire 缓存有效期 - * @param string $tag 缓存标签 + * @param mixed $key 缓存key + * @param integer|\DateTime $expire 缓存有效期 + * @param string $tag 缓存标签 * @return $this */ public function cache($key = true, $expire = null, $tag = null) { // 增加快捷调用方式 cache(10) 等同于 cache(true, 10) - if (is_numeric($key) && is_null($expire)) { + if ($key instanceof \DateTime || (is_numeric($key) && is_null($expire))) { $expire = $key; $key = true; } + if (false !== $key) { $this->options['cache'] = ['key' => $key, 'expire' => $expire, 'tag' => $tag]; } @@ -1489,7 +1663,7 @@ class Query /** * 指定查询lock * @access public - * @param boolean $lock 是否lock + * @param bool|string $lock 是否lock * @return $this */ public function lock($lock = false) @@ -1521,7 +1695,12 @@ class Query { if (is_array($alias)) { foreach ($alias as $key => $val) { - $this->options['alias'][$key] = $val; + if (false !== strpos($key, '__')) { + $table = $this->parseSqlTable($key); + } else { + $table = $key; + } + $this->options['alias'][$table] = $val; } } else { if (isset($this->options['table'])) { @@ -1649,46 +1828,49 @@ class Query * 查询日期或者时间 * @access public * @param string $field 日期字段名 - * @param string $op 比较运算符或者表达式 + * @param string|array $op 比较运算符或者表达式 * @param string|array $range 比较范围 * @return $this */ public function whereTime($field, $op, $range = null) { if (is_null($range)) { - // 使用日期表达式 - $date = getdate(); - switch (strtolower($op)) { - case 'today': - case 'd': - $range = ['today', 'tomorrow']; - break; - case 'week': - case 'w': - $range = 'this week 00:00:00'; - break; - case 'month': - case 'm': - $range = mktime(0, 0, 0, $date['mon'], 1, $date['year']); - break; - case 'year': - case 'y': - $range = mktime(0, 0, 0, 1, 1, $date['year']); - break; - case 'yesterday': - $range = ['yesterday', 'today']; - break; - case 'last week': - $range = ['last week 00:00:00', 'this week 00:00:00']; - break; - case 'last month': - $range = [date('y-m-01', strtotime('-1 month')), mktime(0, 0, 0, $date['mon'], 1, $date['year'])]; - break; - case 'last year': - $range = [mktime(0, 0, 0, 1, 1, $date['year'] - 1), mktime(0, 0, 0, 1, 1, $date['year'])]; - break; - default: - $range = $op; + if (is_array($op)) { + $range = $op; + } else { + // 使用日期表达式 + switch (strtolower($op)) { + case 'today': + case 'd': + $range = ['today', 'tomorrow']; + break; + case 'week': + case 'w': + $range = ['this week 00:00:00', 'next week 00:00:00']; + break; + case 'month': + case 'm': + $range = ['first Day of this month 00:00:00', 'first Day of next month 00:00:00']; + break; + case 'year': + case 'y': + $range = ['this year 1/1', 'next year 1/1']; + break; + case 'yesterday': + $range = ['yesterday', 'today']; + break; + case 'last week': + $range = ['last week 00:00:00', 'this week 00:00:00']; + break; + case 'last month': + $range = ['first Day of last month 00:00:00', 'first Day of this month 00:00:00']; + break; + case 'last year': + $range = ['last year 1/1', 'this year 1/1']; + break; + default: + $range = $op; + } } $op = is_array($range) ? 'between' : '>'; } @@ -1733,7 +1915,7 @@ class Query $schema = $guid; } // 读取缓存 - if (is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) { + if (!App::$debug && is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) { $info = include RUNTIME_PATH . 'schema/' . $schema . '.php'; } else { $info = $this->connection->getFields($guid); @@ -1808,7 +1990,9 @@ class Query */ protected function getFieldBindType($type) { - if (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) { + if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { + $bind = PDO::PARAM_STR; + } elseif (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) { $bind = PDO::PARAM_INT; } elseif (preg_match('/bool/is', $type)) { $bind = PDO::PARAM_BOOL; @@ -1890,11 +2074,10 @@ class Query $with = explode(',', $with); } - $first = true; - $currentModel = $this->model; + $first = true; /** @var Model $class */ - $class = new $currentModel; + $class = $this->model; foreach ($with as $key => $relation) { $subRelation = ''; $closure = false; @@ -1947,14 +2130,23 @@ class Query $this->field('*'); } foreach ($relations as $key => $relation) { - $closure = false; + $closure = $name = null; if ($relation instanceof \Closure) { $closure = $relation; $relation = $key; + } elseif (!is_int($key)) { + $name = $relation; + $relation = $key; } $relation = Loader::parseName($relation, 1, false); - $count = '(' . (new $this->model)->$relation()->getRelationCountQuery($closure) . ')'; - $this->field([$count => Loader::parseName($relation) . '_count']); + + $count = '(' . $this->model->$relation()->getRelationCountQuery($closure, $name) . ')'; + + if (empty($name)) { + $name = Loader::parseName($relation) . '_count'; + } + + $this->field([$count => $name]); } } return $this; @@ -2080,7 +2272,7 @@ class Query } // 执行操作 - $result = $this->execute($sql, $bind); + $result = 0 === $sql ? 0 : $this->execute($sql, $bind, $this); if ($result) { $sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null); $lastInsId = $this->getLastInsID($sequence); @@ -2116,27 +2308,40 @@ class Query /** * 批量插入记录 * @access public - * @param mixed $dataSet 数据集 - * @param boolean $replace 是否replace + * @param mixed $dataSet 数据集 + * @param boolean $replace 是否replace + * @param integer $limit 每次写入数据限制 * @return integer|string */ - public function insertAll(array $dataSet, $replace = false) + public function insertAll(array $dataSet, $replace = false, $limit = null) { // 分析查询表达式 $options = $this->parseExpress(); if (!is_array(reset($dataSet))) { return false; } + // 生成SQL语句 - $sql = $this->builder->insertAll($dataSet, $options, $replace); + if (is_null($limit)) { + $sql = $this->builder->insertAll($dataSet, $options, $replace); + } else { + $array = array_chunk($dataSet, $limit, true); + foreach ($array as $item) { + $sql[] = $this->builder->insertAll($item, $options, $replace); + } + } + // 获取参数绑定 $bind = $this->getBind(); if ($options['fetch_sql']) { // 获取实际执行的SQL语句 return $this->connection->getRealSql($sql, $bind); + } elseif (is_array($sql)) { + // 执行操作 + return $this->batchQuery($sql, $bind, $this); } else { // 执行操作 - return $this->execute($sql, $bind); + return $this->execute($sql, $bind, $this); } } @@ -2162,7 +2367,7 @@ class Query return $this->connection->getRealSql($sql, $bind); } else { // 执行操作 - return $this->execute($sql, $bind); + return $this->execute($sql, $bind, $this); } } @@ -2229,7 +2434,7 @@ class Query Cache::clear($options['cache']['tag']); } // 执行操作 - $result = '' == $sql ? 0 : $this->execute($sql, $bind); + $result = '' == $sql ? 0 : $this->execute($sql, $bind, $this); if ($result) { if (is_string($pk) && isset($where[$pk])) { $data[$pk] = $where[$pk]; @@ -2298,10 +2503,10 @@ class Query // 判断查询缓存 $cache = $options['cache']; unset($options['cache']); - $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options) . serialize($this->bind)); + $key = is_string($cache['key']) ? $cache['key'] : md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind)); $resultSet = Cache::get($key); } - if (!$resultSet) { + if (false === $resultSet) { // 生成查询SQL $sql = $this->builder->select($options); // 获取参数绑定 @@ -2323,7 +2528,7 @@ class Query } } - if (isset($cache) && $resultSet) { + if (isset($cache) && false !== $resultSet) { // 缓存数据集 $this->cacheData($key, $resultSet, $cache); } @@ -2332,11 +2537,10 @@ class Query // 数据列表读取后的处理 if (!empty($this->model)) { // 生成模型对象 - $modelName = $this->model; if (count($resultSet) > 0) { foreach ($resultSet as $key => $result) { - /** @var Model $result */ - $model = new $modelName($result); + /** @var Model $model */ + $model = $this->model->newInstance($result); $model->isUpdate(true); // 关联查询 @@ -2356,7 +2560,7 @@ class Query // 模型数据集转换 $resultSet = $model->toCollection($resultSet); } else { - $resultSet = (new $modelName)->toCollection($resultSet); + $resultSet = $this->model->toCollection($resultSet); } } elseif ('collection' == $this->connection->getConfig('resultset_type')) { // 返回Collection对象 @@ -2391,18 +2595,25 @@ class Query * @param mixed $value 缓存数据 * @param array $options 缓存参数 * @param array $bind 绑定参数 + * @return string */ protected function getCacheKey($value, $options, $bind = []) { if (is_scalar($value)) { $data = $value; - } elseif (is_array($value) && 'eq' == strtolower($value[0])) { + } elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) { $data = $value[1]; } + $prefix = $this->connection->getConfig('database') . '.'; + if (isset($data)) { - return 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; - } else { - return md5(serialize($options) . serialize($bind)); + return 'think:' . $prefix . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; + } + + try { + return md5($prefix . serialize($options) . serialize($bind)); + } catch (\Exception $e) { + throw new Exception('closure not support cache(true)'); } } @@ -2439,11 +2650,11 @@ class Query // 判断查询缓存 $cache = $options['cache']; if (true === $cache['key'] && !is_null($data) && !is_array($data)) { - $key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; + $key = 'think:' . $this->connection->getConfig('database') . '.' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; } elseif (is_string($cache['key'])) { $key = $cache['key']; } elseif (!isset($key)) { - $key = md5(serialize($options) . serialize($this->bind)); + $key = md5($this->connection->getConfig('database') . '.' . serialize($options) . serialize($this->bind)); } $result = Cache::get($key); } @@ -2491,8 +2702,7 @@ class Query if (!empty($result)) { if (!empty($this->model)) { // 返回模型对象 - $model = $this->model; - $result = new $model($result); + $result = $this->model->newInstance($result); $result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null); // 关联查询 if (!empty($options['relation'])) { @@ -2523,7 +2733,8 @@ class Query protected function throwNotFound($options = []) { if (!empty($this->model)) { - throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options); + $class = get_class($this->model); + throw new ModelNotFoundException('model data Not Found:' . $class, $class, $options); } else { $table = is_array($options['table']) ? key($options['table']) : $options['table']; throw new DataNotFoundException('table data not Found:' . $table, $table, $options); @@ -2564,44 +2775,61 @@ class Query * @param integer $count 每次处理的数据数量 * @param callable $callback 处理回调方法 * @param string $column 分批处理的字段名 + * @param string $order 排序规则 * @return boolean + * @throws \LogicException */ - public function chunk($count, $callback, $column = null) + public function chunk($count, $callback, $column = null, $order = 'asc') { $options = $this->getOptions(); - if (isset($options['table'])) { - $table = is_array($options['table']) ? key($options['table']) : $options['table']; - } else { - $table = ''; + if (empty($options['table'])) { + $options['table'] = $this->getTable(); } - $column = $column ?: $this->getPk($table); - $bind = $this->bind; - $resultSet = $this->limit($count)->order($column, 'asc')->select(); - if (strpos($column, '.')) { - list($alias, $key) = explode('.', $column); - } else { - $key = $column; + $column = $column ?: $this->getPk($options); + + if (isset($options['order'])) { + if (App::$debug) { + throw new \LogicException('chunk not support call order'); + } + unset($options['order']); } - if ($resultSet instanceof Collection) { - $resultSet = $resultSet->all(); + $bind = $this->bind; + if (is_array($column)) { + $times = 1; + $query = $this->options($options)->page($times, $count); + } else { + if (strpos($column, '.')) { + list($alias, $key) = explode('.', $column); + } else { + $key = $column; + } + $query = $this->options($options)->limit($count); } + $resultSet = $query->order($column, $order)->select(); + + while (count($resultSet) > 0) { + if ($resultSet instanceof Collection) { + $resultSet = $resultSet->all(); + } - while (!empty($resultSet)) { if (false === call_user_func($callback, $resultSet)) { return false; } - $end = end($resultSet); - $lastId = is_array($end) ? $end[$key] : $end->$key; - $resultSet = $this->options($options) - ->limit($count) - ->bind($bind) - ->where($column, '>', $lastId) - ->order($column, 'asc') - ->select(); - if ($resultSet instanceof Collection) { - $resultSet = $resultSet->all(); + + if (is_array($column)) { + $times++; + $query = $this->options($options)->page($times, $count); + } else { + $end = end($resultSet); + $lastId = is_array($end) ? $end[$key] : $end->getData($key); + $query = $this->options($options) + ->limit($count) + ->where($column, 'asc' == strtolower($order) ? '>' : '<', $lastId); } + + $resultSet = $query->bind($bind)->order($column, $order)->select(); } + return true; } @@ -2678,7 +2906,7 @@ class Query Cache::clear($options['cache']['tag']); } // 执行操作 - $result = $this->execute($sql, $bind); + $result = $this->execute($sql, $bind, $this); if ($result) { if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) { list($a, $val) = explode('|', $key); @@ -2763,6 +2991,10 @@ class Query } } + if (isset(static::$readMaster['*']) || (is_string($options['table']) && isset(static::$readMaster[$options['table']]))) { + $options['master'] = true; + } + foreach (['join', 'union', 'group', 'having', 'limit', 'order', 'force', 'comment'] as $name) { if (!isset($options[$name])) { $options[$name] = ''; diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php index 5bc9d03b..be2af714 100644 --- a/thinkphp/library/think/db/builder/Mysql.php +++ b/thinkphp/library/think/db/builder/Mysql.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -12,28 +12,93 @@ namespace think\db\builder; use think\db\Builder; +use think\Exception; /** * mysql数据库驱动 */ class Mysql extends Builder { - protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; + + protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES %DATA% %COMMENT%'; + protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; + + /** + * 生成insertall SQL + * @access public + * @param array $dataSet 数据集 + * @param array $options 表达式 + * @param bool $replace 是否replace + * @return string + * @throws Exception + */ + public function insertAll($dataSet, $options = [], $replace = false) + { + // 获取合法的字段 + if ('*' == $options['field']) { + $fields = array_keys($this->query->getFieldsType($options['table'])); + } else { + $fields = $options['field']; + } + + foreach ($dataSet as $data) { + foreach ($data as $key => $val) { + if (!in_array($key, $fields, true)) { + if ($options['strict']) { + throw new Exception('fields not exists:[' . $key . ']'); + } + unset($data[$key]); + } elseif (is_null($val)) { + $data[$key] = 'NULL'; + } elseif (is_scalar($val)) { + $data[$key] = $this->parseValue($val, $key); + } elseif (is_object($val) && method_exists($val, '__toString')) { + // 对象数据写入 + $data[$key] = $val->__toString(); + } else { + // 过滤掉非标量数据 + unset($data[$key]); + } + } + $value = array_values($data); + $values[] = '( ' . implode(',', $value) . ' )'; + + if (!isset($insertFields)) { + $insertFields = array_map([$this, 'parseKey'], array_keys($data)); + } + } + + return str_replace( + ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'], + [ + $replace ? 'REPLACE' : 'INSERT', + $this->parseTable($options['table'], $options), + implode(' , ', $insertFields), + implode(' , ', $values), + $this->parseComment($options['comment']), + ], $this->insertAllSql); + } /** * 字段和表名处理 * @access protected - * @param string $key + * @param mixed $key * @param array $options * @return string */ - protected function parseKey($key, $options = []) + protected function parseKey($key, $options = [], $strict = false) { + if (is_numeric($key)) { + return $key; + } elseif ($key instanceof Expression) { + return $key->getValue(); + } + $key = trim($key); if (strpos($key, '$.') && false === strpos($key, '(')) { // JSON字段支持 list($field, $name) = explode('$.', $key); - $key = 'json_extract(' . $field . ', \'$.' . $name . '\')'; + return 'json_extract(' . $field . ', \'$.' . $name . '\')'; } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) { list($table, $key) = explode('.', $key, 2); if ('__TABLE__' == $table) { @@ -43,7 +108,11 @@ class Mysql extends Builder $table = $options['alias'][$table]; } } - if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { + + if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) { + throw new Exception('not support data:' . $key); + } + if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) { $key = '`' . $key . '`'; } if (isset($table)) { diff --git a/thinkphp/library/think/db/builder/Pgsql.php b/thinkphp/library/think/db/builder/Pgsql.php index 5be0468a..acc22896 100644 --- a/thinkphp/library/think/db/builder/Pgsql.php +++ b/thinkphp/library/think/db/builder/Pgsql.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -18,6 +18,8 @@ use think\db\Builder; */ class Pgsql extends Builder { + protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; + protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; /** * limit分析 @@ -42,12 +44,18 @@ class Pgsql extends Builder /** * 字段和表名处理 * @access protected - * @param string $key + * @param mixed $key * @param array $options * @return string */ - protected function parseKey($key, $options = []) + protected function parseKey($key, $options = [], $strict = false) { + if (is_numeric($key)) { + return $key; + } elseif ($key instanceof Expression) { + return $key->getValue(); + } + $key = trim($key); if (strpos($key, '$.') && false === strpos($key, '(')) { // JSON字段支持 diff --git a/thinkphp/library/think/db/builder/Sqlite.php b/thinkphp/library/think/db/builder/Sqlite.php index 55d3abc4..c727f04b 100644 --- a/thinkphp/library/think/db/builder/Sqlite.php +++ b/thinkphp/library/think/db/builder/Sqlite.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -22,6 +22,7 @@ class Sqlite extends Builder /** * limit * @access public + * @param string $limit * @return string */ public function parseLimit($limit) @@ -51,12 +52,18 @@ class Sqlite extends Builder /** * 字段和表名处理 * @access protected - * @param string $key + * @param mixed $key * @param array $options * @return string */ - protected function parseKey($key, $options = []) + protected function parseKey($key, $options = [], $strict = false) { + if (is_numeric($key)) { + return $key; + } elseif ($key instanceof Expression) { + return $key->getValue(); + } + $key = trim($key); if (strpos($key, '.')) { list($table, $key) = explode('.', $key, 2); diff --git a/thinkphp/library/think/db/builder/Sqlsrv.php b/thinkphp/library/think/db/builder/Sqlsrv.php index 52629e73..dc425d9e 100644 --- a/thinkphp/library/think/db/builder/Sqlsrv.php +++ b/thinkphp/library/think/db/builder/Sqlsrv.php @@ -12,6 +12,7 @@ namespace think\db\builder; use think\db\Builder; +use think\db\Expression; /** * Sqlsrv数据库驱动 @@ -22,6 +23,8 @@ class Sqlsrv extends Builder protected $selectInsertSql = 'SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%'; protected $updateSql = 'UPDATE %TABLE% SET %SET% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%'; protected $deleteSql = 'DELETE FROM %TABLE% %USING% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%'; + protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; + protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; /** * order分析 @@ -32,23 +35,29 @@ class Sqlsrv extends Builder */ protected function parseOrder($order, $options = []) { - if (is_array($order)) { - $array = []; - foreach ($order as $key => $val) { - if (is_numeric($key)) { - if (false === strpos($val, '(')) { - $array[] = $this->parseKey($val, $options); - } elseif ('[rand]' == $val) { - $array[] = $this->parseRand(); - } + if (empty($order)) { + return ' ORDER BY rand()'; + } + + $array = []; + foreach ($order as $key => $val) { + if ($val instanceof Expression) { + $array[] = $val->getValue(); + } elseif (is_numeric($key)) { + if (false === strpos($val, '(')) { + $array[] = $this->parseKey($val, $options); + } elseif ('[rand]' == $val) { + $array[] = $this->parseRand(); } else { - $sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : ''; - $array[] = $this->parseKey($key, $options) . ' ' . $sort; + $array[] = $val; } + } else { + $sort = in_array(strtolower(trim($val)), ['asc', 'desc'], true) ? ' ' . $val : ''; + $array[] = $this->parseKey($key, $options, true) . ' ' . $sort; } - $order = implode(',', $array); } - return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()'; + + return ' ORDER BY ' . implode(',', $array); } /** @@ -64,12 +73,17 @@ class Sqlsrv extends Builder /** * 字段和表名处理 * @access protected - * @param string $key + * @param mixed $key * @param array $options * @return string */ - protected function parseKey($key, $options = []) + protected function parseKey($key, $options = [], $strict = false) { + if (is_numeric($key)) { + return $key; + } elseif ($key instanceof Expression) { + return $key->getValue(); + } $key = trim($key); if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) { list($table, $key) = explode('.', $key, 2); @@ -80,7 +94,11 @@ class Sqlsrv extends Builder $table = $options['alias'][$table]; } } - if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) { + + if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) { + throw new Exception('not support data:' . $key); + } + if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) { $key = '[' . $key . ']'; } if (isset($table)) { diff --git a/thinkphp/library/think/db/connector/Mysql.php b/thinkphp/library/think/db/connector/Mysql.php index 536125fd..be1a85ce 100644 --- a/thinkphp/library/think/db/connector/Mysql.php +++ b/thinkphp/library/think/db/connector/Mysql.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -31,12 +31,15 @@ class Mysql extends Connection */ protected function parseDsn($config) { - $dsn = 'mysql:dbname=' . $config['database'] . ';host=' . $config['hostname']; - if (!empty($config['hostport'])) { - $dsn .= ';port=' . $config['hostport']; - } elseif (!empty($config['socket'])) { - $dsn .= ';unix_socket=' . $config['socket']; + if (!empty($config['socket'])) { + $dsn = 'mysql:unix_socket=' . $config['socket']; + } elseif (!empty($config['hostport'])) { + $dsn = 'mysql:host=' . $config['hostname'] . ';port=' . $config['hostport']; + } else { + $dsn = 'mysql:host=' . $config['hostname']; } + $dsn .= ';dbname=' . $config['database']; + if (!empty($config['charset'])) { $dsn .= ';charset=' . $config['charset']; } diff --git a/thinkphp/library/think/db/connector/Pgsql.php b/thinkphp/library/think/db/connector/Pgsql.php index 761fbac4..bbcf5768 100644 --- a/thinkphp/library/think/db/connector/Pgsql.php +++ b/thinkphp/library/think/db/connector/Pgsql.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/connector/Sqlite.php b/thinkphp/library/think/db/connector/Sqlite.php index fd7f02b0..c4e3a724 100644 --- a/thinkphp/library/think/db/connector/Sqlite.php +++ b/thinkphp/library/think/db/connector/Sqlite.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/connector/Sqlsrv.php b/thinkphp/library/think/db/connector/Sqlsrv.php index 08ad45e2..35c66005 100644 --- a/thinkphp/library/think/db/connector/Sqlsrv.php +++ b/thinkphp/library/think/db/connector/Sqlsrv.php @@ -50,7 +50,10 @@ class Sqlsrv extends Connection public function getFields($tableName) { list($tableName) = explode(' ', $tableName); - $sql = "SELECT column_name, data_type, column_default, is_nullable + $tableNames = explode('.', $tableName); + $tableName = isset($tableNames[1]) ? $tableNames[1] : $tableNames[0]; + + $sql = "SELECT column_name, data_type, column_default, is_nullable FROM information_schema.tables AS t JOIN information_schema.columns AS c ON t.table_catalog = c.table_catalog diff --git a/thinkphp/library/think/db/exception/BindParamException.php b/thinkphp/library/think/db/exception/BindParamException.php index d0e2387b..4ed19546 100644 --- a/thinkphp/library/think/db/exception/BindParamException.php +++ b/thinkphp/library/think/db/exception/BindParamException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/exception/DataNotFoundException.php b/thinkphp/library/think/db/exception/DataNotFoundException.php index e399b063..f2542ac6 100644 --- a/thinkphp/library/think/db/exception/DataNotFoundException.php +++ b/thinkphp/library/think/db/exception/DataNotFoundException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/db/exception/ModelNotFoundException.php b/thinkphp/library/think/db/exception/ModelNotFoundException.php index 2180ab07..6e5f930c 100644 --- a/thinkphp/library/think/db/exception/ModelNotFoundException.php +++ b/thinkphp/library/think/db/exception/ModelNotFoundException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/debug/Console.php b/thinkphp/library/think/debug/Console.php index 8a232c8c..c17911b2 100644 --- a/thinkphp/library/think/debug/Console.php +++ b/thinkphp/library/think/debug/Console.php @@ -137,7 +137,7 @@ JS; } break; case '错误': - $msg = str_replace("\n", '\n', $m); + $msg = str_replace("\n", '\n', json_encode($m)); $style = 'color:#F4006B;font-size:14px;'; $line[] = "console.error(\"%c{$msg}\", \"{$style}\");"; break; diff --git a/thinkphp/library/think/debug/Html.php b/thinkphp/library/think/debug/Html.php index f8651aa9..b6be7adb 100644 --- a/thinkphp/library/think/debug/Html.php +++ b/thinkphp/library/think/debug/Html.php @@ -53,7 +53,7 @@ class Html return false; } // 获取基本信息 - $runtime = number_format(microtime(true) - THINK_START_TIME, 10); + $runtime = number_format(microtime(true) - THINK_START_TIME, 10, '.', ''); $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; $mem = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); diff --git a/thinkphp/library/think/exception/DbException.php b/thinkphp/library/think/exception/DbException.php index 656d6913..0ae80ad1 100644 --- a/thinkphp/library/think/exception/DbException.php +++ b/thinkphp/library/think/exception/DbException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -36,6 +36,7 @@ class DbException extends Exception 'Error SQL' => $sql, ]); + unset($config['username'], $config['password']); $this->setData('Database Config', $config); } diff --git a/thinkphp/library/think/exception/ErrorException.php b/thinkphp/library/think/exception/ErrorException.php index e3f18375..b3a9a30a 100644 --- a/thinkphp/library/think/exception/ErrorException.php +++ b/thinkphp/library/think/exception/ErrorException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/exception/Handle.php b/thinkphp/library/think/exception/Handle.php index 8b6e6c40..f523db09 100644 --- a/thinkphp/library/think/exception/Handle.php +++ b/thinkphp/library/think/exception/Handle.php @@ -21,11 +21,16 @@ use think\Response; class Handle { - + protected $render; protected $ignoreReport = [ '\\think\\exception\\HttpException', ]; + public function setRender($render) + { + $this->render = $render; + } + /** * Report or log an exception. * @@ -52,6 +57,10 @@ class Handle $log = "[{$data['code']}]{$data['message']}"; } + if (Config::get('record_trace')) { + $log .= "\r\n" . $exception->getTraceAsString(); + } + Log::record($log, 'error'); } } @@ -74,6 +83,13 @@ class Handle */ public function render(Exception $e) { + if ($this->render && $this->render instanceof \Closure) { + $result = call_user_func_array($this->render, [$e]); + if ($result) { + return $result; + } + } + if ($e instanceof HttpException) { return $this->renderHttpException($e); } else { diff --git a/thinkphp/library/think/exception/PDOException.php b/thinkphp/library/think/exception/PDOException.php index ebd53dff..044f82a0 100644 --- a/thinkphp/library/think/exception/PDOException.php +++ b/thinkphp/library/think/exception/PDOException.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/exception/RouteNotFoundException.php b/thinkphp/library/think/exception/RouteNotFoundException.php index f85a3c4b..d22e3a63 100644 --- a/thinkphp/library/think/exception/RouteNotFoundException.php +++ b/thinkphp/library/think/exception/RouteNotFoundException.php @@ -16,7 +16,7 @@ class RouteNotFoundException extends HttpException public function __construct() { - parent::__construct(404); + parent::__construct(404, 'Route Not Found'); } } diff --git a/thinkphp/library/think/log/driver/File.php b/thinkphp/library/think/log/driver/File.php index d82a5243..f2296cfa 100644 --- a/thinkphp/library/think/log/driver/File.php +++ b/thinkphp/library/think/log/driver/File.php @@ -12,6 +12,7 @@ namespace think\log\driver; use think\App; +use think\Request; /** * 本地化调试输出到文件 @@ -20,13 +21,14 @@ class File { protected $config = [ 'time_format' => ' c ', + 'single' => false, 'file_size' => 2097152, 'path' => LOG_PATH, 'apart_level' => [], + 'max_files' => 0, + 'json' => false, ]; - protected $writed = []; - // 实例化并传入参数 public function __construct($config = []) { @@ -38,82 +40,231 @@ class File /** * 日志写入接口 * @access public - * @param array $log 日志信息 + * @param array $log 日志信息 + * @param bool $append 是否追加请求信息 * @return bool */ - public function save(array $log = []) + public function save(array $log = [], $append = false) { - $cli = IS_CLI ? '_cli' : ''; - $destination = $this->config['path'] . date('Ym') . DS . date('d') . $cli . '.log'; + $destination = $this->getMasterLogFile(); $path = dirname($destination); !is_dir($path) && mkdir($path, 0755, true); - $info = ''; + $info = []; foreach ($log as $type => $val) { - $level = ''; + foreach ($val as $msg) { if (!is_string($msg)) { $msg = var_export($msg, true); } - $level .= '[ ' . $type . ' ] ' . $msg . "\r\n"; + + $info[$type][] = $this->config['json'] ? $msg : '[ ' . $type . ' ] ' . $msg; } - if (in_array($type, $this->config['apart_level'])) { + + if (!$this->config['json'] && (true === $this->config['apart_level'] || in_array($type, $this->config['apart_level']))) { // 独立记录的日志级别 - $filename = $path . DS . date('d') . '_' . $type . $cli . '.log'; - $this->write($level, $filename, true); - } else { - $info .= $level; + $filename = $this->getApartLevelFile($path, $type); + + $this->write($info[$type], $filename, true, $append); + unset($info[$type]); } } + if ($info) { - return $this->write($info, $destination); + return $this->write($info, $destination, false, $append); } + return true; } - protected function write($message, $destination, $apart = false) + /** + * 获取主日志文件名 + * @access public + * @return string + */ + protected function getMasterLogFile() + { + if ($this->config['single']) { + $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; + + $destination = $this->config['path'] . $name . '.log'; + } else { + $cli = PHP_SAPI == 'cli' ? '_cli' : ''; + + if ($this->config['max_files']) { + $filename = date('Ymd') . $cli . '.log'; + $files = glob($this->config['path'] . '*.log'); + + try { + if (count($files) > $this->config['max_files']) { + unlink($files[0]); + } + } catch (\Exception $e) { + } + } else { + $filename = date('Ym') . DIRECTORY_SEPARATOR . date('d') . $cli . '.log'; + } + + $destination = $this->config['path'] . $filename; + } + + return $destination; + } + + /** + * 获取独立日志文件名 + * @access public + * @param string $path 日志目录 + * @param string $type 日志类型 + * @return string + */ + protected function getApartLevelFile($path, $type) + { + $cli = PHP_SAPI == 'cli' ? '_cli' : ''; + + if ($this->config['single']) { + $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; + + $name .= '_' . $type; + } elseif ($this->config['max_files']) { + $name = date('Ymd') . '_' . $type . $cli; + } else { + $name = date('d') . '_' . $type . $cli; + } + + return $path . DIRECTORY_SEPARATOR . $name . '.log'; + } + + /** + * 日志写入 + * @access protected + * @param array $message 日志信息 + * @param string $destination 日志文件 + * @param bool $apart 是否独立文件写入 + * @param bool $append 是否追加请求信息 + * @return bool + */ + protected function write($message, $destination, $apart = false, $append = false) + { + // 检测日志文件大小,超过配置大小则备份日志文件重新生成 + $this->checkLogSize($destination); + + // 日志信息封装 + $info['timestamp'] = date($this->config['time_format']); + + foreach ($message as $type => $msg) { + $info[$type] = is_array($msg) ? implode("\r\n", $msg) : $msg; + } + + if (PHP_SAPI == 'cli') { + $message = $this->parseCliLog($info); + } else { + // 添加调试日志 + $this->getDebugLog($info, $append, $apart); + + $message = $this->parseLog($info); + } + + return error_log($message, 3, $destination); + } + + /** + * 检查日志文件大小并自动生成备份文件 + * @access protected + * @param string $destination 日志文件 + * @return void + */ + protected function checkLogSize($destination) { - //检测日志文件大小,超过配置大小则备份日志文件重新生成 if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) { - rename($destination, dirname($destination) . DS . time() . '-' . basename($destination)); - $this->writed[$destination] = false; + try { + rename($destination, dirname($destination) . DIRECTORY_SEPARATOR . time() . '-' . basename($destination)); + } catch (\Exception $e) { + } } + } - if (empty($this->writed[$destination]) && !IS_CLI) { - if (App::$debug && !$apart) { + /** + * CLI日志解析 + * @access protected + * @param array $info 日志信息 + * @return string + */ + protected function parseCliLog($info) + { + if ($this->config['json']) { + $message = json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\r\n"; + } else { + $now = $info['timestamp']; + unset($info['timestamp']); + + $message = implode("\r\n", $info); + + $message = "[{$now}]" . $message . "\r\n"; + } + + return $message; + } + + /** + * 解析日志 + * @access protected + * @param array $info 日志信息 + * @return string + */ + protected function parseLog($info) + { + $request = Request::instance(); + $requestInfo = [ + 'ip' => $request->ip(), + 'method' => $request->method(), + 'host' => $request->host(), + 'uri' => $request->url(), + ]; + + if ($this->config['json']) { + $info = $requestInfo + $info; + return json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\r\n"; + } + + array_unshift($info, "---------------------------------------------------------------\r\n[{$info['timestamp']}] {$requestInfo['ip']} {$requestInfo['method']} {$requestInfo['host']}{$requestInfo['uri']}"); + unset($info['timestamp']); + + return implode("\r\n", $info) . "\r\n"; + } + + protected function getDebugLog(&$info, $append, $apart) + { + if (App::$debug && $append) { + + if ($this->config['json']) { // 获取基本信息 - if (isset($_SERVER['HTTP_HOST'])) { - $current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; - } else { - $current_uri = "cmd:" . implode(' ', $_SERVER['argv']); - } + $runtime = round(microtime(true) - THINK_START_TIME, 10); + $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; - $runtime = round(microtime(true) - THINK_START_TIME, 10); - $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; - $time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]'; $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); + + $info = [ + 'runtime' => number_format($runtime, 6) . 's', + 'reqs' => $reqs . 'req/s', + 'memory' => $memory_use . 'kb', + 'file' => count(get_included_files()), + ] + $info; + + } elseif (!$apart) { + // 增加额外的调试信息 + $runtime = round(microtime(true) - THINK_START_TIME, 10); + $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; + + $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); + + $time_str = '[运行时间:' . number_format($runtime, 6) . 's] [吞吐率:' . $reqs . 'req/s]'; $memory_str = ' [内存消耗:' . $memory_use . 'kb]'; $file_load = ' [文件加载:' . count(get_included_files()) . ']'; - $message = '[ info ] ' . $current_uri . $time_str . $memory_str . $file_load . "\r\n" . $message; + array_unshift($info, $time_str . $memory_str . $file_load); } - $now = date($this->config['time_format']); - $server = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '0.0.0.0'; - $remote = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'; - $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'CLI'; - $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; - $message = "---------------------------------------------------------------\r\n[{$now}] {$server} {$remote} {$method} {$uri}\r\n" . $message; - - $this->writed[$destination] = true; } - - if (IS_CLI) { - $now = date($this->config['time_format']); - $message = "[{$now}]" . $message; - } - - return error_log($message, 3, $destination); } - } diff --git a/thinkphp/library/think/log/driver/Socket.php b/thinkphp/library/think/log/driver/Socket.php index d30bba30..4f62915b 100644 --- a/thinkphp/library/think/log/driver/Socket.php +++ b/thinkphp/library/think/log/driver/Socket.php @@ -60,7 +60,7 @@ class Socket * @param array $log 日志信息 * @return bool */ - public function save(array $log = []) + public function save(array $log = [], $append = false) { if (!$this->check()) { return false; diff --git a/thinkphp/library/think/model/Collection.php b/thinkphp/library/think/model/Collection.php index 4e4bb4dc..0406533c 100644 --- a/thinkphp/library/think/model/Collection.php +++ b/thinkphp/library/think/model/Collection.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -16,20 +16,6 @@ use think\Model; class Collection extends BaseCollection { - /** - * 返回数组中指定的一列 - * @param string $column_key - * @param string|null $index_key - * @return array - */ - public function column($column_key, $index_key = null) - { - if (function_exists('array_column')) { - return array_column($this->toArray(), $column_key, $index_key); - } - return parent::column($column_key, $index_key); - } - /** * 延迟预载入关联查询 * @access public @@ -85,7 +71,7 @@ class Collection extends BaseCollection { $this->each(function ($model) use ($append, $override) { /** @var Model $model */ - $model->append($append, $override); + $model && $model->append($append, $override); }); return $this; } diff --git a/thinkphp/library/think/model/Merge.php b/thinkphp/library/think/model/Merge.php index d944979e..4a9da81e 100644 --- a/thinkphp/library/think/model/Merge.php +++ b/thinkphp/library/think/model/Merge.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/model/Pivot.php b/thinkphp/library/think/model/Pivot.php index 06c6b181..13525cdd 100644 --- a/thinkphp/library/think/model/Pivot.php +++ b/thinkphp/library/think/model/Pivot.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -24,11 +24,11 @@ class Pivot extends Model /** * 架构函数 * @access public - * @param Model $parent 上级模型 * @param array|object $data 数据 + * @param Model $parent 上级模型 * @param string $table 中间数据表名 */ - public function __construct(Model $parent, $data = [], $table = '') + public function __construct($data = [], Model $parent = null, $table = '') { $this->parent = $parent; @@ -37,8 +37,6 @@ class Pivot extends Model } parent::__construct($data); - - $this->class = $this->name; } } diff --git a/thinkphp/library/think/model/Relation.php b/thinkphp/library/think/model/Relation.php index 4869e526..25fe88db 100644 --- a/thinkphp/library/think/model/Relation.php +++ b/thinkphp/library/think/model/Relation.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -35,6 +35,8 @@ abstract class Relation protected $localKey; // 基础查询 protected $baseQuery; + // 是否为自关联 + protected $selfRelation; /** * 获取关联的所属模型 @@ -47,13 +49,13 @@ abstract class Relation } /** - * 获取当前的关联模型类 + * 获取当前的关联模型对象实例 * @access public - * @return string + * @return Model */ public function getModel() { - return $this->model; + return $this->query->getModel(); } /** @@ -66,6 +68,28 @@ abstract class Relation return $this->query; } + /** + * 设置当前关联为自关联 + * @access public + * @param bool $self 是否自关联 + * @return $this + */ + public function selfRelation($self = true) + { + $this->selfRelation = $self; + return $this; + } + + /** + * 当前关联是否为自关联 + * @access public + * @return bool + */ + public function isSelfRelation() + { + return $this->selfRelation; + } + /** * 封装关联数据集 * @access public @@ -108,7 +132,8 @@ abstract class Relation * @access protected * @return void */ - abstract protected function baseQuery(); + protected function baseQuery() + {} public function __call($method, $args) { diff --git a/thinkphp/library/think/model/relation/BelongsTo.php b/thinkphp/library/think/model/relation/BelongsTo.php index 905ea944..c1cbab97 100644 --- a/thinkphp/library/think/model/relation/BelongsTo.php +++ b/thinkphp/library/think/model/relation/BelongsTo.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -11,6 +11,7 @@ namespace think\model\relation; +use think\db\Query; use think\Loader; use think\Model; @@ -51,6 +52,7 @@ class BelongsTo extends OneToOne call_user_func_array($closure, [ & $this->query]); } $relationModel = $this->query + ->removeWhereField($this->localKey) ->where($this->localKey, $this->parent->$foreignKey) ->relation($subRelation) ->find(); @@ -68,7 +70,6 @@ class BelongsTo extends OneToOne * @param string $operator 比较操作符 * @param integer $count 个数 * @param string $id 关联表的统计字段 - * @param string $joinType JOIN类型 * @return Query */ public function has($operator = '>=', $count = 1, $id = '*') @@ -79,14 +80,16 @@ class BelongsTo extends OneToOne /** * 根据关联条件查询当前模型 * @access public - * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Query */ - public function hasWhere($where = []) + public function hasWhere($where = [], $fields = null) { $table = $this->query->getTable(); $model = basename(str_replace('\\', '/', get_class($this->parent))); $relation = basename(str_replace('\\', '/', $this->model)); + if (is_array($where)) { foreach ($where as $key => $val) { if (false === strpos($key, '.')) { @@ -95,9 +98,11 @@ class BelongsTo extends OneToOne } } } + $fields = $this->getRelationQueryFields($fields, $model); + return $this->parent->db()->alias($model) - ->field($model . '.*') - ->join($table . ' ' . $relation, $model . '.' . $this->foreignKey . '=' . $relation . '.' . $this->localKey, $this->joinType) + ->field($fields) + ->join([$table => $relation], $model . '.' . $this->foreignKey . '=' . $relation . '.' . $this->localKey, $this->joinType) ->where($where); } @@ -124,7 +129,8 @@ class BelongsTo extends OneToOne } if (!empty($range)) { - $data = $this->eagerlyWhere($this, [ + $this->query->removeWhereField($localKey); + $data = $this->eagerlyWhere($this->query, [ $localKey => [ 'in', $range, @@ -143,12 +149,13 @@ class BelongsTo extends OneToOne $relationModel->isUpdate(true); } - if ($relationModel && !empty($this->bindAttr)) { + if (!empty($this->bindAttr)) { // 绑定关联属性 $this->bindAttr($relationModel, $result, $this->bindAttr); + } else { + // 设置关联属性 + $result->setRelation($attr, $relationModel); } - // 设置关联属性 - $result->setRelation($attr, $relationModel); } } } @@ -166,7 +173,8 @@ class BelongsTo extends OneToOne { $localKey = $this->localKey; $foreignKey = $this->foreignKey; - $data = $this->eagerlyWhere($this, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure); + $this->query->removeWhereField($localKey); + $data = $this->eagerlyWhere($this->query, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure); // 关联模型 if (!isset($data[$result->$foreignKey])) { $relationModel = null; @@ -175,12 +183,13 @@ class BelongsTo extends OneToOne $relationModel->setParent(clone $result); $relationModel->isUpdate(true); } - if ($relationModel && !empty($this->bindAttr)) { + if (!empty($this->bindAttr)) { // 绑定关联属性 $this->bindAttr($relationModel, $result, $this->bindAttr); + } else { + // 设置关联属性 + $result->setRelation(Loader::parseName($relation), $relationModel); } - // 设置关联属性 - $result->setRelation(Loader::parseName($relation), $relationModel); } /** @@ -214,4 +223,21 @@ class BelongsTo extends OneToOne return $this->parent->setRelation($this->relation, null); } + + /** + * 执行基础查询(仅执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + if (empty($this->baseQuery)) { + if (isset($this->parent->{$this->foreignKey})) { + // 关联查询带入关联条件 + $this->query->where($this->localKey, '=', $this->parent->{$this->foreignKey}); + } + + $this->baseQuery = true; + } + } } diff --git a/thinkphp/library/think/model/relation/BelongsToMany.php b/thinkphp/library/think/model/relation/BelongsToMany.php index 71ab4266..a41c45ce 100644 --- a/thinkphp/library/think/model/relation/BelongsToMany.php +++ b/thinkphp/library/think/model/relation/BelongsToMany.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -12,6 +12,7 @@ namespace think\model\relation; use think\Collection; +use think\Db; use think\db\Query; use think\Exception; use think\Loader; @@ -28,6 +29,8 @@ class BelongsToMany extends Relation protected $pivotName; // 中间表模型对象 protected $pivot; + // 中间表数据名称 + protected $pivotDataName = 'pivot'; /** * 构造函数 @@ -52,6 +55,10 @@ class BelongsToMany extends Relation } $this->query = (new $model)->db(); $this->pivot = $this->newPivot(); + + if ('think\model\Pivot' == get_class($this->pivot)) { + $this->pivot->name($this->middle); + } } /** @@ -66,14 +73,46 @@ class BelongsToMany extends Relation } /** - * 实例化中间表模型 + * 设置中间表数据名称 + * @access public + * @param string $name + * @return $this + */ + public function pivotDataName($name) + { + $this->pivotDataName = $name; + return $this; + } + + /** + * 获取中间表更新条件 * @param $data - * @return mixed + * @return array */ - protected function newPivot($data = []) + protected function getUpdateWhere($data) { - $pivot = $this->pivotName ?: '\\think\\model\\Pivot'; - return new $pivot($this->parent, $data, $this->middle); + return [ + $this->localKey => $data[$this->localKey], + $this->foreignKey => $data[$this->foreignKey], + ]; + } + + /** + * 实例化中间表模型 + * @param array $data + * @param bool $isUpdate + * @return Pivot + * @throws Exception + */ + protected function newPivot($data = [], $isUpdate = false) + { + $class = $this->pivotName ?: '\\think\\model\\Pivot'; + $pivot = new $class($data, $this->parent, $this->middle); + if ($pivot instanceof Pivot) { + return $isUpdate ? $pivot->isUpdate(true, $this->getUpdateWhere($data)) : $pivot; + } else { + throw new Exception('pivot model must extends: \think\model\Pivot'); + } } /** @@ -93,7 +132,7 @@ class BelongsToMany extends Relation } } } - $model->setRelation('pivot', $this->newPivot($pivot)); + $model->setRelation($this->pivotDataName, $this->newPivot($pivot, true)); } } @@ -105,9 +144,8 @@ class BelongsToMany extends Relation { $foreignKey = $this->foreignKey; $localKey = $this->localKey; - $middle = $this->middle; + $pk = $this->parent->getPk(); // 关联查询 - $pk = $this->parent->getPk(); $condition['pivot.' . $localKey] = $this->parent->$pk; return $this->belongsToManyQuery($foreignKey, $localKey, $condition); } @@ -207,11 +245,12 @@ class BelongsToMany extends Relation /** * 根据关联条件查询当前模型 * @access public - * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Query * @throws Exception */ - public function hasWhere($where = []) + public function hasWhere($where = [], $fields = null) { throw new Exception('relation not support: hasWhere'); } @@ -321,14 +360,22 @@ class BelongsToMany extends Relation * 获取关联统计子查询 * @access public * @param \Closure $closure 闭包 + * @param string $name 统计数据别名 * @return string */ - public function getRelationCountQuery($closure) + public function getRelationCountQuery($closure, &$name = null) { + if ($closure) { + $return = call_user_func_array($closure, [ & $this->query]); + if ($return && is_string($return)) { + $name = $return; + } + } + return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [ 'pivot.' . $this->localKey => [ 'exp', - '=' . $this->parent->getTable() . '.' . $this->parent->getPk(), + Db::raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk()), ], ])->fetchSql()->count(); } @@ -359,7 +406,7 @@ class BelongsToMany extends Relation } } } - $set->setRelation('pivot', $this->newPivot($pivot)); + $set->setRelation($this->pivotDataName, $this->newPivot($pivot, true)); $data[$pivot[$this->localKey]][] = $set; } return $data; @@ -385,7 +432,7 @@ class BelongsToMany extends Relation if (empty($this->baseQuery)) { $relationFk = $this->query->getPk(); - $query->join($table . ' pivot', 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk) + $query->join([$table => 'pivot'], 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk) ->where($condition); } return $query; @@ -462,7 +509,7 @@ class BelongsToMany extends Relation foreach ($ids as $id) { $pivot[$this->foreignKey] = $id; $this->pivot->insert($pivot, true); - $result[] = $this->newPivot($pivot); + $result[] = $this->newPivot($pivot, true); } if (count($result) == 1) { // 返回中间表模型对象 @@ -474,6 +521,29 @@ class BelongsToMany extends Relation } } + /** + * 判断是否存在关联数据 + * @access public + * @param mixed $data 数据 可以使用关联模型对象 或者 关联对象的主键 + * @return Pivot + * @throws Exception + */ + public function attached($data) + { + if ($data instanceof Model) { + $relationFk = $data->getPk(); + $id = $data->$relationFk; + } else { + $id = $data; + } + + $pk = $this->parent->getPk(); + + $pivot = $this->pivot->where($this->localKey, $this->parent->$pk)->where($this->foreignKey, $id)->find(); + + return $pivot ?: false; + } + /** * 解除关联的一个中间表数据 * @access public @@ -566,7 +636,7 @@ class BelongsToMany extends Relation if (empty($this->baseQuery) && $this->parent->getData()) { $pk = $this->parent->getPk(); $table = $this->pivot->getTable(); - $this->query->join($table . ' pivot', 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk); + $this->query->join([$table => 'pivot'], 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk); $this->baseQuery = true; } } diff --git a/thinkphp/library/think/model/relation/HasMany.php b/thinkphp/library/think/model/relation/HasMany.php index 9624fc67..ebab051a 100644 --- a/thinkphp/library/think/model/relation/HasMany.php +++ b/thinkphp/library/think/model/relation/HasMany.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -24,7 +24,7 @@ class HasMany extends Relation * @param Model $parent 上级模型对象 * @param string $model 模型名 * @param string $foreignKey 关联外键 - * @param string $localKey 关联主键 + * @param string $localKey 当前模型主键 */ public function __construct(Model $parent, $model, $foreignKey, $localKey) { @@ -77,7 +77,7 @@ class HasMany extends Relation } if (!empty($range)) { - $data = $this->eagerlyOneToMany($this, [ + $data = $this->eagerlyOneToMany($this->query, [ $this->foreignKey => [ 'in', $range, @@ -114,7 +114,7 @@ class HasMany extends Relation $localKey = $this->localKey; if (isset($result->$localKey)) { - $data = $this->eagerlyOneToMany($this, [$this->foreignKey => $result->$localKey], $relation, $subRelation, $closure); + $data = $this->eagerlyOneToMany($this->query, [$this->foreignKey => $result->$localKey], $relation, $subRelation, $closure); // 关联数据封装 if (!isset($data[$result->$localKey])) { $data[$result->$localKey] = []; @@ -143,7 +143,7 @@ class HasMany extends Relation if ($closure) { call_user_func_array($closure, [ & $this->query]); } - $count = $this->query->where([$this->foreignKey => $result->$localKey])->count(); + $count = $this->query->where($this->foreignKey, $result->$localKey)->count(); } return $count; } @@ -152,20 +152,19 @@ class HasMany extends Relation * 创建关联统计子查询 * @access public * @param \Closure $closure 闭包 + * @param string $name 统计数据别名 * @return string */ - public function getRelationCountQuery($closure) + public function getRelationCountQuery($closure, &$name = null) { if ($closure) { - call_user_func_array($closure, [ & $this->query]); + $return = call_user_func_array($closure, [ & $this->query]); + if ($return && is_string($return)) { + $name = $return; + } } - - return $this->query->where([ - $this->foreignKey => [ - 'exp', - '=' . $this->parent->getTable() . '.' . $this->parent->getPk(), - ], - ])->fetchSql()->count(); + $localKey = $this->localKey ?: $this->parent->getPk(); + return $this->query->whereExp($this->foreignKey, '=' . $this->parent->getTable() . '.' . $localKey)->fetchSql()->count(); } /** @@ -185,7 +184,7 @@ class HasMany extends Relation if ($closure) { call_user_func_array($closure, [ & $model]); } - $list = $model->where($where)->with($subRelation)->select(); + $list = $model->removeWhereField($foreignKey)->where($where)->with($subRelation)->select(); // 组装模型数据 $data = []; @@ -206,12 +205,31 @@ class HasMany extends Relation if ($data instanceof Model) { $data = $data->getData(); } + // 保存关联表数据 - $model = new $this->model; $data[$this->foreignKey] = $this->parent->{$this->localKey}; + + $model = new $this->model(); return $model->save($data) ? $model : false; } + /** + * 创建关联对象实例 + * @param array $data + * @return Model + */ + public function make($data = []) + { + if ($data instanceof Model) { + $data = $data->getData(); + } + + // 保存关联表数据 + $data[$this->foreignKey] = $this->parent->{$this->localKey}; + + return new $this->model($data); + } + /** * 批量保存当前关联数据对象 * @access public @@ -238,24 +256,31 @@ class HasMany extends Relation */ public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') { - $table = $this->query->getTable(); - return $this->parent->db()->alias('a') - ->join($table . ' b', 'a.' . $this->localKey . '=b.' . $this->foreignKey, $joinType) - ->group('b.' . $this->foreignKey) + $table = $this->query->getTable(); + $model = basename(str_replace('\\', '/', get_class($this->parent))); + $relation = basename(str_replace('\\', '/', $this->model)); + + return $this->parent->db() + ->alias($model) + ->field($model . '.*') + ->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType) + ->group($relation . '.' . $this->foreignKey) ->having('count(' . $id . ')' . $operator . $count); } /** * 根据关联条件查询当前模型 * @access public - * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Query */ - public function hasWhere($where = []) + public function hasWhere($where = [], $fields = null) { $table = $this->query->getTable(); $model = basename(str_replace('\\', '/', get_class($this->parent))); $relation = basename(str_replace('\\', '/', $this->model)); + if (is_array($where)) { foreach ($where as $key => $val) { if (false === strpos($key, '.')) { @@ -264,9 +289,13 @@ class HasMany extends Relation } } } + + $fields = $this->getRelationQueryFields($fields, $model); + return $this->parent->db()->alias($model) - ->field($model . '.*') - ->join($table . ' ' . $relation, $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey) + ->field($fields) + ->group($model . '.' . $this->localKey) + ->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey) ->where($where); } diff --git a/thinkphp/library/think/model/relation/HasManyThrough.php b/thinkphp/library/think/model/relation/HasManyThrough.php index 1573fc65..3a9a5482 100644 --- a/thinkphp/library/think/model/relation/HasManyThrough.php +++ b/thinkphp/library/think/model/relation/HasManyThrough.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -77,10 +77,11 @@ class HasManyThrough extends Relation /** * 根据关联条件查询当前模型 * @access public - * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Query */ - public function hasWhere($where = []) + public function hasWhere($where = [], $fields = null) { throw new Exception('relation not support: hasWhere'); } @@ -92,10 +93,9 @@ class HasManyThrough extends Relation * @param string $relation 当前关联名 * @param string $subRelation 子关联名 * @param \Closure $closure 闭包 - * @param string $class 数据集对象名 为空表示数组 * @return void */ - public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class) + public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) {} /** @@ -105,10 +105,9 @@ class HasManyThrough extends Relation * @param string $relation 当前关联名 * @param string $subRelation 子关联名 * @param \Closure $closure 闭包 - * @param string $class 数据集对象名 为空表示数组 * @return void */ - public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class) + public function eagerlyResult(&$result, $relation, $subRelation, $closure) {} /** @@ -121,6 +120,18 @@ class HasManyThrough extends Relation public function relationCount($result, $closure) {} + /** + * 创建关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @param string $name 统计数据别名 + * @return string + */ + public function getRelationCountQuery($closure, &$name = null) + { + throw new Exception('relation not support: withCount'); + } + /** * 执行基础查询(进执行一次) * @access protected diff --git a/thinkphp/library/think/model/relation/HasOne.php b/thinkphp/library/think/model/relation/HasOne.php index c500c02a..db74e4a6 100644 --- a/thinkphp/library/think/model/relation/HasOne.php +++ b/thinkphp/library/think/model/relation/HasOne.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -23,7 +23,7 @@ class HasOne extends OneToOne * @param Model $parent 上级模型对象 * @param string $model 模型名 * @param string $foreignKey 关联外键 - * @param string $localKey 关联主键 + * @param string $localKey 当前模型主键 * @param string $joinType JOIN类型 */ public function __construct(Model $parent, $model, $foreignKey, $localKey, $joinType = 'INNER') @@ -50,7 +50,11 @@ class HasOne extends OneToOne call_user_func_array($closure, [ & $this->query]); } // 判断关联类型执行查询 - $relationModel = $this->query->where($this->foreignKey, $this->parent->$localKey)->relation($subRelation)->find(); + $relationModel = $this->query + ->removeWhereField($this->foreignKey) + ->where($this->foreignKey, $this->parent->$localKey) + ->relation($subRelation) + ->find(); if ($relationModel) { $relationModel->setParent(clone $this->parent); @@ -67,25 +71,30 @@ class HasOne extends OneToOne public function has() { $table = $this->query->getTable(); + $model = basename(str_replace('\\', '/', get_class($this->parent))); + $relation = basename(str_replace('\\', '/', $this->model)); $localKey = $this->localKey; $foreignKey = $this->foreignKey; - return $this->parent->db()->alias('a') - ->whereExists(function ($query) use ($table, $localKey, $foreignKey) { - $query->table([$table => 'b'])->field('b.' . $foreignKey)->whereExp('a.' . $localKey, '=b.' . $foreignKey); + return $this->parent->db() + ->alias($model) + ->whereExists(function ($query) use ($table, $model, $relation, $localKey, $foreignKey) { + $query->table([$table => $relation])->field($relation . '.' . $foreignKey)->whereExp($model . '.' . $localKey, '=' . $relation . '.' . $foreignKey); }); } /** * 根据关联条件查询当前模型 * @access public - * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Query */ - public function hasWhere($where = []) + public function hasWhere($where = [], $fields = null) { $table = $this->query->getTable(); $model = basename(str_replace('\\', '/', get_class($this->parent))); $relation = basename(str_replace('\\', '/', $this->model)); + if (is_array($where)) { foreach ($where as $key => $val) { if (false === strpos($key, '.')) { @@ -94,9 +103,11 @@ class HasOne extends OneToOne } } } + $fields = $this->getRelationQueryFields($fields, $model); + return $this->parent->db()->alias($model) - ->field($model . '.*') - ->join($table . ' ' . $relation, $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $this->joinType) + ->field($fields) + ->join([$table => $relation], $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $this->joinType) ->where($where); } @@ -123,7 +134,8 @@ class HasOne extends OneToOne } if (!empty($range)) { - $data = $this->eagerlyWhere($this, [ + $this->query->removeWhereField($foreignKey); + $data = $this->eagerlyWhere($this->query, [ $foreignKey => [ 'in', $range, @@ -140,13 +152,14 @@ class HasOne extends OneToOne $relationModel = $data[$result->$localKey]; $relationModel->setParent(clone $result); $relationModel->isUpdate(true); - if (!empty($this->bindAttr)) { - // 绑定关联属性 - $this->bindAttr($relationModel, $result, $this->bindAttr); - } } - // 设置关联属性 - $result->setRelation($attr, $relationModel); + if (!empty($this->bindAttr)) { + // 绑定关联属性 + $this->bindAttr($relationModel, $result, $this->bindAttr); + } else { + // 设置关联属性 + $result->setRelation($attr, $relationModel); + } } } } @@ -164,7 +177,8 @@ class HasOne extends OneToOne { $localKey = $this->localKey; $foreignKey = $this->foreignKey; - $data = $this->eagerlyWhere($this, [$foreignKey => $result->$localKey], $foreignKey, $relation, $subRelation, $closure); + $this->query->removeWhereField($foreignKey); + $data = $this->eagerlyWhere($this->query, [$foreignKey => $result->$localKey], $foreignKey, $relation, $subRelation, $closure); // 关联模型 if (!isset($data[$result->$localKey])) { @@ -173,13 +187,29 @@ class HasOne extends OneToOne $relationModel = $data[$result->$localKey]; $relationModel->setParent(clone $result); $relationModel->isUpdate(true); - if (!empty($this->bindAttr)) { - // 绑定关联属性 - $this->bindAttr($relationModel, $result, $this->bindAttr); - } } - - $result->setRelation(Loader::parseName($relation), $relationModel); + if (!empty($this->bindAttr)) { + // 绑定关联属性 + $this->bindAttr($relationModel, $result, $this->bindAttr); + } else { + $result->setRelation(Loader::parseName($relation), $relationModel); + } } + /** + * 执行基础查询(仅执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + if (empty($this->baseQuery)) { + if (isset($this->parent->{$this->localKey})) { + // 关联查询带入关联条件 + $this->query->where($this->foreignKey, '=', $this->parent->{$this->localKey}); + } + + $this->baseQuery = true; + } + } } diff --git a/thinkphp/library/think/model/relation/MorphMany.php b/thinkphp/library/think/model/relation/MorphMany.php index 87c2d66c..2755d575 100644 --- a/thinkphp/library/think/model/relation/MorphMany.php +++ b/thinkphp/library/think/model/relation/MorphMany.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -11,6 +11,7 @@ namespace think\model\relation; +use think\Db; use think\db\Query; use think\Exception; use think\Loader; @@ -82,10 +83,11 @@ class MorphMany extends Relation /** * 根据关联条件查询当前模型 * @access public - * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Query */ - public function hasWhere($where = []) + public function hasWhere($where = [], $fields = null) { throw new Exception('relation not support: hasWhere'); } @@ -186,21 +188,25 @@ class MorphMany extends Relation } /** - * 获取关联统计子查询 + * 创建关联统计子查询 * @access public * @param \Closure $closure 闭包 + * @param string $name 统计数据别名 * @return string */ - public function getRelationCountQuery($closure) + public function getRelationCountQuery($closure, &$name = null) { if ($closure) { - call_user_func_array($closure, [ & $this->query]); + $return = call_user_func_array($closure, [ & $this->query]); + if ($return && is_string($return)) { + $name = $return; + } } return $this->query->where([ $this->morphKey => [ 'exp', - '=' . $this->parent->getTable() . '.' . $this->parent->getPk(), + Db::raw('=' . $this->parent->getTable() . '.' . $this->parent->getPk()), ], $this->morphType => $this->type, ])->fetchSql()->count(); @@ -242,13 +248,36 @@ class MorphMany extends Relation if ($data instanceof Model) { $data = $data->getData(); } + + // 保存关联表数据 + $pk = $this->parent->getPk(); + + $data[$this->morphKey] = $this->parent->$pk; + $data[$this->morphType] = $this->type; + + $model = new $this->model(); + + return $model->save() ? $model : false; + } + + /** + * 创建关联对象实例 + * @param array $data + * @return Model + */ + public function make($data = []) + { + if ($data instanceof Model) { + $data = $data->getData(); + } + // 保存关联表数据 $pk = $this->parent->getPk(); - $model = new $this->model; $data[$this->morphKey] = $this->parent->$pk; $data[$this->morphType] = $this->type; - return $model->save($data) ? $model : false; + + return new $this->model($data); } /** diff --git a/thinkphp/library/think/model/relation/MorphOne.php b/thinkphp/library/think/model/relation/MorphOne.php index 4dfd1c0f..5ec71724 100644 --- a/thinkphp/library/think/model/relation/MorphOne.php +++ b/thinkphp/library/think/model/relation/MorphOne.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -81,10 +81,11 @@ class MorphOne extends Relation /** * 根据关联条件查询当前模型 * @access public - * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Query */ - public function hasWhere($where = []) + public function hasWhere($where = [], $fields = null) { throw new Exception('relation not support: hasWhere'); } @@ -197,6 +198,28 @@ class MorphOne extends Relation * @return Model|false */ public function save($data) + { + if ($data instanceof Model) { + $data = $data->getData(); + } + + // 保存关联表数据 + $pk = $this->parent->getPk(); + + $data[$this->morphKey] = $this->parent->$pk; + $data[$this->morphType] = $this->type; + + $model = new $this->model(); + + return $model->save() ? $model : false; + } + + /** + * 创建关联对象实例 + * @param array $data + * @return Model + */ + public function make($data = []) { if ($data instanceof Model) { $data = $data->getData(); @@ -204,10 +227,10 @@ class MorphOne extends Relation // 保存关联表数据 $pk = $this->parent->getPk(); - $model = new $this->model; $data[$this->morphKey] = $this->parent->$pk; $data[$this->morphType] = $this->type; - return $model->save($data) ? $model : false; + + return new $this->model($data); } /** @@ -226,4 +249,15 @@ class MorphOne extends Relation } } + /** + * 创建关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @param string $name 统计数据别名 + * @return string + */ + public function getRelationCountQuery($closure, &$name = null) + { + throw new Exception('relation not support: withCount'); + } } diff --git a/thinkphp/library/think/model/relation/MorphTo.php b/thinkphp/library/think/model/relation/MorphTo.php index df104a90..7d452651 100644 --- a/thinkphp/library/think/model/relation/MorphTo.php +++ b/thinkphp/library/think/model/relation/MorphTo.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -43,6 +43,18 @@ class MorphTo extends Relation $this->relation = $relation; } + /** + * 获取当前的关联模型类的实例 + * @access public + * @return Model + */ + public function getModel() + { + $morphType = $this->morphType; + $model = $this->parseModel($this->parent->$morphType); + return (new $model); + } + /** * 延迟获取关联数据 * @param string $subRelation 子关联名 @@ -82,17 +94,18 @@ class MorphTo extends Relation /** * 根据关联条件查询当前模型 * @access public - * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 * @return Query */ - public function hasWhere($where = []) + public function hasWhere($where = [], $fields = null) { throw new Exception('relation not support: hasWhere'); } /** * 解析模型的完整命名空间 - * @access public + * @access protected * @param string $model 模型名(或者完整类名) * @return string */ @@ -238,17 +251,18 @@ class MorphTo extends Relation /** * 添加关联数据 * @access public - * @param Model $model 关联模型对象 + * @param Model $model 关联模型对象 + * @param string $type 多态类型 * @return Model */ - public function associate($model) + public function associate($model, $type = '') { $morphKey = $this->morphKey; $morphType = $this->morphType; $pk = $model->getPk(); $this->parent->setAttr($morphKey, $model->$pk); - $this->parent->setAttr($morphType, get_class($model)); + $this->parent->setAttr($morphType, $type ?: get_class($model)); $this->parent->save(); return $this->parent->setRelation($this->relation, $model); @@ -272,10 +286,14 @@ class MorphTo extends Relation } /** - * 执行基础查询(进执行一次) - * @access protected - * @return void + * 创建关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @param string $name 统计数据别名 + * @return string */ - protected function baseQuery() - {} + public function getRelationCountQuery($closure, &$name = null) + { + throw new Exception('relation not support: withCount'); + } } diff --git a/thinkphp/library/think/model/relation/OneToOne.php b/thinkphp/library/think/model/relation/OneToOne.php index ff066ed3..353ce21b 100644 --- a/thinkphp/library/think/model/relation/OneToOne.php +++ b/thinkphp/library/think/model/relation/OneToOne.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -57,18 +57,18 @@ abstract class OneToOne extends Relation */ public function eagerly(Query $query, $relation, $subRelation, $closure, $first) { - $name = Loader::parseName(basename(str_replace('\\', '/', $query->getModel()))); - $alias = $name; + $name = Loader::parseName(basename(str_replace('\\', '/', get_class($query->getModel())))); + if ($first) { $table = $query->getTable(); - $query->table([$table => $alias]); + $query->table([$table => $name]); if ($query->getOptions('field')) { $field = $query->getOptions('field'); $query->removeOption('field'); } else { $field = true; } - $query->field($field, false, $table, $alias); + $query->field($field, false, $table, $name); $field = null; } @@ -78,9 +78,9 @@ abstract class OneToOne extends Relation $query->via($joinAlias); if ($this instanceof BelongsTo) { - $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType); + $query->join([$joinTable => $joinAlias], $name . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType); } else { - $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType); + $query->join([$joinTable => $joinAlias], $name . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType); } if ($closure) { @@ -214,6 +214,16 @@ abstract class OneToOne extends Relation return $this; } + /** + * 获取绑定属性 + * @access public + * @return array + */ + public function getBindAttr() + { + return $this->bindAttr; + } + /** * 关联统计 * @access public @@ -276,7 +286,7 @@ abstract class OneToOne extends Relation if (isset($result->$key)) { throw new Exception('bind attr has exists:' . $key); } else { - $result->setAttr($key, $model->$attr); + $result->setAttr($key, $model ? $model->$attr : null); } } } @@ -294,6 +304,8 @@ abstract class OneToOne extends Relation */ protected function eagerlyWhere($model, $where, $key, $relation, $subRelation = '', $closure = false) { + $this->baseQuery = true; + // 预载入关联查询 支持嵌套预载入 if ($closure) { call_user_func_array($closure, [ & $model]); @@ -312,10 +324,14 @@ abstract class OneToOne extends Relation } /** - * 执行基础查询(进执行一次) - * @access protected - * @return void + * 创建关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @param string $name 统计数据别名 + * @return string */ - protected function baseQuery() - {} + public function getRelationCountQuery($closure, &$name = null) + { + throw new Exception('relation not support: withCount'); + } } diff --git a/thinkphp/library/think/paginator/driver/Bootstrap.php b/thinkphp/library/think/paginator/driver/Bootstrap.php index 58fa9436..c5ac60db 100644 --- a/thinkphp/library/think/paginator/driver/Bootstrap.php +++ b/thinkphp/library/think/paginator/driver/Bootstrap.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/response/Json.php b/thinkphp/library/think/response/Json.php index 538fc5a0..c906bfc1 100644 --- a/thinkphp/library/think/response/Json.php +++ b/thinkphp/library/think/response/Json.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/response/Jsonp.php b/thinkphp/library/think/response/Jsonp.php index de8fb304..404bacbe 100644 --- a/thinkphp/library/think/response/Jsonp.php +++ b/thinkphp/library/think/response/Jsonp.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/response/Redirect.php b/thinkphp/library/think/response/Redirect.php index f45b0e1c..91694cb2 100644 --- a/thinkphp/library/think/response/Redirect.php +++ b/thinkphp/library/think/response/Redirect.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -67,7 +67,11 @@ class Redirect extends Response */ public function getTargetUrl() { - return strpos($this->data, '://') ? $this->data : Url::build($this->data, $this->params); + if (strpos($this->data, '://') || (0 === strpos($this->data, '/') && empty($this->params))) { + return $this->data; + } else { + return Url::build($this->data, $this->params); + } } public function params($params = []) diff --git a/thinkphp/library/think/response/View.php b/thinkphp/library/think/response/View.php index de75515a..48f944a7 100644 --- a/thinkphp/library/think/response/View.php +++ b/thinkphp/library/think/response/View.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/response/Xml.php b/thinkphp/library/think/response/Xml.php index ca12e295..3bdc052a 100644 --- a/thinkphp/library/think/response/Xml.php +++ b/thinkphp/library/think/response/Xml.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -11,6 +11,8 @@ namespace think\response; +use think\Collection; +use think\Model; use think\Response; class Xml extends Response @@ -81,6 +83,11 @@ class Xml extends Response protected function dataToXml($data, $item, $id) { $xml = $attr = ''; + + if ($data instanceof Collection || $data instanceof Model) { + $data = $data->toArray(); + } + foreach ($data as $key => $val) { if (is_numeric($key)) { $id && $attr = " {$id}=\"{$key}\""; diff --git a/thinkphp/library/think/session/driver/Memcache.php b/thinkphp/library/think/session/driver/Memcache.php index 0c02e23e..877d7bd7 100644 --- a/thinkphp/library/think/session/driver/Memcache.php +++ b/thinkphp/library/think/session/driver/Memcache.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/session/driver/Memcached.php b/thinkphp/library/think/session/driver/Memcached.php index bcaf8a1b..2994a07c 100644 --- a/thinkphp/library/think/session/driver/Memcached.php +++ b/thinkphp/library/think/session/driver/Memcached.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/session/driver/Redis.php b/thinkphp/library/think/session/driver/Redis.php index a4c2b54a..8d05126b 100644 --- a/thinkphp/library/think/session/driver/Redis.php +++ b/thinkphp/library/think/session/driver/Redis.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- diff --git a/thinkphp/library/think/template/TagLib.php b/thinkphp/library/think/template/TagLib.php index d343bed0..c5b72f91 100644 --- a/thinkphp/library/think/template/TagLib.php +++ b/thinkphp/library/think/template/TagLib.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -264,8 +264,8 @@ class TagLib if (!empty($this->tags[$name]['expression'])) { static $_taglibs; if (!isset($_taglibs[$name])) { - $_taglibs[$name][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\') . $name); - $_taglibs[$name][1] = strlen(ltrim($this->tpl->config('taglib_end'), '\\')); + $_taglibs[$name][0] = strlen($this->tpl->config('taglib_begin_origin') . $name); + $_taglibs[$name][1] = strlen($this->tpl->config('taglib_end_origin')); } $result['expression'] = substr($str, $_taglibs[$name][0], -$_taglibs[$name][1]); // 清除自闭合标签尾部/ diff --git a/thinkphp/library/think/template/driver/File.php b/thinkphp/library/think/template/driver/File.php index b27e7265..a9a86bf2 100644 --- a/thinkphp/library/think/template/driver/File.php +++ b/thinkphp/library/think/template/driver/File.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -15,6 +15,8 @@ use think\Exception; class File { + protected $cacheFile; + /** * 写入编译缓存 * @param string $cacheFile 缓存的文件名 @@ -42,12 +44,13 @@ class File */ public function read($cacheFile, $vars = []) { + $this->cacheFile = $cacheFile; if (!empty($vars) && is_array($vars)) { // 模板阵列变量分解成为独立变量 extract($vars, EXTR_OVERWRITE); } //载入模版缓存文件 - include $cacheFile; + include $this->cacheFile; } /** diff --git a/thinkphp/library/think/template/taglib/Cx.php b/thinkphp/library/think/template/taglib/Cx.php index af7a54c8..31e0698d 100644 --- a/thinkphp/library/think/template/taglib/Cx.php +++ b/thinkphp/library/think/template/taglib/Cx.php @@ -278,7 +278,7 @@ class Cx extends Taglib */ public function tagCase($tag, $content) { - $value = !empty($tag['expression']) ? $tag['expression'] : $tag['value']; + $value = isset($tag['expression']) ? $tag['expression'] : $tag['value']; $flag = substr($value, 0, 1); if ('$' == $flag || ':' == $flag) { $value = $this->autoBuildVar($value); diff --git a/thinkphp/library/think/view/driver/Php.php b/thinkphp/library/think/view/driver/Php.php index 468d3611..f594a438 100644 --- a/thinkphp/library/think/view/driver/Php.php +++ b/thinkphp/library/think/view/driver/Php.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -29,7 +29,11 @@ class Php 'view_suffix' => 'php', // 模板文件名分隔符 'view_depr' => DS, + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 + 'auto_rule' => 1, ]; + protected $template; + protected $content; public function __construct($config = []) { @@ -68,16 +72,12 @@ class Php if (!is_file($template)) { throw new TemplateNotFoundException('template not exists:' . $template, $template); } + $this->template = $template; // 记录视图信息 App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info'); - if (isset($data['template'])) { - $__template__ = $template; - extract($data, EXTR_OVERWRITE); - include $__template__; - } else { - extract($data, EXTR_OVERWRITE); - include $template; - } + + extract($data, EXTR_OVERWRITE); + include $this->template; } /** @@ -89,14 +89,10 @@ class Php */ public function display($content, $data = []) { - if (isset($data['content'])) { - $__content__ = $content; - extract($data, EXTR_OVERWRITE); - eval('?>' . $__content__); - } else { - extract($data, EXTR_OVERWRITE); - eval('?>' . $content); - } + $this->content = $content; + + extract($data, EXTR_OVERWRITE); + eval('?>' . $this->content); } /** @@ -132,7 +128,7 @@ class Php if ($controller) { if ('' == $template) { // 如果模板文件名为空 按照默认规则定位 - $template = str_replace('.', DS, $controller) . $depr . $request->action(); + $template = str_replace('.', DS, $controller) . $depr . (1 == $this->config['auto_rule'] ? Loader::parseName($request->action(true)) : $request->action()); } elseif (false === strpos($template, $depr)) { $template = str_replace('.', DS, $controller) . $depr . $template; } diff --git a/thinkphp/library/think/view/driver/Think.php b/thinkphp/library/think/view/driver/Think.php index 39a14ca3..a314ad60 100644 --- a/thinkphp/library/think/view/driver/Think.php +++ b/thinkphp/library/think/view/driver/Think.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -34,6 +34,8 @@ class Think 'view_depr' => DS, // 是否开启模板编译缓存,设为false则每次都会重新编译 'tpl_cache' => true, + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 + 'auto_rule' => 1, ]; public function __construct($config = []) @@ -127,7 +129,7 @@ class Think if ($controller) { if ('' == $template) { // 如果模板文件名为空 按照默认规则定位 - $template = str_replace('.', DS, $controller) . $depr . $request->action(); + $template = str_replace('.', DS, $controller) . $depr . (1 == $this->config['auto_rule'] ? Loader::parseName($request->action(true)) : $request->action()); } elseif (false === strpos($template, $depr)) { $template = str_replace('.', DS, $controller) . $depr . $template; } diff --git a/thinkphp/library/traits/controller/Jump.php b/thinkphp/library/traits/controller/Jump.php index 36f2f94d..6a572246 100644 --- a/thinkphp/library/traits/controller/Jump.php +++ b/thinkphp/library/traits/controller/Jump.php @@ -1,5 +1,4 @@ server('HTTP_REFERER'))) { + $url = Request::instance()->server('HTTP_REFERER'); + } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) { + $url = Url::build($url); } + + $type = $this->getResponseType(); $result = [ - 'code' => $code, + 'code' => 1, 'msg' => $msg, 'data' => $data, 'url' => $url, 'wait' => $wait, ]; - $type = $this->getResponseType(); if ('html' == strtolower($type)) { - $result = ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str')) + $template = Config::get('template'); + $view = Config::get('view_replace_str'); + + $result = ViewTemplate::instance($template, $view) ->fetch(Config::get('dispatch_success_tmpl'), $result); } + $response = Response::create($result, $type)->header($header); + throw new HttpResponseException($response); } /** * 操作错误跳转的快捷方法 * @access protected - * @param mixed $msg 提示信息 - * @param string $url 跳转的URL地址 - * @param mixed $data 返回的数据 - * @param integer $wait 跳转等待时间 - * @param array $header 发送的Header信息 + * @param mixed $msg 提示信息 + * @param string $url 跳转的 URL 地址 + * @param mixed $data 返回的数据 + * @param int $wait 跳转等待时间 + * @param array $header 发送的 Header 信息 * @return void + * @throws HttpResponseException */ - protected function error($msg = '',$code=404, $options=[],$url = null, $data = '', $wait = 3, array $header = []) + protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = []) { - $code = 0; - if (is_numeric($msg)) { - $code = $msg; - $msg = ''; - } if (is_null($url)) { $url = Request::instance()->isAjax() ? '' : 'javascript:history.back(-1);'; - } elseif ('' !== $url) { - $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : Url::build($url); + } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) { + $url = Url::build($url); } + + $type = $this->getResponseType(); $result = [ - 'code' => $code, + 'code' => 0, 'msg' => $msg, 'data' => $data, 'url' => $url, 'wait' => $wait, - 'options' => $options, ]; - $type = $this->getResponseType(); if ('html' == strtolower($type)) { - $result = ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str')) + $template = Config::get('template'); + $view = Config::get('view_replace_str'); + + $result = ViewTemplate::instance($template, $view) ->fetch(Config::get('dispatch_error_tmpl'), $result); } + $response = Response::create($result, $type)->header($header); + throw new HttpResponseException($response); } /** - * 返回封装后的API数据到客户端 + * 返回封装后的 API 数据到客户端 * @access protected - * @param mixed $data 要返回的数据 - * @param integer $code 返回的code - * @param mixed $msg 提示信息 - * @param string $type 返回数据格式 - * @param array $header 发送的Header信息 + * @param mixed $data 要返回的数据 + * @param int $code 返回的 code + * @param mixed $msg 提示信息 + * @param string $type 返回数据格式 + * @param array $header 发送的 Header 信息 * @return void + * @throws HttpResponseException */ protected function result($data, $code = 0, $msg = '', $type = '', array $header = []) { $result = [ 'code' => $code, 'msg' => $msg, - 'time' => $_SERVER['REQUEST_TIME'], + 'time' => Request::instance()->server('REQUEST_TIME'), 'data' => $data, ]; $type = $type ?: $this->getResponseType(); $response = Response::create($result, $type)->header($header); + throw new HttpResponseException($response); } /** - * URL重定向 + * URL 重定向 * @access protected - * @param string $url 跳转的URL表达式 - * @param array|integer $params 其它URL参数 - * @param integer $code http code - * @param array $with 隐式传参 + * @param string $url 跳转的 URL 表达式 + * @param array|int $params 其它 URL 参数 + * @param int $code http code + * @param array $with 隐式传参 * @return void + * @throws HttpResponseException */ protected function redirect($url, $params = [], $code = 302, $with = []) { - $response = new Redirect($url); if (is_integer($params)) { $code = $params; $params = []; } + + $response = new Redirect($url); $response->code($code)->params($params)->with($with); + throw new HttpResponseException($response); } /** - * 获取当前的response 输出类型 + * 获取当前的 response 输出类型 * @access protected * @return string */ protected function getResponseType() { - $isAjax = Request::instance()->isAjax(); - return $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type'); + return Request::instance()->isAjax() + ? Config::get('default_ajax_return') + : Config::get('default_return_type'); } } diff --git a/thinkphp/library/traits/model/SoftDelete.php b/thinkphp/library/traits/model/SoftDelete.php index be586342..70f31ba2 100644 --- a/thinkphp/library/traits/model/SoftDelete.php +++ b/thinkphp/library/traits/model/SoftDelete.php @@ -2,11 +2,15 @@ namespace traits\model; +use think\Collection; use think\db\Query; +use think\Model; +/** + * @mixin \Think\Model + */ trait SoftDelete { - /** * 判断当前实例是否被软删除 * @access public @@ -15,22 +19,21 @@ trait SoftDelete public function trashed() { $field = $this->getDeleteTimeField(); - if (!empty($this->data[$field])) { + + if ($field && !empty($this->data[$field])) { return true; } return false; } /** - * 查询软删除数据 + * 查询包含软删除的数据 * @access public * @return Query */ public static function withTrashed() { - $model = new static(); - $field = $model->getDeleteTimeField(true); - return $model->getQuery(); + return (new static )->getQuery(); } /** @@ -42,14 +45,18 @@ trait SoftDelete { $model = new static(); $field = $model->getDeleteTimeField(true); - return $model->getQuery() - ->useSoftDelete($field, ['not null', '']); + + if ($field) { + return $model->getQuery()->useSoftDelete($field, ['not null', '']); + } else { + return $model->getQuery(); + } } /** * 删除当前的记录 * @access public - * @param bool $force 是否强制删除 + * @param bool $force 是否强制删除 * @return integer */ public function delete($force = false) @@ -57,48 +64,71 @@ trait SoftDelete if (false === $this->trigger('before_delete', $this)) { return false; } + $name = $this->getDeleteTimeField(); - if (!$force) { + if ($name && !$force) { // 软删除 $this->data[$name] = $this->autoWriteTimestamp($name); $result = $this->isUpdate()->save(); } else { - $result = $this->getQuery()->delete($this->data); + // 强制删除当前模型数据 + $result = $this->getQuery()->where($this->getWhere())->delete(); + } + + // 关联删除 + if (!empty($this->relationWrite)) { + foreach ($this->relationWrite as $key => $name) { + $name = is_numeric($key) ? $name : $key; + $result = $this->getRelation($name); + if ($result instanceof Model) { + $result->delete(); + } elseif ($result instanceof Collection || is_array($result)) { + foreach ($result as $model) { + $model->delete(); + } + } + } } $this->trigger('after_delete', $this); + + // 清空原始数据 + $this->origin = []; + return $result; } /** * 删除记录 * @access public - * @param mixed $data 主键列表 支持闭包查询条件 + * @param mixed $data 主键列表(支持闭包查询条件) * @param bool $force 是否强制删除 * @return integer 成功删除的记录数 */ public static function destroy($data, $force = false) { + if (is_null($data)) { + return 0; + } + // 包含软删除数据 - $query = self::withTrashed(); + $query = (new static())->db(false); if (is_array($data) && key($data) !== 0) { $query->where($data); $data = null; } elseif ($data instanceof \Closure) { call_user_func_array($data, [ & $query]); $data = null; - } elseif (is_null($data)) { - return 0; } - $resultSet = $query->select($data); - $count = 0; - if ($resultSet) { + $count = 0; + if ($resultSet = $query->select($data)) { foreach ($resultSet as $data) { $result = $data->delete($force); $count += $result; } } + return $count; } @@ -110,46 +140,61 @@ trait SoftDelete */ public function restore($where = []) { - $name = $this->getDeleteTimeField(); if (empty($where)) { $pk = $this->getPk(); $where[$pk] = $this->getData($pk); } - // 恢复删除 - return $this->getQuery() - ->useSoftDelete($name, ['not null', '']) - ->where($where) - ->update([$name => null]); + + $name = $this->getDeleteTimeField(); + + if ($name) { + // 恢复删除 + return $this->getQuery() + ->useSoftDelete($name, ['not null', '']) + ->where($where) + ->update([$name => null]); + } else { + return 0; + } } /** * 查询默认不包含软删除数据 * @access protected * @param Query $query 查询对象 - * @return void + * @return Query */ protected function base($query) { $field = $this->getDeleteTimeField(true); - $query->useSoftDelete($field); + return $field ? $query->useSoftDelete($field) : $query; } /** * 获取软删除字段 * @access public - * @param bool $read 是否查询操作 写操作的时候会自动去掉表别名 + * @param bool $read 是否查询操作(写操作的时候会自动去掉表别名) * @return string */ protected function getDeleteTimeField($read = false) { - $field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? $this->deleteTime : 'delete_time'; + $field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? + $this->deleteTime : + 'delete_time'; + + if (false === $field) { + return false; + } + if (!strpos($field, '.')) { $field = '__TABLE__.' . $field; } + if (!$read && strpos($field, '.')) { $array = explode('.', $field); $field = array_pop($array); } + return $field; } } diff --git a/thinkphp/library/traits/think/Instance.php b/thinkphp/library/traits/think/Instance.php index ba45ddd8..428c8fde 100644 --- a/thinkphp/library/traits/think/Instance.php +++ b/thinkphp/library/traits/think/Instance.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -15,31 +15,40 @@ use think\Exception; trait Instance { + /** + * @var null|static 实例对象 + */ protected static $instance = null; /** - * @param array $options + * 获取示例 + * @param array $options 实例配置 * @return static */ public static function instance($options = []) { - if (is_null(self::$instance)) { - self::$instance = new self($options); - } + if (is_null(self::$instance)) self::$instance = new self($options); + return self::$instance; } - // 静态调用 - public static function __callStatic($method, $params) + /** + * 静态调用 + * @param string $method 调用方法 + * @param array $params 调用参数 + * @return mixed + * @throws Exception + */ + public static function __callStatic($method, array $params) { - if (is_null(self::$instance)) { - self::$instance = new self(); - } + if (is_null(self::$instance)) self::$instance = new self(); + $call = substr($method, 1); - if (0 === strpos($method, '_') && is_callable([self::$instance, $call])) { - return call_user_func_array([self::$instance, $call], $params); - } else { + + if (0 !== strpos($method, '_') || !is_callable([self::$instance, $call])) { throw new Exception("method not exists:" . $method); } + + return call_user_func_array([self::$instance, $call], $params); } } diff --git a/thinkphp/start.php b/thinkphp/start.php index 8af62ef3..adb1bc65 100644 --- a/thinkphp/start.php +++ b/thinkphp/start.php @@ -2,7 +2,7 @@ // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- @@ -12,7 +12,8 @@ namespace think; // ThinkPHP 引导文件 -// 加载基础文件 +// 1. 加载基础文件 require __DIR__ . '/base.php'; -// 执行应用 + +// 2. 执行应用 App::run()->send(); diff --git a/thinkphp/tests/.gitignore b/thinkphp/tests/.gitignore deleted file mode 100644 index a0306ecc..00000000 --- a/thinkphp/tests/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/runtime/ -/application/common.php -/application/demo/ -/application/runtime/ \ No newline at end of file diff --git a/thinkphp/tests/README.md b/thinkphp/tests/README.md deleted file mode 100644 index 0c1d0869..00000000 --- a/thinkphp/tests/README.md +++ /dev/null @@ -1,132 +0,0 @@ -## 测试目录结构 - -测试文件主要在 tests 文件下面,主要有以下几个文件夹 - -- conf 测试环境配置文件。 -- script 测试环境配置脚本。 -- thinkphp 测试用例和相关文件,与项目文件夹结构一致。 -- mock.php 测试入口文件。 - -## 主要测试流程 - -thinkphp5 的测试的主要流程是跟 thinkphp 的系统流程是相似的,大体的流程为: - -1. 引用 mock.php 文件加载框架 - -2. 根据文件目录,添加测试文件 - -3. 执行单元测试,输出结果 - -## 测试举例 - -例如测试 thinkphp 里的 apc 缓存,将分为以下几个过程: - -1. 创建 apcTest.php 文件 - -该文件应与 apc.php 目录路径 `thinkphp/library/think/cache/driver` 一致,命名空间与目录所在一致,并引用 `PHPUnit_Framework_TestCase`。 - - ```php - markTestSkipped('apc扩展不可用!'); - }; - ``` - - - 编写测试用例 - - *具体写法参照 [PHPUnit 官方文档](https://phpunit.de/manual/4.8/zh_cn/index.html)* - - ```php - public function testGet() - { - App::run(); - $this->assertInstanceOf( - '\think\cache\driver\Apc', - Cache::connect(['type' => 'apc', 'expire' => 1]) - ); - $this->assertTrue(Cache::set('key', 'value')); - $this->assertEquals('value', Cache::get('key')); - $this->assertTrue(Cache::rm('key')); - $this->assertFalse(Cache::get('key')); - $this->assertTrue(Cache::clear('key')); - Config::reset(); - } - ``` - -3. 执行单元测试命令 - - 在项目根目录执行 - - ```bash - $ phpunit - ``` - - 若想看到所有结果,请添加-v参数 - - ```bash - $ phpunit -v - ``` - -4. 输出结果 - -## 相关文档 - -[各个部分单元测试说明](http://www.kancloud.cn/brother_simon/tp5_test/96971 "各部分单元测试说明") - -## 大家一起来 - -单元测试的内容会跟框架同步,测试内容方方面面,是一个相对复杂的模块,同时也是一个值得重视的部分。希望大家能够多多提出意见,多多参与。如果你有任何问题或想法,可以随时提 issue,我们期待着收到听大家的质疑和讨论。 - -## 任务进度 - -单元测试任务进度,请大家认领模块 - -|模块|认领人|进度| -|---|---|---| -|Base||| -|App|Haotong Lin|√| -|Build|刘志淳|| -|Config|Haotong Lin|√| -|Cache||| -|Controller|Haotong Lin|√| -|Cookie|Haotong Lin|√| -|Db||| -|Debug|大漠|√| -|Error|大漠|| -|Exception|Haotong Lin|√| -|Hook|流年|√| -|Input|Haotong Lin|√| -|Lang|流年|√| -|Loader|流年|| -|Log||| -|Model||| -|Response|大漠|√| -|Route|流年|| -|Session|大漠|√| -|Template|oldrind|| -|Url|流年|| -|View|mahuan|| diff --git a/thinkphp/tests/application/config.php b/thinkphp/tests/application/config.php deleted file mode 100644 index d94a8641..00000000 --- a/thinkphp/tests/application/config.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- -// $Id$ - -return [ - 'url_route_on' => true, - 'log' => [ - 'type' => 'file', // 支持 socket trace file - ], - 'view' => [ - // 模板引擎 - 'engine_type' => 'think', - // 模板引擎配置 - 'engine_config' => [ - // 模板路径 - 'view_path' => '', - // 模板后缀 - 'view_suffix' => '.html', - // 模板文件名分隔符 - 'view_depr' => DS, - ], - // 输出字符串替换 - 'parse_str' => [], - ], -]; diff --git a/thinkphp/tests/application/database.php b/thinkphp/tests/application/database.php deleted file mode 100644 index 24434efb..00000000 --- a/thinkphp/tests/application/database.php +++ /dev/null @@ -1,44 +0,0 @@ - -// +---------------------------------------------------------------------- -// $Id$ - -return [ - // 数据库类型 - 'type' => 'mysql', - // 数据库连接DSN配置 - 'dsn' => '', - // 服务器地址 - 'hostname' => '127.0.0.1', - // 数据库名 - 'database' => '', - // 数据库用户名 - 'username' => 'root', - // 数据库密码 - 'password' => '', - // 数据库连接端口 - 'hostport' => '', - // 数据库连接参数 - 'params' => [], - // 数据库编码默认采用utf8 - 'charset' => 'utf8', - // 数据库表前缀 - 'prefix' => '', - // 数据库调试模式 - 'debug' => true, - // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) - 'deploy' => 0, - // 数据库读写是否分离 主从式有效 - 'rw_separate' => false, - // 读写分离后 主服务器数量 - 'master_num' => 1, - // 指定从服务器序号 - 'slave_no' => '', -]; diff --git a/thinkphp/tests/application/index/controller/Index.php b/thinkphp/tests/application/index/controller/Index.php deleted file mode 100644 index 803fe952..00000000 --- a/thinkphp/tests/application/index/controller/Index.php +++ /dev/null @@ -1,10 +0,0 @@ -*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }
'; - } -} diff --git a/thinkphp/tests/application/route.php b/thinkphp/tests/application/route.php deleted file mode 100644 index 45bcf79d..00000000 --- a/thinkphp/tests/application/route.php +++ /dev/null @@ -1,22 +0,0 @@ - -// +---------------------------------------------------------------------- -// $Id$ - -return [ - '__pattern__' => [ - 'name' => '\w+', - ], - '[hello]' => [ - ':id' => ['index/hello', ['method' => 'get'], ['id' => '\d+']], - ':name' => ['index/hello', ['method' => 'post']], - ], - -]; diff --git a/thinkphp/tests/conf/apcu.ini b/thinkphp/tests/conf/apcu.ini deleted file mode 100644 index 9c2abed2..00000000 --- a/thinkphp/tests/conf/apcu.ini +++ /dev/null @@ -1,3 +0,0 @@ -extension=apcu.so - -apc.enable_cli=1 diff --git a/thinkphp/tests/conf/apcu_bc.ini b/thinkphp/tests/conf/apcu_bc.ini deleted file mode 100644 index a7f6182d..00000000 --- a/thinkphp/tests/conf/apcu_bc.ini +++ /dev/null @@ -1,4 +0,0 @@ -extension=apcu.so -extension=apc.so - -apc.enable_cli=1 diff --git a/thinkphp/tests/conf/memcached.ini b/thinkphp/tests/conf/memcached.ini deleted file mode 100644 index 7d09664e..00000000 --- a/thinkphp/tests/conf/memcached.ini +++ /dev/null @@ -1 +0,0 @@ -extension=memcached.so diff --git a/thinkphp/tests/conf/redis.ini b/thinkphp/tests/conf/redis.ini deleted file mode 100644 index 6aecae48..00000000 --- a/thinkphp/tests/conf/redis.ini +++ /dev/null @@ -1 +0,0 @@ -extension=redis.so diff --git a/thinkphp/tests/conf/timezone.ini b/thinkphp/tests/conf/timezone.ini deleted file mode 100644 index ced3e0d7..00000000 --- a/thinkphp/tests/conf/timezone.ini +++ /dev/null @@ -1 +0,0 @@ -date.timezone = UTC \ No newline at end of file diff --git a/thinkphp/tests/extensions/5.4/apcu.so b/thinkphp/tests/extensions/5.4/apcu.so deleted file mode 100644 index 42a24a660e00f2fc2f57494bc4f62172da7cddf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 404136 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 z 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 z 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�jPt<4cw1~GcZ$l zT=}yCVjCM9Vs^azP5CteGjF*5EHE54f^=29$b>uCxVkBk;^#W?JWua>ieo>xI!<>uYJ2ONuU$j!lbz5EYBN}QDn_W<-u(2nr&IeBr#;ixp6+YUEZ1=qlyB(y zLJha07(Q7OE1m!~Ztsg(903vSc=5i8tJ)l`+UI+@##S${8U3iF@Ro?aZr()5Jt zuXB`l(Da3h6uR7b)f1|acQQE(*7P>J5b@PcsgY2XypvIa zQk83GfLoyWJERps|C)fAO~zO&8Bm0qfeP*7V)w?x#-hy=^El)z=iK1FvABM#*ohObR7^0?L^Z_&cv&34wrZjZ%QJ5 z8P~#)m{|=nDI|&=4I2rG@C8SC1D0MK|FUfnKI6Q+S;v#vY-f@ue8N%Q3}1~)uOKzG zApWCrY2pu*^EzNPuB|~TwI!sx9M}opS1TZwtOlaDG=RHCfIAU>p2oyY%(roc`9O;E&_DVHN&rd*2nQRO%eSml8Fe1;|sOn4sL$I>Wg1C!}UP5Fg}DlJj%KQkE~w@h48mTk~0#nt0>EH}S@UZ_+@)Di?91AF($c z`16qKI|W=j9C}-^3e6 zzKJ)Ce3J&2sc+TIV8jQzh-VOf!%^NA^#FqZm8(Ra@DoQhQu_cW)JUk>-cIu}1m1B% zUK{2i*ooAPB;sEvmm_{yxfF2~4tQq7#aCqN_rgy$Bf^^{6xS_l!~|fcj3jG zU%8ngyvG$k!!O=jvMz=7a_8l>DQ{;PVbagf{S)rANjR?2gtbdpJa}nqS8*?xYFwI$ z)C_52-d>rZN_)aQMs3~9oPT~zfq0luWvx)7y!!YHTqvCgYVc&Vdm zsjWg~8{v58<&AQdr6%4e_f5P}?wd4FP+Oys5x?NVY4lse8~9Jc`WfeykB{L2q=8f_nz*>X$+LX7yj67j@egu^OU7hgW&fh!}Z&A*{dk-CjDdPQ=OA{ZU zT!#1%<+8+EjkC=sccyCtX0`??Lp@8pjdB^{ta54MO65|-yW-9|EQFaUAWb2}yD66; z-d(vgag}l@;-kQYg)nop8fJ;7DVHHGD3>Olu3U=vHE>}e@qx!a`YPI4Rsq5%9o4uU z8tAJ?6UGCD_I6(08G$BKoryP@eG_jo`zGFG_DvdCCWnR$dRB@ZDbyZlDmJ@N{1`1; zF=4hGiTV^=z4C+{b+SgXIF1paSR8v)D8D#wT5W_*py24>+7sLD%@n4in6aQVg4Dk${*UbbYo~c}hxTIW~c$RWN zT3g0efh#i1#{yC^p=0Sq(}ca=H!0AXaV6}J^ooQ-_!;4_g8bNmG*XKAC9Qmpc#U!? z;=d`EBmTQ`K-zFD^GsZkh9ewyRP7%C|EQEoShNI}mLfG@o+19NbE_wO)lo%?f8Z!@ zN}PsE6cq6k@$=5Dkx<186#q!A;*qln?uJSDhY)~ODNiM~X2Mhd0N)K5%~U#&c#Lvs z;<3tQh{q|HC0<{-O5)!umm_{jxk}=fmCF*pqFjdf56Y#9UsDe45otSI+X|@+96}bI zFyr#D{;~6_CmaMNzqpkfWadV-ixeHgui(<5NR!@FUW;oRtZTi^j3Vw*E=Sz0T#EQC z<-FTQ>Te7iX#~P1N7cubk`@dEx~}so5;i)j))(>)e~f4g=jH9ezKOR7`zGEV?3*;O z%sH;?Mn7V2Tlq4qcXnQR!V?@d!x!?7#)rfD80Y1+4pkPHH(82HKSyeY4Dm#~og-Y1 zIIUcYcxUCjAw&I}T?lm!!cE3UTq$A5Q0N*bR3!YnqiTI2uTdy;r}OfLjBnx%8Q;Vk zGQLRz%N*yb-snf{4VecJ>91VGdBXLa&*5PL&i60px{-m>_$IgZ^*R5`grG+C%o2CGkhU$$eao53!RtOI#ju*yvZ;weS*{s z8RE+I?PewSb1O$NlLKiCiI2bs{6oX|_Q(>pnP9KTn^}b0K}$a4vlAet5`M?&>lL_Z9psPpiC_oBIkc3(_ucPv4 zz#62cafyq{rHSj6%Mc%@T$Z>|xk}<$%H@b#l&d2C5S;1MfSHdXhQuE$mm~f}xk}={ zE0-nyr*awMAZ9KbtveXw)FN|8i|n zdk^4)N->rc3L6vji!XC~x@c+%t3ZY4WM-DA9pSg5cFbs1yvb04eUFpM$9tFFH^Icr z7vkHMOB4T>av9>gl*m;**t26Msv&6!BT$!T`&)=o_e+%ojq&D3gOyiyf?Ngn0kx;cu<>EemLwm*Cd@TSz$SKVvoC?aAu|TRP-M3NdG)T&w9wS1wI_jB?&n6xQ|UC{sFwaJ8dqUkCiFQt_Vkg^CnnU8Nf-#BdXOmSueG%E}Y6 z;t9`nZh-Z}>J^W0cQnJnNRytQ!3UqWF+W6+BF3|K!=;IjguUq%V$N-2N6gy_qepyo z#FzM5<4(CkDGKyMFDK5IskdeCeEZt zsG*!Y&$9=C1~)&kML1QJSpJzxT?e>IDIk~Z0+d`QvRX_ni($LUAR=UOG9n1?btQYt z!!RyA=S=DdUv!lB-W0u_Q4>P-VvMi}g4IB;AvFVtcoU3FGx&)4R~d~RF+XZ)?1(GX z*IN=;=0_+~1`v=-d=sy}zKK`49D+D35)ARf%H@dpDK%3$;x{68E<6D0mtZ3mA-vO3 zwfy2Dl@b;g3e`KWBH?|Gs`rKJ;}Lxu)-;uO%(xsl)3vbqGg4Dq;z{^`l5jcVO65|- z{AC4WN1Tt?5to$9xc~qd$F{JM)|(8tk5Yt(JE|}ZaJr+s@k4EXTu|QkBGlrhv$$QH z&~$1yDpfA-(axkmsMYn?DuzT``7R)#hLmSW2RiXQp|(KLk1`*Raux(;BQ?ED+@f5X zm|sB?yA1I>waXH>D_2R}tz3?HzH(K>mxBv$6qvapVn}?YayjCwl&d6Ord*cz8s##? z*D04KUZGrycon!XKxTfahE>G(E0-gFP`OIthn33`^HYVUrHLO^yEO5zaw+0#@tKt{ zKxVE3DS}nR{LGDTIpQ1Cu9BFay%M`D@y%+NA?9~T#4b&Io7#D6Jcplt8Mcm)ohSDj z{HQFOOQ^?CYX+EbS3>P?!&D|Wy`EKykRP+H2o`sH-|h3I3RLB|lM^JvWKRpl0$*|k z76{qg2}e&Br=PfW-=<_^CjLA;{TQ44=}p2bTmZEU^Os67Ob&~Ly=P;59PkU6>;zNu zlaRz53<=Lwsr(rYLX*$v?cFiT4tAq0H+TYYH`0V3siHFD949fGFa9zAw5!Yf;C0}) zkjgQQkfqDGkFT(<322iL#YzOY$^}0^Mf_{!(!`G`mmz*!xh(Opa+SnSD3>E%ty~rH zQFtpz){wOo%p46;>RClRO}QL#LAgreTII6Db;@Ok`L?B5Lx`uVU5a?U3AU-j0OPIB z7X2e?CZ`5M^*i^DMdkeT8*fFzeQ~!XlY{U;N974`b)OuYLAVObp3K>yMGviKi+m61 zXN-nNTJjo{q~?j)8HkFFZ8)|uTOsMm8b9$l zLJPXfkxJl%H-VBLlR0IO8EvHcq%hcUYzOnRn6CdnE4H^$*q>Y+dBW@Q`3UJ3&V!3E zH-zd(w_okLzn0~^t`vvfI7}dMj8B8lYMsknRE>mekTJm``TNJrY4bD^zT|xCzDOs1 z3iAp#sq%z$mqvYf5i1#)+7EkEdn*jAqmho6wua58&P-B8~S1ul8uELdCN7xO@8ZvjX8WR3`gduZ} zt0Cbo2-zyKB5Zie#>bLn%hm5*S4b`4Dn}JqLS#S_UgE}ho{(|K=#2-FFrfKKv)xf# z(vt87n)-d$3wgp_T$J^MKXFuvfj7G-ON8$@s-BZm1F!c3_ioion71dm`I{%CV8Yp# z)n%W{QH4LU%h4$mGk0P-(1X8zGg$LyCA4<&}@qFbn#0!;66AvhtB0dc7zJ>voYtbW7GdV#KvTWI+ zPlha|5_WBN4ZY<)jF1f=6V?~+Z&rLXu-=}OU_&kI1TY9{H!(0qPJPGF7}k_4}*d#c@?3;MXvlj;cK8| zS6Z`p4KnMxpz>P)Rw+furVm}&j2s3b86Q!MgY95y#D?I^PyGr1ug3G*Bpo;F{*txabl zoriQe(iKRr&;Gyhe+Ig*B3+Ag>q*Jwm9u|+du#tT()W;lfV7<6%I&P*zw3V*^v^_k zCDLU` zXqhXK-h}k#lP!M-()*FFM*5X+#g%M6uD1$$A0v%>y#$?CknXeCT1-V6xBnq-FE2oP z8Pc^#XDzWFry>2H_J0cHyo|K_bIR*RJ)T3l3G5kXJidR`e&{Z%a3#`ZNUueDJ<^+y z#>-m^K6|&lvLn(4q;dNR;3p#87%BbZ_Lt)Ntw>iQU4wM^9_z6d>HoCUMs*qMAeRkOL zZz276^{4!Q(%bI|8*vfo45T|gY5Coe?u9h_l;!V78n16Ty>0%N{115AMsy_7BGRGX zTK*=aKYAt}xy_gJ-yDA1A)SnL^}ngN!T*x~GpOhLNIyZk6dy5KhV)US&mq0;cggKj zPVc^Ft^FfNA4N*NMgOASZU0OD?;@^kp11K&M|uv@cq{xJ{JAgKD;FTW0qJU_(_f5x z+WgYr+qC*6n@&giZKQFpAN`B=%U`w%cOo4|dfe)`vds_OY|}Zf+O&ItP5ZxP(*dOA z&OdqF2eu%ci?j`?RndQ6e#7FbH*LB<(rc04g!Bod>S+=GT=?v@Hs6M{18Lm;-S;gs z_5+))gOq=wH;4S*NaOz1h_@ZrmoBju3r>k!+I$}L5Yj7=UWGKC@UPGD6CeK^Z7uR+ zY`QjO(=49I@~^z{Z^Xs*=$9R9ukdLx{o?ktTM2uXL%+EFjv$sIU4itrxFPbiZ$kbA zq+iq@%^$o4zds}8UoJq_CI71ZQndH2NLM1AhvyDX7~o&EkN=bof0oF7S`voA15th+ix73*8OaY*_2Hy(d5rFUURU(;+!`+96TkEpY&uXW1Y&i*O0``g-Ec5Q13!rZ*3 z-g&{4mW7?-Y16(Qd*!6op5C^u&JmfCTgZ_gl#4B`v-{_kntGZ#=e8QjFx%ES$Ees#vuF3Tp2S>xTW2e=G!9{V zmlS60q2#shzd>v%KI_Q;SSSL1nwaV2m?kE&W2XrE>!+V~(Vrg_Wx5qsVlF_KD9*o1 zka<&&{%I48yqI3JmCc)SjSc-XmJX^VHQMxFHpyOKIuSG3vVnZae&lPaWIv6>f5*P| zI@8$@X8bINX`Pt=Gvc59iuGqY%VvXk{Gfvt0la3o0r)e081-lQ@%neh{HGpcRDyu% z!yDVY@i*_M#{JC!$+XEh`QNwIx=eKmlBz$F&GWnGNGj{1e_4~H| zQ@?NPKV%cv?ku0}Vs8AS<*)gH^Iv%=5`ezQUb5M)G3|wl25t)dL%#I z?Z+eebp!6NBl-0L?wcd|2?6)Rk^K4r_qmb$1_Af4k^IDf`_f209dO?n$!{2NKN-ny z6mXvy$!{ER{U6D15^!A~$!{8Py&lPL7OcTKJd)o$;QBg}&jegINAh2aW*x2wws1HK zDuUQy0T(L*9O9zJf-8d9;CA-g#4K&LB8VLZoPE}_xAStnApT^>%=al|W;cI#soo3n(Z5P@}Hhh^sW@~hofoJ~?2%i+s zS;B|yf0p$(`-XY_7<_QH&F^57;2Q9=!1J3k<`X_fXW$3c@EX{g{lM_Kb1d-y_!p_a z)DrW-ze^qPM}Rl&5ylDrKD197{L=HR;ghicvhbsVjf0in*)C+xKtt>f`+?=w(99q6 zIvD)Q>utV4^5%6cbhu8=3fUm&0Us=}`qkji245ZHF9SaSegO8jQ0Ek@GYkAf;Aera z2LA&1A@Bp>-vyr?usY=bL3{Aku-{PThiRYH;Aer~0etnTR%a#nuYnIv8yTnhtK&vz z7We_!cTpdFHF)#;_GbLgI$%`DWWoO!_StV+{c7+ls1JS!{I7&h8qdEi!@pdHf2R!p z-@=>mw)R6?;4Ub4l+0JdXa8)8h2S&7C&lw+*suJDHRO}-y@WUObS36#8aju-e&C;$ z=(o)jw3N~Bf_-+BHQXFJ1K_K{PXxadd>*_EkMMN`_*vlhK)L3dhNiwlqb)&u^XJVB zzXJSz(D^<1VRNG)uQ}j95k9GX#>=raY|nAleplF==U9f%gI@tY2R^`Gal!-S;9&6S z4XjQ#?2n;7?9KjaUY+2(H?{V&Y!aLaet0uWJP-Z~@B`5Qsg()tr~X81_!{_^!LQxW z^52s2WM2OeepIk|P<_dEVZIvro5=Co%%cG7)ynW{5bPcD>j$e3vxZsl(}YiI&j#U5 zyA5n@?H_=>`NU_~p5_KjUa|v)uam&f0zVb}S>RWI=eWH9eD}6irwjJx6O=}OHTZfA zlwS*P&NEA6=Y;1%-aj9{9`f&h8b5#j34HvVIY#c+Hc)}7B(LUyTc1i8CV;O!Q;Y~ZQMmxxK4qu0sv2Ta{&@szfbt2_CD8rB5yB_wmtdd%&Pe^^%h(T;;s3J?e_0v+CgDx|E76Z!2Udcg zwc5t>TRZH6;gGjn^xrpOA6#VF$8qsv@abiicnbW4b#1w8*IJ?%{Py7UXIWxn@OuiM z)Na*f_#?{jvxPVH9eB|SS72RQ6!Iu6lAJ^PGc4JGYs<>m-wXTvwXlc&Z^#c=UY7mv z^#b@IoFBd{J6e;4@l>y~HxETKNuAFdBS4D}-c0-B$z4fR)8LaHCWZUsNQ#^!l$ zd7zBWbFlAz)!NTQ`@aG{{j}x33;qMzKWO=LY!U?WPOFJ$=weIE#(K4>@Ja2NE5jcE zowX~i&T{A%%h)%S;TJ(?DcYIyz*dxd3Ha*mZHFHr`+<2~BYaZ5 z?g{O!P4wR<%GkeI#@@U`ouqHRO2ji;RDYK;_WOtSvR=t4!n~%#sQ^BGp(Wl0-&{uL z6xgpY53uFMb^8+V!|z)GsZRL1xs1+3uuq?E?XW!uPlr65Bgq=rXTN93y>aaW@YNq! zg5!L=yn&X~ZrclQ#^+khFWT=V{DyKLv3h8`P$&icL(1q(4|QM^NxDK__IEVoQMQ?a zfigOmmeIMRjQyj~Ph)@I9%a7-K8yLj8~As?cVB6V_b`9|LH;bubHCU?8YHRRwh`X6 zPjH!SpJC{KRd~~$!>?Il5AcVU(P;?nVH8O^%GjS>hW~LHetD=b{fqmQTTsTzGWNeO z!~YdJv#z!RmqW+=f^O2h+cM*CU4)nayw_LC@Q0M)8-zFQT)o0dy#&R1 zW$YK0;m-|qyl{e_g}m(Vr`c=Uz~lz-YjJ;i5$bhc8U10{5Bb@Mb&@ zW4@08Uxa;rtgUDR_*vjrVn8)v9`%Pjj3UXIu&;&=%!3QT2k%+qhtQtOsE>7n^}U@u z+Vgw}JuJL5o%b?7HEY^Ak9Io*79WSaXC7=Q1tsZB5kBji2M3g~KU{cI?h5=q;W}v0 zw-8=jyw@%vFXzMC?WLPW+4O7R2X3}`95;d@ z_#v$Sc)Svv0KWTtYd?tiPYrp?MgKhy_PMhyy9+K33ZE4Jb!GV5%J2_Czk9r`5Vob@ zMex!Y9SQYZ?9s=%+8S`ZYMO zHi4h@UCUz|2--s)!9|jRGW^BRS-O*Lhkc-b75MJEt;i7i{dVD#;(w|P|9TnzpU}^) zu=;XL3SaBV1C4N=VqN0-c60EvKCpHZV80vqwZkL%1BFkDvp(eC|8yAV1jq!(L1!t> z8yKEJJNOk3S<5@%aH{a(e7|rz%fR8B(4MNAUJ0G<_btb{b{qJmH(Q?Px?c#N6#uWN z^RTsl07bl9#{SP`_;ok4?YtE6>;;|4A&*QX*-!YSc#ek7@OP~7Qus8KvF{Ff|2}jP zbXK2g1ulTj8D(_Nr#<372KMF`nUmr)ztGG!hiRC+SjPUnGQ9bn=x|@S(W;yVu?l%0 zZ}?dQmZ$?i5&Tjdh!AeDE%-dfGsoLkg-?qAh%$UB)Inj9q_2$qKxi-LVeG$hj0|5( z!LLR<)4*R2e(f2S;P||)jQ)dV_!mPRh(?k>m9bw}4nj%&wN1#&eInM|NzmF2d^&c& zaG>x>?Rhlp^J}a?4|HaivG0ZbtnXRF&9NSyTE_lj;m!K65}!L;2K{S<&jLr2dqe#w zWAQT~FXIaJt%u2L-~;eH2YxJkQhmpK$&SxltbH~H&u_4p_iN2-a>!d8{dZsClk^WQ zW8YB5zO@YB73#?O5cfxX|K+>jhY&ye{em(&H^P44bsPP7RN@!Z!Njcr|C=&8&%%EA zB5R0kAb6{c{rYkMFzbMMH^jVFhW`e^*5FrSo#cGqk@h%e@{=xK0lymK^Fuh~g->e# zR@mp)v*nuio6YOAGWI_$!~YyQE4Q*bw_BNDRT=wdX@8eBycYJa2_No{7jG9b9RGiX z{fd;;zXSFgNX1RNt;V{9V{b57_@w%N4fg3btiaCDIU0O`j#>`Bxs1+|&>lvSv7?e;(wzIU$K>Khi(k(LB={l3&p3|-Ka2*$$Ap99g-?oqVQ3$X#NzKmXDQwnJ^&_{QXl1-8Dd`7 zmC;`X`&oBdyWiL(c(jcDGq4|e%o-k!bL{J7?Ef6vLo}K+H?_By=5};-mU{b|disLq zp1$6`{yB4|GzX>9*Nf9?N=F`ETP&3%cgTp`H@_aa)Y4U&+uk+1sl60_(WTVXzaWtB zt#r4y_O-T5*=O%PcMr^kQd`RcliM?}-<4_U@90>_at=NEkg%A;Y7RQ;&=PZ|7-B6Y z{8mj^N>g`psky0nUaJJ$v9Q$K)xEG}zUw333TkgHwJvbv$tN|nkI0m|N?YTawo5YHsRlHMCI8J#7S{7=ysZYx9p4VNnQU6+hZiD{j6pG%FHjDE%=MYZ*zOM3&!l*GEHO`1bWZffppJ4s@+C5JVazLjr2wYGP+_OSVydghwe z42^6Lh4BX?`S#YP9(#4<1=H5ySDQwd_nLA>8qR6$Yo0ffYH2mYZX_oyJCcy59Z9q< zXzP^*iIi8G-PT!>A=;ft&S`6pm0`@=yP8^}=KZ0FVSW1(S{EkNv9;5T+ys$$Bv#t6 zR$7KxM@LgPMqKZ_4x+v$Hx7I3@Q^DqSNddp2X?rXW-sh(?JafpbTzm3_L|bosBfFw z+0+h|X4Av{ol-#L8p0Rbp4Pe2e62mssjIWMPvp9%CB|_$4TW4SE+@7{RI}h6=;wBkWs3Wtb=Jqc6 z?wn}@r9|CMd*xio&Z?zVzG>GrQry^ggzMr+#c<@7>|nJG?quwxaGu4&=#}}>Jg?Nz zB%|KWw0%da_I33&wfEXfRUDjsz3 zk%yLoliTLlRm!d+NoDS}0?_d3Mm< zH%|sgOQ~nRS?bNwF5dE8(Xb+B0?L?@uCsZwk94=mhTGGE@g449G8X2vcJ{UgVNqSP zk8f@66C*S6=C<~gEFn8*Yio7&H;z2~;IEhVn6k%|y(NBGlcQbP+~3nNOinDc)pQRAj^Nl&{K4 zOZ2wN(Za-N3zM(Tw#c^M+SAk7W%kASHox3|k=35RRg^O*Ry5ENi$FL} zaU_w>=x%F?g=h*8r`D#9(tO!T>;i3T*wJ)Ct63+_7sSnUE47B-<2I4VSntC0m#Q@D zZo(Fq5c_1phm#hw#;iW!(&p-k1CZz$H|}%c?CzIsyEMm~vAOP;(?Dd>McODlB}bLr zzzB~LI-O;ADw$(SC@bN(GvvXt2u8G{6%X=L^QEH>+550IIX&10@9&%)4xzBod-}Vv z&zNdRW5{YL2l${Aexcs9)q=>%=+0naPc%El$k_w0`8aH*q(Aq(qrKw zJnw|koTj#R?b5w$gm!W5#d6!--xrwHQ!}&9+QlZkk1?C2orye!+rv_1NpPpZF!26P zH>#scP1)roJg}R#F#T+*({z%AUFvAZkuW8>c?Hz962d; znj0lQ3=a5kl8#(7!+o1Fbwn=yG9?2;uH-jLo2no-6F^ZSLxq6Gdb?o8djDtw-jnZMWu* z*u*nBt!_=XHwShB)uN-Tn|T}{hbifdF7renT#h57BV4Sc=DK~iNPSEpW@x%{T08WN zWNH)18atacA&X~!e24Cq{%`JH==DL_OaZqVpDCFQEPrWkzb!Lj&7- zv-^AH$)$h7 z*C@4`C%7YS<-+yNJg<`#&fLqoJIR*ByCm#=CJW%qbt+i0k+8DWFt*0hVj+BL8+hJ{H2ZwOd*kw%q0R zHFY-2X~lJ@S;0EGPKr%%v`o7kkHQu+tsXsF*`sQ7)R_Ko!)$U$JH=e(l4Yi^oWz^^Vk@3$4!bl&p2dZPT{X=L7T@_ehIn%lEz|9-bK2Xw z!)Gi(c%TTE6M4Hps-63Vu<5Lxb)4FN;P=O_;quGEDxj2-9yr20T;I$Pv%S# zX+kau?Pia5*5R`o*Cl2mg#J=WQ|u&%Tb#P^nY#%?YA|x}!QyZ;pi5?yhque#dEeaW z>B`Axza#gk@KhWf4yM}CJa-@|2!|9mz(?Lbg+s>P`O3!B-4#M}>Xh+?HaC#>GNxg| zUkV%1Cb4r+_y8kZf{cW{M+)yR&6CD(CiuHk^kJfIDrTmbJ6L)4(h`Q_j@99L1_5%< zlgR92erILpxO>iJ*Xg<8$*zCoSn|4|r**!0BxNeh@vHYcX1;oxjV@ufH^N(3<8O<# zkL|)0ey(|<5!NldPoLA%)lr%)@36^MB@u@^>&T(wMJIzReCG7^@Z=l@8Q#ry_sehE zG3M}?7+I6d`Y0_F{&ZYOhl@y`+YUzD$JiwYo2&HB0@-cM?YrDgj*LxLXdWWMn)SBJ zuh&HalP6Pd2%?{~pTqkDsk;0(QrrlHXW;1IwxLPz;hdHA#x$Dl|5{PWwC}`XpjZSb)6vm*S9Z2*vHX0EW7feDD1X&W3Zi%?HB+)c& zYjhk%bToq-E~6RTaKo?$aErJBjuLS@O#~v2fVkv$-&J)wm1BC|_qx9Kd%xcwUwbvD z@B2LGsj8=*dg`e<=fqp`{pThpB^maomvOd1R8cJ%uR4+WX{!2V7+xdC=!1VVjG;od z>r7lE{$uzYsoOpphDV$u+Z*5No8ili(QsNy#iGiLK}qM;RQK(**t66~-<-TU+3ilNuO04l z*QR(w^HZ|gYLl~{I&;yY{E_z>Ny*-n0?%dPW75*yR}Najy4;KJU-7*UUw-bF2V|JC2Xy`xw5DE6zSVfgexey9D2-@O>KJXYu_9zV@dHKVHE1C467T_ceUq zz;`*m_Gcx2tipFSzH9Mahwlb_-^TYHeBZ_QJ$&ECcO$+Z;`=eapW?d(-_P;o=L>wd z;@gJrm-ueOm!EI&{SIFX-|z9=fiFKh@$JC(2Yh$q`y;;m{2Skp3xgX3QHdmoNJ zb1M9{u6jbCa)lXXN&C9;kS{ z@r~oFQ-A%eJ$T+b6Nlfi=}zg=(^qxg`ecATcvu5A))Xw_zF6etuV9w`FuP-_FnZ@UQU4P zejMm1Z@Xj1g`Zzqy}Qp@Z=Lt~rJJvve8j++pI;hy^riP+9F#KQyMc55xoU6nL*pOW z_S|H5Rr%c`{`%R;Z{JkC>rb!jm~r+G+s+u$`}rX+pOJBB<&Q@^_`|*{>+Zd%cYf7^ z>t>H!bI)Jj*gaxqd&}vkFI#q)=ipzi`^S$-nYf|xKOJ3vz_rhP+5X|KflK#YwfN&#pFcdX>a)itC4aGI%=ZtiiI$G4 zADjR2_Z79vh8_3TX{Y}BYTZNOq(e{lO?%_AU#>DX7vBEV>X)W1|7`1s<4fOLdj838 z?!Kw|)^|R-;-bLYCHW}(U~9+kXAL;rSn$NDOWzy$P-f}mKK)BB{o=W;z5%;aY9DC1 zqBQ&b&RuKf?z-r~NBiC}^2r>|-Ov6T@tCpH`I(I1+7o{gCa|9PWgvUv4;hHD=u{4T2qui4WQCs zK+pVD7fc4C5hzK0~FC;46p{HLQ&&+;o1lzV;x zyDd!6-qRBJ;mic`v*GJK*}o`3J^ukcJ;`4NBlKj4yAs%WYl3>Z67=s+3H+IJaZmM$ zB2nw9KL1M4u4fX|GcUoo_{!CDxvBknF8724T_ZO{~VQo{~UJi$v*ccsLvtj$DZV$PvCF4 zsC-ZIQxez*-D`O8b$$*_;1AOil>0;izkM-*KYW%z{@Vn8dq#r#oR*-y*J8Z%WQXe# z^y5_t+I23J^yCjW!(ct}k0cl`A18?C^AT@*s^?n?>~mZKJIqWF&yP#MuT3y6eobJX zC>q;Sdj}+_XHJ6rRehJ3!BMJQB@dWdW zJAvH}PoV$O1p1#y(5?d#*zM>9{&qzI`OyjZISJy@aj=^QU+3qg1occwV22S2>bW3+ zeRd|$e{%x)Lle}$DnXoi9u4ZrAI?nRZ=(|EuS+1mA%P$I5{&E01mmkU!8q-mz@DEc z@T=Jg_=91GW1O7}{6YfxdlU4_)&%2yVuE-(F9H8x0{t6BoatvY{2(hkT-Et{k>~U? z+ICCgLdEYwzZ_`vGdk)ef$%Fn@8e(c&9xH4J;dh%j0^G&YE$CR=nsDOiMZX*D0oKV z+3JGl#e4@o6$RmQnLKS=1V5pk0&c9}^P-YZ!@Nx1{gD)`Q~VOqkEnmUA2Z;+H8qH2)|Gs1=`y%5JSYC5D*zyr#+(8&6;kSNwFr z|8bo=N|ozfB+K=x`v0oh6?#D`fZL1Dx$paD@Ab&#}sXiuy`H zRV|}H)zkZ}l>3*`^F4wX^)zuq51(c7wDEUk|0ZtM;nPPM=qyx>@{R9GL7(#TG9~X; z^*KhKHm(=r5#xdznE1Rc55^J7&IQWOd5S+>>B)LU5=&J*SE+JapOU=V_BW1F^35+w zzF7IyF4UKP-hAIsabk%)ZJes?*3m2prOue6>{Fl&R;lDulszlB*@=%jZG4U2v_nyy zpv8VMe@(La5Rt?@-evdW>qLg}j64`usdjnSOX5;x=MNR%yh8H#s&+lC?AFmC`6{Ky zrRpF0MiK`oz5@L_$Us#1yR<{A;!BmDHf4WRtg%@6LqQ+e-iMU@gdMln zs(x%$^9bBYd`?y6cC<h}YLz1xju|VlBQhs9Vc~9wY{aVVO zCJ)A8imzBFi8YFUSNVAdZ!F=nP#%nXl%Ka*Qt(G*pBGR8)~DiL$v>j_uT}kVKu;KZK!r8o%$_ z{iW)8ppw7Jj;pUp;yuOBQ}L~1rzB9E`1~0ca=vJD_|H_;U(I1DcdU|kDLq+Ak6rEn z)$bLJQt)Th@5ifpHhd%bDy4^NY0oy*@AoNwwz6Bt5=qo4{%K{OMr9wEMSSv64)ruD zzq0Fj3Jfdq|NDnZK{by4rt06?A!%Drvh6==qPSF^Hf~n-Y*06aM=QQi^?T@Fl3@PL z&#TIB8y}E(sc-4HTiZzz1{&G9y zAAvq$pZQYp1f`#GlzdT*Bpy}#L#n-vDj(qeY<{LIK1=0wN}X|(Dz`}a$t68igfc1t`<@kU|c)w9dz z6jlX_D+7gvM&Yy>b7p`nsV?Tv;#o81l^KQOt}C2ScJ+*^Kw0J3S;bXVWmQITMM+`B z^oqjS#j|FWm&D<;%Ca&6s%MwYE~&U){;mpCmIf;f9A=fx5mZ@aWqGAR1=q=+)K{kD z#P7JKvdXfqGRm~_<`!4ZnK9>Tp>IxkU`B~7xwLF*P?E(J6=icu#rdk>R45le1LZTz z=CD~HN~TM$q_X7n)5O_nvu0EjPA{&SZWPYDu6R~qMWC{jRv#_$Psw_}gR^9!Y(z5EpU`1(hpscXGvT#mWbpVR0$|`kLv&*k5E1Xtd ziKdlOL02JHLt{y>va)PWpb$EW9qNlqOQ}`rHwtONO4Vb9C}W1`NZD3u>Y`*%qN__a zQkZ6Tg)j(uccyG{MPNF*qO`DbF1g|WEF&z@1CRDsR823gER)t3I!b1h70-be^dMf! zo-dcqB4trfpv)mEOJmc7OeOzyid2>gHZCNp>J*wQFYOWv&gn^)V&h_!PQtGCycyGI z@nB)uoZ_joWSfJ9SI;V+T0E<&a7L*yZ#L>at(-!_=LM*!gtrt1c!eB(J)f#9pWE{Z zx;6*UACyf;CzVwir8BB3W))vgtD$0n${A|ZR!t8EO3UYB%+I(QURz}ZstP&SL`CW2 z!8vi)ab6pQ;}n(@mrR#KP5dgf%|Js{%`TQsTO25#5&tzyR8$P~!qW1R%Cc!$EL99^ zjt82ECHGivRdL0P!rA4e!C7SvsafT7t}ZMopM&5vM~x!*(Hw@F?&{()tfEvUOme+L zP7Gg;WK|r^%S(bBr}h}KNsXe6v<2Em$0bowUOubKW##FL%CcGI#d1(oPAkdI`STft z6_w>zBVtqu8`)$DY%{eO{!L9Y5L94KHQeIfHg(1vjD+ISX)|ogR1{ZMl@;RO;@M@m zMyeFFsR9T)veDDZ0wvQKs>*|vh@2vr!+Mk}N7yW!TgmWQDdG&9tj?8`S6p8h zC@(~K?{-Z*T-&uWSS@`JbWsbDU3fjl`S9};}8+B zO9YLu;|ND=37S-*<{NoACkr(-Gur5L6OGNTw8K|iYbk7_#-3E75%D3UxcEh7)ktgP zBq%RZga{y0#Y7{bLS;~RPL&)y!8tvh>T-iBj8+w`m`fDuvo{T>dIud2i?hGF%!gj< z0#c71an$VIRg5Cyje#Azt}QJqQ8^6rm%?emIVD{uX8=%-om|<&-C#{s^uzgJ_h`v0 zsE1=n*es~Q3+GG{+07WlJ!vJ*9#erZ?-#1sh||YZ!xr_k+fVp0#DV2Ad2Ov)IQXNL0-#*GIXkUYr%vL|h9DEZy*G**_8> zDpOxYaL(2G#H+_3;ZnF-s8h2L4b^Q_i3{L=a_lma%h4V$Rrs5e6jw2WP}hk8IW<_N zLm4rg~S zxBCOXO9C?fl19#p#uexNW6v;Xd%-gyD$f&M0^70CEWne(gQhEYz0nC86+}+vXZV=Ix%H} zbDZoS8Op_{kFNQRU8!0l(^Y#CvMb#EB5GkUE55FH1`;}?D|X#`X1mK*ae?^93%b#~ z0&|mC9tFy-M!q3O1nbiy4?me{yQ0u72;0}Xn6AkWGb=8s2x2+fb-JQlb)+~M=!WRt zU6P`@pqO-&Pb)1({o)flTmTsjJxL{Iv$$N3|AvDjL$}jIia}2W67`ugX3a7%_ZEv; zfWJh9jz?$ZS|U1^PrU{XQ3dbAbckliy2a;Wc^Yf#Ii<6ht!mfcl2Wlh}?!}T9xpjBi9`Xfd zLE-qk5kBrGsoye(veCKRf@AW-lm_#bj0YvtXBJLFR5NDHm|7V)rKPY@@K^ZdRsV+&6^<+M{q#D8ZGkN+HQZwksIwkp*p+35Ohb9nbB zeioaQan$`h?<;i4@f=ZihHMvS|JLQmVIx<3y4OWVf7EI-UD~^Awd>s_rwWOe#UJ`L z$+$o9|Nr;@!~)W^)UX_z^t`X+!8dr=4BYAIW$aWN_euD@UY+L^_ukDrT&c!>#SNY@ z19wVNjMTwWhrB*Hetolg@6+D@zV95lq2A`;@BFjmJvR?!F@`O_^mNG=Ie1&X(ZS!R z^fWv8MT&28@VAXn<=)c0Tw9OV!9T3@gdF@6cDWAT*3;(TpHcEgsC&7#ey@YK^%Oby zCc8ck{zbb!4&JV(aclQ-mnnIVgI})rA_s5Fha9{u-{{~kA1m$L?BLfa{cR5ZJ-a^h zyVvs*#d{sRttaH*?Q$C(ysf|4!P|O_n(pP=_V+q?yS(lJu?Q+{3yj@RE zZTI@vv^W)y$(Lq zAci@f&+0C3>sjdF&sTbuICw+pS?Ay*?TUD}K6zuT=a(2Y-{|TOIs- z#T&PGFE^z490$KZ@zWi=E#K(i?^W_?_1*P9Y3q0Jww?+H|FV*Abnv$QH#ztgyWDX1 za&7%y2mhgxuW<0+Dt?KB->LXb4!%?I?gib;J;;s^4nFHH=~rF{Z`ZTh!DlEvOB}r2 zzikeFxRN&`-RqOD_-Y4lm)qpvCoB0j2XEUy{f_SXXWQjE_?FX>M1w;P{zfI=?) zzf8%uI(V;=Z*%Z#lzfMS4=H(LVfXgFujJhh-ca+p$H8w_@>vePNXdI0{MSmpz`@(~ zDRS`NEBOis->CG59Q?nPe1n6xV_bYj~gSW@2$HAwmd?3rg7b*Q-2Y;B7 zFL3boxc2_7yFc7|uJo${2XCl+x5&Xqm3)PRZ&Q58!H*d$^*1Q zNWf3NeW<8~Q%`dOK2x)UUeAUE{JsQyk;>bh<*rM>XQ{l}DZelQZ)o<{>p49E-Z$W?%^xnd zD}!To0=_K)Z)$#`>#5iJMdzC|`7^b0J2ZKnFVNa+KTFKZmL=dbwf5@r4GDPb&aVE# z#$^1{q4C(djDPlNy!|erIH~o!ht8rtX&S%XCUJCYe4ECnYy3MJ@6q@pG(J<~JsO{- z@fjMQqw)6N^y2AtYQAIDb>6GVAEdR*)cCcU{sN63rSX$Beu$=LnO3gO7isd(YI>$? z{Er%6t?}xW0C6^?@jgwyUgOm(YU1odtv)*6pvkL8{H46c+wbh~M5D&@9YXuFMC19l z+3Zh~#+TS6j>|OuVU2Ir>e-FgtDB8FOxc1rjdwtjVXTJl4r)YVxmY^~u!ab>7tEzt!YTO(CS~W z$?Noopwt)78#R8B z#xK$MB^uwP@tZZiRpXD;>bXhdkJ0!xjsIBFV`;qFst{*8H2&Y3ys6d^RIOeO5@)At z{8CN6UgMiIeu>7bS9-+RbsE1;leaX!RpZmtI)e3iTjMh|{#}hXHGaLu8x2DR!s}x3 zyXGX)G@kd^?T=gI576wKuJJG1!Z>;~-oC@m)0rC29Mt|~X*}y>e{wYbJ)6YQtMO?X zZ)*Gj8egFCy|wyJ*7&}fe38Z{Y4X!G9KNTAPVVp(2s`33bKBVz_URSU2cvUU_ zY0!AQauxq9)OdHC#r&@EnOgmqX#5~ezDeV8>pT8grtzI|)-aki{$Pz?r}3*bzE$Is zwfbz*_(L@LHjPi$cuV6C)%XsLKTPBIY5aDLH|`!P5Pj`%jZf2f``u@rc5D1mntZy( zKd12?jqjzkH&f%E)a0`?{%DQQ(Re+sdNuxgP2SY_2Q*$B2N}+{2QA5 zbd5h&<0~|NqsCWj{Bar|()i;wzFy=1r11?JpQ-T+HGY`JH){L|8oxy2Pt^D(jekbt zmudV-8sDt(Cu{sVjXy=>TQ$C~<`0`R{!~rAP2;mP-qQGNjqlL-_ceZ>#-FC~#ywsB zf4at}X}tc}mRsXr(&W=MK0|AlN8?9m@|ha{lg4Lh{GT;GN8``Xc(2CiXuPTMBQ?H2 z{aO&XuC@ogG^oMwMZ ztz`YJ9rJkJEUM#=oHPnHqn-#%F1~ zU*mH$e!RweHU0vPH#L5x#usS(g&IFu;|nytNaHWk_~{xyOzW2ljh~>&S8M!4jSp%3 zDVm;ojelN~Z_xOy8oyBEFVXl$jlWdmmuUQ38sDVxlQn*s#$TrK%^Lq#jbEqnk7|6Y z#$T@Sn>79kjc?QVD>dHI_#ZUBL*u7t{63BUMB|NnyZnEb#;0lgRT}Ts_(F|O*Z4ge z@6q@ojnCBhVvWzz_`5YeN8_hzyjSB(HQvEEH2ETpzgpv`Yy5PL zuh94z8egsP%^Dxl_7<*7zokzenSjY5ZR_ zzFFhvX#6^jFW2~1jjz!7O&Wi##4vjxvtce_#%zJQRAm;{7o8Pq476se6_}}(fE+Y|4Fk?y~f|7$v0?xNaGi3e1A<(qsHH> z$uH6PM>M`ko}od=PPyz=sjT)@Z-L2NDklahAYah>sxl2)vQ_NMg6Z8;Fl0HUwTtd^B;# zZ*2c-#2(@{ftL~wC2ke?Y2ssun+0A>d@OO3z>A18h#LjIhxj<+27wn4A5R<-cs}u; zh${r1N1RDqByc71FyaD%uOU8x*emc<;uDFp1iqa3Bw~-i6NpbHb_+a?_!MG8;4#Ff z5_kM6`ky$9xJ}^Gh_i`X1wMiJG~#A~k0It3NvuiW!-$6yHwt_p@d)Auf%_8wnK&eH zGVvM26$0-+1~`YfNZ{SX+^UEb2)v#6Ok%IV+lbF1&JuVF@hD=Cz#EB26T1c8Kzuf_ zA@EA#bBH^B5&ci>C2kXVDRC}wtH4hak0EXrcro!<;wFI?5$6#%3VaW7K5>J<3y9Ap z4hcM;_&nkYf#(sM#6<#E68ne?1iprN9I;p6sl?|KX9;{cv7gu@@C4%V#BPDd5nn)T z2t0=PLgJ47qW_5th}#4{jrbzsR)J3-otTtwU^@KWMp;#Ps5CZ0;%EbwCD65=L-7ZH~dHwt_YaT#%g zzzc|{5r+hxPkc3Tg~0QOIRV9r1g<2WL0lm4HN@8tdj+0KJd-#};LC|;5qkulKs=k+ zE$}$vImCv*V~ER%JNAkGC$1oF6ZkaZYl&M0K7p7^j##t6#}HQ$Hwk2OVy5IV zkH8y=Zz6UJyn&c0c+3!ZCGjo99eYLp6NiY~1YSyfD{-s9PZQ54ZWeekaSd^kz>A1$ zi5msJhq#WoLEr_%w-JW~o=)XCBBb1ByckE{lpal?>`!NA#stwyNMqlE)aM-@giccz}tu)B+e3e z3-Lq59)UL!|Bcu!@CM?Ci4B2Q5I6Hw(O&_)+2} zffo@!M%*ayJ;aX_Hwe6d_zB{W!1IZpB(4y69`O?5B7rN3pCT?0_!{D;iM;|(C4PoD zOW@0ipC$GPJc0Nh#BPDd5kE(42t0=PdE$Vo60aa`75Hi5mBh^g zFD70^+$8WK;?=~B0^dWthPXlC1;lHKLjunyZXvD^cpmXO;v#`7iPsYs2z(9k24b(k zQ;FXu&Jy@?;&+HW0#6`*m)I@vIO6w+4S~lHzfat;Tl7D1D{-5^rxAZZ+$!)1#2bm5 zfpag-y(D*1?!-xE_@|4_@Gs`A-=`%RMs2eho|utlhW#0yyl`H|Nq+oF4|rX}YBNH( z)-~*o48|DOuzNEa#qpsG`kZUnV;Rlj_-qF2;2QQ~Mw>XkkBR6K?BDA9OQWV)t8CUH`C^T|V_8v3bVy@WM%Nm6kVz!L+pl*ggQs%+$ zbp9S+_qD6`Ul4A|%Mi~OWbeq&-qC(w&CIl<@sZLDj}YLKM!rZ&#`wBDd6Bcsa7sqt z&t~+F43kZZ=4BM%>YOa7!*LXkW;BqI;}3sF!=jdX8D?(hCw0w%CApD6Mq1q-SKVin ziuhrBRNcMY1cbb`n)PHO*0^fj)Q(cKH=2?2vwVB^nkD#^@&V4fYQ^;}`8l}GFvB#> zbeQF&53)ObC;|pis?$3sW_X0gd|0333+0_ux6xI{xyo$GS7zAZ56{j7^nf)2DZcP* z5Bf0E7v90re!vn;n8OUu^w3n4qG{^B!5NU5H1$@i4ykJU6xY#O)6AN+CR?^0QB1Zh zaHbjcny9olb|gI6b#xxv$yTJtss!O>#bnc3@@Y>D5^=)F{>;2}H9gl1Z@OYi?v=Sy za<9rQTqXKn7!e)bSs?vjm854@+&honc-O(ZD#mm zKaL&#a3Eu!FZ`}QT$*8FJEGbjIn4~;2se%#Y=(a{!-trWOE6L{MUP$L#?c)a@2*?# zsvC;hz>{mNq?&z6uG_{Dj&=LtJn6Z@=U*N>B)2{`Mup z2s``3ZD!=ki~=(zY(`FxT#QPTW|$_LR{Ju<%}6f1$p@3JH(hz}!UxBPEi-y!hS}L# z*UTbKS6vX+%?;g{F}RoO_PgU{#IB;zMgRJvWo|P%F~dt&I28e{t~oe1bi)v+&&%)z z`j`>-+A%|t{1H!X4dO&n>{!{~(v0vp4hB*6Ax7*4_?+D?=uFRjl_&GFn_o@C(F}jV zLKf`o?2MHPN#S3UCYw;>fdHIKc`$zn_wq-AhFP~UaHAO+hYlZ;X15mOIFs!SZ()-? zY;v%KAqQis(^Y#D^jpk#VpXCfH0N|PI$-$-!^rN;M%Tr1m$7dC@OHB$C4+@q*J3$i zcWd1+T$Z2xb!<3}+3U?n>J5X28twHB^c54Gmkp(&I0`6Frmk?+m@CNQANhb}%i(?4=U!*yr- zYGNLL_y99f;P!K6%6~?AMR_0E8Q1_{e3Y&{bxXI0z~|W;2L-P z-#A`W+g5R(5mx@qH5C2b97yhL72AvrlR~2{Oqg(F zYFOKmg`3eMKm5&O_@l?I#sPZX#5Mk5Uzsa@>1EcmCz&HRRe5AQt7%R$!>ND6`P|OI zt0Bt#0_Q8gS(|z@ekNU!d*zf>7#u1d)r<~7rGfeRo4{cZe@4}C;1n}DdKyl3wy_;k zR>^LQ^@G!C@htW>#*~H`-{7@~Ynbdgp!cEW>F_kTEmDBMQD*o(GrX&Fqi~=Jktdzd$ztk_4`@$auPPH!IK{a0ry<3GMp)p#4L9P_W zj%THXy|SDCi}G&$eiPh8<|~-&{G479Ihe1QfiqmgFbTVc`7?@K!zN}_xQ0EH5rR0= zlm>BpHltA-UsUPK8zOx%qqQP!@r8fzV;WC0qa*5(LYv{AU*o71DGTR!Pj)9FMH(Fy z$Nmf%JeO`gjv<8!iB*Gj9QKj(OZI1Kdf~JZ{!L6X=!;C)%7>0P-OBzRu`|3nAE746 zSMs}cD|IpjSQQvKzT|5&yc50R4{x)ocXf7-S(|b!%H9+=s4ymDemY~m2mO>O$Is|j zvG~Xf@AijxW;a{?+YuaEwD}JcPQO_1m~DSJ*$T*KH^;VZ2iKtc&rfmxLC;#dyQ+tI z(NPiMCeZaa=t9r?!{4Ip254;mi00AC*ZdPUQU2)*|J$06R;uPF)*saMXZ582f6HGc zV@XDTL0XF==BfYaFF{O7J^Rc5R(+RXNy++($o^l}cMS${kM;dgxO?~hwDT$9FP89n zGyGxP;eFxXt$a8f!cJ~@jddn|!tD`s#zt>EE@^zpj@+8n$a^}iCip5R%4e zEf^u=qN7gqm3)NJU{wJA!SftLfc|UONBEblPj2|%@%rS3KlX*+vzA(zf$P2wud1Gz zH?r;KOME52<_-HQzivl$pWKn3=ejQVJX)1xMut3n0OEJjE`Rt3v*a_TXEV^3Yg5uO z4d{W=Q4c%5=S538+aK$)S2kz;_WR=TpX;;y>^-@YeBs})O1l^dr;HI?pCNJo2<~O| zK~)6+cqGEm%@_f`@LH40Q)HirOqieR8}Zw<{Il#Gj9K(g*yM;jjJ34v z&)Rcj+~qpKofqB~{$kh`e|XpU=%}5!(JM2O%$hYx)_3TLkymD<`@(&EEh#&p!MO1P zlz)U-@{2!dm#7aT*Rby~U{PxSJXapHBNHBJ1t0&QGy{_-YVQwYTA=Bqfx+ zZsaF(zuVhNmyGB4lf)vo=KCCxru~ANzvaO{)<@{Hw@my(-XT^#NIw|r*LsnPwixo~ zU`*Wz`qq;WMm`rA@aH~5nOt)*?puhi!io*{T_Cw?1UCHLG*PdZ{bl@J9z6imWEPS=AePU2b@#Z$(?` z_@s5dnj9lA1gRL@V4pkqRaP^zzYxr1yVjs^`9C3++6WZsz2!) zGjbDBwa!3)Ok~zeFg((>{$|Z8)a@5{@YC!aXdSXXOS+Isj~b{gG;KdF zGZ0e$)A>UZpa0P|oLUti16`jo6q_D{%o0Snyp{VxImX&^vA+9jGsc}6?(N8TA_KFV zL)Q;Z3Z&8^xFpH!m28GFlE$QoIyvS0nvr>FO#2QF&BJBAd6^d(a^K)jX825XN!;GT zaEwQAv1Wt>WNIsMc#B~TDaPNVm#4+@zLjx8?sxg4Coh3i?nL<6llZ}?AOkBG_SXH> z7dg4D7dj?__0EVpY?WroB(}O0>y_tRq=|bOiT{ zvzw8tNw$w;WPs5V^?JsKzrz%Q?JM8jt=M~$*+_VAAjtmU+R<7IHy;;0343Wk{*gbqY6e3o zr&cVntaSLg2-xRGQ%0FJqmohRL>5~2nXC2&{P0I-Cy(bsWqd)o*D{M_iuQ;n1XtS&MGS}H%{u+I$M!SAK zug_$!hF8T_LJ~F&T!{J>KZdy{(M$LQK8-)$CJFRV~yEG+q zW$(y+lS3djhdQG}GNBGy`{7`#n-6ud&se!`@kGnNKNa~mh9Xvo*bNK+XwAVW@<)zq zF*q>tjoiqn4721@;h}KFz=5G^uMr%MM9%tXD{6z&)`?%R);m$}4?y*}oD<_alKK?2 zVo?*xu@3$m7e!KU5zMYm%qJy-vFOZ~V{fh3YqT#?d4jAjw&BE99o7rsPh@?!V*d^c z%1moB#zkFo^))p+l0u_SJT5SNx9fyvByLI2j{21J^+l+B;)Z>@U4zC62hth0 zYW9`h;#C)}>-7BL!mCnO;vS7q(EcWZ{$Sh@;)ws&dKzsJX-fO!;D^Wgd*Xal&rjgw z;ZH7RSmRPI(>k2aAy$1iUu=#>5HoH*7N*HV9n2E!V(Rz?L^@Yr^KBO`>%ufUlV`Z<4i>+98Lqni__Y?|n809`*l!r=@MDY}mH#`q&V^g9!(;unuaG%DFrA)eY4;&q<0-OP3V$l*AeG7Ewhxg@S zX$3b*3lGl73vaicg6;j0ljq^2FPslovsz#|+YN*lMw;9x2Qy(H-N!UByv6GEukJFT z>aj*(5ZbZ$7q%nybhaamg1=x*2Ivb zvdGvcP}-7DGZ<_02P4v~_A)I{{V_UeF$39qkbEnVWLLa}D=uef;J$kSYa2=Z=g%JA zd&8O$V-oe{1o#rXm2J$j`f;?ObktRp-X4;1HIjNat`k#0FGPygedA%>obfPk-Bt{B znzV^7k9~Orot)SPIsVbS@ZV{1w#9J*6eK{m?(dzg`TR!f7QS5tYj?W(uoe>v( z-eHf}3MtBYLFs)cE z{zu(S5f}8LeR&yaku<1pe^li+>-UO&Mu9;5iIgkr{Eg< z1`*rMb-lCQSE?=QA#ICfYrjP8tb?k25HMhf<)L`Y?De;7{5e8%3-#O5aM6C;RL!@^JeB%A4hrL-W5hKm`57VwHw z(t`nW1dPYmx+Gi&PtNg2XW?cB+&PQAjNKq^@JTRUin~+<~uDp)y_114pfmkRWYuJo} z_Tai?SKSk^MlP~)HH0b}K%O}S^KWaJ_-h=W8`=hPug$)ql`kZR~1X8Q(XAMKBRAal7iCK|n;p@&FUz5^R$k zgye7o;(opi`*-j(I_gzKT@m*4k=x;FbqiYN_bB*h%$c%am$TrVP$Bb5>jl)3wT+-P z`PfpZe+uWum+Zj|nB)%!4Y67k_KC&yz2&e^?BTdRs`7HWiH`muE`OI(o~zaF`3V!h z|2*ENW4!%&H%x+2lrBaQet7I3@$uGU8gsK6W=LaZafJCZMsb*7gvnf{5zjqxPziH! zh^1Mtzo!P*F&tdDfX_qpR)Z_O+u+*t18OA)S3X;+2G=k(xUw*~Zc>A52q%N+fHahs zcyKjBi5gs)VsQO@FRB+!{fP%Ydf*sbjhuef;Nqi97+jecTznR>`{4QxZR%-oU5bmW zr=g{5aNURrLk+IGAJPWbYN+TwxRk$PIpgJW#^iFQfXkW5T+S3>@|dpX7fjM}eBJVH zcO^ZKuLltBIlgin<0}aj72}`NL3H$MP%GU$(@{6)_{vn{YYDs$<7;FGx~+%t73OJ- zugheN!`efPuT1gYi@knE!4F{ik_A8SXirQVUl+rWtnG=Ytr%ZVKz)znD;(EX=+xJJ ze6=xxM@Qcsmp|1h-}Crt73*{ER@lq)-0=QxOLGe@1^v2Tn30Dvmhpnfvl-1e`Xi5JtP@B1z#tzC+$8WD8ErUX zwadbhWJrJVM`fXW$}Yt7(ILI=VcG)^$_syL9r3oz8182+#M+nJq|3OL!kYLw{EMx! zSHwVCV@8xN%!mEdJ+if4>?dvrh1Z&dH#+{j!!ws$j@ z=%ZshJg~zNShlR^Ef|(4CI(DmzQ{S&G4FJC*1~P~3oon92;n>y#)Cuqd%J1}KsvNP zCE$hQ&?_E?%Zm54=x{l>a<|`gk`)^VmzVJw{d|$g0hq_1w*k`kLGQGNw>(g5^@daN z!Mm28?q-E+Ga4yW%;*mjgaFLwi{gO@CIXw`M(tVl{1Y7=LQ3tQLsd_^CQxVWZ! zr6y>^h3JDE>&f@Uh^>1|;9AAYJ6I3n4i?f<>>R*Ic&LfDtoE*hJ_fF}0o9-pbZvEK zPTZ0UZ}vqFhNZAkpzhR}Xx9=HVEv5JpbL=~w~4J^IQUUFQ5QH3MY?X0MGScZjh!Wu zV`&@SvO>KJ;U}?vw0YP5EmSp9IQoV-=DA)D4#|tmcJtY#FkKGK2~Wa3$b!N3lLo_` zus_V^;JSKTmsbz*FvJ1KFaq&B#*e zENNPUcUpZ_gIOBHgAd1+K&?IoWA}HJlY1#f(7*5G2vQFMbMG;S6X2=bY{yO7_r$Zm z*x@?Wu--%+#B!dS5{Q+bZ}-57Z-gvjdV1%C0@-b@+EQ^IPvBN zh)YqLT&{102l^uC;-Na+mHr)*&2Cd{%}Tj5D0cu_VSOk3Zb$_R>zq&|q_;bz52SQo zO1}zeJaTv{#(Nl2azy+aU5U-bH8Bt3mb}Bu0m2L#8FCsQ;x)scn&D(0QYQ4^7*Kp@ zBRs}!<)Hq#k+bn!-<`jrfPC@LPYQk+_ISHb1r(*3+Oqc`bLIY&P>3H=A%3{6?+};K zZuhvzNw^Qa!&N(7fH=)Q+7upeLc3CIWr|7+PJA$?Bpfub~_0_bbSqHJF^D~Is)$OcTSj$DL$v`{>dujY0v2b1%D90 zrb}Cr`N4McfR*%wmAhS&n`1lZy*-{u5|I?eA#=JBIZ$@9h_?vv=OQ37_r>Fcs2*0U zi0ZM~sDA_VNlV-;fZyMZ28eqcba_l6QMGk|ZvRpE{kzsXXczCThz7=$-}!ClSdnY6PULi&B|kR$$gJwBD4m=gVkTvzrgi!AmeB> zV(fS5Be`xa;;`ba1w6KX9wLftLHIjS{~oLU@T&h2^m4j74-iMsAPSg$eqb!{57 zukE(~I0@ZQjV)77;9}zgc1Qct*_{4n_)FyS^f1F3i=x>P>FCz}n6S^_lg@`iF@|{e z-G~t7P2Mt$j`l$HYaFW9#b_*|;d?NF_gk7k+-Q0ij?(^`cK-#ZW8Zjq8{|W|w+1&7 z_gMqSn~^3F^{}gaAjI}VOl9}Cvxyj3&tszIoexc)w*SHXt0*t(wrv$0q8SGcfIE&z zc3?-@lNDiUoA<0S*ubO#a4Qu)CUTSB0T1$%S))?Xn!tE8_h69v$26#rA_7 z2i9ZAyV`T*diidH=0#re{0h_q{e`=STQR#@Z?RqiM+`pY!ruraO2rDOP|QTSG6y!Q zc?|*)DpJ=bMmv?MXJ77>bEIfZ>a4FlhMKiEuj%X@l@z?Ky%BcozQ2tbpdSR0oyyw< zvTK8f>9ZpYXK(N3p&{r8?rK}N+x_rbv+RdY^*atK!weQ6_*@3NVh5Vtl&(_91Cc@w zw6a7VV6(jgr=#=A(Q8c&G#C@Po1r^a4vWX_O>5`CY|Q`K+Mj6<{pqSbA2R6E>%Ox4 z6gdJPs)fB4(CF;BKT$^8ITrVf<^1w3`Y&;Qh+QfxPfQH7Hu?b}D#u!hYub-Rb(7-N zeg7@lV_ibODaQcA*Gq6MygtWz0$svBd{~T3?qjJwY?6J5+M_i~ws{bazf|4061G4) z0uRe7pH9t)syQlQV#naOoXS-Sh`f%;A)~!|1PTtuvQP@1l0r&?5r7>~G*A_C6Z$GP z5{9zZ7vdxWVVMZ!S&=FKDY3h2Im2Puknj|DY>mjN47^Jfeiylv{X*4;@SVmw(Z2|5 zlNqYT?GhM>x497B+^AI#n-|suD93nr)jr1a*o<=wfdpPoPuhnISV zm+}GwmY|oO&Vd6hVnYb0>1Yu2W1E0tuZpO~8#R~-E~M!)#j-CP6RqKfs~Jf{D>iMV zsdB7MZ-|v&T{ZN|v%I(kYETZ6uuXKrD*zbxkyya3G2-R9H(tj%Q=AL2x#Eo$e|SUe zFVf$#*Av_ZpzMPDrd6)z@qD?xp2zdq+IpV(eIzxRwZlWD;XQb{X*`ySoR(0&n(nT$ zJtlIbo04d2KfI9S$MZl7g#l9k{zW%Wh@6!hy(DRT_-DKpBcAWyX>G-gJ3N^mNxejh z2D9-%l5`yTfVfD2(wO_;w(l&A4747%g|Sa8QX$%-uK9KLec-*$*7gn4a6c$IWD?S4 z`!)%taj{%Mq~h2Tw|`DzmwC*v*bMIn19I9t393(GOh#1V$V2ugZY5gQdJHsV299|c znX8zGyCoPTyYEl3KI?CF)W9T)WLqg%nRuRm_s$R-! z!n-;Hy+gMQ?lt!YR2?sa-3UKZReu7Tvp&3iwD-ykw{?K1Km9N(fVT(aUWOPiVlM-Q z;T{GiecrDzMLzQ1ZRbH~XZvjp*&AaIV7Q{OwKNUJLu&57JVyK}Nd0*h z@%~Jke4d3b3&x*ip+}0hIDFxE{E;*BB9&>b+Lh3jTl0HzuIt{l2v&OnH~Pa!;UeF8192jX}$$Tj`4_dgm zOSd+_QRuMgRs~DP<0TxV*QHt?EaMh~ScMIEQ>2UI!#}9^De%mcZty5Pm&#jKfKpIR(;4K%iHV^~n)vDn~qqJ~_0S{dhgg+*(GL6C|=dO zATPpiSAF@s_)obLec@jxUF^q>iJ03?e(qC`XhPb5NU+S3eAHHVy2xwseqY+geuvfj zqu<4Q0oKyx$eGt?Z$uWbocm1Tk$=qn*7{e_3Mz{nWa1SEGctH(WP#9xJ44@7(teH~ zYaMQF;dW*!yGPrh&WkMM75R0a1^Y%CMBy8QV@1rjHp5NjuTIgaSRBE3km4Q8K!}$x z24`@eX>Cffe59RIr=5q{_NK-lmL$tI;fHlQHEN~X{3DK9!SEo63=xdbb!pak^gcpeS3pWV z=o6125_@qJoDhUN~8a+22~$buLYvI{??M~X)4Vu`=hUYafHTSA-5)WHi3u%Xf{1(&J2k)1b>;XLN#zD+#*t)ZnbiF*4%{aM`D{{H$2jZe6 z5g!wQ(t6`X7KVr!xe0wZW;$nMUw8_9b2j`h2)``LF;iL5{Q8?r?$(Mr!?odJUs_K!p}EZHd%0>KhiXjXnHtnQkk37EXdEsqIfzR44d%Yu{7v{slP!V{u{Zo7Y z1kVj2fN(jm`I*knE2dzN>q^WwLQl>1WIoI+?yx9%_1y7x`P}hU@%d-%SU2*a8wM>s zFE#=spYQD89mmX?{m7i~tVm!;&Hm&7Zw+N)E1gj)gytazT#C74u7_DypXuKvUJ_c0I&Ya}E=*&Ol#lG^Pq+Ur42KzX0(x{HeT?n)?RAApdZ~Z}A5@ zIsCA%@2chVeYrKAee%NlVSwB>Q}I@T>$WwJ&ySwBFHYsIuzHP)-ncdml~?Og*K*vV z+m63olRa(8-lp8(gT<0Q;bpzaAbO|ylitJMKfonYWIg{f1TGS4cC!pw2dqe4 zb!F&Fv}Ig0Z&g~&wmvoc`?zlV60N~YQrxBpW@7AK`wna#LA3pZc>@2!24b-FI!3J@ ze=+C6=WHIX$WPOUtasy zu4~`LM%4PQ{)i43hJ?~A8GN^y^g$;cy|w!WwsgacNwC!a8i_J7MC}^*lGem-kQsM8 z-_D&#*Tt6KJN9(%sy&3$HJ=eZhh77&7p8#>B9uUtm~!Vb$-frX_a3->UV0st-$! zaV7mjX41OOHoQJ%RYT5<79@#3sBDH?O}ssACar``kj&xzdH(+YlucS0`w@O2=3zZQ z;NKoWa=?3^k>mjGb8iv1NfAhy0eBb*W1nGEAg`Be3OTMzY}$NK)n`ex&GA_OgLKK;jvfBHCW zEcE-MbGz67iYG<=Md~CT;dmOts{YR-SpB!FujUisllS zVrRlS1b%}>J$Dx>g4kV<+e5poPKJ`m`M7&D;^~=PyABr17fEWwn*-Ch>TB>$g}v?Y zbpVoLeGli{@mO5aD1cvY9ADI|YM?$Wu7I%#Q2K442mM|`F6*iM*i zjqj>ifza}xre%d*vx~d5EG4h%0WH(5K3!UhgqE{3E%~~Z0n`#5aRWHHX@fjSRB|;l zujqieIDzv)9OSM}?y?j}#M|;F#PVx*1aM~uJ#wn3Q>wMfqxTiE_V}NH5PuX9z{ znh$}e+cQ?!*5)5Ip(p#o=h=^Jo#(cOBW%d)o)*{PZ>q>!&-5A*S+MD$t~=Mh?p(L^ zD~79Ca|2dJWpGvO&tN}fT%^CnTcSR(kVbQiuJwZ%e&0k^YJL4ZM>U4hS}Xi_`T#Oj zEVI&(B>Qk{XnhcGIdjG2s@s6;eVA4JBWGsLZIpHFE$Z0Kv;WicXqU2**zE8}8XKXF znO24!e=zS&7IndE7;CNH8s*=6WHuK33O(~(B^L!h!>@z~SpRyM{Wjt=LB~jAf6%bj zNcsao|M1#@;OL6afsW;3D(ad~Wg3U)8uwbwJUbNgc+Z$>e=3{K=vOy8F?bIL`|q^IzCXtl`Scgx)Q z6JK=jKqTiCj`UsR;Yi;xVeRoJ{XmKT@$?-l1uh{z5y{dt7@3AYKbqHK=kK>a!cK|~ zSa2;4UFoe|bu>h!x1Zoo5ZcQA-z8BdoXsxGm$a74iw@!PzP)_ZB>bV(kG|X$)S34~ zAi?G_&VDA&BL5Xj5+C=Utot#gj)y(mzUUEK{E-vK^BGOv31D0h+gI)BYJB*jQ?NXl zjqw1H7zfYDpgV}?t6)vu8}j3iTP?((!42k*z$Rf;i>w);GWjw|0XN)bJ@>(~?Pd(H9lxda3Pr1r) z6{D)S%A3he@%;GNEY>7mNpGgf9qHq7TAJz&4(v#35b1z6J^mr&(j4(&5&Ij)r@j8d zX07WLZv`Iw6nVCszY!{PC+3Df;u-}H1gdEq{fm`8a}Xp6NEfZGh>UoozV0KgTWWsA zYI++Yy&QY4+t#8<`M42}<+S3|SX`t3J)!?=$0Hhp<@6eRINp|wMhbs7_f~N^eaxG} z!L9vQnImQeN{AHAu|U$N7u{8hRtthdwJ{x{*R zpWq%eis|io*^56;+fiesh`(aXcc$swm{PamF9^Hw7u!&mm)~Gr&?UaesbYH$(-fa0 zvERGk-$};O>YPV7Hu2YdEfkE9%6N!*o4cJ~KOp?*WTD6&ja+c#b=y#FKtMWlHZJ?W zG$6$;$7F`~V9LjX@wFR)M7N~M=3VeQ?ZoEc7wk=d;%Ni_{`B#)}(r zFU8~LoNsV5#vT%4Kgo|5A$iB_GYmkEff6+aT(^xzvZeff)3n^TQimwFUzNuD_rl-z z%Xs}M<{uYkmukoS^C_gbeY6+R%b)Z!CH}|fpHEd4{ttU^0v}a%1^!Pq7)eOtLXC>; zQ&EFu39^{5XhIeyFu^EWR5XMv1PMt@CJ+@NnglZrBT-SYwH2#UTCJs3F``9KB+$B` zBE_YGE#ga~f{GODGXL+n@4m@o2%`4)`F(!>&&S~t&U@#cyPbRPx#ym{yx{m_$$OXk z=rv?SFzXh(Fo;{>ag1CH&5AZ<>@2tq9)3N;5BY$ z0(3aUUqtTC1FlBy)llPtf zoe-k7_X2GH*)H*)>Mq1{BVslrgsY~K{C$uznv6iadR`?GuaKo<>WF$lKrMQ zdi1$L)^PL*3T9pX2blZrkiJwmn!!*GP&P;e4p7Q+l^mdy1t2%?vQQ-lC|3bFI4L<} zR5bu_YRH-=A1AOjpk(|7L2;NbBTvdrvrlGY+wbPhB6!z4i?;1t&iIotJ>K}}H>B9EsCkJ>AGool^H_3WPYgu4X%o2nbeBpvQ@K!@9^ge({J`gO z(`Mu+_&J2aJ4gRzb<>(40UxC)*Mno|AHYb~9 z=*EPm6a*)Z>kHR+j@hBZ#emqKFm!J9yWQhMr67|W65=ZWlg3MZX=;{^72D1fM4~JxVs_W$;Uy z_kLbz-dolh;r;yYYMhYGG}0MW1Dj`25~vqJt=9IBT-5i>6QwkU234!<(#E;W{mNBC za~W4Y`8mvo{VJVp#}G>~k@>$X$E?#I)eX?He2P`BIVWBXH@TCMlEsQQgk zWU02b(b3+@a5_c#iHs6nMe6eYN}77uM!CZ`oxFFO$+z0;P;a-oyjK~nF^a_VuzZok zKknMAgj{Uhq43?>d|9Y^x5$0a-!F$5?CoE;vO=~m-}qs&^eL{y$QQFC)f%9D_YRN_ zscy$s2QIwrSuO4X7c*8-na3aPsWP5=DQ`VZWHlkpm(C!kZrZaxfT6s;$OY?bYNY#W z8BX=r80)6vM@yEo!l-cL!IoTm!U36!Dj}jdFhRtrQphs025yoT_-tq zE(_@&e(Q#RE|Oy(CZcanM8L@JCooLp?dQA>d#&?E-F`0r;{!HI8RRti2j)v&Ma=rx zR5=u4g|VGDOSwSJM`biXB|PTxtx(a}Je4)zV(#S-n=Ks=s;Z}qEGyKt2Wm%*ylhu_ zFrk*0UHXNEvlRpO=of<}AM+ouvT38@UqbU+^y7|f)nkL}yUG-2HH&LRd#g#PCq`~! zr2IS06zOt&Iq8bvZuVB>XXb!CBH!jyXONMI!~t1xlWxvB0^abi@xgF@guQ1BPU-+s z!$pjdjZ!Rsj0a(JdB1teTJmWBY;{7@7b;|A2_dq}x{ugUd=SRVZ9Ny#Jm$3)BB7~; zxAhJDw_&`>dcS$$E$T#o_j#Q@_l9zxj!%t#EyJLc1as*eN^GP*AWh7Vy}Q=qdZi#A zn`5Bnc3BF}l|rJQ8ovy9dLxCmBUw^W97rtWi5UT})h_3mvXxaWF|koc7Ms%13$nx{ z{e^q2R7LbR3*JEh#BHBQ%BbNi>m*0#+Ms^%wyP?!NtkK4!;C{BD2?}dtHjN2xJa76 zx>D*QA3^YuVCNsY>}`%*1;eTc>liBy9Bf}DpDIC53Dt!?Z^1LJH?0!Ze0;NJP0&82 z;`hK22|Qkelk2Ew+F2(`@bRmHp5neEAzvbRB%H1j zt|wRM>VpYCDMULVlKrTM5y{VFx0##(J)Pb~VUH7;Y)~wu*ZId)6P4XQ9g9h++vjJL zd|KnrFe<_EXLhQJ9$tSt4KAOBc$!|`ypdb_`-LyqD&=lIy%g7Ws(H|={1ar9%NB+< ziOw>x+}ti(E@LQh=LYy7%fuZEDP^#HcK=YWNV|97%B6qMErz}3{n9*HG>s*5o*^)1 zj?z4=1arsQQH4v7NB(jD3i53U)#q|ne!=#hqBzIZyHSL}x!%EhRfTU`G~aT9e9M^O z-D)jQOtX$i$>!K3daSIZ<|j1Q(uwk#w{7Xo2G|*B=O?8VJbf}6(i{oRRRp#-%5cVm z!}qj2aid_H!?7pAosdNz<~puMu`OJiK8Q9ABu`e*yp5}bTtyVmRsyk^J-K|332A4n z^i#L*X(7Vg$d(NT`_0#Bm)uS7M>ncmC=FXNWEEwSH+raaP9Cy`IyvDD?YUHsBULf~ zZFdy#D{D`WE+}wEJuE4@e5ybheEvvwjN*%DTD#voNz{N<02Y^B5XvHRLAeEI>GymK zHa7r;#^qmHkJRUS>r$bvR-t^340M4)XP2|1r<{E1-4SM1+GD~Xy+x5NspYH*CQ2Mx z8y8aHRJi^04TV}qAv-QX0W+Uu89;p25!MhiFQRPDP*Ix)0{(2I)q^th5uifN;$*H3>k>%wx036JFH~> zNiuh=k`%dv-sSJ#+jKV~4wjuCja#IZ`lhN+CfM@{`R89B z15@gcS)G;0@^`4tB{FZJItk5#k+_~YbHh!+>InCg0LxVCY`W~QkI;W<4+|#}nqokN z6pUWB3Veq5!`w}KMMey#8KJtE=6VR5t7G{gtf0%f<;u!> z+QTCD2{+3P1f(>G)pvSckA)FAg>#OM0+zUjz1{H=pqoC=^=_5za^jefj`6Dp=oo7# zY0!R9{d@cRWT`0!)|}=oQjg#~B^a|-v;kiTWe`C>k~-#~bj=7^Wgr&@AF z-Hl@S4@I!>cJ3Z^cMAu(BQ8#tDgDn}1BoObtgB9PMKPE4oQxI8vzO2$ zu+ROFr@x!yGp?vUtW{pXbev}i^g1VcJ-rk8P920Z3S^XUQ3pl|aL>60vNa5>I@>h0 zcar%k%wuMCYFDxQNF8M^o9>V&%dXdwGzGGbccs4F=m@ToJa_vSNdNl|3rPT=XwgiOTv$*5f~pB z9Q4SbzetPBV!tR`8*ZVSd3XmwW!x`?grEA#| zsb+y>%a%97$=l5gEUK~~&tK`9>}R^xctfJ2F1E7(ea&}R@l{c2iyMBLlS5gc#hk)J zHI0H>MoFG;0H}PdqXVv}>_kpjB)S^wN$8o-j8&ep`Q~3r`ug4b>(END11T;7?#89v zAq-8pS>_00ttBBW$)N^LP@j1}O;1?&A5`6+NvUJ77SN!4=&xI;1%J%xX;XX`s_8-w z%4YEeWvvr^W7+N$sOuv)IVk@HI~%It$UgIuCFITe_J=sq5;M@#xs6+#S!q9C!o9pW z4BO2VA@J_z%`RET>7c^;hweWoO7SLNAKrg_PfA7k0MH@NIgKB)F!1aud4Eklx5-v` z+R%M6=enLtbVX(0@cXpxWAz2JVEw50Q@o^1cJ5>p-;6oS(=rY5~+ zI9EpFz1j3$bms{&FY}=aFgnq3HR%hFccpEu`*7ICE`OzpOqN~zmj0F_S>8sLtw(&1 z%{OkK1n!kUeqH)OK0(O*N_{*`<_t2qx=@6m7!Sbn(uIbR`w?P=z#L4NglK;ZbgP8IgfOax#R|EF!2$J zCPLGSM@_U)83DE)@8)G|ZJ(eDgDTYXsqX1}Kld$+8?%t|ed%G$?(HhxDGlcxwB1`v zZw$@En(s#(@+vWJ)KJjQ$h(E~nBxTIHCl0=m!lR5h1B~j)6e!VW{1QU`Lx1O#4fq#;3 z!}aB8`bQ-g>zfZOKWh-d?Vnf9bh8yS*XJ=RdmF`ngdeJ793UZ^jrEQ7V9aRbo7vGD z_ZaH*aB!Qaj1kE$UmqE@eKHPTn&|SnkdORCGha!wZ!HC?)cgGq?-M;i$VvTtR(S>3nVX53|6S;t*uv(aGw$ydmuhx!# z#$LI$oFR{mn_Vv7m=jF?<5c`BgpOl4(R$0Q3O}d2>ZhnR0 zGkhkrG}8pqDK>tZa9PY3ZYllojcbSzlnV1iQTD!md++`p4PLlN;&f~9EtBAnYVh$Y z!EOzHzXYlVKU)P-d10dzgckp^gerz#uu#%f47bH$F@d4t@OTJ`7KbkpVNIe^xlKsA zw{?bOq1yUEWL3EoJL0}UH+JbCU#~5h<&G_lk|@p`kres4+Eu@h$1RN_qIB~{k@WUP zX=3@&7?odk$%3$08ikl5^z!3zW!IxrTVX{~;6r*rd*fP-`;=pmc;y;b@t)xQfLRbm zhU!?-oHs>V&AFB4+=QBoS&HV8C{~1yC!yDNKi50u!ATc;p-lrh%kx#zSur@&hRa(a zl*3{9;+u~kSdIM8i36yZo+4|e^B~D>Tr8Jo&5}o1gb^pz6kf8B&7`N&sYGt^8?J$` zGP))-zKCa#vQls%Tf`f)ihdKt3nKgD;L@%d+?yv7U(2yoZK-)e(^rTy8q4i}SeU%N zf&bk8r=>B(onomjmp>CNMjcoYVvtKQe~S{%^(}C&PZx3&VOL|BKEjlgo5Pf}_KUpp zdq}v_7u_X%uZwai37=(&f2c~6t1c`F&s2ey(%1ynl1wh7wba=`Pf)~1jvvz%{Dsv6 z-Utc4me{QMD4G6<+Sm%}dK$gEDhkwgiJz^C#B&3qdQwImBCc9atnp$o2)K{K0fyV$ z{<#ubSK9W3rB@M-gXy9bh8jw=dh;s*XJ^)ZhsodDf%aqHjd@13wXQjow5%5R<8_jJ zzlJ-$M+yXly566iz@%uOn=n-)nWFjR|F!Z2IWXf5(YT98C> zd{P(5$o)B8Em3TzZVv=#unyK?tZn>ti1@Jw1sM?-7=&2|t0;*Y4X%?Xre0PHh`#9f z;EP~8DRq7?)f08To&MkNJnHmm!c5TvydQsusFjWZ|CJbG&oJVzzesh9Z^RW`0Xyl# zi3$fox=#VP?5IjU_0&tZd6xI#HN@$tBx8E-&!~5>_nu1mI;Kg0_qlG@&Hfc5Yg@-$ z5uvb<*9dv7lWQb?ySa@5_+nni zKf=`$h1h1CnU}9KcAkPhk$Ftkn88mFdPAl)q50A?nql{0FcW>zDOtW$Up~{0bf!9A z)@{czG1jV@celh1Y$x_YXcs-F_-B4uNv;@ieAlYoo(5$UcC0`w#Gdu;W?SMdA>#-3 z9i|=onXL6;EIQWym(x5Cz^PUJsKR_u0{_n)l)4m(8V&%mC5`PF<&?QWJP z^I5E9vZH+?AHUzg${6>A z0Pnvu67JkAcDpvpPgWyizg89au{C4y#&~&k`$udyTVS-WUk$IE$$@p%LRb7(bX&GF z>91dU%Zs{y+>R5eL!u<)b4E8w?Pv00>KCO?-qtTk67sTsIfa)iIyUl_G1b@i@O{Gh zuckF`o3eQPu#aS+0p`VYfM$G_FZBAxCgZnrnzzyw(oWw>z>;@q?RJa8TnM^7<`2Bd zPr176RYCkmu84){{JC7di!lXu(xn3Lh0K4Mm4I}AFL{1?*y{FzD=zj6KN z6Suf!6aM&KE{7NbF0KM_`v<*{Oj4K<0lEE%n?R(jqh0>-hTA*a>Gqz9j|*90oyt2t z$sI92-PM>q3(K8K`Nk*a4tz&Q{BbxfCnmZgu5?*bM_J3z>lmt7iBc^7>p*ve`4hwa z33Bz;L7chxWLT*rmqN^|x9j3NPu25vxwM>%;PwUHV2UZGSKWuIL2bWoa6b91$4_M= z!VYyG(H3hT8Ea+AwLr2q8z$0||A7d$N5Ues#?|m+HlCuZlZ6=s?jg|at>Nm;@h(Nu zK0aMR?|6gYSCuf2PnEOTcpfl1)QyxSM>~MpAaT8i8~5~XJRF(Ow4S%d!%?2o8xKdU zZ>04YKL+JJ!Q!njQPWUY3 zIiDKzTTCBCXC=G6)hTXoeLiSP-fy9F-S+fZlmOYNujj9tAU3G9wt@=1*u>k~AQ*qX z5R`ZA4_x0$dsAX*^C)lHGEv`uxVs2+w!+@sP8 zSw9`dC&-b>;QS|CKD+!|q5IcF%j=`=+i~oxQ|#8+b=jC3Zym0dvHEoMbB~on%L^lE z#Gd$LC635?hMHHGOA_y?GK94kN~oVHc7u z_uN5>BZUUzl?PGC4s+}rhO&*~pX4fe(Yqn#V%KrK|eKL z;+-2&u4*wDj!8ybQ!MajI?aDk4Mc6G=C&>W`E!G~no-1JJG_eC>CV*2|% z@N=ma?sRtMU~IkuR+cbNEX!!T!En@_7kX8@a!yisw(^&VuU=n}p!FyRs$6CQ@mZ(d zmeH7bN(eo*?yci{i~MXLOb1G~w`AF0* z^k20TyTx1UH2*zMeUy-?PE_YFT3Ms7*Vp@YE~CFAx>yI&PU5|w8>lop9}U&#-=V&r z&rLL%jYQ2EMjzIn3L&ig_e+~I-{ zH>wA33Vv$nvL~)Mp00cJH?Y;)}C$f+_*Wvn_a~?LI0ril;d35t@Cy@AGG6_up}e#>lkn3 z###Tk&(C4`Zqce0uxknd!bORXau z9WlyO$s%$8xTh`vsQO+|NKtHt=y8C3(ZO)l{zrrl42J)Q_#MB;sN%j_^_hxP^Klur zyxG;AOReRihpZR`r^nUZ zYia|NYzW&zHPuUFJvVV&qvoS*y6_KTgC;j^v$&fRwC8r4hiQ4?WVXX|Cb|gmWRWQ1 z4iR2n>5^)%7uPtcMQ~IzOVOFMm|4lSnC|am1a{u8cBS2>xD_*z zM(iqa87_L#jgStkPpO3MpZHGWQ}z|Kgumav&g`bI6J}ca=M2k!@thC*i)82UT#)Ni z9n-!V{%B)uh{eb%Vof76svr;%KuN z|8mF8nuvtv`yw5VH4H?B0=amyJp$-VXueyZbxtp#dA7V53C-sVOiyTz6xfi^Ea$lo zZ6=j_)I(%l$)U~Bt=ux^lL3IMFa0B%5f3#4$rTjOsUqwWubb8L?hT%Ilo3U|Z>to1 zTzlo7QC>N`aKf$N{H!bW7cri#iBArS(gxwHw-jSi!+9S=d^1`(SNp%e?Bjc_!WO-UC@_H1x zdY%Sr>nY}wt0ZSek#q5K)N?gz=kdYvhs5*zN8uS^6oxNg_HMpiyRZ$<;S)KR5>n=gr_ECx;)rnkp&!u63$ol3o2l2da?Mkp7VSl5GAWw=vE2@K>y1ILgwVeNjl$N+d~krDo4y zSAbhSd3CZ~ALi5dDZ9Ph{Lg+V6^KWtN=2}Dd@(0ViXkmF_;L_I1K@=#i6LA{X!#QE z<;vF*`EItHQW%rLJoR~eKnaZ>NHhAm_JqX_xpGzPO5ZieQ-8eE!=>ehb(p^Z#k}0k+KWpz9F&yl*t$SCvojwM08 zF-_J@KEaQ|!JM}ecZEFf33*obsZM8W2!4CWb3w@StdQsOkmuBp=k$G=^iHuO3SG#i$62Af-FOu-7&yKK~2V2osF% zq3h8A0W11*5SV>s-r(!^a*YVdmZwgo{B+8@JHUGX{+a6`wVZV0X6edm7hvlK)kT?i zX66e`)&OV6sINlCU+eyJnX#I$UJM254(C=R4|`wxZb8nUEV(>CY-5>RsN{LC)mm=|Ou@b7$;|Q<=QH5D%+-)(q;0<8JzuRt z_;Vt>nfc})MV#fkbA0qqzIhpwBgMd$SvQ3l!X}wdUUB8x2y(QS7h7d#Wg?V&uMv*O zp&?ch*;84}1kH?K_UhvEE-v3Mr2lx%b9vWW9qA{oD3q{^?Vv7in{-hIZia?kA?F<5 z~oAdI+3SELV9!- zG^q0V$Gvy16jLv__lLaml`eZlc{jXUIZ`JZ@i9%<8Or_S+qgC&?F-+@i;r{r<4$&` zZL1mOO53^cIBK7){19$`^vQCWuYcTgD)}u~&BHeGkx9waTxT^?^7E~7(+Fo0+RZzV z`Ob~%J{9p{$ojarcC2p}CHWR3EmWJG?s;k*Fk#(zu3bxLJlxCEzwxlsbFzHywnmsQ zJtX5wb&;vGCp@vf0)9RXd}O%WUrEY*!h65@-b7`kJZ+tY6EW*9TtYK{5@y2nN>r@& z<@05ET)Us=uQKFLj^?#guR{)a+Wr#R`W`I9qu2$?2x`18Nv=d_e2x`NyMVWK1>%H} zK#UqY(9;!|Vg;sj1WnXSf^~}3r?phzCM>8Ou^i$2|5DA*L=wEoy-E~ zFt+hnb{zM!q{tlu{*$)58b>>1P0=o}m*}!pCwt7$nq9g686jM#l$8B5LaII!j1q{h z__>1WE(l%noH1kAHv9s^Uh6tt`I-7)n|KjKFR?*8+2yz9$|WeQv(X-4o0#B>CN|%u zQ=+iH&L6@znx_AD*|W|h+ab52$Sh^QIiBeWN}tfo zWVk2G26_IHXfnA1Yy0iGH}cXJCezdr3owR1Wq#WEST37z(j*(MDg4I#go3C&16f`e z{Ji-d?^wqh@)ZLxk8rn}Uy1!JTc9zO402==`P6@9|I)@`0lsbN@?{wC0(Pw=miex5 zK^(i>GLg`94|7bW3I6L-NfvX~CB_rmP14NOr0Sj5-&Op%3olMSCkuMXarXb3egY(I zbv?P<%^=f>dOD%SKXF$kG@ZxjD@zN8#VVfEyj#3REOOx$5?3L$z-yJp2 zFeg$+x%dcQPzHB5TJD+@R%{lWl+o}FpNoByTJjW=(Db&{7sZlJTFe#_b5%^kioz!? z*|bIy$>!e~rRaACgAC^ZG7ane=|rE~U_@GBxpB~&>3LlKhm38d0c4L`)D(grxAtDi zeH*(`1co_ULZgbqg2V}%X#SKi;Q;5Bk{G->u=Ry#3uKc*iAcgVL+#*6o0y!i^cg8X zcv=C9jy0MV$z?9-8L=hjB&Ms`h=yH7*?oAP%c>>c^rJF_`W#s;)hBiILT{9z|7}_k z2(fa_FD6g~jh17I0SS?&HFpytFCsUv+>j(YHc*PL{yot*RhSgY1v8bF?06e8S%hY$ zwP--T`Jl*7_%5IxsN7V^^GT6~Ht;$03!)gJE}$oR{L zz)qr1H%M8!a#b6_`sGlvwD%L5c1V~nk#59Doc89D-@4L1S@5{(!)|}yM-6m`KYBRh z>~R#3(Kic>x|`)2%l;u9J85%|y!c{HDL2H|fHrf94zmr1n-~tY5HJ-!D2?Ka`NJG& zgI)yon0xSC?Kh`GD{!&&cY05%=}}M1l-4Y94Uf}mbXP*NvgB|=QofL(I?MZYp7)?t z4{JyBB!fz({VieHH&W%aPZDmfA_}~}RjTHWI3zRc-DWJ}g|=eTj}NuE&-~M?5*_6**JxQe0A+h-G`XX0GR58mW-F+-c9>UU*vQw)o*5v-Sa#;m#neF_)jRlB zqMJF{kg-Ix+l*5U^0-20csH+4RMGaEE66j;Tb$G}Svna_$~K>b#?R$t;G4~yX`I9= z=zn-^&y)d53X~$ycVfpV8IYk~I+zC}K`xg?Hg3n|hipW3?33|zLmI@-%74Q?>WC0E z;2)RT4+`%$n8`oMq{obt)T0NSXhol5MIYYrTcVq9Wa)J%+dufVm~1ajQ;Tt*F_xAS zE6X=Iy4w(1020?8Rzq`>3eW7%=j9Tb4yj_eedDH=8jj8jW!{mETPVXfJqfdso&T6n zn~*OVS6ZN@!zL5o!7%6c4j5qGJ)Uin^ZF+&{R2n_=j9~BtSuS92c@|CVX}HUY^?+2 z3d^lQ3C;R2Q8L&X!H~n9Wd^2?Qo9Mw*9jX@Lxzk*Y){%Exr%}!S92N+`c6eu<>Mm| zB=w9cyLlZiQrMfBV?sVa>Af~9$n6HY36^Yi`ITlzenmZ}*8X7*Svq_DMIb1rhzmnDIXA9ZPs{`K;J#CLz9QD}h}3#$nWy z6u!9Uinzka@?M`LM~bJUcrL^Z9K-lKB?TjpnO+~6Rh;39u+$@1UmV!uWnWyZEA90K zy<8FK$m3-+O53uqosLMZ4t*9z>U1FtG~^TEZCu#(BVU@yT%J? zmR8a+A3#Z1Jy%|(=UyXfgPyD2Axoz{%w@t>kn$pNQ-G?|ny(=eBFz7mKI$J=e43s0 zwsbq|M1ss;kV0@eE#LQgU!PWtS(#5;$$Hu;F8}F1UZi~*JDqYEpN~@?4sbrPQ5|Je z=OUfv5-}aYJTIKEenr*Ag{8Hgnv%Ne(Z>9uii)aYqpWCdMQMrQsWQ}ik*Cx+yUv(> zt*5khbhmhAHKnDajUtbybbhr*=mlX^)>Tv()m3vVJ*71cm3~dBN@%p9AHG8lDxOuI z?^Q0le4%jC%EmEwrSx9-k2Ov1K}GQ&&-udt#`;T+yXTW_xBTXm&GUO-I`iYP%MV^% zy}6=e(#VI3I~I@I^V$PKMKC-HZ)QcfL99*&BAeb?PYhWoLBm{m1-Oi>{h}$rC#c zo;rBOEA7p%H!eFpzis-;iW5(F>`&gfW?l)#QQ>u8%>H^<(R*7y+*W$aZ!g*Rr;BGs zoD{wJrlD_E^eVpnU~@t7xP<>EKeTMq=Y5_24R`w1Z8a*#G`4-@xGHh3yI;${7w*lN z^~N9H{MW}d*Ub4%TF2gdUfmlt_7{s9dQaF9Jt@w8bM@EFeP3I5`mG)Fp6K(CG1&X- z|E_sr--A?di9FbxG=;^e>)yB(~_HyZ=?O>-;qbuQ;x5=I-nZ zH_u%BO5dIDG~GGvgUiOf`tS)4UE2Cc%A4nWu;%j9M?2oVY1h{MhvJnJM${xpVz1uk}qknDEeF+Oo!7*!b(V$mBPS z8&7n$#1v*GE-m@!;_A8mls^VqqF$o(~CCk zY5wPb#|0(B5b7`*_jV2Z!%yGwa=BUjNOu-t`@qG-ZzX!jZ6~sBy%t zYmU3?g_K+VkhC)Xy(td=TTl1BddY!1JF*6ko9`@p=;PscSCriL&cP3UA2G9d-^9&( z{&Dbs^~xPi~Z;BN-1r=W6iz|lO3}^jam8LwvX=YRk6Bn^Ni~sia0H0 z+)c)&gU*|7sqj5DV{^ji{bw$FdCQw?OZ^$cugdRu@`Tf_88PtRZ5w>|8{^h4YI*9b z3lc}S?>_w>vsW}_uK9QUS8rC1crxRogq)T+f9RXI_pa@2v)=lp@vrx42S;b6 zK5_Gs_fL-+{%CW9v(Vk=_b2V}-nMN~-+$b+_tt%5uZhWD*s*lp?=vFLeeca1`zI#G zZn&bQrFp3lx9z32<)5DYMEQ)$!JQS4HCGvjPyg_=<93uiHQxRHP513BdU?m9e|{eS z#k*H!7hPGpa@(5&U%%w?6V6<@eeGPw6yM`({@xx)nfleq;~u+g=0hp7Z|wW{kiXt} zLBBCG|MFz@<_nkopScEyuymPwVqnio9$Rs z>!_^qKfNe6rfnSRPTKGH)!eFl|cg(Y?K zs}EHrD>Vs~7dy00Nb0O228+gf_k!0IhL*gpa9-)PA;hIx_*6>4TGe$` ztFExCUUhcG>PSJ=NJ904u3KGUSLN!u)y{geYtt1Ltd61%t>6&5bi<^kLu$)a`_C_} zqudghXws-o5bmhCfSVa;5R=orUP4-!`~cm7;aMo5HXK~asPwywCi zw6<2>={}y)YDZN?iKDV~p+i_>b)`ZGYaL}3MRRH$#k%vB6nTm)3&&=JRK%EHSL-om zml|{E=@?&zryR9XRbx=bq6)Fkt}Csn8lob0i&tD!Sy`oGRxKdfu#}Xu&(;Q%s**?n zjc!y{Ei|Zft&ul$0?M=u)|b`}GO7{(+ESygnqrk2*H+cl7;`J<8dep;(e zc+jWD+&PuPSz;JUo6fH)DJ2g2%a~hBjvhmct*s9kNG*Su?1*52D zPMu^Ou&CA$ z>-gHy#@V$*$gZiOK_qRdycF(RV(U1(waI2`g8Z9anKoG17meiHXyK2JZ zvrCKx6sf+tv=~V=&Mq0K>U}JJhx0m=7Y6eOsZEf>Jr~C2w`7H4EvmWJkPgLv$1dKt z%7aQp)m=s>OBSY8&O=%&jZ($$(#qnhI+>499Qd~SOZtlcVR=Zq*n9}m z2;ujVx9?F-Nn5oRpFs}Fsc0C*Kvl#LF|~`NVsz2ZDMd&O8MY0Kly8kh{VuMoxE3KX zs>>^1>r*o_{LiEf9aQCnUl{T*Yqij*Xl zl`_ItSL~^)DXkr17|FIUsrKz2MJdd=wUy_3j0$vHDP^jvn^S(#z#)bs(;70xMlfVF zwnhq(nNZ7N+}X7vJDze;_=9VU%1RAAzV%Svkb+iMRaICGoL@yx^DwKh3y)PqXDF=^ z^iA}gEHFfY|Dua_umu-v<7E$KMM6mhkuPZGk}L9f81Q z{AKYsl)qE?i{bCU?Sa6fD@fz6K;Vlz1A)E#y~5vm{vP75mA_GU2Lk(6k{5r^@b_E( zZs+d?{>u52kGmX)m$*0H$rxOwz1i#+mFRGsb`sC{O^?GPdAvc`0PxAYv*|B_z85h9 zTqEVkKBr zU5Zg!X#{gT3f=s9;#L$&I+2}sNIEh%vC|5rklaG^n?DcLbwol+Z<2!QCO9!kje!yC zXb`$Z{s!84irr@9dc+#l;~k@IIhxElwH4)(qL#wSE$7wnWf5*J=#D4ponD<#4eDwW;!jM);PP`QCwG3 zLuYq*sysy%j*_a%Qog;*JV-jZnqx70C@!tg{oO$wW#FHLTJls?k)D{j=qb@rLvWMS z&z)a4KggtW&n`I^CNf-MjmiKtP0i#CTWbW>8x5q&h*3Mcl=P$x5J}3wyhCYWYrs(2 zmVm07`AUJNKOP7qJ`o74!liJmsl}E$MUM#S7S`0pzT>yF|{r&QTdAzV^7QUL`H0JW>KN$zz|1h zdd1~+m6%X6Iis~giGuYzARr9Nb zjSTX*%9t$HGlF5)iKFW5pxPCAvb40Js~fcT?K0XXjfiVV_IQAxTl4LO`eul=*q>v zB#A5Pys5c)Ap~R<`kK}Kl~u{m&`Yy(GB2Jsd1^>%*?EOiaxV`_aOzZdSMcPECx--O zxZRFIMptY-F*z8=7S64d`91zO)ld#}&Q$4FE*ZG(mnq_4v0rE?I$tewI-FisOFNW+ zSYx#%jYt1KyS})zv;h00pOfrJ$%MwPO~M8KrIXO}4T5TYHF zfv=Z#jAYRlWsc%^|#|77uFCLI`T;MAXuqs(U$9%~(9zrBI1Eez7K|o7unkxaEFTjHv;dRF1_En< z$-s>g4m2fv96A)+r2azk1GWLHfx9jW1XclEvS0};0B)CXpp%19NvvEZ16{y$U^%b= z*aEBut^u|Hw*prIO<)`FFmO9CnblbnSOCOSakK!FfNj7O;I3>w-zNAR$_*@F&&hVd z10C$EPG+lz0W{fdk`LU<9*J^b`DE$`EMT|JVPG;lrBkrG4g<@9ED2LdaBCUC9bf$6k=QU&<}TPjHp=&Gi^z_x3s@A2SkNC%iyOFF=< zz?H!AI`{}&33RZde+@7Rco>)tOj-yZfv$SWC3v8NO#?~SLI-TSo_v8@Zy-Hj!D8ru z&Lxyz@IV85b!7wm0UpNwUI}!ykT0+R=wPo%xetB-5Bq6vpcC8r0MG;`{e*gBQ6HHcoIIbttY7sI$%Ap0JsuZ4O|0k0k#2G0S`Y#JfL$u`2bzOD--Hfm?m?fQ?NC3uiTXuccc~+y zJ~867xZY0L`URPTCUTVbr_SgWM|@&VeA2{(*oDpp$3>@(IdAv?O6G7#{4D9&oeR32$}8c^B)_ACOF17Q zynI9;5XrOsll(V>p9Q{Eka@v+`lFUbM^Xcvj~pMLbZb<0yy1_|j!#||lM$b?v{y!aYGd!5_*s$r;#0HYQ!?U{ z$HyBG5@CG2Q_4G&bdp8|0wX0q{Tl@IfKLa1vZS98pSUzKBR;7yYC?Q|lrtheDJwoP zBiN3T&V$gWTo4G%*J%h4{4?NNz$<~!VIzP$z&C)uOmGy(ADJDWv@FUMZ!C?bn2j+x z@hR8FCuhYQ!0AWz&ld$&j@Z( zeBxwc2!1AbCwPV`m7b0FfKTiJzYM(CQsMLuf;W1=KLb7)Jk<^UB;OsH{;VL@;@5}Z zQ=t#XM@Q4%;Li!8?+?BlytJ9{qnLWRc^m=00sM)i7a|`tzaL>jK3qZhm=HfJ>iEb$ z@u`SRn1tl0E+lf9gC1b)x6qd-)F=!D2CV1IUKKYIkaUC_NCbgstee2X;F4Waa9 z`AJ!KNcqMF0t*G9=T~^0`aoxrQb!PxVA$-Nz*q*M&{ZADCrFl#Ws#Z z2g2yQrM((^&yH`6SRQ$6ls|e|Ow@T1M>@f=qme;qg);mjr1uV`l}QX)=j70^9xo@!F4!=Lw?+%jjm zBoO!w&yLIE)3qGmEV88PPxxWNUzcz-o=g&=$Q5Doy8^nkm$FM!=u~^=NqbI=PgxLT zuS?6D&aJihSyL^-d)60sD%nrU#C28mWl)Ggr zdbekJEe{n(t2a9wV~IDFcpImqe|0>6b8KQr)ME_nA-w+YGr%!w`sGtg-q-t~$ z@mCOkPeC9cW{3R~{3GCZfoG}}{7L`Z41PQKcLnQ~#?OSQan9R+s9pSHI%zZ%%;{HYK4?3v zOK%ZxX)o2D!jUxU)(b;8ByopK5>bE#NN} z>}0qf*%(Eq$0ia>#`;NnWkI(Vx}OBw3o|gZzfXuyk3108T-t(`_)U_332R(Bz8)7D z-mwDoNHihdnG+l7ve=v@BSlyKn~C30%KDk0y2ih(`1C2zXR7hu727qWO^96(?AogS zD4GMrXR4{}oC0d+=CMEc!{AqlywYyV#f}UeHztJeKR@d3p80QC27^eVg7jSFfk2#2 zZy9EWJ^n|XA(Bbq)yQv+7xzM+e03nOoVf5mMfi`P(d!rooZ}S-B;C!>wL+)r-`)O~ z=E{zZlp0w-p+5+H;ymV#g6d9x4fO8V$QeO;k%IyFidI4Yf<=#hy&^u}Hh&_Q6D2oR z_~nMqg|BEvG%t!@YTlsawQJsxDf&ljeaE+`AI1NBNv{B3Q*Kb7h4Ej>znX_+kzT*3 z9_8N>G$sF%UM>8Wdgz~&I~reCKKO)SK4Iln`Ao3NJuB*9&+Tlrhom=^^b!{^e)k|Z ziVt1=c4B;bl&9zPta3|w4@&v!DR=ksb~5$sCBZR<-7P??5L$QOttiPqjbz1K?`~nSosbpY(Ql@dewN0EKTJ@O!}HN>%lluKBqP zya}G-1%J|B4}w1czCp0ckEQLf6wI(IiOf&ZeGxj>E#2d1f!_;0AG};fD|}ie_V`k< z#~EK~Qa$Wk9vj&ne94IoPDF`hr9X&F3Vhwu7dgoSKMTC%W%V~qt!0sAQZgx53IDYc zj>|px6Z|6nlW!tN2eB6Y3QZr{K0^Np|F!f$zZrZ3_)vOj&v(GrgO}?KdmO)&9BTbF zD{6H_PhzOcCixGd0*9Ar|BS|u1!hUbSX-zS9Q?gi>;%8~%a+M}XQ}wh8hb@fSCWW` zLc%C7#8!Qqh@VdU&~}&n?gj4xKSEJj{|Wwa@YUes!tgJGF9$y(48IrrTJWL#k#xQS zzXrUByZsaVNvwUW3QJ$)a1i*F;46gKEqWEBkojx6(h7pK?3Ss}?SbxML1?>Cl+&aT zyHWC41fBEN?(-O>|G+!I&kTuQq4QAnCp?{S#5(vB{EOgS;4yE4Kf&+S^p<9`f&~8+ z_*Ce_m8@_`OE(I0(F?f34t^ooV}(@~nP?UkM|1s%>)$nWRxdyjJ3! zB8phekMeGflKE-%@<pBwXo{iK0g`l^#LlE$dYRExDcvebO)R^IE7N-UHqMA1;r}G<~Q%O8yWlai_WFivT`SlPWg zYWyB_3iW}0rIbVY8A9#g+u)T;*%ecvYrQuR7$@m=*&n60KJ*a2mhdtO*FTZRW#FB^ z>RwLi4-bNOfWJ&=yV8pkB_i#+necSNOS^}6TQ8CHKZLFYy1_z+>#2zNl72Lf>s8>_ z3SOr#eyMwO_yEFFey#PBvIE>w74?(&SvtJSPACb6OZiF&PbdDp5<}S=m&B)t@uTdc zF1vIYbZyW*ehj+Dq07Hd&tKePzu4*Fp~EDTg(S)M9q3Hx%wwb%%|N_%)wk14C5=JQ z)!$F~w0*ElM@ zkR<&$8nfV`K;Rb=uUk76!B@+)6uJ@6ZT}8*Goh2U=Wk0-`e74v8=<>i<~JdB_Qr@? zqn1ZT4G|4x`#VKHJ`R22?^%Nlj_Y0ev1^{G>`QzAGC}RZPScjMq!-P^-*`9>cq^D* z*gUh#UX^*~?X!^wkrVpFCqm+ijl9@;Qgam5 z|DkV#K6HG9m5yi@KG%YGN&X~J4Zp2fizS}}2;W1v8jrMo5V^Z4q+KK(H+1!X4g{*K zbW%hCWyj)U##gZjTm|7<37@X}&$s%s^5?BR$ACmu?$64nQ zhbm&fT>LLb%uCe#^WyjeQBm__ddx~mj-)qM_6R)9UhD4j@-Bae8mE9_S5 z<$qa+f8YLZ%hygF|7h}gto(Z_v*7IXk5#{8mH&Uu|5);SwDQ~dA1WWVemhqDWAW!$ z^*?0SSlyM2zO|J!pc%FsQTp=rH*jPN&fI9p+R{5^V%@l7I$Y!1?TKCZ`9jzp$v zdb^%SQXGkqd`9bdY)w+XhE@w6t$+T|d?x99f@>f;pG2K+I4IEcw%!R3@9ACYGc&9{ zHXTdOJ^tov`lIQCo+1ftjgA+(w?SwP`LBoH4L>lSn{>SJ_DJp_4?#6(`tK_Tx9E7` za+~shIG+_dpU^!dl11uK^0Cq1N8d~P{8r}^y4OL{%CHj*gFlpS>vTSL|FM%DZ$E^= zAKHJ~bw1(xATum|`}K#`=k=qskIPOt4DQqP-?x1}J__IR!_v2314k*B9o`cZIXF>| z_jdcFEVn2NdWrz=-%{odxKU5!#2&<2sy#2XD`#l_f-}cGY`GogV`7~lr zzaPRkDN}*Yhb?j4ey1EIpC8(P=IeaI^?`AeeA?BfC+^njR;q7*5qVpr^9hb~I*R%- zL=VxunqK1mzx1=mj}2M??DuW@oh|+9w@<&@dMR<9g}3YP9Bjqp%Oq-hg8dawdw#O! zEQ{W@w-U9W+T&1yY@pz0kF)kTZnulM{0tRtH{(`a9v#hL%e}o9&NV}k2k{M~t#^BT zmHQIpXU~u9{JzoKD-2D~d`;EI&i8onY=;Z6onY=;Z6} zxK6_@8t&9^pN5At>{X}p*YF$-M`@U&;dBklG+dzJQVs9YaJ7c(G~A-$P7U{Icu2!u z3v~V(o}=L?4RbV{u3?#m3p8A+;awW8)^MGMTQuCM;XVxyY1nI_&R@fGG#sU2j)v1U zEYom-hD$ZPOT*O~uG4UfhC4Ofr{N(Dd)4dwH9SYdQ5xoGI9~V!?iv89m$VMcFQsHzb7nw)eYV4vo&Gij>T5EUEQ{@ z@bs|o7sA3DbhvE~z7iJhSkgWJH^ahb>2N#$y3IKRPUYmJYYeXO-&c z{~t?!CxxZIz12#q;Z_ZQ*FEi7KI{Gemi*?2l`mX=XN84_%kMQ|;o_Mu=?@mmJnjuC#}F~T1?M)*_52)E09G&mtMbF`5> zZ8n$q)(v&bS5K;p5kp1|89sPeokETrXuYcwik8;3d=KdjR+{RxVh_m=0vG8pIqYT8 z&+=MCM;q8J`Vqry`c=1B^oNssNF0=#zevZ6_Xg=7v*@-Av0$~fWYjG;pc<~X@amQt z>#^JaR{qZ(u+yvlrxkp=J=AogwocYWI#zvd(XVE`$flYtlGmCzk?J5e(!J=O~*QVe2wM9^H zl%dq3e|dpTZ$wxH`P^1bJ*IyjAIi1LZ}hV0XPg{Hs9&x0AA7;3Z#dne&q?T+elL=y zCmruRLd=>{;Ur@dMe}pXR(Gz&QRUZ2| zzfkdd-412!E9AM$d3?l6a3Su)6DjWr5rYY*tZ_5oh4bVH5dn%9_Y6rolk{t1+!{*d zJVn1I#kqv|RQ+niy+Y#7)AVa{ob+F3fBl*gS4FPQ)Aeg=+}-5h{HcCTk9&_QIt~5m ziaQ0h>^wui=EuDbKb>dl*Mhhq6x=x=A{K1qS+nBeIfmstC*pYZS|0bB#7)*Us*bx7 zPpNZ|e)YsXFU1%V@eftO`nZ6ke161MUZc)xh={vCmiOTiuc-H%BI3|84(Eu7lOc;b zt1%)@t_Et z52h)SoX-eLoN^Vk^Dh>69L@r1l?@hioX({}@SN4!iO7XqZP~{uld@po7A z4}~3PV^4%Olb3j*?cb=oK9; zH|zCsMz4V)G2#whju%cra5K-*^87m$@eK)(v; ztFRR3EyRyoe2scbJ%MZT9dS!uQg7)e$QLQ&8dj?} zm-CO*A@0V{)LXuDsFdZV0%{O>R)KRTjTG0ItlnlhM^eJLCb|DA@~m>_*RUb3`C;`| z?fhCwwsefDL%nma#Jl+`!bI+!PKns^IR8hT)e_;XL=5BpKf=B|JgOpl`&MtM^zHPP zg$@DIAuB>4fIxsq!X6+%*ux@(Rm2Sy0YxB)A}A`jfy*c=qo6a2Ix3^$;5w)?Bkrif z4DLF(Fs|sheD8azx(WXA{qj7yx8AB#r%s(ZwcNUO`fjL%gx=y!O2<%i=(3ptw<=vq z;>&LpxJ~J`U=rH+g1{Y0PlSnvu6SMGE~Pu5@}VnVmV$OG%~>dPRRDFMJ?pzD#-`x{ z_bJEw*#NXgpSz$omtK_#Z-e?Tb=ZXV@s3enfRMvfTbkTh^*LG;O%S>rT)d6yJ%Kr) z;kbLpS(xi&`~@7MZr`@-Tc1G?x1Sg6I5gL@@%u9Yqa6$>iBLGqvi4Gh8kU{y^X98z zNXU5^5;-~l#&tEmZPV6qvbxiTGqzX2FFC8v+n|Xrbh4@^i5!lejeAz#WTgg&p9KYH)sO+LrV%R3I?134-J58DK~?&DNSsw`P_=#$vSih?O1{(dQkyO7+$}vxh zE(Yp@u$Zi|CT$REaR_;Wnq1-BjHC&NCE^c^c#B+TF)jBS#KM{THH7oNM!4GJ{im8v za}#?ws5nZ|T8fh({FgFn(xE$0xcA>_aaf6Ow7^3yXJnLRX-@PZEk5cA-ADdEs+*XtxWyZyr?U5FH5jUgzPzE1Fc0r9YN6o0-q6<^ z7k*Xi1@H5Q&SS+L&mRTv_lD4C9k18(so(?NP!X}u(j_BtTYWIveXxL_J_Yp-YR)6x>(GRuj>{!t6|QX*6K}_Vi~)10gkEA2XQwrO1tR=M zTrxOwR)mLe3ekH|Zg?o!a_s7Zz84;LRC-iGSHY;m!_9!0#83%Mg-X9fuAu%FS5qvf zrQa4SC3@FF?oii4qz82=u2IElsuisWdrU;{*I*jz&aY7f^<>Gwne4Y24D%55AL@0X z&|ZXV8|eX@-CEKAMhD&o=sMK*e#!I*u2IFwF~+`Sav9!BIok|4AY}i-)l`&oWoxR- zp{3BUUxdmB#%-iean}6*NU()f9MKa*LESf)KL z-Yl5BXR#@!WxzUuIty2$2rdd@93ErR3ewic6fJS4q)F&Nq3Odw9@LlNn&S#~v(2j(ssTd98D;{hZynbONYM=yhHO(l?;65F&e%m zok2o35LU9fHb0dg)G{#bVpSL1Eev+08E|=J~u>_af*!bmk$+^-($( zKZ<8^Nyrv<9}4#JM>9f;V;~6XHn>_#NN3=n85_upSc1*U$_KSfKxeSTbH;-rC=VIN zHkYLtNa&d91vUA!je3Wu--D(A-;Hv-L+vx2Q*b)IEbkp=r(NwNu7}>E-hr~>%YTlu z?jUs^r9FG45_bFUv1Ai1&0sUXFKLv+q#ZM*p#BwU-T;g5 zL!|_D0mw4$fHJBhwVbhyV(N@y96bPS5*bKKpqk!c?FShY)$=hRMFty`&SpCt6> z$Q-ROs2yyLUtvxt^zBSowo#K>1=@ zpyQL3nH9N0k8$iz%~xF!(MComF4j$wj3z8KMKnT)7{e93A!^O!Oi5?w=ZfB>f6e@@ znOvD>@+OI-5DCc~`aa|A=ynj{pr%rS`c5=gP(PT?%g=I|iA)3#Nb`#oGr=95&KJH#n z=$o*693Rghr;8uZDDepfX=%XtM6)Xqji2Yln??&=0!5O&cRZO+We_Ev{4d;#M!>G) zGbJd@W@U1NJgEPK#Eg0Dr19yDibJv)_Mw5SoBsj=%tIjM4_SKWgET%{f_qF0@vBG)EFT+n`=z6qK*vygGCo7ofg!3)wjL;|OhT#GWn?tjq+;BS!=Y=$j>7ZO; zv@rA`Mx=0|U70KnJ%~0A7pa(}E)VfHsKXs4RW^`cLT?HeD{f|Zi!WB8{%DhMnXF6L zb3<>k!WB{$x7K6?51$~qlnrAJ;o;6U9UI0R!^2%H-mYX24_8`xY#?(K4|lcc*g(FI z@^rKKPb$=nZPi`PfzD)0B7xo(?qTJ{mP8c{J$$0#KB~7ETN0g_zn4wNmc$uM@1t&z z^aI$TD`FG%9s#q+;5P}Y!e_jPu#ElTGp{XR(>U?77I$~TXDyV5(m*|&@M43a`q2t7 zINP9v9!vSpG3%?O?nBj|Yxbck^f|E1@Dj7D*G1pLwDSzA)ZBdxFEyyEKAp8(W>7cB zdp==3pPxI806DG(!MS;NbARFdzTvoezT> zS5l5I4C>%``;yIa2gR%}+> z%W&&ps?qRV^#@ASjS2H4EPbD|%X}G*x!4YBik&-<#=StbAnewmTPDNHRU34*f(3Kt zI^pxvxn*p)!1hrcTF)N5B3++rX@VEp-k%8Zja7K1h50Ci)T`7JC?u#kz6UjjD(nuR zB&>g+U@yOdn>}f&YU_n0lSq4oh)adK|bjsIfJ-X;zI%V-g5?< z0Y0i-m}Sn84n<5$=zC%KIYVz3%A|gnXqZ72`U#@p232Xk4ayl|cvkCu&`!=s!?R9r z!61>-VAAUK(@Yy}(i-*8EPafTY$D!k1C2GPNpE1WvKc#>I?_ z_aI~}n-Zl=c{5_8>M5ql#g3Vs5fRk)%aw0Ti>2pd#V#=);Tqv)13^<-@RK4(I73_H=6IIrhrp%NnII5qM4xaFmZv7Lxr<5FSuKUos!27r5IWAJ7P&F=SIoQ^ zi4ds`5LztT14z84gCv!HW9!Dc$qV|Xtn z?>hht@5SUT-w^1k&d2Deu2EH%#jEx{9TY!;)d`!xT3thCJMeGvU&H+W!hg4_W)!Ke z*$yJ_<{hgb-qSuroGhD;hb*t97a8$#kTk8th<7qME7{_kEI)iy~waTdQT-}??ZMM061OMX;6o{RyA7|-ir~7zc-M2Em)bB zxt4k?#zbM5T}x(D0d31%yB#^CWx6W9(N))}sO9sZy$ms&r|k}mPnSNMq)TOlAW5=UHaOMWTqx|gR1_@zPe4UWWUYVe2G-g zsYhuyf&qNawtb7zkx3UWJ5rZ?e(6@YgTo(@Q@Zm0ch2SCZM zu;g7*a;n6Pbx6SSfo=78gWMlr zaa#zlfg;s|%=;)HN`DxJqxPxcd6)ofsckPs3jU6O;x$|PK9*hyOF!WO1k}DCkUp1C zirdHH?gi}eHidbC+&&`YZk~FP#dSkMC5-oP1S<*Vo_CI;{!Vxs;ruh_IqDyT2LO9; zdqcfM7{$_}C+?!Sf3qgT5QCva9r1vspOWpI zrhIPi(9lJl9H+K8DKw^E)N&40>l7zZHL)+}P<5%|Bzg~us^u)I*2{pR#`l%BUoQu= z-a{(2xk2>jN3-|4x(c+HsR9V6njp*LP^!9BNyHH=!_i~1JWN@HKaM8n~{fW!K-{ z2lir*xm%9o4LqOan=pQE;~E&IH?GE^&~POz-ggtkSpX!5*M4=XD$%Oy`xS`E^kTde zal?}VeOzN~N>N6fen0s^xkj}J>9$*-U;GVv9i1_6C*Kh$HRx58mUp)W6fW-`3)Vxz z_$BNcAghI1v%4AK)PsS?*#ZXIoOAse?ZR`esRPzmU&eyazkDFH=UmNUReF5= zhfn3+z_|$6-pL#uV_|(tCr`{`ufXvUsr`{_W4CpH*pBz5Tki)0G zn405(Ts(a0OCLVfJbdbFqt=6*i#ERS_9ZNgY92oItJD>=HXLc(!zSp!>7I?3mY{LpZYpl*ra**)K{Xm;pQoB z);xUbD^qt0T&Q{Y)R#Vds(JX-mp*)|dHB@VRh=UhT&{We)Yn6uO!e>(9uJ@Tda8MX zFH*WY#XM2{0lazmRP*quuUhdlkqzCRD2`bMfjg0b<>!>7Jc7H?CU z>kMCm#W<7K{7UQTM51;zRs8Nz1XZ3ja)OYOgspjER-+1+ul#j!wnGF>1;h-Eo z^*v6NxIBF7+herjxIBF7d%`G3yF7gAOCLTB=u?p)psxdy5KV;j%A$=imi8gBucTtL z9atmJno9Jispvk4mQ$wTYX1#9j^{oNHTiF1FTm5NI}$eLzq!94pWBt_cLr(q9im$d z3b{8B-D*(Oy@Y6+K{@VeHh5oRk(-Aoo^%W4??Xr9O-nXP_7-z7b@~@$=MdAb&DqvVAz(&C_pj zIp-KR=N$cfE07b1=f+Ll{1DRePpy-fQFDw|7h~c`Cr9-z(-l zV&j8${NZt}ClTM~S&H;~2G2tjjDXVQsg;a=RkB8HmSTI~3c8=tSzl#VzQ{l(e!EV6 zA(^Ty@nCz;XoCeH+RT*q1v5=Rl#@_@WTs3dxf(6?Tzg*%l7+~XFH&YIW_!wH8$kg} zOt!_Ae678I2ok>aGucWcTlWM?Ypd>Hwpyh&S<=*a41K+X90gKPt>nN2*p4#}PU^pd zr1tEB9rzO_s*Fva>D{r-OdB2kM5d=x&6(b9HnNa&NpL5-p;CpMOM-V>z@`Y^V*%$9 z*Ulw{oJ&Hfx#Zf@VBF3G6m92{GcfFNF4<;f-})dJ;V*}i&i_4^`2X*@46%!N7jxS0!X z6Z5FKVmoueZK5rBr)Ms>O`ISY=gY0z#9xHo&RlSt7$n%vT-Zr7*v?#Vn=shUTyUE( z*v?#Vn;0ee?abB6Z9--)xJ^_^`Kg&p+nGy0PL;^arS}-^n3+pIVU%NLu48T!0sW?j zhC;Il(OOuq^vp&3kl4CZY&M57fG}zO5twDhbZRmn9u#&~^KXV}XAa`x$NwJ~eC9aL z>;6x-q1bdQ@g-Q#9W_qbWpJ#N-?kDE2!<7Q3wxLMOZZq{^F3^ ztQoC#ufGc-#yD%bJKjbeVw?-z$5`nY=R&vDtm*DyeFAznuJPc~6R_A0b=``g%e}J{ zEmLJyUyl0@Mv73cYm9o_dW_SdlXePHaNDFrk5LCl99k zXG(wun}tD%do@cKYD%bZH7Q4$K2zncBO3F%j@os{;Ccr1&34d0Df+LolHEXp*h6FsKWc9EK3hH-!OBUjCwDP|qQ?EG5FS zl23Fv?mE|9UA4mja_Ys(VN!4}GH|iB?nN6R1N*PG?nMUgRoc22 z8N5$v>t4j{bT87saWB$`V0W$Di*$&LKUZ(TAn0DC+n|}eUs$}uqpf?9N#Ets*1gE! z-5zb-iwxfD(bm1l;C&ugANYN3`R(^;>t1Bi4|ue7FEaR$M_czIgFo@;^{mMEHvbWi zw(dnH{isLZNB%#m=dd=wKF`ueR<*4+`Gr)z-b}fZ+XJ zd4~x1q8!+SxA=fp-Xg-ih@a!7dy%&8MGIua{KTuRdl4Ix?nQbAdNSOLO!`r;ZXynP zOnQq?Tlb=A!f(A#Tlb;`f;aiJbuZ%MBF={SV59W93FxcQP65rS(NFiHNXI)QVkfQz ziiv;6e+~oYQVG4}NSvL&Uqw>*04~AhP)S962xmo?$D`sy$(EgrM@ZtshRPt3aOqwY zA8yPv>G=6NAyV2FxzL4iHN|qK{cW*QqMzApfT ztdR_yoPV3aFsFM_q}N?SOAn9&#U8*3yA^%q@jCF+y(rT6pOWc4T(cGD`yA#pxeV{6 zXxqpDFG>jLOk7PxIsLb$x*S@J4C^FRToM$>7Bd$D{~rmqu!jOh- zsOVl4nV5m%13C*=L&fEap_+`^o0XyeEM$#L>mj7oLQ1`Jos+}iF-KZK+WMHHCC-#Y z_oB%3vnBgOxV97bqIjbsXwQ{Je4MN-+S9!#K0^&ILOc)1#b>J1Fm<%2dr^Fr>VtU5 z$&rEordbcu1f;ZMnhNM;NcYpdC^F+e2nO^KTuoN4I9n@%#ub^xcTfSHhikUtDzr7l z6DT6mObY+I80aH&P7>n5xE83D7y!A9Yn_4aMUi=Pg^KT_3KVCURiu)O=p~>pMnqUT zJl%^T^RJZ*H%bQ9=!tX&3DHHu)YRsu@&lUP*H8DN$b#2}!8>UNTrnECq;*Vl(7h`J0oOrNyrw)XA=KpG*)DBjbs><&cLD2WRMV@8BE*QtgL)M zv&sB)FN&PAQW&fi2DHuF(+nhZ%=7}97S)07Mf*WhXx)q0<`~Tif8$=%F6CatMQr=$ zAS>L9D0llcC=JFW z(Y+|UyhKpcrF&6!Wu2geOZTGeDw8ki(!D6Vr$H4i-HWn&8&n1R{TSSH6Kj z<*EDOQ&3vIbuT)IaM2OyPvu+pqAwXE?nN12Ld$e78ja0uZQYB^D$mi@y@-#k5U_Br zxEIlU`3z*;iwtc-TlXSEn{@K6d(pQjDI?`xbP3C_?nMlv&Go5Z4)-E<74t|$LGquW zg}$JsBAk(OFM2nf`|m21n=c6AUSx#O+PW7RA)@*%=n3vcW=79(@~wN(7BGTqNW?P; zivexji&AyA?nNe#)_b6MxEC21($>Am5J$CjFEXhK_RKubA~Ln^MOpKb*?<+d=F2A)%4P&?S# z(_j{6;X!dP${oSdw_&nr-8{M%<&HKe)1`Y+?wG%! zd$QymFp}J{ZwgAd#Yvz>BXQEDdr|HgX@x?$(4~7(?o4jYz`e*_ zj1HAM%b?{hc9ERi=FXs$Er;>2mE75!N%&&X7tyxRDtxjsvm#gMIqW>C4W_Ax zD3H;Ki*=JEqX|V!5iJoS#&891h*~qbLDJdzxuQ4ehnc@MlRu}Kc(Cj?bCZN*4h=KT zj&2&^fTmIc`ek(8fc{rH?_ko&l12m&Nb}1X(~1Gl)P_y|_a%Q@;n*x!_TYd%UBZ`3 z_^6abfz8W-tw_re`A4x5R;pEqjq1EfkKQ}U*8GsOvt6H?x|UqK;H z<9Xv5q|Nh5J#T_RTADd;qS=m#=AGx{HQgd~2?$2^emWuLO=S=zp4^R(>U2WNn<+tI zHftJULGQ;cC{9Ru(;1Zq$!6F`3$kwJmJLr|26Qik{PQ7c-fRid2`S!dDPl9k2`TPZ zSHWE6sXLxwHfsmYSJ zQPT-2o_0bioan^!E$IwRC!~0Rh0U5yNbz4ig!>mgwaAxC!~1V2}#olDPE-J zNa}J;C#3i>CnQZLqmOj`Z;^7H?NF)W<6=JzmFftdDoK>3AJOC!}~ci~po_H?~!G^&oU68y9p!iXU@A z(p4D!;wLI@E7J){(+Mel%n3=;2`S!3?SsbfAdam`Iw8e--w3k^iW5@&jGo{vGerE% z5Aj9>)}2Qur1)8XmWI+mJ)HPrgQ6~-km6?>lyK>U6hFtT!jdkXkmBc>4Y&%IeJH-f z>|b_qZ(-Vb235LrLW(ansH;mSr1&y}x;cJ2A;s(YlwBfDNb%9MnV39fkKy1@OeduH zSP9YzDc;CnjEBbJA$oX;$n>3w};u|fiW=$ug_!U;>g_=%C@heq}l)G5d z2`PS+h09U@7f?^Lto=7aIdZYX=nK>posiFQ8W6#vZFYdiNfw!`OU}V-E z?Sv#hP!sp4)Wc0aosi;Q6+})<{@@kRA)G~*+cS!q_w3N=1TnH6dso^Y7(e{5w0 zG;5GgC!~0TT8L_PsE$ui&!($2@%U;@I=)(ykFVC0q94`_=UFjCp4Xq;wvr8MY_bnnP7U zv!s9?<)E9=38~G{ErW;D>4cOR@&ZUvr zkP;0ht=^>*Qew18Yjo*^lt?)txpYEGj5TsLxpYEGjC)sPX-0iFc0_&e0JGd-TvZ3f z2`P6epFPZ@#xmRO^XP<>yWAjc9um$^b$eOPU%-{8S#iCB>|yFJpbs*5DK2JQa^#K|{Px<;_29fs_AlQ_z0pu1F&Fqs_o(<@7uiG50lSJ-83S zME-4V8H{Ns<+=Slka13u7PuqT0&}U!?c|6SaQsKv1oQHcEBHNviMG8)lS3P@Y}PrrO@NV13XkUv?+g7JJ)PXdAeiJ#=B3NH=`s?IyEA&}##u?JmMuvhjQ!?=3qTsBb zp(a`Z-zgR>HYg#jS#Y-Do^&IeW)Tq@jY=uidAx=6k%k)z-OLs{qeT@bZR975Rv z{SmI&ip`ZH7ZRDCz!o(j>NrO(6f4y`s6T&*weQ>+*@G^ERc$LbBJ9F4owi+BJ1T`c zdTqPiA}Z2(T(PySG8K%vH)GCe+uewkaF_K4>cOJ;4%!dJq)-K^)Zf!s;lFizm= zzX7!@=yV@~!L0~Z7j$90RV1xzT zQ!<R(<4#cLd?HD&479P+v@PKAfFcI+0k!+SE z6A}I}q$!wtH7J5Vq0Whd`5duKofjBGHSetpEYj{JNn|;dQb@P@nOa-a8M)A?awUgg z1umQN7hQu}-nny}{L}snWy6>pem}vtp9NL9OL5O{DelY? zs@-c@!kW>7>Y!g53`;lqB|p<;thOklA)-)*=rFPzM>Ix=Xi${Z5D}%i+_~v=N^jCF z|7+4oucVVWRGLcKgCc@-JT{ zDC%Cov@8B7DB=DYJo2wH`EV?aEq%3V%?kH1SZDrqZwh6Vdk+iV8h})6ziDj0n|cYV zbHC#BaI>MTcikk=E!^tE9E!TpSUKC~$mK9=Bp0dRatLn5POBA8?brzdz0nG5VRA~> zvsAU|bk?g?dTRyGN)xfVt%{eDg;GXs%k$ziIcxG;^463OrYWh9R+Pu;)tdZZnw$!2 zMJ{s4r8Rj7F{bX+;cv;sB3hI82a$gv+wsj09?Pc zD<&=HhTO$VW<9}^Ph^@ zu&~Po2nHEU6jt7!&fay1&Au-TqHYFhndS?tNXF?TpwA+o@fa`)dp$)y3?>SD|3E&9 z1=|VRafhSN7giggwA(oV)R$z24>|f5VjW*NAXvqgi{hHCI^&wdorE0jR2j=N`hSwu zsO>GZH9}iYT9e2hwJEHdAc<3PH70N-351WKI@l3Z1J4(#)oH3*(o{k!Q0N1i5q`yj z2i+&R9!lqWiMgob)&)F?fvj-w+d_IsNNLO8l2m3aBgWgL8X}gMP2NM@?o>bwS0i^3 zLc-hePay3u68L|_^F-nBK0H^XUu@T}F zjL(H5E)j~$aV=F+*==Qr9(l7w-;Qg6JVQT#kkr%hKSC)+edtFapHTRQeM0*WT(i{& zr2CChg1azF>?j=Dt|u(y7j%-sMzjCpxcd-QIN?{Z3GJTM185=*fPG*F2A;x6Y+?=! zZAm$q?a6^*(TPA)whO9oUuRkq+XLI`?jn{jl`7{fbcj5sIS`9aaP4CtonVoqmm` zPBxTCzNBa>IcAig3ei+@>|{Yz(lW_$EQ~s3Es_&Wzpiu7Ad8f@k-$|aw%ELUNLC!D!Y2>h!a`-1f0YxR$i@yuXEIQ!~WDGJ`QPlYf zg!6a?rKpRYjPiJlrKr+u;A)(2F6v4nrOA|IiCWZ+?;L0{ucF5nRZS5ol8*lk^tGZB zpC@kylSRGS^#*UAktynJ9@3q>B};(%Sl(^{bW>y>*+cFY%GuW#PgK-X)X%5~(_Re} zTU1*PjzI>Sit4T>ch`tR{*EF#&G~WU?w6e6ye`_x&Uo3^6sSc0Ywai-ww- z)VT}5v1ph<_3k1nX}Cd+&?i+C(5y_bJG8o^XxxZCXuoH3KsLTg#w*9LpO9kz0@EfM zROg=5xQZql)aZUnv8EW*WK_^(P_x?^#S~37f-H2$q7jOwHA+(~b`Mio z(@n*f=bbXwDVo8W%3$H|0WphCzMT^PBNt;sQS;}Nm`j18*~U;D_hO_J&0zx99QS4d z&HY+XH1FIqW;;dmeh`!pb1Rx}%q{6|hP4+hFfvxS^N3C{sLC|2jA|?#NN#B?@%fL`3`flafVe=2kPU09P~d^g<{{E^J~mCt{Od z_^_`;5*^zv22I{vr(?lkM4)4dHFs=htV-w2b~?7V7UuZJp_Gmt1|o-lc>=GuwhEJI zN%1{o!cI|Qm!F1BiCuo;0Lkspa9v5^FCdg5wxe+ZYEzlcLC+7x?U)g?nYF+#O?!CxSNQ2aD2d& z>4aDj5~d#lSV{jG5UHeRCgLN_rRO#EgJdt}W1+Cr$bxU)puEy$R?qGwOj~Z2jZyc1 z383>0O1PIomeLDM`y|~sYE-(ypbGaB)VB0OgR0zWj)tZb{c=#iKZO<4k-xAdf8TT z{9h#jd(Q=3q_M2;d!+w6YFF0p6Diwq8%e+iDUs_S`lxzW$zfI-8eK*c5p4o zI2!+t%>HFi!u<+5E<1FCq$S-WMDH3@;qrHZ%HIF8q*ck5OxXu?f1p-BYmc-KUzfBx z_eo0i5l?||QB;E&tn8D|C9TmdW9k3tFo0=I?mlYda9=^q?rQ4uvq^#$x(~pj%Dy;H z&|=p`k0|@{azV@8Ih5tU(HO_77Ugbd#;pTL{15GG8{d$D@_Y zzN0o|L;F?qn6jf>eaeP*8KwQfKx}BQr3(IM@?t}KBU%0QmT<;~_ITKH+0Ta6KIQ(0 z6938;6(@%GI{-S$;MbJCgvlQDjpRO{^oOjHPf@=(q^~r8Q?e|ea%+h{QTj_vFJ&33 zx8Ng6|Ba<(s`-MCD*YHmb=5M#Egrp;=^>d^yO zx2W1Gc$){Zl>K22gh|w(mQLaw^bM70kGAwAN|Du@$V80K@!!F69-y6>r}~u$cM${nFNn!jG$OM-#%0C{h<^t$ zMv6Gpnj;t1Atym-mxt`ESUbw~>vRTM-Em|kh{#qnKf`BGE7@uhYs#TPw%We1MNF4; zS^`ZpRqzUgvlZ>K)njKsZx&)6+@+1Ch<6AvZOc@V%*-h-TgDTTjpjrX%4vO~_}}TI z2wF2oE;iSh&{RPGm?o$qfm|%XTp{4nu|TmoXkV=)kj*k_rvBAPu$gK=lr5&0!|@U& zoQ9ZyUW;qE2EEhpqHU$JtVh`21am6yvJ=5hQxI%aZB3@$P*X+{(HCh19JccL3S; zrry!>J#L^kU?1{D&-b`9VdLepxd0DDk9#AAiSoWC?`{xd8B*TQu29NS7)Cb4$2UuQ{DZSa9K`v8osb$(i zcNQsUurtxM$-RV)aI%4Wz3#KD{Y>Ndwa@ETG3zWAf(FFfa7x!qdC-79H_0}cZQu<) z_hStE<#P@3HlI6>oaY(11LG8bnZA5JTOp$tG!RvLJOfd#<}ZM#Cp<=4NApa*`iq6y z>HGxh;@zm^Y=UfK~h*QZi9$svL+SUVw&4<=6M)K4=KdGAaS zUMqx7=l!Us_huzqA>LJU)ssdSbO+`zV3Y*?~%2*}{l zT|EVh!B1K$br0I83;Y=XB+C)xLzvHjm7~b`b1yeaD|4XDRQ&vo5*B)4`?;5Fd;FL2 zUr64by}|cH`9ZS(N`%vsJ;%iSXk(_OV}7wQr>A2aA4PC_UWS++{QZ07^W|a~>~SF! zuKYd<<@CHcO`kCIy-W#h4RX4xt6^$tCn~yksIBPERu$bT<(i7_Y*kSkFBP@)Qqi4K z(G&SJtL~P(Cqi}i$Zw4I?1U0b@%P&5^iRh;VPi(8WA@sZ`w?R*_>A{h1)mjRdhleT zdQK>NUQfcy8S#=t*s8u__&B|K_}ElpkBls^u6E)O3$h2ZmXl zO!r7*O5;!W9BcgPo@0$~<3%TyUUV|u!^W>1O#_+kAxop5lZDTT+*eRDO_;k1YL<)x zJ*SXR4CE9^bb9_CF{XLXlVW@1VrWuJJsfU&v}Jgi_!smTL?tZu@PXB6?gEc!PJUr; zg-2$~o{yyYUt{?{pN`pTVys^7FvtnBzxP&aOTm4hM>?IV9FD5Zq+JgbIVwNFFo&?H z>njXY2nR7~SJIam;X#nKQq(d~)Z+B{4ua$7#k|A7soPtaXMG*Sva8irw%1ON+IAT- z;qPgC$4~wo1aV*X%AHb@n$%C4W~WH1Cia(}xl^<>5k0w|^iG>PzMnB$le4LxFo7%@y1R zEovmolMX`32B{J<_|C7YtROS&ooD#VMxexB*?Qmkc?Rl6#Pt_7f9Gdk*aPeg{)B_p zi>ldXJoiddvqMPC7>VCl6$URde-A7{hDiPwnSBx9&_+-XfS)3M7^f=rF$?4mmpJu@aQPrj_aW)7 zK!TzBkaTa7uBOn6TV?OVXU)P7P<~E={z(w9^(e^*e%D1UHR$~I?i0? zka=vmbg920uD{G>2LFdxD!*Ljvz}O{IwKW_Z8PyzS!Unb`-LFLg4{#I2Db2B=RXlO zDgT5n+5k05nME+g$4shYD15%^nX?~@_gLupCZP|^UJ+eo^Gl6E2# zN!L))S%f0#nn6gth)^UI_MAT-CWEXN#5Z zMSE|-h}YNv=AzMaDd*o1W#l}Ua(+oDa>`No(lS7i^IXbVPbhK5RCVD)bu@+HYmL>KZV{-~GtlZ*g>G@ z1gia(vnbBjcEt*B^QP6#Xs*~&6u(+Z{QUKphY-I>7>ym?33+CzO}27#t~Goy$}I=W zAz4(!ECwG0y%`c_QBB+iM~CC1%^*edR&D)ivCSRXVz`9B{GzdFN=_VY{gi*#3DC?D z1b{i~d_*jhM_WH<_Jy5+W%4lTmlMnMVe&soEShaABir}Db$mQj?fi$qc0m{5Td2SG zQr<(rwR4le9i%+Z=DJ!Q7EpzLTB2ujeI1WNs-&Nrg`YF`C8RF$^Atz}M6Q#OyrXd6 z0X$HCm$z8B9|CUJavd1q?~c@c42WbB8!APPMSD06PukSK+xzors&b(^N2qeI7gkP@ zy?>deY7naHgz9XYy3*crp<`2Gl~C;#syl7!1NPoOO*KHM-Vv&oZR$aLpPi!(H-09 zjScIqc-Pu{Q)5bnVX0IJ-p)D=_uJGx_P#1j$iXSd=qN zlyf<7Z5BIdz3{_NIoHy&FAbaOUhW7u!pBwW$DkfK2P>12KFSsB1tl!E!d`0ccOU`Q zhQYka$1S-!5CLN$-6S=bYcPKKxk*ag2<+6{W^@0+-i^JE5sLdrfzjmVzOdHfHpo zC@Rn&^fD^{NqV4n^RCrqRDMY0>%?>!h9CBE81`=7z1ob@j|hK^(q>rR?c=aK8{}qK z{fi1C`!vV~3NtEm9jX>!RQ{cje9ks=AA@J_ z5GCG;C}T4Vguy?F#by?W%~aO{OJ6eS(}~4qO#aQpVlxZGX8sCn`qDz-hc79tHl68I zv5{z9%0?Fb#zsyPd3rKkY~=Lc*vJ{eFKr`dijABGa$_TBiH-b=SZrjmuv<6K+Q`{r zBS|b=8XmvJk-z=+ellh<)AN2WMO+9Xr$OCnsIu&RZJO#lp}JM5nr!Mkd*7L++A35} z3DwIs^`O1Kl%`rGR38e}FE%xEn<@F*G}R8F(pbMa4MjG!(%uWuo<{mhgsL;CYR1{r zlkMHu$Y!B1Hd2vmXEqZ&hNUO);A95y;tF=IAcMV<|Yq{-GfWevt|772;5o8{%ue5OY&wv@B( zB5%j}0~lgJt!*eGO zkCF1hxQ^#b)d|An2yl&ar>WGr_FmV()j^dIlr=D|W~8n6GDoRQMiOX4$|($!0%O{=ThZKdwCclDBb z3i(7=ucK6>t5oXFV^pH6qoiWHN{ZznV2y(}JE z_N8>WQ*`+vqKqzg3WG0*MVC88mwm9vH@YO+R}#gU-WJ{HMr{L&$tB)nb#Mwf7Jf)U`9AtVKv{0vNLtffWo~ zgupEbjAp)@Ed7)Aj?FqDcnt(KzfGJ#9uvrs#qu@Pew%IdJrd`9k8HDMp^%r6_#@Oi z=AQ^uVI4N+69hIg@C^d@G2je=AuzySJTAamd}0EDN#y&r<+~WRg4b0-u?!T#?vD(x zfcFs?x(g(enK6L*egb(;UO0?V7g(i>6?FS3lQAnD`>K&&w2I}Kz1U@FmU z?_-(V70D$`9=aH1Oc@V|HRj}*xDQA4e zmoxMbnQZ}9Gp5|Z+XNXt@3)yBvUj{2dlh`9avoPR%z%(eOX(amQ#p&XxASj2Um@pa`_)W-9LXb?T$74UNi}%}l1@j`_$-oi> z4l&SzKmt8{%0>jJ@~ya!M+D9?s**y~_hFAp+Uix>J9a3i&#}|P!!pfpKn^pcJuGwY zABbg0dsr43FA>Z1VA8)LmLbjL&qbFpL)yc#$fyQ}04s|iz-dm0^BD8+(s+{nDl3eMF5lkV`3Ro?-K!n&EPfuAe2#O%j|GJV(?el zjBkX^MMEAz;#B}+enQ{?19~_Pz_R&s5Lm=O5`hO1m_$yOSx!kG#2o06#Gg{+Ls1`L za3up|`3wUrBnzc+idohX`AWSiX(hSc-X|lyd7f>LQh8Vy0%+7xDyzm*h(#TxvRd9n zEb1`nuM&$oO#bhPMIEK`u#i8W69LOF^B#sUT)4=~&vGdaQ%tSAWUKH}5ZF<}3M=z@mob*vp!=t$n;~S6KW%Jzl0O=g( zG0=aEf7$W=My%qA1*nEt#W!LV?-Gj|z7eZ9=@ej5gGp~D7B!gsYl%e---uP*30x;? z_*Py3=Pm>mJ$xtS^#wL>IluStZ6^0#%rn(dDIaQ^#+S$uD{`X`Rr%F39#W6#hxn6` z-)R_{O11apNH&V`i(;-7sz#eS!`^R6Qw4--w@{st;$iR4q^W{J^$w|OmfO^|_HIhc z5{h3)0kscp4_ROHsBM;J^@EIu!Jq0lGocqz`)i_xl0{IPsQopm_HbfR`)i{1JBUT? zCjB{LQM<|iDY2;iHBo!$w3OOk7qzb-7PY@2<=qNw)c)pg)PCSNwf|~GZ=u@%?Rg&7 zAZmXa`JIL;TcQ5;{w0!)B0dlHQ=3yf(^Q9rY9Og< zQmLm|D#Pasp_oSsXS(7Kt*PE#1#5CzEZwE{j&XQ9HP7D*01ZhlMYjGteGWVd_-?Y9 zp=vrIraU0O)UnCt-g=Bnk87eZ*0_2Z+`{}6N{Bx%@)3~qx*X?Zo^4fs{2yX6y?ZY% z0#i`F0T`lhPZTyHlwPOy-eOQT`O6TM>1|nMNgY5T?Vln=lYLeS(pmm-LfU+iGF&^S zNEf6?Jx*ZAl%16aF|1)lGJN|Fv; zWVuMvU{-LI|DYt*9hd8m%(d2kRFaxkx6XAkfLia*Mjybp{8C92t9Dm8lCJW1m85N{ zB z%U%Avg|s@&-lv_mFcZpld2rx%+~`r?XWWk_NCO!S7CA)cU!Olt(kF;0ki%Ai}L=- z!!zMZ%_;&1??Wkc2E_M1=b`U0c<{4Sd6!foGXOtJ)y967YUb)Pcn_?zDY;-#Hth3$ zBr}JKUxGL}{gE$+ohIj)NB_*40<7G|{S)a5pFP=ydvkwU^yC8+C)2xso2gNAE~Hdb z<9jM5l;SnIRW#q!(S4&-{sO!2EWVo z+rQ>8yc3~EkNq}R5gVyuFvxtslak&iq2tVTB=hn!V40UvATK`ymbqSnYby}kAO!pjSmxyt%g=yiZj{(8 zSWM;>4>B7+N||}31o;`T%b$!Eaamr$((!I(M`iU{$m zmBF~`4l1Z4#IIHc+u&FLp$_q@mBECC(a;W5JeY4`B2-V}wiYHsFGTD5h+nM?R;w!ouU8>{`ztt5@sp@HjjTfad}45a0_6jlk?O1)_LJAsXpyX& zOpP4P4`gQD%mVRCX__C%%=(={TJr;$S+^Jz()>VX)~yCb^(92x49d}`k>_oOXF@L_ zqFXw6wv+FYX5BGCP*T21nzh}a3VoPd?lN4e@V%a_>wkoZ@~N+^9hD67Q(sw+Q3>*? zudK%(1S7}G4`gQTVSR$yg-OISxCOf@-1RVk=BK{GRqslXj^?Mn!o57AJgxbuukcCy z;Wdm=nxFa#58x+w;5e&!VlG_wndEDy`Khn)!0!bmH9z$g9&9RAqWP(>@K94ih32Qe z!Xr%=snY9+#tadj)jEjTBHTDuP@U$dzQWTFqQUudm;BUMc!ohunxFa#pKQ=V%};%W z7qL40)R&Ld{vUuevIk?U?*}jmXy1+)y+(4;4RY9tppQ(1eGGH6UFf}zm!JBI)KdIh z71X_v64XO*g>w$Bk~N1RMDsU*gZfT{z5G6CH2+x!A7Zer1g}7m(E_%b_X`LSZO7*H zcEf@s+Fk~Rw>lx%Lt+nw5bPziHCPQqd;b~SGvxbTu_ZMSO8*;~V@vD7leW$8d&QP5 z5~MZ1?-g5qo}j4a_q}2lyo0HUjm7VK#a3K|@x+54A?5eIVi)q4@%bC1)nFW3`JkXG zeHretRsR-bzV8)V-5=$6itFV2Ua^)OLG_y7_lm8VEvQlRV;-@K_%oyM$Ix$J5RI+9 zUQn~{1u0?|el^?_WNE2<~kXFK`TU~eII4Je#VyXcZX0qnmhE_a?227{D0JxWZ%{&?1qJ(S$beSE?|b=AGN?lH`(FM5236_rA+f*K zp#MkRn?PArT>YcB?$pIS=MLSshYL-2UucGwsk@P(L561NrkR_05D^3vjRPVoYDAnx zMZrW(qKR!Zh(jXA2?q>Lkr+*gCeA1t=Q+;Fr}6!Md)K|)&G-L?wcdN{t;brNu3y!z zUAuNw?NjI6vv)PvKSD>5MjCd^8p!_-h#BJfUXgK37RdQtkqM1pVR^n+WTHwFurw}_ zCPiV}fZj%$bCNEG9Fa-di3YxzA`QFq?Q^dTPYRaC)_gm|=9QI!m$ z9PL%qyEnL59_>}she@(zSh%9Timc_)UPU#$vvU~vz*}^XqKsvfx1xTxiYQs>a#4Tn zWR2y~UPS|xOC3aMWBWYXt7zaoNal|A8jnWXkM{Zlbf~j?pW)4#bH6%^imw_SbnD*$ zRpMx`+)}t68V>C@SHYrVxP1PU9D3bto3g$;+DnOh`R-^hDi-$1k6q z&7UCyBV_yMk@Y(cV-s^J@w*Q1F}^$6i`D6(=l5mX@4HRUPlEn_bO1+t)kAfm>T83( zPsSga?qXKjf_@o>2}gS=-X8Sb(O!yo1pQs)_o*x28T8%JURu68=)0r66z>UQp@aT& zN541dyQ96d{Dq)j!iK+e<@E{BF>{h#mRb;ZKA91;pPt{7ulmo&5i0y5OxK zY-q@zgrN(4XBc#a{%^iJ+Uq&NyFFL;jn@1wjrbkM{E2(Oz2qO~_vuK|#!wZw&kHXs@3O zzl*}YJKF1J!CS)qjR%9iTX3Do_meQ@=rHssX8#5`W0rTt5RdjM?8(QlnEepfa>K$D z7HKgPdf@;UOP;%Rm!dpTj!OaeuQln3ydm0M*pQ@~$d-$YM|-84&p}^kWq7n#dXi4l zEDS$*7xq33wXlS7)n<8!Mj5mg|H+1|LO4R7_uTw7X8dGlzm z!ZFQ4HVs$pDDV6osV;#Q3!9G>sqSV=`mU{48L47>ht8nIbLL1`H8E!f{&?-wF?NvCt7m8xGAFkzQ0fge#KuMKq z5C?DW6rpO(Q*o!FRJWt|x+x6tXs^P>CkrXJVdY|6xWy@^c`TMukg;x8wB%_^ycQmM zmsI}-S3TM*-D(KrXs`4v*;L5UUg;%faS!B=0q68ma}I7DaXq=XX|8-dT z)T1Tqq`;CZxH;i~7Q z!ak``k2VdasaB9w0U`5qdvz*5X2me^Xs^N}GoXmsN?dh_xLH)WWOQ^mc(hmHF`S{H zb6~m(kDnp6xS!No$LDKF$_aZX8V=3pK61@jQsMl31)4%_MpCyE%1m%o+4-228^UpH zaqVtl@Oxpvx%pO}fu!1}Ud)n@9PO3Ho-}u~m%i!9AMHh*aATQ2+Kc{;Oc9Uv>W4bTa&ZH&8Un{G+t(3hgPjP5AtP*bF2+QT;7(Oyh*V|g@~<7h7~6;9fir69SZy{={L2-bBb^pxp^TesGJ z+T?1xqrGz5Qg^hM3X$?(q=+xLU26N$UN3>G9PM>JIr7`_P%4<~vpd>LcLCPlMZ-`e z+Zlv7^WD*2N}Tfl$<1N0D|JVE{hCbO(Ov<(#$YGi(Ox{=iJdHvqrFP1S!{W|DIjpCouS%A&{9d`FMp1X@Ey`CWY`j2@_9~ss*5py4 zbjnjQf&t5;y-KI5dct-$rda7TeN?b=v{&hLMO`e9_9~t6_iAmKM|+jd{8&&%4!bCA zRf)5fM|+jd(w^e=4_YdnO~+227{sH!O6MqQuzNAlOXn(Tv^?6Ybe^IX`*-xTbUwd` zLx5e&qrFNOXbTJNQfRq!p+4>`v)939mM$J9l&kF$)>}FTONVb8_~ldS;fmHXJ_F8I z8V^c&+b|pRsB}54qr7e4<9q25>@Sb@l1KE?725>juhLZ%h%X0OaK^kOca-2LiWWR#0_;$~fo#G0_x9MQc( z#2oJ6m8c_=SEQVapF4UjZ{GtroAqs;NfU{r5lP8CbQbd*ndBocO!uUIj*a0Rw?#8@`PPBn@R55`Se{jN0F7GE1RotS9n}k*}}WQ6gzq}M)n~d z*HyNNNwj!aGnmM6U1dupDa;N(5xJmegs=iRuB+@&W|cy+CGK&7te5pgrm~)fRA?0> zEn60B3i$g;X7f+dJgzI<#pJ9ikLyauoXN`g zw_=H=J=x>o9gV+)#J(%7@p)WVI_}^ApVlIsFh^x6VVyjMrwa|o81F*-8JO?sv^%({ z(Pt>nbg`@3;{O4|kuEjIN!?bT$91L4WMhl>eK@Ww-PMsU@!!P)OqV;j%;#}k>Fy4$ z^m$xYy3(8^j8^+Rt}9*T7_IT|gaJzTFsDiBdY{L2rF%-L{DSgltn_rX;Y%4F*X8pk z%XA;vuyf7&JgzHUBW=kqCbZq@exghH#e~K?-QSht7ZY0V^ZsKdHT4>5d8%;UOz9@mu~>dNsl z;y9KMH|0`}q^g*B;&=VTbY#Oy3(`wFfGS*rDsd- z7gX6Ca^P`Y>AAAX`ED#dk7||Uy3+HvVW6@4xL#tGDhctpuJnR=NX9ImdO}Z7bt@PN z&ig%*8`B%j%TSolpd@S_ASpdMTV7dqkw|424;kxWj!P4wR(@g{i;$L|+De^XCi?ACFs zzmc3Tad4r}q>7>WG&y{rO#62 z2XF`};Kl;*D3Ig2(idJ!etc1%zKEkremt%#y-88n^0=<_#fq$bfOGE>Mc~Kdy3&^} zAio9-T{itrX%_sdaY?_M+xakddiuQ_2ktJ@?`v7g^0=<_2U?b~JgzJKq0ZOt_OBd= zkMuomg*}sUe5|N45E?-?pWMWjH({-0(%&D7M&)g0I^b+@z?Y_tGg8)DwXooScs&ub?13EDm7ZqKLN_ZL z(sK-*`}9UOw{y4Vb?(;u&fQwjxmyc6cWY7SZY}QItwVF&(&M_)%M9OQc#W8Tsq_j{ z+!GSja(Gut8dK8ej{xaaVvhA$f?~^YUFjpuyGVPDhSP7oISaMrxUTeR`PyO|PIqh6 z`aG^HeMY`NKjswtpccvZuXxj$MZkS zHjJ+Ee)Wf?mL+pLm0?wUC)(~0WUj@8(01Aqqe3L>DZDH%Qry0(nGSJI$V0Xv99Be*aqRk{{vq}x}@;d3R2 zD9UJCqqMCoURki|(eIJFoU+sHnC0NkQ+B%jz>km}Mw6%PbUSVm3RLBsc*UH+#qzwt zS)xCkbDn9c<5(OE^0eU$(Ml|X{(prG`A+01B;*JB@A2~w6k9&|dE~_GK3vP?8<)?J zD&`32@P>FiM)?#z?1jEVZuutLhZPdIs)U1)DwgM*pF=15>Tp|oeIAcde(`9jG$CJ! zC(!6q4xfdzz4l54J!nA6H{S*-naJgrxruD~LrVGO-$6)fpFg9NZ=nR76FeTHd@I@T z(IG@83T0*GRE!{*@*&3%kH@GOvlYphy&BiF`7N%+obkoy@FH_X)?tXp zV^oaYCA5zU?Vm}jg*+akqVXju+>fhHfiFoQe3WV*#*zh@rDKOSoL_StF2=eg;B39;0Gv0~!qR zc#Mi^Glg~@u4(fF(oygZN-2=zF)C)>023t^sG>Dzfp|Pd#heQuFxS8dgMsF90&op1 zfvKpN$05cVusj~4Vm`-{cJY`YKnwb#U;JW)$7571DQL$p8p!M=zyJDq2;JM>5DvsiGmUl?}A--a@=ougI$r0EUM{6lw8hyptc`Vfw z(w9bD+9AFNsyL2{4e@x4%KpCtLBW0`TPr6lgbA1Py(^oNxI1vw@pz2N7Me%ul*eOK zPNpfOPI){=<bh>U zJRYNRzM_^u=-4dapcNpE*`smAxh%LA%f&6KyV%21vGOZx8AB;%x8kZ3pTa0D8M?L2 zPv|S_?h(=laZMXasbn(ObV9e`epFd6E9EivY%r63!j(g*ng8KhTzr zOL@H3e|bDch{t18uIL6DJszWS_0gpN&&OkguE0yI%44UXv|tfBvbyqw7m&6*DWh@? z)xtq59}9FMo5Y~WNg0)EuY(5kqzrp2dQy3ke)5pAjC5DIj$H7rMdI&Qo=iPprb3y# z)r1yPWv8qINr)$9RP~~YLIcodRlo0%Tfk&ZRsYt3yl=xlqG~{HgT)w9RRcLGAqu_} zsv5-k%GuKw<5pGsV2CJVc~VAI-FqTMHW1?R7*#_K1-}A0DWhuWZ^)Zb46BCe&OuMg zs2c8gTb`6r)u49^-(F2QN9a6CiF&F=s(Nq-3h| zeTutc)p!=rD)2R3)r3KU>g?Y!zEu;oCk^&J=(DOxd(vomQbtv?q87`OGO8viYK164FXTfsQSU% z>;+HCs5<^8v>&s-##Qe@Past+7Y?!B9$`C>8(N6_LUzClNV+iI*+IX;BC!nPovme( zgTyf2**cwXjh11&v-QqyS-u&}4!&C`TVVuz+GK_b2p|-xvGK_b2(bE{@ zVD)OtFy7fEoXz}<$uf+0_ArIJLzZE@vrF|OuRS5lFy7h2-2mb#nbIwzJPhM)8OA%i zT;Wf{_8m;b>_Q9DbTl zoH$dV=~N)Zqgi@XPDG95o}Rt>9E_UlmLC=9*@sLpK}(mf1?sCPBc`)wjiNd^Vz%c& zidy8gZqEUVmf0+X=~=62y*&^26h(aJZGSlmuwLgBK79Q(jAhS*wL3eEn3bMG+? zPxQA=M9<}j4mu9}_a~}vd~PV%Z6JeR>6384-b3cw^qyz!W|)ZToAf@?YF{Shc2)U8 zOS4sdv!Z48a@M;=(Q5k?CUEtw56b>$jg6wY>f89D4&R~$?T=XT*ZlrJRQ*lRK2G=> zKE7iihwKVywfc5GH{PJ2jxV_vqvPX~V*zYK}8Mga4hbB~g zSGm2Hte((Sv9sLXMYu=dedTsH#rUI2wY%KDLii`XF2L^^<#r%h{aIPSsq` zHsC1ja(ULRex5T3iY>P{aKK*Ta=<8*+kS-m+)A#nXH!?Nat(oVh2_Sw`gNV4dn@cg z?83X+g%>JtyXfy>(^L;$>}9_>sD|Ho;XOj`$5Y7nI4MI%W4L-9L^cJlp}lOc{xe{< zZGTYo8jzc-{K>1=Kt;MGvFA>Sc9u> zZ!bqmACFkGSfJY!zlsW>CE#iXwn?pRQj1-CfVKFcaq(few4Vqd4-PM)(47dt>DGQC zfRqNYhmg`O@}AP22*9HD69I%UnFK%B8(nGcGy&m!W3F_&l;%zoU|C?$6Hqx~rI`0XR4Y-fujc)~jvH3<6HdN5 ziFo=`cA-`xn*WSX@3kL60CNqKfkC;L;z7LZb}_|OQTJeBnT=s-*Bph?0V_{JNS%#g z77sWHhbJJ-56%WkAg_&K4wuF&-x%ho)$^r|IVa4wHiHqX>D(}10oC*6jX5v84UGr- zw_(1T=OWq&11=7femoapM+TtMa}n-=ln)AiI#+$4=~wz{J)w zqxQuDCL_qu6BT4X6F4|`41-oG8j-6sT`G-+UV_s(v)nNZTwQ@d?^0=-jTuIA(cor^ zR=Y3Be3_<0zNXHW$oo&T7<6^V1CrCwA0Ti&zdS=w_y@^oQ&1*{c?4A2=S@NOd7#9! zy*Mb!ys8wGmjwCfH1Odp(w7GLur_cFwlZdOkk3N{`J;)sEXenTs-??dXCuU4o^V9I* z80wxU0N=*G{4C5aE+&?#aE(lbD}YCy3=NrU!&ibnxHWLdsC!9&U6`x&NtBP`m;RSuKLp^Hrre zI?Q*KI=hdN+1)r;LanY3voTseRvi8#iczC8exnSEx9fb7)O)zs%yLs z`ZD7q<7p}1c6pz;zosdY!TxB%S19`tDh9^WT;)o?$Wb*%#*pf2l-*0Ji8Llx{E%G= z1eTHi@sT@7(SZDyK`~(f5``xtQH;bSBu2M^tZ5?9kARw5k%*px#9|~yBhgGF_pD>N zpDZs6PxuOX7oiaUCea3`Inel5=Kh+Ykx4Z1-5k#5@`r182Rb|~mp?92Fd9O!yT2pf zW-gL7t~3=ztH(wr*h3KY38fRhMPb)dk@ysenM}Ni#Q8{!ZUk)$UBnqit|^Pe1ITU~ zfJ9_H5)DYKM`H3H9rG95-=-#%Jc<(j8@_?drywG~inraVnY-`Ozwd#l`6hv5dKd?@g0+}qK({q!hKqkvt;8F9rCcDUFdw^J`c1$Kq*%`oXT$5g;9?dQX z#zf{koMJ9u{&!;Rax(R}S7qA+x@Xb;RK9aC-*F!H!`Mxe74#i%11AAa&0zClzPlfF z9wd}I!*{g75okkW<$p(Gb_n2fnbY6%Gbsd!8O6P|2^elm&O_-8PLI3p*4BUL{+h6n zDe|D`c8a-}&3z~W*EvDo*r`?agX9Rt$N7Ntt~A%E}ae-@y0=RzEg4IUUn8jP_r>^2luoi-MfnrP}M3B4ZYTih?o`c>w{83m}~ zujcE4wS;^HWLA^kb`s;}zM9+WS6L=~Svx z-3QrL^@V8f9an9ctJW%_?V)IkP(FGG2xlLE!l^ivgBrUMd99bS#it1WNEV+u7TFvN zk^j$>-(2M6_g&e3urvEa{$41PfAh?jWSB69LauR?sfV<563Biyo{Jr)wt|Q+qkg&x zi<>V$f%!V>4dSm*0L;ZZ=3-#Jk#cw)aDyD9qvf};oNqKxPFrIy!3~`6rGUBN#0^{z zfJumBFAlI6C0b01gpHuCZ{+PdC9T!-O_(W^bTju%zsPl=0Qtpc!X)HvLZ#8I$Y^Q> zx(x{b=9yXS#QnNK&h>b(>v`d&FfHi$2xQA9M(DY_ zxnF+Om`2B{+5JTzoT>@vt8jc(IOdL`dDU>WV3R4_UKMU;R$zfSgGTc$V_F@L>)hY( z(bN%OrsBON%ud>z6Xz{q@CGngG;wIYHm1#0z2|rAJ;v!W{A!hF@wICA@*In=g~cY| z$@ja8-E$QYH}yODnd%u7kKO{kj={nW1Uc!tY!T-3%;W6PZ*=>)+tvJJw-g5Eg6P_b zXi9dWzmZ+&+^xVet!@u;TJ0eI`@vwcBgmgo{40PL5#JHy4=Lk`UxU>%zYX$-i1oy6 zLxArL@&}XO0FQh)3w)RCW;v~7LwmPuXfdru%AWQf+0zEMrd0R$$hJ1PH4~V{o%N?q z;-5aOlD`SAOPgRhk3(VgkC8YHiA7ADkHj7(wj%LwCVq~@k}Hw88HxLmSa>%Q5M%~f zXB^8p?l1Q06Ih?Mja4J5ngV5&M z+2#I@MAcuRD>?{I%OG5UJe|=`iym$U4)hOV5=Ja61m=9`6;v50zQp=9>_G8cwuVmz z^?dk?#Doy7*K+3d2+OM8?OL7tn1~j53Y=eVMr*PfdW30xDt`(rM!rXwR{khri9FjQ z%xB9T#Iizq$WHm6z@x-uR)=Xb>wkvFgVh1kJA4i;-C<*J0)eKFLdl_xqmel&JmOK6 zpqUT7A2_jg(^?D&FWQH^MbGf^1TPQbGM7rq(WSTtzjnf-$oe^WPPi9|-AIhaOVdEp zpMg%jR@u)pC(*{WYWJ79ZXf%5E$#XX%-BgVjB@L24UcII1pa`$26?D%mF^c^2P{w4 zt>MfF#g6$F3U^poq-#Z?NOutuqxa{eoBPWE|IIVqxjfI-=Yus) zsPEn1${Vryrf~AucD8KUwjocS56+h7gOXoC7ix= z%(FC`+qIb;j{WLA+T0&Ova2P>X1lN%dvmVY?b7THVtGj2F3m2yCD+V$Y32!FG_!`i zxj!PtdyQj1^bguh>Q+ph$+>3kmuA)?Pe=Uz2uJ(@VmV>#erYCr8?f9e?~kzVbYNBL z{nG4Jz@sGE`GXPOFzzFkee^C-a`4w^JAr8e+3ulipQ#EOolI9ht+Fix-MlH_EsO6n zc??)cbBVMAM>Th?de2X}Sd^VtDS# z4Fy#+GrEw5C-&K$@2HT0g|tDj&u+?Nnj;>9F@YwD@`+i>aoJ5SYL+&j1zGqzkr!Mmg3v!4InX-w3s2@JHYw3Qp~Uf0wXi^wuPLI~G{9^PH1(3s{+! z|5`gaItC4L+SvvkqMbh=F*+M}+S&M&)6P6Iwm*nB>U!GYRB`!BTHNzbu#b6_Y!sE8 zhdfouMp4Pr#G;aoqLNR6Ibk-6O45G@(s$}1z9AU~tSZ_lDmn{TZz|`6cvIN}JZ9}G z)IV2NQz2}_=w+y=Cuv+1lHW+S?%%-C{4+&=K{uFNoXBUsqN1ORiWjt^F`4Tx$b09% zVci`rd!84A^4-MNzzCVAF9q3lw^ zlig|y@G`pEAZ#kj1BYG%o~Ayu&`C6U3%a2*;qxFZ$5zzfGt#JjpgTBdHs(ZsRlD#K z%Ijz4x^S>`;px8t^W!U2fFTPUgsGwWJXoao3Gf)mJXB=<0%%m>08kGT>e0^w^P>s1HrnysHGxm zDJGMORw|;c<>Z=Y77PT7GxQFy#Z^Cazq0ugNdA#$bB5dk24P@z+j2&9Oe6N2z{>Uv zxhcF2JWBL_W|VrbeHr4{LHtqt?ao{*l`caj8{f|v)1(jG%l0!5KU=(^f1d))-)4ik z%$O#5Bprky(aGK<(Ev{+mdURE70&|e9;(Ukjam17oH9JMx5<##Twt9vP39%w9l&}= zYm!G?JdWw?Zx)07E{Ye+1f66!K^gm;quF9O13f5Rm%(JC%b;z8u9YcrH*DgdBzR9t zP!S8vM;!UvqNdUH@JRQUqsQ=K+SA)a&0!41i0Z6V;Om9y#B$raP1JlYhpPTZDF{_$ z#-MV7F#+Wli8(+K{15a9%)F0H4qpw_CDhi4+b#YjCIBw~8${}TGvlg2{m+6=?^_($ z1e)HrDmcPLHs!aa#vIY32im(k=#YzSO4my8U}V#>^XpL=fRRlzwGJ>EX?C@256$xT zFyE>_(vrZwFdl&euO{*0$1rS(d8!Ui8(r}3$*Csz7A3|bS5FYSaGx5}Go;}-!!~3i zZKx5sCkxsBIt0Wajlmhx7@Q%E!5PvRoRK&r3vZqXvdC{BariPOqxLeXCjl}G{*2lB zLZr|f5rkX}kQpg5kXpW|V1Ud>8Q-SylM2fKnURcxDZ3qNiga}_V;LYb(#^rFWq`~` zxq~&90Wu@q9mEHnXf;ydV1vCHEkr6EMBpoSG3#K9Wq`~`4+mQ<17t>eI=Ijdg5Z%} zrVW3B)ypgcWJda!Z30(Y2FQ%mxE`&s43HTa;NUvT0GW|NX03E^y=8#R$Y66AAl*Cd z^|;eV4mK+VpJOBjWMqiB4ZIm3(=tG2q`^EW7y;oJATu(~oGJA9^o0R3BU8+H!T7*- z9{EjmxXoAw$c#*L7~jS)KxV`pUSExmV|;3OhM6k$cN)t8nUPkJo}b6qofy-|Y#irI zc@QA8%QR3%?uki&%*caOiN^q$kzJ~tfX4utk%v?{)?+V4RYwc|k-6R&}2^&m9u z@m><`#qQzz9WUDls5goD{Z52l1JQ#ROd)DXoiw|!UV{C!`{o#ArG73slqe;i&h=wo z3Ij#vHWZi!!+N>Z^`|#chJV{&OlE}f3jE6|(r|Ly{eW^~YoIV=2*vy~{1dD%1T4Oh z3`dgRUcizgR|d=|Hg@RiC}d~@Gn(+2H}Fx_nNYd8>c+nV<6qgYk;i|(bAK7}DjYv$y5 z&^Ah|vo>!8FF@yWMv%PtS=s-ejNoICKUkeNf=>#}8$s<+-Uuqp8^Kl5-@Fl&drJo+ zI2pyE>UJZz7rZ+f!To~Ujo=!gZ#RM$2yQomirbB#;&vmbxZMc0N&R*sNa;Ho!MCOT z|7--Q5@!TeJ2@k$%E=i)RR)dVW>kpU`@mkz9s3m@55!!~56S&1mz&0&TEe*obG9yq z1qVvd=WHF9ptE&t$ZofFB%-YgtF22(O;RV!9L!oX*ifw8>N(S`q90)SJ`SQJeH+bS zlKc@_Nikr9+WH;i^4cEZrF+B6!H z@!ux*7jHMJj4@8{jR3 zB5E^5{TwhQhO34AM!f@)VzZhpEHf#`HD^X%MCsM!E)|wdM1|?^=GZMGyETA;5?VTh z{k{RDrJN>Zv~&eGa{?GsMoU+4ivzTD1-CjtOJ~og&>*9w>r$&Aux&U7E^fPDFpvaC! z?P`Jfot?t`&Q4)|XQwc~vs0Mg*(uEL>=fpAb_(-5JB9h3ox=RiPGNp$cRS<{wi~s( z1?G*K_9$=E6y}ZEDbm5bQCm*+bTDeG1-Bcu2f(|dQDZb%ah!5HyR(J9-KaGSZZ~R* z+l`vycB7`a-Kfo!`t3%I(swj!f06e8vr(f;oKaKl{p!Ajk%m3lKXltmpi+601~8)%C^_-?;;F+9-Ve6@*@m=UT`(JL>T(K;HP7e6h{3} zBJ77_U+5y3+n@dwx!$AL^4VMjb8iYZPWD>XLj-e=5zOt+6*vYB5vDUL%EM5MfB~Sl7i&GNgB`ng~R&c^c_)0D|R0tTyJ2vc5u#8C@Z*N_56r=JQ$h=b+G?X_d#_{$}JztRZ z7{}XNzeP~WV*p9-^si#1%y^9B?Va&+XqDP!9B=Q3#|f(O7{}W?^G|~6yo*ua+wd%u3<9Nr0&qDJBQz3oEpJuKB5Jxh9hB+0w<_@$Qw$T1eb16oRZg9T@ z7r)h5!kGKB94raMB#w7%#AEE#hY&V4^4CHc@EFHCb_ff&>4@4VkxJ}DVPrQ( zE;fp7M;Ng?Ue5^}yRjw^Xo(L$9-_eyFW$gAD(44(_l}Q93bNh?)QXR6#tedR9wT@i|@yg4T+BX-9pX)jV9BX-AI$bvJOfv)3| z6+u!`PEl0jF=BUo>PVri^BA!^KJ6ul0VgDn5xe8lPZ13_dW_f|pTSibtRCkvVt0I| zmW@X*)}dEXORf<{?2gYlOEMafQT7G+`Gd@1NM}Arx*_PlV%~&MI^6pVO))1!bryuL z8r6-4*zjM=&yDNJX1}?kM0#bLA(x*IY;76X+JD0l_mZd({+ovF)7OfDt^KzgTw@v7 z+JD=;4;dIs%AQBo?>LN?50?_Z>+l|9>xkcz>f*G<$6UWXu(jQfk@4FDTU!RU_CGSi zWu3JJEdyKoA3F@kH3qi!KXDkIYYc4df9fz?*ZQKO{||?E2Q33z`=2?yCx}h~f9~+! zpxutO;D6!p3qf0g@%O)Ucz@8oMf{b+?*=UcTl-%-3}+n%w)Veq7~VR!lmEX=FEk6I z60!_z?SE&Ug6hR1tS9^PZ}ShqyF-?Nt^My!VJXYu6LvED9|#T;yf-9HDt;)qR`3fU z@lx@_!QTqrAF}UKztP}hVm;sw^d@mZkXC_#t?d%bb-#-%|0ZM^*xHY|@{M83z}CJO z+$sDn3fs%64?p;rU^o=<7jC~>@N$v&Ct=LgS}K z@3MFU22FXr*P~X{ZopNWOg;h4kFV~?2Q;HmH3-n+VI|2%(bPpls5xg zdt;Uh*-^M^M|mskNX5X`Uh{=QwOOdx9B+#MjRaS-i<9{VH)jpn&u~o}-e)_|c2J*1xi^!s=CIqrHEnno?m(+78Q9vJJyytgo9Jq$VuJBrsiaCZ zh=VtGl~6G}s#2Ywr}_{#1>G7&7}(ld%wM*m_9`KzB6!a)rg_x(Ix^Pnik6YlmgZsZ zd57|c!Kh7RadbNfgZ@pT)ew~PE}PKXYIzqdrNk1my#o0R(3V(g_G0>$e}VBz9B!^f zKIEh&<9{7iKE$X5?V5^8l=uh(TYF1dKpM3(aMh~ZeRWg>16zBCA1_qva7`QT$U0Iy zgeJUYq=+!EwRgldLVP{0UCp1-J8o$@R`?eB_EtVDRD7c8DtDMyNF^81OVqxBjD#$B z2DbKAeI^yYkqXpbcj#R!NUA4cyI!M~%8yzu-^dPj^~i%k5w#<5?JA$Ea`&Wi$>`{C zFtD|EjQqxM4)pCEf3(!%AZx8n`C5{4!nQ!5$b7Wut@)W$XvOYhM-yuL}dt%>WjGGLTgJ)Qej3>7Mc@nn9qc;FnB(lhFrP#Lz$p1HW0i z%AHoXtH3MekCP2u`R^gCKi*L8^0UFkpJ2+Ms!D$U=1($F@T*+CF5tJw@~AxFh+_i& zWEoC;^9V-%6lpWUz}Cr%%W#cJVC&?F$C38<^+?if#{%9?w30l8TWSd6@d+e3%58uG zF$rv)tQvw+kB4$3drTEV{Md)dlkCMexva*(*2%u-2ugXU;BRu^F9c;g2DVPtX}zq+ zz}Crw71ekQY@HmYh=Hw}P^VZfZUD}Oz}OHWTSu4;b|RRCjI?3Pnk~cNDjzFlltatf zr&82jgxm-NTPKH8DR}ZlM(hSCqait#cWhNmqbdeA7h{qf$C<$XzRcc_SCsM?*g82u zQO09n>*Pd5S??=M?_`sr8jpdklg*0i0+Ac3`$>1B<+6X^;@@iyLCaO2B5lh4$UXf| zGo3jS*t*~ov|i)iZ*E1Fy^#a`fZOE-ECXBn4;p<`wG}H?1^kC(?eck`1VZ?`9c{+` zoA6;rn+=qG3cmiMW)9dENMLLKar1Y!!NAu3?)=KSuO!32dFJX0gY>)~Q~ud5^IPQ@yW(Y3Gy}!?HeCWri#6-@z ztqZ3s>f$l5b>WP9*Yb7@X5q|Hf-+t;{uZ{X#95DltqW&qPis6(ARHsHTqx^22DUDo zqo~2#iz!$*S5c$Kz}AKH6t#E^Y+X2igVbyF7}&aSfwr*FV_@sTg);-}!!nP7tqT{Q zCzPu_2DUC-ItLU8O60-mnWr)cTJPa!OPs*41(fpm%^$G}m)9dx9=~~~Ej)t#WngQ0 zW-VONED%rQj5b)fQi<_2{t=s5MS=J<4sG{=wzFA35#%#Z`SobgF9}YC_RA-50(F(S z1v)-i>0OaK^kUln+#8mAk51Nhdcl5kMfPU-4}n7~F(( zf=Z3raZ-OhGNSe&xpD>L`CroSp)?{tIt+ao83hd(oo^Bm^F;>BM|MF4?&Si0Cq-Gp z=2tmmK_|N84H08OCt_}uXDlOwCOp{|;ptzZ!6$rIT4NatIuUnpfJBZ@B+T8IDh#5< z2iHWQp;{Q~V+O`Mkv2u$2pc7CRifC{ZLy36ohUUANZnS;SkQ@lEa-~4fkanFy2LUT zbfVnBWtOp^6WtwLX&DPTQE46)MyoAjK_~LDpe9c#DY%D;`67( zf=&cyjLzxeiM0jJvq<~6BXXM1oFT=x_sOrPD1f8N+b?55CpIYxdyEC0xLA?(9^l-&L=pHg7Ifm$ zUy+~0f=;}%5(YqSy@_{on+1Nxn0PP8fg7^K`&yRr7z;Y_ftF=F#)3|KsPnbE_g9X? zNBV}a!ecDx#K(#%VUx+`lP}q_#DY$Ie=}N^7k~+T@C{<_Xr$?UEND3)EDTM@<1q%;f{!s*S`uT-iP-F@#c%9v@yB(x_~ScU{0U-nI77wa zPwZ^*n_Q{0_{|PFi$5uE@x_cxF}mSukd0bms?m*FBOU@+@IO4!z zU$ZRBc)!71PB%3RW!Afgs98~s$5_zmNs8(`eleY%tUMdMJ5HYs47d(Q^#t{Y@8FpH5b9IAxExStHs#B0 z04E_gZPv3)F3x7Yj%rbR6tbgoPF1zMWr*5~CFfdP6SNr0nffi}I2BVX#Z-p=wAf52 zmyS(d5Aw93BD50A(9BE7h`fzCQ#|=wB%?OigAK5H8B)cZA1ZZ(A&!fuaN8gGj=7r# zf*@)SmI`FIfE8rN`vFv;FOftJ>0X2(j*BloLMpA!S7K00-S2W&tnIZ|!qMp%pW@Ab z0hNqT@nvp&JUqrC$Wc!ea0W73PVp8>z-PGYVTg;jk_~1cKQ9Hmf-UJ+J0;bTp5VuC zYD#*shrDfM`vCRUI_?X_l7kqtJ;GqdB?HP)B_?r=O9sx)S0B{ks_#MXN@^8ZkHG;- z>PQB0prjO15e73Z8M=aeB(8DEu%D5SVZ+0zK#IY*#w86Zl=b+jamfghDIao-Fs^aQ zm|KyI+BU*10LQoQyRfop6Sbo-L%D z(N~d_gYATUiBuD1`Z2C?Nz-jo;kQzO!}bU(FoAEzN!v_<2;&-;OnO0RUlrQVapnJF z-i&iAav?eyVO-;q7QRM^+8C~BQ;ut~5UZ$+Yg{t9k5CN2wHh&kP_d0eIAyeCGge_& zvA>LvE&~#XFs^aQ)aj&UT;q~yM+@x3>=_t64p0pH`xW*+jclE{$k;v+;x_1b8 zjB8vnrwsyg;-4@WXf7v!yu3iaO6GBhX?hvgxMV)ZlfTe1u5rnNCP6hG;~JMNjZ0Q66|`PnYnH6khn0<{lw0?bqd1-A6@o0& z)zmW|t-PxSq3Y3EigyNIp|2&!Qcdoi0he}!ag9rkqhcd`94_tq?+}sRuMo*Kti7N~vVc?PP7xR$09) zn#WLHHkip?;j*FBOz$z6`GMZcu|iDm9#~$%-nGaH_3n?&L_r|3i()s%K^e6)){%K& zk?BQ=BLkrJOus`>7Gts|)BiT4B{FbkfHUW%e65}ts5@y!2F?uPh*Rl(`=NR*zip<{ z85uZJ*8~Qb(}4)X0cVEXOWqP0I5RW`;Uv6eW*8soFr=mQo5>7!ygfz+&NQgK^}VYp z=Ll7Q%A?nDW+as@Hx9m*$&4)l#~70fGmYnwJ3pz+jB6Dc@NpL8%#3FN9@WJ1XC_=M zsLuO4)RLK~J!$Y58939VJ!$lKzsoc$YVjBuI5SC6E0jnT!3v>9OdS zGqeAM8Nj(J?C0dzGcs^yuA)Ydk%2Sw6t#Ga44j#-sMULqVl7a#P*t!{(K3&bfisI# zkkuX|17{ZhQifuU$H>5$L$%`)891|qJ(ZOgVPxRUVOuD%L+1tt2{1kwym2h=Jhh zVhond(OTB%F#=2G7&VMmg#*t z=E=s5_|h}-JuHD4(gQ^?CR@zVg-Cn%l5ALRK&}J18LqRb!Q0F-cQ0=YL~bW+SwRj= zX3ga7pgbv(ag}*?BtAbVZp!pIr1l>K4)az^m`h2ozh-jJ_JZ zuM0-5@54pRWxYVn!Q^qGA=t8kIf&SBmj1;@z`Ogy^N(X>PGr)|>nGBkNOeB-F5*zN zunz*m?-2?&-uy=b_UBleli0kOH(<@$Q{a)!=%nYOY`}_>5m)hK!utRR_9LTH2!rnf z{)q5YO4R^3Xei0ExGoqyZj{4aTP=tS@LGmngs$!ffVqE?? zdycs&gZlx{U|9o-tG^(o;!ZVO1;-LgzfTpRZv-B4!jXu4xL%b03Nboynsj36ml!mE z2x^}$PkL7ZAJRwxe`tDPk?`NBQ(U6W{rxQj9Dn9MwPoul)D^xRPHWO?s-7UbeAaaCg3rm+}}xgaO-OHJeVxNqMdG zM!2D5kKAcD*+&m@2dK@qWf7%ItHBhdpXW9k-nY75+%q`IssMArw zd&pyKFS7WH%p~(q(D#)U{}&EwUp|1Ezsy9kQS8XGG$Z50>i(4$WSrRJze!Ro=yOaq z%Ah~bYFMAQlRsj7?RR1gq!q!xf1~whuy$1=uZl)S{s%DT*{jm$tAJGAS4AVQ0du0i zCKLUTZ!ytD!2Kfp;lShB;R|3K`7h=gLV&>u_aOfX5KOogi4T#eJ&?#2ZN5&%{Sa>_Y{1hH5UIn*AJa8Q-CpD zK4AUFbYi!*~GMUVk*|x2q1m>1=Zr>kQI1_dD7*+v}W}Z*x$GHV3u0 z`O^-1_|(<=zP%5`|^rO}cg)Fn}Y z>Vw=HP9+v|Rxh`!vw?^4N!JVxlIOj|60_&vpuCI;8JXQfg1m_@0MdK!P`UZt$WmEt z!-8C6Zvr=`l2{P38s|vnAz?@kbzRF=pkg+&*NOah_ZPGCw~$;V-71nUMYWE0;m2fC zXU?SpRt3$cuI38f9`Wx<6weu&>-;L|{5=t{kj|}=&b>%1onIxL?-|w39T~*z3H$)4 zHs#ngxW7X%O^y!oWz;WOT)&*q=ZE>|9YvW=F)9fA$dd$XUj_%lY`r-7n^NURNaBQpT zyEK`ec3p3#SCTQ4>1o&X76&$=^IdOMFol5^{JVmD`DM(M9zB5Wc4#ua@VcE}4|1@e z7haJIwJ^B^waQQYhE~Z;-HRtRh{Xps(29WLb!9#h42AE z7s3YwT?ii#bRm2|(1q{;K^MXY1YHOp5Og7YK+uKo0YMkS2LxRR9}sjQd|=RpunW2n zZV$Q;?i6$(+$rcn`2R-Gh5tU%!WUR-8fhWY6Gk)An;-4Pm`s@-qmY(2sir6C__Add zN=!B8zPxM^tJ6!757*vCmi9H5quv^~US4s3XTf?fKPdrl`?Ag*$WmY4z8{1AzW`H5 zV$GX_NH`$|a}$+=mkZ4xG9GO9J7%?R5nc+Kzmcg_8_a6>@gwKUOr|FQBEG}hyqS$O zb*^56`wMFtf(=Pa^^vR&lT~QGB6Xu_bX3>6zkdX;*&x@}8cE*YM{B20xW@5ldmW+N z_Zr#wbAWJ1j<8&3Ses*YXS)FBo}idfIV5UNwe}236!zlRmzz;Xs9<#qH1V~Yp#@byGxO&M@iWu z=xBy^JL+OVWN5deE*30)&7``*B3KS1L}>H}SYtZLilg*@w#L6eCA^K4 z5IC^L3e`~>)>xrBO2Zl}R7Yu8V}#5VyHq>sC>?%Cm7|W*9j)Ml31H~jIC&edIRRHV+;U2ak?bgu4l)d+|v z&edJE^Q%2^uI};xJ1x%DT^^hWM(SMMWf%L?*{iz9@blyJcoIb|?Y7VKIwV9L&Z{~$ zmeLiQs67iM2yKvTu|^G7zt7uj_m!=~eA@lO(;Wy>iMgUe#WA8MNA- z$gMbxx%8^`h6(|_s=Z-fgQa>^`|D1J{S>ci{}lT1a47GFsqs%`xGniv1B=pM|B@i} zs`gKBgaY~d6}_tcGu{!TUe*2&?-it8)&7|ow9VgS=~eA-m?)^BJ!VRqbE?qLl7duWElwH;e(lV^yzeZ}|CWUcIX0)5Lp5ysG0f%)=nWc!*bZ ze5TorQNvG&@_|^q73bU#s#kS@{4^QeW#tJ*Tz$S|^6@L_x{wK%$`(%Yw6pzSfBm zJp`$*bz&rEEr0c-6J6pEMe1vv7)1tLjIA-0jaH<-)`>BS)Ym#OR+0KzCmLzeg4KUlz`zSfCpR2+Y{qpx*h`Yob&^|emS;9AZ3S|?^|8GWrELLGRE zf{*xGC+7S?GA>3&hQ8MELFOi;yMB&zLooh|8HD+%lVG2@QJCtdmho4O>PCI7d3L?0l``pF8Y)t>a%f?0l``Upl;BeXZkPIqZC`<6k@M ze68c(IP83_%jP%ae zI_?J(f}O8*yj$=^OdXy8ikW&1CPvhb!~}?1-aN$D+V444GG^i0&9Lxf{7*BXmw}k5 zX~}c9wKGtZ*ocezS|=y+z9GKW$tJR;Ng0l%nQZ=}EF<-`PEJxQm{nhEzxN}k6}5YC z)n<7wIe>im$a_k1w^+z(Kec8Q#7Qtf0*4YwZu6 zDYWx&?ItULx3muQ2k1b2t^E<_Nu`T%Ei$|#rn$DXmhwIYbIBibtB}!mT06=cWJfCc zTKmm^5vu2fip}v>`QJ!DUu%DI6xKN^E3ca@MBZ%=tfZoFn)%a)3H>Nsiwy6+9cVkK zkG|Ia%p-($wb1h3+<{hE(%0Iby-CO}$F-Ze5)+JfP$g9=`da&QZx^b&^HjW{E7iYY z?sdZ?zSjQYmxOe`kPd_*xD!azJf?}XQoEuhPg|m|wSQ<=ki!!T*K+Z-PPQ6??!N?w zq~2`1)7Lt=#5`V!{4vmea;f`(30`L4lAF7RDyO*MQs(z#n;+j zas`s`&A?Twa!=M#5ybxCJB8{YT#F3%X&osZLKFTnQi!j$f5clt`~j}rObB}9MyF#1 z`da%dJ>*7hA+Fuz4%3HJauK~m?EqvXWWm$d+FvzFDvXy3)ZdZ$3X(dOuwAcFOXWu` zm#_F*`$wKB49?9n;GRn5l9i~#L0@bC7|zfLeXafD@042i_iA8zSjPl zH>JY+`3juF+Ki-%31ud@s=U2MEr(2et^KvVK@ket_&C|-b*Ha&e7vFD-RWx`pJ1j!RaNx0j!!bJ z;8z7->v)SSk1G0F$0zG>X6S1jpCWCFuXU>81(2(+b!r5k_2gAr%5BHgr8srSKT*I9 zek0mRjdB|x=WCs++Q4e`wNCZ8QV7-8I@N23t2P@NO7(q8kosDu2EHpueXUb6b*fPnqrTRuahwTM6Md~y;}xl|b!vhl^|ek- zRFoB8>r|5>^|eklD{{WpsY&0X>^3>Nl{-Dt(S6c~R>-a;mcKMW0f~gqa?P%54I{vVu%?2{`wT?e(evX#Z*E;^V z8HmSl@s^JNUebK_I2ziC?=f5|`p`g6=nQ?W92ul;nsHhrz*&*ZnI z^tFyZ>x58W>-Y<9<5?WY(APTtk~nQwWaG);`{YRH!+0vFJ6rX&ju*=Q1@egNVZ6ve z^|g+t9kKda$BSKQhAXo)SX2zA^tFzc1y>=>PVyt^cqaI)?2mK4)`it97GLYaUaom@ zAuQ~DCrmr11bwXw``p=sNPVpf`|AEgeXR>?6w%lE2Vj<9|85 z4t=eQrs{aAuXWM1`BG*}PG5IYplG@x^|daVF~hY?U+bcoiv+2!by2HItiIMov$Ut` zYh5&ZgHWokbT6vzSCRT!7tK?ozSc$auaSD{YhAQJTTox?qJ>jMPW81eT711w zs;_m?(hH&PoUe7!;fmDPx@g(2L7DfpE?UkzhCGz>PFr*Y`}!yUX5b!0M5%DMQtqj&sSzax|7c_z1zNE(rp+(YkSp0jQ{ zkdE5FhF$CEv!lnYhd$CK5DZ!q%iIW!`-}+2577srz_xfWyvxJUP(OJNNPAAXo0($CLQ5RN8m$ zq66gtbhk0%E^dGShu?&HZJhVN1H?&Ha!u6(Z%_wnR#vr@`)?&HZ}-7ziHeLQ*G z-AIe=Pac0%cPc+na>APWK=On`WS}h2;6QSXB6S~6o~TIO$CGPyf2Ho@$&>Wule&*5 z*XgS~bstZjtVrF*lcy+B_wnSZik$m+vW3sj)#5&$oX$BT?&HZBRE@ZgCud5MANVF) znH2Z&Po6EMK07_0bGp;%q%(AqP7fhNXYO>8 zPG|1S0|`k;0%4AT5CbGZ1{20a1VK^4Xb{DSpooA$6d4r(6%;fm$RI*w5(nUa-?eI= zA^QD#pZnc=zyEn|o+rC&?OL^J)v8sis`lRX9!>|0nLIw8JV&Xb%A-#`!AWjYN{^2x zw<~3jk0*DWN_ld8Jo%Yo3|Kinp4`b^r92)VPwrAmkB=uWQc91HCofjY9v@F$@&n3~ zK^Yr+5@(uM@JwBfNlRos+WXVI zikH%UQGX4Sy>QXE$jyX$HZ=;Dq#JOz%v{Mlx!9Qbkw`cnw*g0su{}UWK342<=exL; zGGeG?+P9qjR8Fgu(-`^=mFCn`ewFuwz0A-MT8Me5<}bJ{$H%K?rjdu|a=2y;WsD>* z{X?~uFp+fp7Mui8T~>>oKkUiDel zB!@|>2lHjOo+M8-@Oh8yNmB*Cb(1Rmt((-4BJjyc@>J7QB=sbDYWUV{@#bk#AI|rp zp{W+7^dxzzm2A)q25zSuIX*t>V#<+ZYV;2%#|%QrF|;KovKi=`R6BcsE#yh^)L62q z97>dv=8IZ2+H;S6LO zqqt^F4X*rO&UrZ;oI7A4IZ2-CZW7)RxR#lz8l(f^4ljNz{=b}P6NuHXsM|eMvYnk~v`3^IRo+MAre;JbHBzdYwml1lB zJhkXyC`=DIWdy2TOb3uhGx(cY!Y*bM=1KC@QuZgKFi(=FmYpP&o+M8#XMcnz$x|z6 za=z6)NSP}i5lT;zr;em`!;|ExRqqL zp)DuLQzy}|a(p~J%nZh;ljGy*sb4@^j*q9OFMv~V)baRuy1TSLDLp=(p2<*1oAUU0 zdiD=ch&JW%@${TO2~{taO3$khDSCW7J-@F|dVD;+fR)jvY(;vpj%z(Wo?fbyJwBdp zz8S3e&VTy(%9|Isd3-$G`hl>1gln0hmdYl+ zrVhOq9hq*Ek;3ES=@Cp0EJ}}}Wvb=)c(oiKua@KE)pC5iI`8;+x??Cf@rW5#lH=o< z0hBDq$1_8>AWx5vXNEn3bR{42XPRs{ujHG8%y3;v`}oKr)68zB(RqA4(-MoQ(RqA4 z(|R-nz>)R%cxL1?lr6`{GouC%fo#5p$c*Ne4qaNwE z%yeyu9v{ziDW%89Gc%Op@o}0c>a#I=d_1#YG3+46$1@B63JcR$e_s#%7KP$@d_1#Q zDLp=(S)!C4AI~gRN{^3cmMNvj$1}^7(&OWq6{?6HAJ44(g>;1;AI}`A4c}6E?0P4& ziY?6@AJ44*IyIK#|Qf6HzVlg%5$+pbV%;4za@$t<1kAw;;d5|fyp=cQM z^!RvY<0|cFIX<2_Ms?KVZZRA{JEOiTXSY zFUQ9-C#;d%C8)Y&@o22yYx<8yI@SmK`zPrG(^xa;bL9FhZx6Oy zvP!9G)Rn3)*a9^}GLS=8-iLK^%~0h`#Tr>|n2$abSN=If)-+9_^byEO)inPiE4`&a zdTS`1FA8eftaSVsA_b1PjuI{t{YH*#3iTTmO5p0GX7oF*_5jaG*NjnlRzJJqu=UTNy8}}lm?-2baoRO72F_eBjHJTLa_YL@IjePQl);r$0)URVQN|k&Q!u*=fYqJuj zS_zJK2kV)3E^@r((5|-W4kQOHL$b%zHuGUXY%^9ywJl82r(VRarnXfFbcgg=ZJSE# zj?qH3BQ6)t9_gFfBUp|f=ESIM?MNz%>BNmu+uBi-!_RbLlPGrdY`8xB+l@t`eC-&@ zjWq0YV@Dwl)rzSi4g1~L7cjrnj@7bvgBcE1J5I|UaAPYFylTg5?!&HrDN3E>)5yt6 zUl-Ebok7Lezqh)z9px=(?Dd$%YCFRz|4Y~a)J~lSH8_AiPc5b?6~z8VYPwP>!C0v6 zQmS4CN$m`!8fB2wb}Q8yJ48Fo)=q1eB}T3NSgRvOG@M$y;FuCyTnB1_>e3l|nBB8j zsj0DgC|$cmrF6$?>On14swd{)Q}fzovSj}e$ez2mk0^VOTA)Gi>)&s{ zMonUcJ2s-oX(-|xaS#pV0pZ~%pK>M+Y17!ZB18EeKLLDi3m<=);!svV&nJ*EzMKNq zA|nN=>0Q>oi6ik7$WQ^tor#?L$v5JMJf)3)?SI$56In*IxsU*t?~fy^F`EWT*rqKxIdC-I}&&lfU>2}qMJwYY=?I% zKY%x86wh{eU$w+8NcL`1Vl;p7IPs9n7eL_SNsn@S(qj})dQ{kx9;5h!$F-aIFac~l zl4l0d^^9>c33#vbJmlE3cN5z649I~GwOJ`J@n07f#Q!~K?_R~&j(lc3WXf+J|I;x% z@02lMU|@8-Z!@`P8j?}@F_*)SgPaEo{TIhUZbcyk$M86alG)=RN@kCPD49JDqGa|s zh?3dkAWCMBgD9Cj4x(iCIEa$j;~+|AkApk_{oRJ_agZMi`5zt!IY%0(znk|T9L{?J zvh$CFydd;W{Y7LP2iXa6^498C9*&3nKYuvy_fr2q9|xgH>~RpaPIw$djq}gPK`ugp zsQ+!KAO8j}Y?sWayi5O(yIkqWT^&vbF%R-~^;q2A zG|jf9zQLBmrcFYhbRzwKv5$6@E#dyFit{1OAfwPchjSa!dOE z3`wv)7P9u1lyxrZhWC@Wmh=br)g|dV%nY#)P*ceON~gBhP-Ii5c6}^ho=g++XyrC$ zj;Kc|h61MwM|3Cx-$2Th_2iw!sV>5M_eID_$&rav-jRuT8@*nSOvJ~$0-p3HC*IDJ zu2fI1h$8@=V-G=PA{YFoZOvDS0OvEQp0JcYRWFkIMDLpa~pQMx?nTStTN{>v$ zJ9LB7fd(7}336m2K7~m=G7+Ep^>v%e*rdSoI#hlb-;^;ZojH+O_kdSoJAaAYDrU-Nim z;!og;`jje1CgO|uDT-{65=}qF-HdLK63y2l#K;CI(ZVEc&J9wcV1tw>*dQfFd`&oY zgOoUe<+2;3#7NFu*$q;naD$W>eI&XvyFp46Zjcg%8>B?x1}QO4%i0Z6B5#Al5KWzA z2x5ao`reSl;~)Ma6&1skM9!3HT&ut7?M8>BQJ5+w>YNQv%g zsFu$}xj{Tb2kHhXv6lK|H%N(fO4n2QY&Z6mS%giu$a|W1-T4=O9^=LK(9TE7Ta)w^YHbW2LpM z->hS3tbJ@KldQZC5IWW~yRM1Z8z{`_dm*F&^^5mScUH`qB8G~aGZ}JgWjAx?AlR(W zY1s9B>X*2wa<+<`dLIGTj5p!3`HYVs5dY?4EAR%y_7m;Ix38--PCwCbJT?3~Nzqbb z-n1&?^q1NuvbIY>HrxkIU$N`)-PjD6jsXX8Yd`V^{2YltF!3l7wbjNMcmN!O{s?L# zs6p={@eL&KZ!pb7m?Qps?_>S@0)V#pqjv*(BXe>Zf(9e86N$zVNJRGR-!^0d5<_co zDT##byUrPAUZ8odhiKg)9I$_XhO#F>Vn1oc^=!rT3|NMl@36p6O~@E-E$&3_t=R%U zWr3a=Y|GGJKVv^!2m;W8XjZb!+y%x`t{t1lvFC>0f%f%^9N61Wn$yCKQ*bMnipI2X z;}m?=61%_<+-3=Gm3rH)Qi}qXhzFP!Zj}<7PR9_0TRoA0|2ZQNOYH9G0D74x|dmdyTW_+Ipq+n}2tuMnBUD?}#o3Xw^? zLSz!}Fk}+%Fk}+%Fk}+%Fk}+%Fk}+%u+5Km7&3`>7&3`>7&3`>7&3`>7&3`>I5LT6 zkx9H9GKp7!OyU(FlX(9(kV&FGpD&bNhK?x&DFLQFGLnUR7rY@w&jp6R`zkw_-b^77 z_rV{9FbO}(osIkQ2|;w`ILYk5waj$lwj3X4zLu6x2%@tb;W{SEbp}$pOOiKq#lz0U z4ShpbJT-#_w7j7!p8hjgOY0lD;_enOaS7Ro#}mafSra!Gd_z|}yHhyz4PEh^lZ4VY zbj9;NCzQUSE1rLyQ2K_hcmXR5-_R8oyrC;Dd_z~nuN+IZ=PNFhOW4Ei?D9PH89jt*=R>=KE9zVZd*&?d_z|}g30ot;!(6r zg}kAwkT-M{@`kQL-q2O#y`d}a;L}j=F3wmpUqQ0uP9%HGY!}m!{8o#ZL*21x#0L(@ zsyCPN2No0v_i}2?^`yYk>{iN;9Ytw-8l+etUqGABvJl^(MSV*4jwj2NlAJIO$s73n zX32OYcbl7j$O?E|*WAL6X9c6lzfUXZ5yWV7EA7CwQD4MlL!2m3Yh$kr1od@_;KO6V zTfKd*P@7RXQ}f+D!!1qKkyPPnNeZOSGpwje=B#Jffz^BkY<@ups}@+>XUR}4 zPilWfF_6sP@2$L)l24HCH|J3@zY8)aus5ni#)*_sMGrM6(L<~FI^CSi&aEOUyE%pa zr&XUKRnMeupP(>Q@;owAAxJRWA2Ii{8U+dFjjHFkDs1~B>aBVJGn*^xdMAB0HB(5N zaKaj6CoW*j3`e01k+Mw>z4kuLvKg_&0ygv@NwLNPs#H~LoElMU5!E7djWliv8#flY zPVGEaw;CWmIw#K0Rdsc?s@1G&GuZp^hndV#RR0Q)TGdgk>XB?!YgrYUYs7d*(|B)y zbZQ%EpkvWCt!iPes;5v@owVv$R%MpdNh6M>WB~8<{XR?nQR32CTk5lb1?0bmJ_fjC zp;7+G;th47QQn|YP9!Pv-k`jjK-P#Ky-7d%6Ucf%>b=ELFuE`D#BUC<m|ur5`SpvCZ;L;xd;R z`b@e3$~WIYV|~e}uKX3$78$5tG90Nb;>=$*^yU^RdYu$)k+Hg0B5{ih*6R&NYl}4R zdQq=c0@Y21UDqmV+$?H1ZRV4#vstP<h=6ltLz ze%MN%{xL4}e7L5fl%=$a>h95DbL*%;C4F0_BmDE`**fD@7R zWAF@Ehs5hlEJdPz5E8SISjt2P5|=PB3W*;eam3-m2AzqVKOhJ1FxZLvZ6#~zd+h@< zFmml+2q;BjBNHwXUu5EaaQ}>n*O4f0G|s5sAYm2_+)bYx1h$E|IcNkDUq%A|Mw@CH zbE4U84furp`vCG^ry<3ICUV#&hJ?nLNMkGosUc)C4S5|&ekNr)IMu%f(iw9Bg?H&! z)=yf=qdm19oSi@L-6(zAC4Fm_v`cl}*7emrXNo%}h8kzA4B=Tu#&8pVDb36_9O^5P z*(z~ijyjA)fw_{`Dj`5ukAOoxmMT4OI;<9*Ic>(9`OG_HWU%$vj9cyBhfqZ?>|7>b zfE+TM70QMgX9D2I{w!5?gVN#lwrIbNw7AaO;?H-29uDl!cSZUyK{?~iK91j4wZi?j zqHy<+Ws+cnzLR-0|^UKWfC|ddhs2N|1e%=mB z9{BWisz1p}@4Sflr{FS?ySrW%@@yh^cfBm+*~DEa*~>znP2}#b#P04Ua(5TAFT$K) z3T8*=tM%CpUBx83p^Iu)pNTnu{|;cQ>V6x1-ZMz?$^LC{m7*f=xRXx@=uz>0P@X?o zvb?=;-EcMS7B51Do_{j3qNg!m5zHdS-<1^VV*YWxci>TO0=&^n7lF;a9ZE+plO*xb zqE|9m?0Y_ixUX?-IOk?2`Le?QJhgH^i{kz@T}TSoYe@8BMizFeq`lWQSD-}}c8dCP zWu>rFESH0wQYwUw}-7$4Y7}*%*vK z)g`r-Yz% z!S(2Zk|WHyLVwx>ZB%olc^7PaD;WF`wk>HlMeu9B2?z)hS2D$XLHKu@fNup$W|{p$ zUu^<*X~}F$?=``T%%5ZFeI|I1^ju5tH$j{ho+r=QcvdZV2_IUN^oaJ6h65(Jn`3sN zDUterXz*LhRPftn!_gI~l6z?qc`I0QpIS%X3YOfj#?iNeB|lL2!$(H`H&MXzUqDyM z&|te{Xz(umL+&#C%iVJPn$92)6>J|knBgXx-4Bx-7B%KA}3Q2wj%gag|UCU6wfa z_d+RjS>n^(h}hh!{Q^#%IFCPV>ozEKS>pWDg;MCU#06gzN}lbXj6oAI4JtoD`p4CN7#Mq=ha^Tzt8ZdlkAYamhVGTIjOGr9TqV zLYE~jdq66(&}E6s-S|!3^|yWPv3sowDzvzk>MK1MF8qm&M23Dx3;k z79Y(ZSD$j@bc)s|a28 zAYBYzvkrQcj{S*HA#~Y(p+e{~r9$X33ZU00beU2ibeU2ibeU2iblE16*#Z6k!j@bJ z?=PLgWZAtmMSh$07(NS$95ksaX;sh# zy&^B#XkQ;}MSYRqS>^%3<#ex?4C}||$AQP(mo2$Ds3iFZGaX|@V(o!(j?FI)CK_Y*&^tEmf=g|3+`7$iQcYp!c+>tjez0VCU zMIT4rvh;p8xR3GEj~3PP6!t1z-7y=?vmk${hxA|*C|M^SJ#?G(a&S6+>*=$CLQ+X6c`CZ};SvUq5$f^kam(5`@iIKugXUvh?q)_TXC$C+W^ zZ&AwgU&d9d~_P9op)D{(D1obd8^McJH+?mO_8L|cax=#m1Q6Av$- z!sGCb#HbU6_f%YK#g?2W^Y{<5fjbA;iLpGd=J{X2wcK!;t>A#wQYxExXo*P=3)@d{ z)rNA`&F8upR!nrgDO~Rg7pvp^`@hkEcxZ{44Pf&8A-LAc=;joDcp+7VusDf1i-dm# zuH}YPdLD0{`G|*>n9qHk=U*VaobdB_RpcPDExbk8zJ_b9xE-fuWmPWXp(PeSE?iG# zxwuMDuDNtCWj%#mvGOm%`k}DW5L{kVY$BKRg7kIH&~i_UFM;nRjvNhk&)(t|;GuCsuj_^J2|Tptv0SgScxXi_q%9uWlemx8Fg)_VcIzEk4RV(9{0Yc+&qKE- zR(%6W&%X;-Ey{&nz9EQ*mRR$1;rcbM<%WyDe2)83MPe;E+!vu{;%FBJ@q8cGTJsoM z$JJAQfq!6dCpI(+SF><2U`!>KT*NM(KNB~iGBSyWme{yL3arrrsFT2ET0m0V_NuLI zc^cpIW%%xAQ;+$A2-uqyz=fLXCB38FK|Hj?@$^vl)3A5qqy9 zyA++3*lgglo?ncsdN<>*RwJo4lHv)rC>!tj>@xQx)_7{C2p|TG`sT4&0g{@Fs=^Hb z<@60A)6A9Nso@vfk?D4u=hX0&Q>4qz<-XHL@X#VtWbIf-JhVusq26`GLyJr`zd&5A z=Rv8+4096X)#GdLNVg1+dg7r)W=eNDY2u+pW=Wmy{a_6GyoYPqeYm88u}zp3Egsr_ zS_N_SZu||#S0S$OC0Yl(B$)7^g?QXw9iQmydcuR%hETx9QNqaNwbF8DR0y)G#3)ns@@tq4=wT?a|6=-4k2yQ#6yeRZSLe9!9z>F1wU+z z++)hhQS2sm^!M!2(Ft~u`(D!}J?F~|f4`mKgP;pbvNYY#=90%c%hYg2{?nJ0ans{iDM@=2lNq!cWiac&^$(DX1 zTbg)ik*Bh2UE-ldp0-K^!E@BANc<>6>G3Ayy2>uGsj#Sv(6h~&2%XeKtB{QnsPa{pCMFT*l z+(TG7v5{qQ*tx!U1G6n2nyudAp*@Pw&XJ>dXpiqrewiCjlti0?7 z=)A9NCTp{JXzR3b77tDPGsHvFy@+3>cxXz6cxW4K&5DP{gHarO4fUv`M>P)d(6pr? z9vX26_-WheaGu{r1q7!!jnkCUB zw^;D}vBJbV+!iQPzL29NpM#&<1kJw#+yyh^wycmJlSwL(l+2+|^PY`vPautD2?Til zRT#RSe`B^RG0k)$69t5%`&E=P!wMkIaa7Cilk&e6i34%l^ErY&zfICTNXLPMwggmz zAfZvMgd(Bwxr9@;05JhbXjg;7BB3$Ki9(UklnRm1^vOn0MI^K_!pDsT#k-1x#w2Q7 z{V@I}6bVg|iiGwK?t=fz_)}()(0HqgNN9GuK+$V&#Z3$Xu>ORpjp*O~5g9|5;0 zt4FdmdD7!ZTO_n?cyLL@YO zG8iJEDHS52DHS52Db?b*pJJoCxpN+1kLlk&QjyS@OtfKB zpIpGrbYdHHNG_DS@6u$8D4{`+&}5V=5*p3g!0$DZOZTGyh7`w(=hGza271}DU&;;c zdfXq=bn8z>ndC!A?f??nY8WgSLK~lJ67^!dpbMb`NNCsg73&4EZ#vJcMlp=q;Pr9H zJzt(5a6DNgG<{0Z7%ZdO7n*Vr)f)8UAoz@BZV!%OMLWeg-G+|f6*BL#k2Jc2a@Kp1 z9mhSv4i3$WExA1S1|9PfD{5`<5dHE}tMjJdR!lZPLQ6}%n}e^C`EpBcfkD=zow`)r zf>ecEY`k61hTY8`JC4>UtA-B*$+Lcfv_(SGp%)^dDOFUZNN7rhNN7sM9XCZs+OdoB zED~BB2CPLwW3Ms>D-xPgArhKWArhKWkhex!{~YC6B($q3uL12%zN&%Hi766VD1ocX z|XO{qG^9ZNB94MA;XyP$U}`SA-#%Og@Cq1mbfsoK~e zn`?vz8V%Ygu8lmKRQBD+-&nvanf4hRt%)772|{F_Ik^ zX91AVuA)X335{tkv%5IEY?N@!Wwz&2?er9m%wx>)NGCfmEbD=UX5e}?76~mZEwN#% z9ix7*lOy=7YG`b5^JVech+$qa zy%jgg1|zwta&odCh5?tFl^v5E9ab))Oyv}%LL{_1Brill(*PeLp_TV%xey7Bag;Ao z6bVhK5D87G5D86XhDc~CGeknuybuXZ^Fkyv)ht9pQz}G48!Ec2MSBOLk?xI%a%Ejy zDVOn+&HA!4xS!DN!+-}CR6J5S;oWyEk3K0b~e!Y!3nLQ_|; z%PMG~3fe{A&eF1)%CG$(ILi%fqJ@};degX3ZYJ=y)u$C{_YZKWs+n_<^!!D**2+8X zO=P3yeV@Yoeai74qiOZzw2&a1l2cAkYvI}OFTTjl$Rs@>FpyH!4RuG*tcm%_>i zLaIK?n%v1)`d1I;#~EeMVT=T+hIJH8L#OO7P%5%ZYM>VP9rssYObsEtnS0z|B%97e zvP_bx;kRdtH!p$>I6Em!no=Q58rh&3416L}3X}GI%CRtM?^BK$1o2~NOUjvnPE2Kw zT`Ei(*;I~5+|(B=lZpqh=MuPfc)EG7LarL0DcV4eCSVSP+k z>D&j&%3ij9r=V!!cM6L3z7+U}6rjlXKr7pE7g1st8Qi~Nf=tcmk36jHaIG~HapnIC zPSN22xRVAQh#{BiCghpt6Y{LwY$TsBtEvi$wplpNz;&RJ#_nZ@&H9Yoz7*G5iOOF> zN(||^1T0O>o{0+GS813z-xA*M;#zKgO1{I4Qnnup&V8x*#qcx>il!@y5EShn;sGHj z8oOJb&){xq$q_<@plIw*24n?AyIiOc6pj6n14X0B`M#K+Vy0I9QK*g>zr;)(N$ci7 z(W-?CLD8lP6@sGCW^O|Wigvb8At)M6!lxvQTOf1&KA}QTG~L4NFjWeQM(35MBr+&B z(a!Q%guBMnahjV2MWdPQV-XHy_nWX@>LeQ0eGz-)^sojnlvz+T!e3cXwA0`y9Ao@6 zHQn7QaU%ppW8kArAI0DF?3Yl8liWM#>hzqXl+z;@>3O4t3PI7P2o-{&v9j>UMS8JJ z!VMuPno`}4dtyC=Hvbr`o=?cLa`PKpE97DaRf=-X#5hm4yd`|^;i`j*$|!GMm{w4< z46;1G9@lb1EtO4tO&yv;Gud#jA|*#IQgY-XrAIE@`>1xu z9B>Xk0ahB5K1gA&8$*LH!Ishx}oLB3nAUqc|u4xH4i2^g>)-}#4;wAXFATMbcJ-A zD>{UbZp_F*x_w5d5YkOs5<VwG3hAa)N9<%o$;=X^LP$5ILP$5ILP$5ILP$4NB!qM$)Bz(6LC`Ws zYQwiw38WiaD#5}X0W~wLFQvv7((PGlT+cG=)KNl6H)e2!p^$FB5h|!sNVk`S3L)Lp z-Rdo*o9Y-sx+&GF-77JTu|Xl-G%tj7(`XOCM4v|Vd@7B}oulBVcuK@va5bj5VoHU$VoHU$VoKFZPu0#)D#R62D#R6|9oUN> zVO-bRFR3~#u9(&y;)*F1;)*F1;)VmXc-L#!z!TQ*4{H>cF+Il8j zyRPd_6yge{Vj`$+&1;X(j&?v>Dj2K1RV zUyZvqcEco4J<7N#Hk5e_^f}z-*i=jibqlqEEwNJOEuxz88t0{Ykc*j_U7*x0QJ2OC zn>@f*w^VblHkhMX!|hP6LN0bb{~}cKe451b|IR^N!#bAncG=kRm=EiYbX#rUu3M!l zJFz&euv*np@Wr~Lbjk=EcN~hjjVMeyTjaTZSH%ReIom8?mc1d zKFMu51Lj30easpDbF|z%DP}T%1Y@&6$UXTUtkV1^ggx^l!)*(2;GSfRcUtGd3g&cU z2DX8N&rHne`*FXS-2bi0*; z`?G{LyuUP@Ei(;lS)0flz&WIC7KWS|I0kcd+ZmiJ22mI+LvI@`hcS!V^y7B3mDTVt zW>K5imxnQn+VH8c)BHdglk|CK%npnrvqnDDsJDkr=Gwpea2n=mNNInb##uvM-oveS zY3~|pnQF$7B7R|P*7C!hlGf|4D7vBuSKk@4kbQ;gd2Z#;@kIl^(q;hR5m z)nv%si90IyD$2c|a-TtOo6l2j?;eVcIM?@+;t)Sx?0+@w_bzyy3D>dH@Gi{OP-g!Q zZ86Rc)YLAHb~z1k25xCpm$RzxgLEc5%HqeGdRuIk{rfv)?q_i^_Oa4)t>B+%USxr{ zjOnqQZ`i+QB6}zHT$6}=_?9^1FL7(~A=C_-Hmq+0JsT@3(0pie9O()SN1J~M>5bU8 z*z(^XEjE8keC#RE9n$_o;(s+b_%Y?nw*Fh~-(#Ue=bANJ9rG8dbOTR^O#Q9Reck?@ zCLA9M2S4qZXy(yTZ!zYO<+#a5IsE$!${!7nlXl%A?Ro{bv|YD|fYu{GOS^87c72Mp zv`h1^B`xjJ^4}*d?Yc$U^*hkouCGYDhK)qKCfWLD+P{;bgSP8-sq}O(IaANHxtH6& z%5j%)e4ZR=*;cmf3Y_$`JezuH%kDuwku0TUS4hj6M?o{`u`5KxnWUv#9(fNJSqO<0w+d+%YT7Cj)(fKLSc@5|ear>tw zV(lX>UiXZ&;WwbC+;8=I#QuE&cGPwp6eR|ag}zg&t=7Zs-v($7E}Y7HMV|i80vBkY zhrS|BIaz7=?kgf?52Z|PwWY_~zgo|0!f_`#V6V^8UiTQY*79`6)Ly?t{ukPj=WMVfV}Uz9(CTwh1tB67{*+9J%Y&vA8k z# z0+sevHh!s<|$Yp5^c zmb%AKm+tWrX>pICE+@j_U7*E1G{1+mxQCWMjkLJOP?uBpRiM=!hPhk`{1)_-<81wB z+P|BjgATE=QfcE1s6BPJ&HbYNs~jVQV>UU^vL7&*RJmrq<(bu6?Q$~mPlDS>%c`Vh zKfx_+S(S*W?glL_tCE(jB`qz}{PRdl%e4G0q@`t5(y~WDYs;#oWo0wbvR=0SYWsH< zbWptqN~K4F31QOaj<LMiaG z&t{R9mbuchD@aSrH2>SArDa8=NV*u76QAAv6LM>2i{wT#C9h7AaNHG z3mcJ$?0ItA+#`_q2zQ)C!)c?azSQ4rMLk)iB3I5ej*mbwS>k(CV$s*;g$<2L?0OG$ zhrq!UOEj4@AGECGec2scOIqeve7uEPkL`i%F_$wO>2a#CvahDJ(u=^b7nQb4r7zOq zpI;CzWnbiYXkTcY@lxgQINUx*QfmA?Hy7`alnP&BeI1L8vlwgCm+uCv=~==}-o9$B zsJ$uiZz82MV_2DQxR=$WWiR@-f!N2R4jin05iYR#9QZtZj=WG23Y`x*3 z_(PC=73=S2pPerb@%)mo{_~~&flEWbyFmQzWYC?|=R%kJkDHh+#`%m(>--qB;$KI~ z%ngtouX{E8?8rPn3^-1*EXD8-x|@JcbiXkNbhJ9z>+# zzvxqB{W;1dIxK51r)vwHV2S&ouy%Y&r7kDPK;K(=D%Y6h1R3c2RZHxGq`tQ)Q7bE| z;~=eK6K)^=PJ8(`VWRq)GmvlafM*u|uJ}n`^v9hp-)|YSq93Y@+!azp@{T;@@&iWH zsz}~Yi-aP1TSAe%`7#_il@M6_2|fV;F&d5O*OxXnX60LKS)CBQA_w!dk_3_(MDvi;1i zO6E|(Ec6{sA}9R4`_wvm!r!}JjiV?0^P%syqX2##2}0s@5w=TkLwJ||A$R%1LUNb5 z-*18_C2v%|^9j+viLDWxa|N{_wnlLd2)tN;z(r6Sazs!TTO---U-N6+6>JUvi+sw% z_XRvV;a`h*1*$04OzKNYDYl0HWu+8b!@o``#n$lmDy7&O{`D$Tu{Hb~lu~RB|3*A_ zKn;qm;oqc`Vr%$cQ7NrX(C%O5VYv4uwuZltUpx0Ewub+`eoPWu!@rlK%<+h=;oryh zMExohDJ#U*C^v1mSm1HD&X>TNJ*bI;1wxpKr^9YYn(uWT35gwsrlrRt;p=9)< z5LqJd2(i<7IA7oqVrMK$YOmadzp*nvDU`w^#J21ZO5qV=TmOLJ!&lcE5$s}TT?+ZM zF5wYkXRj7Y;Splz+%J^EBgD47E|kI}#I|=OSWe*)VmtZ@rSJ%`b59gX;Spk={+Un; zj}SYLC+XY~Jc37fgpx7KQGKz%BgE&J8$kGccp0B(jzz~}l=y^4h|kyWLK*`3 z?bdjY{jRXWCpn!XunIUZ7)VUm&ai&#UH)+pu6LB-Nq&R+b4E9#$2X&0ezX&*_Jp!-VuO80HX z!}|8pfvsq@KtYxcVv-`aVO3K)SSerLIh8hYf?@~qi<#0PN~Pq0W9iUuiz@Yk$zD24 zo7WgyPy@~;mC_1TZlfxnK&7R_A3#zNAL7ksE-JN%5Ao*>PqC|CzhG{XDjmO}9)A6s z>~9j^226Y(Mbl0BK<=o9fF z{<0-E`;{dBV15N1cpkzh;zRruOCK;k5g+2OTKZx9QatI`?D-A+GCUC<;;&2Hd|T}w zL{N)%Ithb(=!>l5)I{%1=c zaD5^^#NW2`!!C>p`W;I@>H0)`h`(#;XI-C&5ApXbebDuZ_z-{J(yzKc5g+1zvGgI= zzmW6?mj1w%-;#;{%~W6lMD&dKM0|*UXzqpS`C`~7;zRr+^PcSU?P z>=W?;-^&jY`pJlo*yF?_?$JU&8}a#tWxU9}LFj`KpNJ3fsC%b`$yXyj5g+2kEVC*C<;naK3(ml) z(1J5iEC-o_Gw7!zAvlA6rcv*B1ZRj1+=NmX!nkU+oL&#FR%-MJ&Jb(9TKK<=Yq{Zc zo5w54=2Y|u&Jb(kIpe7RQz^h1`S1cNoZt+xQSS-w-*K&x5x`kGkN+?mcm!vNjU5W6 zsNae!j%Kj{$Cj2-*=N9oW0MvL+cI3Wp`7#cxd_e>>pD}o&JnKRFga)c|BVI&XNb-G zniRStTZjvY!wab@1ZRlNd0zN`hikdvf+CMM&wK=Dh|TxmU-(&UT+0oY8+p7ck}eQi z*dlDBaIG<$;Nn~qD64W2oFTS&iEtg6<>DGex%hJ&x(4(J&JbIFb=K$zh8VoFR7P_oa9QqH05M1`>VbB%iJy`dDy=tLt#zf-@Yzu<2vL87{$n zw1$z4|Fv7c%!;J8oTZ}vk5HROaE92bcCbeMNw{iJE;I8DL2!oHnxlkk1Fq$UOV50c z`%y(~Ejhdw5d~sL6BZCNC$2T-7ib;VZutcW&Jf%1P2u{EaB+rtoLq8|9*Fu+;YO(p zcsf;V+UnB+i>jqj4L#0+Dse4F@C)lEF zJboD!?eYlD5IglT5%4n+K;Jx+6(Fgc>qULasSD!MOdY0;zWk&xKHYBEoxc2DG2UgT zUEiq{aEAC4S-JKhI77VCQ13njXNXTVb?7|-XNb=*@1stFGsL@PcnCN{e5Q1#f-}Tt zNu8d8Gi*ckB^I3FE~G6uLnov&uJVClF#bBk6|O!zP){&HSEhkeV!;^(FzWED!JyxG zVGO|;mfB(p&Ty(wAvnWjLWSTAS}p`SFTqfn+oF17+yI0I*F3(la13BeiY2{e;} zGbj~;Gbj~;Gbj~;Gbj~;Gbq*ScsJ4ZGj2xB0?rWsjv0oU^S~M6cbkd4Bj60h0?rV> z$9xgDe1bE?zh_r@j!$rg_`OE=f=dwHzg9BAs)E8kwFERF5{OQj7VIK%0}8G>l#TL?#LdN%yO`Hc!Ck zkuKHpZBl*{Zbbdt<;oEp_3x4NbIA1+&)_lKC=T%qUc%;7HlN92`xM3T4`P%9&p`db z_b)dfdu0QW#WS$u!oLkeG#Qg+5jUT!$Q-vZpwZ{MD&QF?bCYlJ3~t8e93P>|#ua!5 zGz-4?^(~%(i%m41arhR`K+AUf7SG@|Dcd7h7Qi!LSK(9CzJh0F>N`-g^N`-g^x)=%Z4D{hsh-aXOGD189r9wOdr9wOd zrCJ@eGy= z>H8MXAdO;tn8S~2fM-A@IG!G*KV2aHg|j98GOB%{`Kgp`^(~%(GPnB{&%i!<^IswJ zF4?)_sF`o^3>Z!LQ%gH2`C>b)m-`maKt-+fEuMkuyvetC20xd2H~SXPK*=p=e_ymy zL*7WFD&%5gTwgTIQ#=D&qr~DFT!gg6Gti+I;u$Cv;u$Cv;u$Cvcf1tG@Q&$}XYmYv zMS1aQW5f%Zy>XP{IaVluiT`PR#M*OJ~gXp0W@uw9={OLB= zM*J>I+K4~Hgc0B38R&wmT^4GQ6hK-6_X#U$1vdPtfE7m&xyGhWEE4CQapo-&Mza> za0Sf=)fH1Uz$>0X#k3#xW1iv}R7__a<(m(_x~=F^O7RRTW+-c0xX6{adNwr*7l31Mx7=)E zo?L9q{27Wx{bjfv75Mmpvd)S6TjkCrxRx?vsASr=g8fuMt5nb!`VN)m)Kq?zd%#|9 zXb3IDJXG^2ZphEFRnB|^$*BJ}t~G`-iu;3iDTRr8^0RD}v$*W{KE&P1U46h1^&4gr7pdxTw7J0dPtGR9QsBTe8Aq%Qo z$p+0}uNYDuaSEzO9Yr|;Sx`OtO3EQ*LG>8*U4<;DZdaxJ7{8aT9!oZrLx~yv0 z*r0k!CGJN38eElYT$W2%g%tj%&l?^=45~Y4OQ{9fQYWw!ZJb}h1C3yvdWNu`Ev$6z zJ!ECSTQvw`P(4jNkst=u)4w7GzAgnQ@;(+|!toZ7w~Gwk-!OKnXFM&u&k66FxblAm z!=(zxukfMy9zhJMyFW%=)c5d`u-sJPS|QA83xXI_&+Lc082`8qG}73;?7~^?a(fc4 zHS*;+(GaAajze-7?p+^vd>Ny*P_jp{(%?|P%W|R^EF{qw@HzdpP$m$-A?h0a1 zz37Wjm}B6S5fHbS4j|7l@V9yiyO>cpa|EcR>`z8vf*4dU>kvvo462v2KSB_L>J>CO zk7E+VpnB!CLMezr^^vr02x3sZ>S3W2#GrchyFw|5LG@9zncJWs2GwhZ3#A|i)oW>z z5X7K*{R*KJ#GrbE?prK~LG`g*UuDk-R&S!6kUlYZD2lf@5mJg$kZyfOw5WGHLKCD%c0pc=pcJG>T|?P?rH~%2n=VBu zNRP3y1*ITufoc?`AU#&SLs1ISE%i(N6N!i zS13wB`bcfKpcJH6v856Xyb5b}cic*k1Ms-w_g7mRUDM~?Ff))oqQ3}$>X`Z4Kq>tBd-VKA& zh*6(PNB#Rb%!yKvKH+C_<7`yz5tJa)bTyI|lpxc*u?g+ijDVGCVUm_7C_$!G7ZM6e zkZDsV>K0If%!p44r-Bk>j$pYgC_!cwZxNIrGfgQ4CCE%yN5R@RZTx(ZQg3O9b#nlv) zAhU`tngu1utX9&35@e2I6y%pDu~z!W8ry*iN|0GgeX^hgnRQB9P=d^QWwxLMnGH(r zE5d1JELAca*$dtl%%U|{Gx$dR(HIuVptfNgre6t@wF9(K3g%KfP&a0H19Jn$Tt{u+ zOTj3!Y;FBIv8WR}5AnaYpE4H3ZbL=2{cSOcU$uiOQ3&x>VrA`M#v80$9PdVm#Lv4T zv*bj?y!P6ml`W9YIkk2e^`rY=j8RkDr0!o-b<&1WPVI2AVNh4C$I<-S<|2`viv1h| zrM5-O)y9sY9<2j~vp#kSCWcx$oz2L(o74!-7+57aaW;gE;;%_qg^l!1f=abVT#aP% z>OM_3BfsjzQ=C4-wK{w}cwCk!s#@ptv3mGbM`zRVs`c4)P_-eOu86I~F1t?)g>t4j zWh|)HyM$V<`j8064{Q8UNGBcd-pOEZ8;v{O*CydT$Fg4|iTyCH<>nu_R>&oZV!8me zi;ZE(8fwl%X}4Xrg%LBR6-Wp?(C)U=3y1MQy9<;`Bzd6Sl@NeJr*H3We*{`K-A8-fYz&X?iTImy z;&0B1zgfidwE4~aykOWeDs}UdRHO=H(%hVrelw*v1C`(wx_tA|_#Mu#@T1C>t64^p zPU~q*Zxcg=2Q8-885+rX9fx9m31!+I79N`B_GQLt;~+5GXh?TCNNLG7)-@L7i0@56 z?shU?3DP;@Viw*c74%ratLplKQle-*fi0+TC3ftx6BI!I^aUP?Gde-m}BExOPC zJqsM$AY;^Qth~WQo4kd4qXqWi7-MFQVKAAe2BhhFv$tipuF$<(KjvlqyiukSldopsk zKN^2KGT#R={y`)b;+@v`Cy=@o_ zu^5R7Q;;wn$K(1PkoY&{&ur&kB}|y@Xqb$Gzp`P&*^0li75ek7f2GcJ?Y}Xmw#Xs4 zzti(u9>W^O{DUE>N{-f zFCL=S_!TtlHyW-ZXeV3EXE0|rZGc-n-CqjP?KY5>!LU_Cz6yHUX&7{88LqUt@J0W$ zjUdl91EJDmB+-C#UZ;O840Xa%^d|PyMP7a;r zZPD`-(Bd8Mh&UJ=qNA>K70gi(b(>HJ$@LUe^ z_EX?i)ntsi?BfHVodtB{9$V}Id#KKQV8+kF{rF~d+$1Dgm^cE7i;;|2nS-P)V728=98#4Aw%PbF90S zr>l%v$a9W$U$w+8@Ymg@#3G(rjNj?QH^jN#_)Tt;+KR*Vsy}s;EMA5b=G=QR##@I;c9YL|;pYUFvf>V}7xOcKM@Z6QadDs8{Y)w27Zt$ih*i} zq_CBRL$Yw7HansFhOUG`o4cvKjG>$Dwiw+!=T6nuz_1-VA81@wUd~CRd-3bu`5l#u{?~t6&iUf z8Jy53V9X1^)%gK974~*IKL8_?VwT7T;F??juFZx&an(Ln2e>N2X?_64iI6bj(l^6^ zDvbTY0E}Ron+x!}grS-Ur`dWml!jq;P`;}UE(&J@VQRF>z{O&*L@XX-#Y3`95uTxp zY6zI>F1c9U1c#!HM8DxV@4})x>w)6Y^)U_HEtW?nh1Q%v4gGD|LU3=r6$VSG0ilvX zXe696TkEJ8RvDx73x*TP7%LtMsH}qEm>U%gjaD38eq62@5*qVJjKB$Dh?|&Gf^3s= zZL#B5rl84o{6Kwjb>xu{#xNPy46-x76}cENHP?>Z&1pG9GB8ZnNd)U_=^`60W?1=_ z1Xk7(i54^eNm;o)D_2o|44R!+71}T-Hyh0DWAbN%c^)PQYBN74C}-v#h{@aGMf(#ZDf&bgMnj0oE zVA~7FH>0Yo>~-aGcvR(t!ewS23znH&2v4#KFl2%}Jc2UZPvKzCMT5@6L&?-I5KTLL z^iK~1M^}Cho`MvHkM1z6%nZXlVq>_HD_o)FM@OhTC)Xd;es0d19QpI|HAS4X24H+f zZciSGvI`0W;=(*p$X%4LP;OpWoYyYwNta}~4(qL@`5Cz&z3iWEOW!UJ!>PnoL{+Pc zoz{*lu^mZZu2tbIvpQc^exyBWl+yj@Qa8JfId%Cy#e_=b9->CeBO|sCg zL9SsmbMG8kiZr`s}q*he+X zS&+YtN@e#R`m`#yjml)VHDO6zrsXL>`Hn^EO;$#+FO>5uY+Xz?XzW$g?H`s*#@$*}@D`aBJ`PRRQ ztNF!pg$iarwHo_7f9``#3gT=2nxfM7kR3@?Ib&iL)PS2e1OBUk`#*O9@gIiU@G%xl z#`(2EA7fSKA{j$rRsLhF>M(@iC(6UYgT+B%{LSRzZ%sBxO8n*Pf$VtilOKQc0xm1f zd#Z(JT4DS}$jv>*Dh#;UdL$SR2sdB@^W*QJteV0!I2`c#QKS)WU?**ks3AELuLHsY z*^n$#^)MUy=tzil47zzy_VAYg8VLSHusv)@ggZ0qo+EPWGI{(@PiK(LT9dmlTdn$P zUa0*)*m*-24c~DU_H()QCm0FtoBz-@&xzr}>e&Cq1KC1%&pnbAC&Btw%^L2dv9b&8 zj7Q-4?veK(91ff-7w(hmbGLFqtY1zXo#%hC_bz}{71#doK4mkp~K~3EI}%R)T1s0zP`{ZNW#?)`C@QZ!4(1Ra-&r z%UaadzBF3(+JA5Vzcn*!W}mZ9>f?Ivcfb36*q*)i+H2OVS+i!%nl-a`Cc9pw+bNk* z_sKlXoT9DhRGw{M$~vv4Ghr}doy&sxQc4U_g1!&#U?~e8B~HL3oe?F_fGBnX{=dtr zPQ~;X*fDjEiZ@|Yr@P%!*Ja#`6J3X4o^aamZ?$AB+m7?|aMKi4P;5uk(;sr2==KCx z$Q3yeMc6li=EFV?)Yk|V;psE|UEs*6^XZX@7s;l8lsSR+Z znL`bGsCvk_gcew-<|^5FtH32mR7~lMVMz<;8f`-;(l(BYa%8O)r~d2>qcUfeQlA3R z*|d3(;oft`dj8ciucEP_#@9&r1cO>blfEK4#5q*2sU>e|j^!;)Y=OF6%DZVb)~`KHMn8de83>^oCZEd9Ef*8b8K0VEi~@v$f_d&ZUM`Ii!Yp zC~DF`AY$do7(Fy@^`;(=o~+SH31MU8yug&%OhzK8uHiXKk$!A7C%^IT&Sa3wbtQ8X+cewm(d*>j0YbrQ3H?+0Cp>qS)aZwt}-uS}P4439NRsZ2C3>!W# zVEhO>H|Ltv#LoL(ZoXGx03Ee5GX@Po|4}R4`qEou;W$m8P2L|!@L2*=J~sld=4yc}^GB)pn^QWMm~kEervZ$Z z*5yX=ova4BgjHLa}^2cU_lsUgvVCr~%wrg*c4 zQ~llXq%Mjkwsir-GJ~C#ABu{jlRb%?Okgd+WmF5b++l}q?}f* zoF;A*j`)V>UO~#hcGge4Q2rbF;)D?yn|bbe_`4*bNYR*ZMC=(D!NICWy!|36M`Uz% zi+-ej576&5^i#o**d+?(LAhU4goi_+n@^YZGv`hp+Bdsw#+a~JR0>uz_t%N_;VB_m zCf4rGum2a39FetiqO;4+k~P3xin}s<_pCP}_k&Zu`aL%E@8K!q=i%w5p|XWw_)i0a z;P@A>RKdjkO>ZaQPY|!1QsGlVe<~K^_lvRR zqPO%9qObJgj=GhtD=UY3M4udg^h=(?xx)m{cxOwc_ydIU+Gw^1`(jwxuh? zVRA$~>dDmc;2V~`^m``#%%Pt@N6I7TJSxU+-g4s#S^SNQqJJ-|6Nm5JDj$iC5n>8S zy}BHPA<29D z(14*~bTJ+A$3O9BFI1UcB~B<3sr@3A5{IWQ7kxz)qC<`sAFh3Af;enM^rtS9r-{Qu z>Up^++;-bCF}_x|27g69{(2dD^-vt#40|gf%LmfK?9u<%&k65!dh2Lt>wM3qN`;Cs z=foR2-uo0rlXWtM$)X|A1nX?=h6VoPX-pX)KHS&Vu+~lmqfB5xv#;kt0(<4rfw?Tz z)O=v7xaw?og`!j)p{v#Eo^Q z*S5FO+>J1HZ9}rHG1i>!Y)rL52#qA3Yuh?qc?eCN3i@gtJ)o^b@Br&IJdN6S`= z1BdLah{`RC#FOdGt%;Jv=4dork}tQ)i)1uBEWn%dqxP~K}nexXQ_ZrIEL(Ph$b+fvhKr`u~ zGwG)uKcNUQ5R$kZvY&n;qDdBs)8tMFHY|su(Wiioh%Vwn&xj}@jz@g+J3yg2`bpA{ z3Ts{eCY}rWHGb?BHM3;R2 zwln21qF2_|-*E;?Z5m_FQXVr;0+vIEF2*e%zyX&?NUG#~C(M@8{*jn+^o`WD0 z;>!bg6CBVXk!|>mY>RA{Qv@4z7h5MFT-2Y%K5aO`?n6QSgm-E6iCO)8~*-gwN;TidKl{@Hn7X8dw zCx@EB64AYA>#4iNdRg?k+)gCmDT{DLiGvZ@jmIbM7TvN)Mn%8eEc5aAXrc%< zW#NN~EpLYL3M;jHFmgancu;ih26^6Y(Yy04Stst=2%>H|@lE-dA|i1_q>O&$r0DNO zC%B2Dciw~FiqwPMTi=v7<)$O9n(i;&L2(3PQjt!{$=6;F^ZxwL!wZge&9(fgmf7@E z)@hlJjfBr8U5pJ+oj?~-#@IRScgabM=G}V9ic7A9!Y7JF2#bj-Bqkk{2VNUeH(^B8 zDIkR!77@8WA`&ped@)%zM>kz3>SZBr#>r-oBdSGQZN%Ji?KPiAmz4UtB#6KcfC0?dZC9U90$|C&zzR+&mDT8w#IJT^f$4VJRXz_T5gpkY!T$ba~|V zaM1*Dv@91TG<-wi_JI-c6yj@9EmPZ9$?bJAEhcW3$Et^MnS!$AG4fd%{mu&)JtK|` zSA@itLq^1()^CR*RSG2E5Z2Gq3ZZ^Q z-%c@Zv*;QWN0*DPT9Ji!=gdf-rRNFJ@Y;`?n*(qEx2VsZqrS`0!MsnAUruFPlZRW!vE*g7l+R{R!*K(d6sw@MQ=q> zeJw@FIxhGi3a&@fqhgKReDY`dW-hs6lO7C%k@{VbI`o7b5^=ddKUrAz+I{lmtHi!B z2fr)Mkj;0B72D)Z;;_A9e0j;NbDkD;sXp-`xX?uywW;m0UQT=sRc*R#5IX*kF_;(7 z(gV+mFAcy+J}YL))E=>Dzq|=*&wpk)t)Q04{r|ozd@`BycywsG4(pv#xS@6`cpyCG zm=}6hymW3wCHitEoX?nAvFEZ{bEQ^2d>PDNb?GCao#?ruTg3WpRnH9%Z+SL+^0D&% z`{Wd*#36G$|+4-ZW=R2+_ZihRB`Z-W|^oAPNC3VyjUFeet{V3|6dAF`U}z0 zKT1~F^w59HQXn&$r=Uy4cD#JenU=~G&nukE7yYL)S2o1=#r^*!(fw5U7^O2R7U+4omG5>nH#^xmnbgi<3)V|3u}|#o@^l z?*H_;6`P6|iw6b{iif<~3h~{6L9x%yATfF;}F9#8`y9?K{Os2gRE3)Q~u8XUl!!iyLdj*D>wvzij7l#qBSwA`h#y@@KhQ z;4cJ>mlYMOioxp-eN^A|hn55WrGjrhv{{TD#O>pKwPM0%^%QgSog2Y?zTCc~Zc#tB8Ihx^NSwtZiqasvCRvhsVPM)57U4(@mco7Ya{3PV|?y zmMvMk{3dy=Y#oYHWPm`tZm#IYvO!jSlBR__L;`_IFU94@Tv~;PH@ug7}(?g=2M72K>o|`YVG%8jN zZG$*8|JJRlsHnI|G3g`W$3*B?M8f!!R=UcFcyVmFBvfCsM7AT`lI?ZjQ}X4G@TvI- ziS>WGdun~7B3zWedWl`R(w(%hmILOueV~+@TTD_x2C66 z4BsYdH;bv|qPAR2Efuvzn8}OYLZ!%yMt+6>tU{iTh^ZWTYl@u8#jL$)3eQ3+%odRz z1@DZAiM67+TzohsP8}f$i(bY9nBvA}fj=723}EN*LV>^cxb0<#|M8*O6)@&+Z=}KZ zJU(9=7TY$GaXlHTT_*aADu?iI*So*Pp{$nVG zqKMm2%RzD2wmq|>;>)2Tabl@xOqJtuqg;|7z4O5Amb0#Jd20I`uitV&PMRHUdG+~E zc8PJcY&E?j^x{Ev!XA>H0#q@imdrx@@N!h9T6DjFO8^uSJv*_`#wxXF)BQ8&c2IkU zFQdWs$1&v?*2Rm%WgcO*8OEn_^i;hDDMAB1$)08L-E-W2So}a7<&XjQ~SO% z22uVn8gfEvQL$*>Cf1jW@U6WBH+ItX~y0C{fMt8DUp@9 zkXQ@-T_yDQNodhWq2KqB$~Z)Px4#tjiQ9)G%}KR}!0H~-nVzg9j}iJT2*1-WX%pk2 z$Ovv8=!Zj#y8rOtpp@Hw_OX_^Vr)_CPetG0CGus8!Nrl}R`M6Mpl{^Ys?n1C*=5mB zhfh0JVb8u!e(fHEyevHRSgfLE&D}V6&+M|x&a6BzyJE(!iXm)|^oFqydd7$ti$!-f3 z*nxE<|F;iQB6)oH^TEh;)cTdQEW8x_e?LwZ=I;_Ot*;ehn-MKsk0r|B%OLm{wUl`L z5H-y1T#p<>umO)ALJhcQy=wpuvnL{(#qIsu#1oOxhS?N2v(;K!>VXi3*->)yZ>cSj z@M+_5Wdj#S?5v~=31lx-vcKIgi?YYuuOR4bF#&67Jqd|RQ{sB8hiA-`WpKiWh~Mj_ z(IMLa|7kt^S+F^uQ_UI4(VXkioR`s@>x0d?j-(>n4yk55wM0p}J0gyxTw@4&Pu+w} zR-rg%|Kf8|_d}>VLwL~z6^F#GF>>ePb0y^mFegz8@`=l6BX#E()dNpmhLv5j)ckX$QeD^2kA)Q!`F*PeB#vK$r z%@;i@_H7)Ir<{J(%&qHmVtIt;`S1iV=a6;a8ttim3$ll27qH(`CWhbJs~5sgu4`Ei=k!bp;kpy6c2zY$h6jL56W4}{RNt;njJwyp9^F}RU3Bf4@G<%r0m zie@vCrV7XwMfr{k@hD8SpnvcyB7_yBH__WGiZ+wbCQy1x`5tli0CX{l^4FpINGd|k zJGAGjJBNRaae9R)*!DC8{sm2@cn}sNB7A;Gd=y2HFF7E-fz+l%+LsDpJpV{ta|+f- z#Z~jQbf!)FfEJ7Bhmzc41^s*qKSoA*l5)n#G^fN<5*eClq|tP_IIMK~V(}r0%tFZY z)ZPw@0F3y7LQ69!`v??klu?Ke4=UOo)zC#-@t2owPanML4Eb11ea*8oucBxbmZM7J zuUSw@`B(ZqOB_!VSy(iN=Y+5p7%w-AOJ%KWlP`%U#)bPsg=$D4C(^s}KDDixkIkj9 zxBP?JxPFIiP1=rr&wJbNc{i|*PROV=XGcdvw_f=-H+H7lXJC=1w$;ogHZnN8A_toH z=di^aSe;Tf0EMwj$16losT9FK-jwcs-mFXzt{t^aT#D7yejF`;E2~j`*c_o$>SLLh;0Y32n~tj)J+TK zi?gwn-GZFkoSmXs9*oW|p7C?FW-QvDrW|$(o?1+3mSq>I+bOAXY$}b2UdVw^qcD63 z7FFMcL4>`;f1_E9YB}mu(to$%BwIVQ-T3T-L0FA{vzN^Vwh=HJHWoZ{#)3^>ePfRb z84L^z5ak{6UNB}eBZLfV5#`B0ey3azE;(+(8?x;q<>!55I?m1Xh>q}SAu&-NoV2J6 z2VF#8>LJmmJMeOF3VRR2tp7W5l<%{9e5X@_2Uz~or_tVPy0Ol>4J4*=?#3bLkZG6V~53(^%Z$! z^6D^lQTL0y^2)_SeMmoCEfPDExD}TU;=J0fPm2|$;>=Xp9fNF} zdImamEs5-pM86v#S3#M?QmC1Pr%H-15lP(-SQh1~As>Wc`3P44D$!OXK6G$MwhZAo zLr9h)a^ENqmd|-n{5Z4?Q7~@QA;wE)?2*Tudmi-u%gZU>daKwk?m_YY12 z_zp#xq3f^(Pl0E~(jTWoNKWdJFomHySXDuF7u{CU&*I4L$hv)tD#|K`79tZS#->Qr zBY5F~*kfH0!iI8DBzK2IjXXI0-0A1`e&oFE75AkFKKJ;pmQUayX< zO-yg0pC7Ik6ZVI2Wa1dg*j4nb`r^-?U-RwyyF-7R@Rv~daLhS7RRA&ng9;$tbI=%^ zPd>;4kvM$x?oULjs6Z8XkEa?bO3*>4+KU)5F6y+9%wJVrrWZ0ILZi)`JD}kxuB0Ee zG&xUJzm5E5@lfkeZ~M!H^tJovG|j2sCuc_GEfeIVXC~}fJYjp=gt9QcW*k}yM;!LV z2eqg9U(;Xz1LKAF8f2*BjVe&&<6q{y{5zei^-Y*L!wiE&2WABv!2FL5I4G##SmWJB zAHiTF5RbfL^ufAUNAGBSy2|0PXtcfZni*}Sp~c%}<-$tQT&vEL6xGcUM>dP}ZauH6 z^|V}6S+S_B>=q>5kKBe6EQlb=w!r7hZ9C>Htw#nRJ!e*{JbBM5RP|OZ{yIeUAwm5 zu=pcwE#Z$H_xeJU?23RIZh&$$KUgi#KY#?nk%No2x0T(On4OlD-`N#~3jvK1MjpU_ zY1Hts<93wA)34zqmG7ykm!410-$6{p6f9SF4q#IWM~BKPZV-vx@;uS4f)MdX4=2fn z!^gv={2LY@Veh05Y6xV4eh)Nc_-(kgZc5ovL)hV9LZXf+P7~XUJBX! zDE+(Y1TnU@q^a`E$*}9NikV&fO?kdBB^bl2u6$vK%8J~gEE<0)<$v;`I@b$o?{Gp# zXD-NVvcdU|$-MKj7e)Z9U~> zm3NA}21>=Buyq!aJDS9VBJsD&i^QM9IQ@25Gp%AOL0(d^q@t%{31aM}eVfGk!76bv zyrcN+20B~2Xl~iCJV|T{V?PKP`*P7!Tla~ImTB^&isvc$*FPer7K!J*{l|%;)SF*z zs!{6Aulp~TuyZM z)eq(;JpwrOqQ{bQe*Skw;6u!)0Oa12B)^>F9Y~5mR$4 zm|)^3#?$kyODi#k+eR-wFixkH_|B!37^6JDy|E*mF*?VDy9_t-K}30Ka&ikVx^)u| z+!b{l+F{6BRUMm8w_=iK+p$Un~X>wAXIBU18 zox5Yz>^afDS75fmzF+O8p_ZZaP(8MSwiT8|%T5w2Wl>?-&_(GjfUgicWy|dH;@M?& zi8*rO&|TyWu%)#Bv1pz6mjRqX@ISpA z>nt1}o}<`(N*t!P0O3ydKPC&d49QKRX9U~*2Q#R?NfpY1VPs&+aVTpLIhS8tuFja< zEaXGDMCvT}!_`;ZsAyDm}gJ3j#;f zF8SG;w|x~E?Qa%~Da~TR2ol&S(N}x7c6$-p4H>v{VS1?Ih3N3EUAHb@0cELYI?W{x z-&-%DaGG%BOAm_axRm2qKjfKBhc$X>0}Ll#Wa({tqN`eV%&Ke=f8GH1{oMy1-nD4@ zmBSYeN4KW%}@*5DiB;*s})-g^1SjUSPZetB-qc`Z9u&OxX@Ilu13 z-uth@xwtDIz4FQ{uf3>6-XZ#Ncr09U6#Z|i`yUR6ObvxkJx0DDEA~ObxS4sRcnXvu zIZx@zx2-9Qfzdfd9n(Zqq6??Zwk#BR`^%D)EK>W@)9F>Am&Mg$n|R~$@_$CIbU6-y zQEBWL4&Qf8MKt=7L5ig~Pb5FCOX6@GrJh26e@xx`>n@`W@DviErQ$Z&$4@RlI3yZJ z#7Ud)Uqbs}nEz_a?-<4(Zl$}!(F2Kcabya=s@5XxAD{Y-is&#jTqvNM>Eac=s-!x~7mla|Wt=eKABR=S>^{0_qMtJQIY2+^j6hhv zrr;0imvVMt`TCeKbQSl~0WAgX9h0&+Y}P5IG}&eYKk(0eTuJaCRz0pC{~oineKHPK_9bgMcQTX0aoYpdYwZk}NBVj8!iQ!Mz{ zI6rptK4W-tq+#1H;0Pf$rXIfO$?+ulSzlHWLE?YI@=F=-K#!Kgz^=M#< zq}ojpM{E{vZa66GzA^`;hLG~da2=9g#3vV~>@MGhGlFle{tWT!X%-LSs|&5O>XwOP zuxiE0GI|FPz7F3)$O}&kiTegh7gdM}vRqEW%YJF|zscCr8oy=J=PLKe)xQ_xaVFPZfYaYdr1NbQi|cPCaODKQR{G#<#JX!x{aZX=2P#|)o|$jy=0 zhKA(iirJt2T;)Qz>E=2LXuc7xi^^3M(}tq6qwUuW4VRs_;+fAb-Xx~bDfTsc_aUiN zanY}DAMU}+Px*Ms623V)w5UzqhaIC@xl^1`E>_n5bjL!aqH*f2w9x%@qmK2cJuD51 zejT(Nu6Fxqi5^lBfy#D0Y;Tow9Iy;%%VRu__CgKfs~fk8pN9s;EgJ`M9%9c8Wl?;x zVo+Q&KqtZ{J=SuYNXeqDP}%8NZG~j*KB6`J(yL0Z zhUn=v>In1eIO`tY{Q8-do#|hT5iC(f_fBy#P7y`Lt2k-@bHp7t$~))l169}4hTg=3 za{iT~eNesKyLlJ~yJtr)x#O9KX~I1MJD;^UjavTcOt( zc*8o~t=^{gy1SC8SW}#mQ9TW*xJJg3tzC)K+H^ApXhRAwUfYF~7hAMczfzL&x)bpp zyyFpXOru;=L#n}x_o*-L#F`Ub9kIst2GpALy1Mb@op`J>-9f`Wo=AAjU5So{lwyTC zV&wf}$|0&EF?M=NmZUzkVZ3WoyginPH^)+5LwkEyFPP#lsx~w=5z^~QP`0gsC{pP} zCxmWK$8}aOj&BCEx2=z(U}p_|Jz#M|avkZTt+_4Ulu45S5w)^60YS8Iji@b_Z0|~W zJ@~KBt1>uo#^V0CsO@hOFRV)bS2Y?xYw9YB;uX82OAVg zHi9OjS@h+O7#F4LY0Z>~x8S1zc#S5>(kHxRf5%$9L!Y81c&XO5B=wAkFZeX1+v%lw z)ma_!jk@3GTJg^4ig#ruVARl^!P3SQB3H>Qo(~y2!MXw1>X}d)5rE zne3sxKi1W4TANBVw54LOg@z>5hSg=dk%T1q+3e76`WjJt(iG{!hbff4pl!0f7|E!< zMx;j)?5DFL-d`E-Y)Q4kFp|_26djoIhMk8LU8d5g0lrQrsr%4(jotkat-Ybu~BBP$mOSHuPxwv_R(C_W(j!v(uGp4M*-&3E2 z!p9T1FzG{^k&&q_&L-5>*%a?X%bK-CA@ahIg(2$!#=V`SPN7EhHY7Un6)LX_g9Q@w zQg`D2@dl$16XsBP{V5MG4HNfB;zIS4Mwhm9#+wSU*!Q4sw3ql&cQvKERmXG3uB9j@ z!xS;-;B8=+&{tCz456!o%sSQ{@AL@9;B9P3HMT07fEL$cOBv1(flC}s#5i;|)wv|y zv9x)<9v5s5rt6#VXP{~9D}$nEofs6vGkaLHG(r$RQYkTJMqAQ1T-x9RQVGvC08J+o zWi!-Y*U~zV(U&eTHe<2whNkKIa+cQ#YIF+?1xQ4XKAPp)4Ek*AlC&>^jyu!j0Fia8Zn{L;|v4HoGHMR zTH4u#c{YwYwJX)7oQD!4-Pj8Mu0YMOApuw8Rj)Yz{Q1?@=;I{*DEfkViz-(vpYOMJ zU1TkG7F2h*HX6m)zSLcW0mpNU>I6Llm?_PT2RAFK4zk@vR;v{QV^_-6a|FpZLk&D? zA%-mGKCZ`X)1==~4Bh48+;ErzTE} z1h1RgMrMt7&Czupym*>CX;QbpvH_k#X%`<3)2M}TpB`pOno?0pO@wgmO@TBhGA46$3>*ji7`bVGtfFUc#GQ@tCKXDMUBx@#@46b*DAFLx`@3C_H*3at>Rgnv zH?370BkS!7|DsDp$Hd>?e^QGQ^Z{zqWOJyXY za~gQ4Tq|O!jD`>gmdkY*$C1={dQZF=!vmHLTQ-`@?!_ccIL&P>P$>-nJ2z2$>*fUV z038S^Vpu&O!e~-wePj3_Xl7^YuTOev0i)svwfIm=9^LIu@g8Oe#05Iqqu4+xS__#} z=IT?Bp2n)+>HJ#E3>csc6^G@-R^?_Or~iO|a~~fC3*Kr)uwI zJ9HsDR8?29jlPKm?V0%-vv!MjNe9B#rltf&5=FcwGNuAGYVqK&QgseG65d%)M*g9i z@|tbbiPahf@l9HjW>uqBe$=);6Q7YcqII2eM!I^X7OWY3cGXY8jtY3Xx@YKk88KDn zOlekjWMp0KO*}k^|AIx8^AYd#A~;S`(A}b=VPBN#Z#Tv5X7S-~cP?pAmmV6%{QH$( zX>M=p)>U1&WJTfmh4|8I(OF(BNlRqat;)zT;?`ky_E(`ix($uMSqHXiT6Zyx8QW&g z&~vg`>Z(nIj|=NB)t zsc5_6qQA%j7(32SytDQwad*~J?YSh68uhyV{x!7r~}qaph1N@JR!_zb zbJhOE_9uBE9etz4h;e$d#t4~(7E7x?O$E9a(OxE;YE>6*p%gTU*7YZk6M6f*KP#U{G?2c(ihZ3nkdXXt~%(Pk5U(K~=HRC?$jJY))lV&RfspU}`;=Mz_ZsIUw z%j|!|61`LpRgDf|vKU5)sy>rSjVj$lG%bmx3)<+)s1n)gsa`m5`TPqUl}gHVX|GEK zl(vzpQsQ}?9hAwW5zx>C-@{fx-WQcq8iCek_#7!)pPOZ z5`F@_#p7sK8jDa>S;xAjHr+LJ zCYFr7p$E$Y%(@*hB2z>6*mik(p$;v#CCPK8y5PKAV@zK|Oz=lKOXY`X@^K{a*?8QWAeWO+t^(C{ zBAi_3p_lbHN=X8Eoeo;{;LArIG(kEbi!!D`eT%U$U4=f)I#0nyK+#VUOI(;SuM3d} zA!8-`rhFl0xFo!c(lI2TUuqcn46G8L)y=7XV`j^a3wScp?fH9 zQ0oD>_VqF4Gt{`!Bb2kPMwN~16)1^`g-QyBTvffGI<{c`{0m}>=Yx~-0LbX$i&tJ! z#ev#z)$T6krPlVR;IbMJLSPuvEQK`(Qk3utm}l_-BMiZ*R-frzWdJnL410ryuhL_h z!a!%KoXr3+87+Cm7>zZ&dkt++m+9RP%(;}`Q+atcFDhLjZ`GRaT&GR^^N+7fp^k z(4Ay_s(~3HvCokr=0n1d8jggXXIf3;*H}uXL6NG+o>Wjg#g_ybL zFOOX?zjA)f{Mfw8O4Vc@KNQSUx|r5fv=J0n)~>d}R38&J989B(hYEPmEZ7`ulD4SS zBFz_%pl@3-otUI~+Quo?8>eY8p)(IGf1?gjFsC4;1as2^CElVE+}a|jQSrX+bY}}z z%AQe>UM6d^1g|tlvedUU-{>zQL;QGiTc7isxYc1EJg0xaQ61zgU}ZW&BO9}wf!sf4 zBE;WIJ6EU~wYs&VnwqJG8tS7JJ6djnSCYr;z_?UdPwG|PIJB*9jUx`AfUX5b){kZ( zZX&k;%YilHPlC{eOeuTNDidO9QBFIqB{lPFYho(!z&L~X>ve;%5fw`)S4g{`YH*X0 zvtgxCpUyQ|zS<#HFNV43h=F!hDCwaZ0G}Pl%+`)c#LQ@V5OSJCS%L0C%oM(vW35`o z#MWXeM!cz*+3};&^u9i^=B^A+$xD^5ZOq_k#w-?}$eg#ry3~*I7mYN5V&+GO;@b_G z-Az`94J5S|A_to6Mlh0WN00@tj^$U}O$dvYhW%5L750Wi$xi<6#G!K$~ltt=>*%<~y)gNM+ zSwUGEjbu1AEUI<*VCXoGu~L)Ag|$%)-P)~V9*;x0G`lHrZEf*BIAjykp?BGn^N38P zka44C_=cid-l%;qH6{{?v_AGD937Ir%dm_fr4dE2droWs|d<;bE1RR zB^e|(tW$x6)`GTiYLL>DGBCv2NCfCDAPPi$&L(ZW4cA5O^dGuV^S`T?mKZ8%s+xxd z@zN!k%*+s=WS-Ika>Y0$fEc1%MFHSVJ>K51HjemK4JWLGT-ZkTL9W=iig+JJ9?GDD z;|Q*J`-B2?j3FIZH+FTcqp*RB(pb$1vh|?_PO5^$&X$z4$Y>?SFsNGXKF~HV2CJHp zalQjf2RZ?uzJ^M(2hD4oi9qZ^xi#NJ52t{oRFl^mh{Uzg&_-~Nn(fr+Rb7{$CSg)Z z!hz6~svVOWn$t^EJGHwwS<_O+p;W} zr%`uS1(6XgJMmQ&M4lb2qrlNWl3n?MW;O!6)?wh&iRpzOga$R%JqyF^X! zWOX)zX`mz!PA@rYMPq4J*isL^jeVOS^$S_=Q`O9c^nK+|OEs2wm#wc|qg9(zrwA@jHXa4f#u?6#L=2a?v z!R~k|s8e@I)m@pz*{;a?FdQN;^kXpCccFK|#RE9#PTCx`18vOQ=~ zV@8YSU2uU)Dv~$qRsk5oOnb16Ml!{TY6K+p;VBxx^p`?1<9<5WMy^LEKzQZK7NpL& zCEI$;vYRJRHJg%<{p9(xFG9%2WaVFDCxLNW2q9*)y>M4;0e z-Eeal-5EmCs*jwHt)51NUQziC)E7z7l(TsL1&dZJ)&Z=qC(&C71t?fV*Y%OwG3UDg z*ma3olhB3$w(>h@BS{Geqg01La0Icl3pQeQg$*(g?IIh~O$YKCQ{;3g6HA-OZ1AKX z8~}o0zztIV&puGmO*4v7EI?+2#RXj`J49;(;640-IlVwIlcOH~I(el=dxim%1ELy; zi}9U2hE;fH_5yS&2)Tc~G7DhNzcD~+E zt475ODDTqI4}-U)ym<=#*z_<5bM#D&l@Sctgi5+nI&0ynn!6LE5=GcXizci^=vV`J zH)uqi$bi1Pu`E+sin}bL&bX3EYo2Ulrm0>N6btb^^lLJXty7%^bo8V_)j?bwq9d_u z8bDF4He|J*V6t>L+=aae%xjbwqm2X~1JxWJg{~SEa;aD!SzV-o)wY#;tbCV`3mx9W z(E^&GNfCPA9jDtAcU6`hzs&?WW;(n>`9Qa*ctkr+L?V3Juvu;YsgX~S05XZR2SVeA zWl(Bx6)4A{=sPe&Q1@VxNBRV(?Q|chWPdre((HE_#nZq_rcJWO z*j%MGy5_b7l8#QGwdrI(0y6q5P0Cf15&NxDO$W&JlKo(WV-i%p16#j1HOyl~tzanO z%|1&hqp6`=?~o%E)(7h)6T+VnYe#T~F|PcnGG2_SesoL=&5m?Lsud|$>OS-nO2Iv1 zcK(LTjBbE^t~>0S(r{%AfJzR!x9}swl^y zwzyih>JT(ze4uSebeM&deuCL3PNx%HeQF3RV>O+M3+>rusGX)-)t!0`tg}DPBF%zc zF(q{>OSCITPtC(Bp@)zcW0i)aPIpl^K}tGX>?ATlygodk=wLFWt(L#hgs4^}-xk_xjt%Npp&XVD2$bNQoZu$GkRvY1K)BFE(4MJMU7Zbvy1OlPLv#~3Dd7{bJZl5N<_gy`?b8K5-yAO^j}GGpJ` z+JRLtA#416;yFVifS6;a8bpR6e60? zmx5D-zJ7XoYBDaC2jM7mvHOr2PwZORV_BB0SPXH%ya%C7su^oyy;4*aAqt~pE#}t- z*GUx9QY|(Dv^8YQk|hW2j8XvC9%uvx1)cBKH6vF=ku>js(~Wj1HW6$qWYw?&U4?-v z%xaw}og#=ohMn1JQ+3-L3Q3g0%~R9UD4|vv%q&yqszfvOmX%X=RAw^UK2!bOOv<+? zBG0Hm_`76HO+F=Ha9%2N@7Rt>Lv7P}$8O zg?>n?;w3SLr8;pDq*dIgP4A<-4R;tFVraGAQ+vwUt;4{>UY45Pl5P4VB(6x*&~6b1 zt~#VmXI)y%-z$esL6B4&3EkM*ZpI06&Y1Ak00o80_M{O*gSf4Q)TS@Gd^e^6%xEgV zK?gGFX)LXnD%IF`x)f9DQ}x{_U6_J z!xdJ|UpRTt*wC!wJ43C#F$rN196VrdvD1CG@#`v)tm)oQACMr%FI(w(UPjZ_;~gob z4kfVP&#`EH7*1QQZa>nMbjXBI-R4ELgu*mqHJ}HJ;%Db6b!S@XXOwd$cXBFS;?2}9 z7b4h)T8ZkQz208oW&DL8jQ)P1qUMD|R{mwTyPeojU4fI!=(HKsv zm~9tq{xx8j$8`EeuTZe5j5EbphhT`q@ln1pK`xX!KSo~-GMNaK-OOOFBSU1S+VH|z z<`d)t(|BC~=d5UtQ-$Oz1wvI(4SJhct=`o6s*KWFI&BT;VwhJZcOE&T_RslhojmH} zg|us#StA`BP_|4PVifBp@FpZL8#73id8nmcfWM6+ZGV}Sxp9i4{I&Mcx9R;A8^2;% z^8n9fg*{zno^jOlex|P@)fBBP({3x6^Kr4pwHR(xGb3!qPGMbI+ecy(YFuV5GH2wg zX#&7^Ct`H8(OXY_ttjPksG}}pvEXG)=5OK8LK3Ecf4w0Rc!GE zXUER3sU`L*<4RX`0_1&!PpAj|*V2$!ODBK$AHKh#{)N01jLN<`lA7#C_`9s?-vo2b z!6ir%;8JKxpJT3JuU9gha=1c<(+-C(iDdpOG`I826%sMnY*Ez)vX?>wU0|*uuZF>O z7PZnq_EKn|h2|Ramf2?pC^T0`vOJq)sX?qU*N|7mV9cWGvrAoJ5Z9Y4>5SnYI9wsa zk2{=X_@KiTGW>$W1$29bd3K|@LbnXwYf;q;kw zeJ;c|*BT@dnlkpn%q}%F&=Z4KTU5ZNxD496D?^_#X-6@!jZH8U!aX88FHyy4pTPo(i!O-Lw_Cb;w zrv98QwKBW1999x!w2T>j-ZH8WG75C=CPRIdEmg(f7K^H8@EaCY#UN`W!|JC6N8U8;GCm9}(PtMUllr2<%?}z#S!jyx;8T^w)t<2_>Lz_WHHO%Nu%cwrc zD4@-QhWbTYs*1r8i>hYuFw-{7iVSjdb7-^BP@m>BA{lGrQ5y zKy?i6wy1#X8^u4D!bC&p;Wl;C`mG)N-M7Mz(aGc*vK!AmSE zAUKyQvm`YPx>5nbHyi4^%$4L}_@qO$WWbd$TbP2Cvx%cWkorD_`Q@VNHq5!k91*|~hU92-MOzs3iF9v3Q`wEd>hCLAO#v#qA)huR*Sp%XNuD#0 zj>cD9=^tz--+;$Blz!%Zxzy{XblA(GA@l5S<~qSkdzX5Xw}#}*ljY1)y1mon-;dwU zPeZ1%EUJX2;-_N_)kJVgdy}W1z}yU-lTbt1atd$k-?txOm~cCD*i)e)nPjfyju@Wo zaCr=$?r;SRPdDQf?&EQfZ_YMIFf3sB9EZze_+t)dAlEb&ZicB8UB=*4L!86%HW=zp z*iuytPP3%~aY&7!Zgr)cAR3x$O5b3)EMst&L501(ywQp+vc+oOi6obmJ!pzQWUE3_ zz`zeXTpq(ecDMqDA9uJyhW9(%RECclt0hF|l`x#|a8ntc;BbWuPjt8fh6@}nkKyAS z&Pd?2!fj=F(D4j%@f?0WSSqlr&L+vF=$DN+hZzBLghwo?i3e%HCmEh-9s-xgaG}FV zhB?hkbPTgq5n`bf_USsM1kDs#pY3qB?(vn zlcX$3je+ciN!l$*prS_eh)Kej&=|hT77HwbSuQ3;G0Cti7La+f;keaY$!Zz?w!`Hy ze4oPw6wSQ8U}$nEI!F>w(SxQmj}wxJ;eU0t=P~?4hbv(C#|~G>@BxRL$}k%|>L_9O zSB`Eb!>@!jQpNjx^Qu9j@Jxm|`9lmDe%;YcW%vz;D`faBhbv(CZHLQa7^@ETj}*i3 zPYg~8Xc}NI4;tvV=8Aq{(3KkwMwY>HHC*lvJC>@iH6q?-t~mmX&l~FPc9fQEXZUW* zsfxiLSycU720YU+N4BAGJKucV)>wazY5(0;51=#6wHFrSLBsTLgr?U@{y$^6_OV{| zwNn3&QGYN6)uYwd$~D(YMzNs2M~s?m#8i(~s#1)a8hpekZk&%HqoStNIFgXWha8M+ z^K+zU*GfiRo}(D!K4qU(S(c3B4)#~~cSE0V^zD<9Q6~i-G3q1s5o*(VWE6L#k0GO~ zZ7DQc>yc3x1s^f$V*3bn=~9gPqX%EPXU4Jx9_|@U zs;AZl4Zx%>R$JlLB)ylY|T#?1eHo-=eB(49Jz`@V`Mu z%a~EQWwbKLh@)#OJLjHnHKj-?48QJhg$%#taFXE_E}s@q3iJPll`5bVCb`9u)G)|d zXK3Ir<|$W}Ln+MYTb9u>2Jg41m8TeK%WNuaRHbm~kQWHff_2qeof;rW64`C>DN!LuFTgv3b;BuGF&(w>VrL!|NQbfZ>}Qu8?6)B7Pk>q^)ZmX8FwsW!XS`C~P2o$nua=2S2`I2FCq?ZVBI#{-!u$}R@ zxaVQ}yzPYTjAt>+c_aRQG^$nc?u=_aVL2n!khjl&f%{DQ;fG5m_dNrt-) z_o*wp^SO`CGRY+j&ch9lW6d?kc;!;3+fp?QvYs(GnbGlq^~WrUjD=+RaxF1$H7tH;SyeG8YzJCFnIpCnnJLSjV~25nu*p>{A9F&JtFoK? zuqij>Z)iLlrYT$>0=2zM1R@3mBf_aCr<*bvVgzy`N!rcd!cf80p|(|7yTP zO}QLCmrH%yma1Wpn+A0=qj8o|4TCH%s7^LdSE}^bJe0oU6~X)dw6b zm-=U0sy0|E;9$AbS8S;$gWTD0oy>^43#edI1K#v|h9{RMSC?HZm;2inEVnR6xrN#N z|65b;b=#J}Ksws!&(~+!TrM^w4dzPr%y8V{@)&M+xB`ZM?{Fmy|H0u382+Qfwii`>G{b&UJaFf*dObF7-uQsy0|EFl4wCw=d*H8RS01 zxMxP(4L}8(8nDmr8A+bB5(T3FpO{B4S&}Mde6nq7V19i%SSnl1*(8U0-QLzQ(@zMj zeXPigBbaSO~#_-t=m&b6a!xb=mhr^XHe5b<|F#Ju2%VYRnhm#CH z?QkUwKjUx(3_t5|c?>`2aFXFS9WF4=xc!$J8jQ2M4ETUUji$AFOH#uiHx}K&j96Zv zer5`=NI5!Rj!4K!mI9&eg!j<}2E`hqQ0!{D>F)JkUb zwnf!2$TFeFN0VroMORck|q6|J|+f~hs zT)P6@{g`3!3(F{Aws)FG%nbonWV7WAS&~)10tUXjQ z=rmZ*8obx)rk+J$<~dgK513{+MuA}#G7Pzb93!#Tkhrc2aCyRzuuM6){D&c7o#Y^y zlx1)^NV*NlwbmwkCBus+=w62>e8uCNDuX0X$nZnQ_z1Htg=-j-ub;r}EipV+nQIPD z$ff?>T4fD`vuvrA%&5+yY8Ygh{z03+XL&ChP3YfSlI2|2#kQ{Hqm_EmmZ}Yw3V1?p z>XWuql)cOa>ejoTz93Z4+h5| zivlW^X1k@TVvu!{!xOSMvXAzir4o`T3X@+AI@L>&xge%A~67Mx6uB!rErW>(XrW{<> z7!uY=4w6q867J$0B##@Cx6PFt9K*d6wQk81hWO?RgCs(R_Z{aW%m80;LQ#-8Y5S#hQTUZY9%xJibd5h$YTBjHJoNk1)L+dV~iyUctR#&u|i%gi}NX4 zD&Pr&rJ~GWp)FO-j9eqCvlYapm=rq^n+FaW7Tw2k9|1XNZkU;(%x2eBpfT&s6+@E2 zH!Nz+m8S1MZ?2$Xkh$k@ACDQSE;fRIgk?I;GFshWK&~SPBX09ttErXQ?RdsKVojj2 zUl_c6tA>F;X*xj2;y5Pay znMSY6tf~XAb6yZ22?WDjniYYb&(`YWhRc)YN=}2}UpQPI!@qL40)~I>aD@y%?{HHY z{*A+xF#M9k&1AUb1TCeC@AziAK|;Wp49{@55{5tOa8nsR$KeVYp6PG}49{}7JcegG zoMd>J!6^axX1ODr$#Av9l`y=*;ifXY%HawbjyhZc!xuSR9>etxCmDXg;FN%)b$R%B z{Uk?}%U1Ea=^dPFWYDo5-Vqp7T<#fLF6gAqqd!=Zpp!O_oPa@(93Y7@wNJp{s6W-T z`D3>2RSceKbcW9Wa6hx!fy&lwj*kUAX?Xt3@n-N%i(1AYSC`Y*y=CZ+{E+Sc1A4-9P_UtY+yVnJaY+!zX;$*ModhXplt6@cDkiY$3RYyR4jn zZe@~9mZXNkBMobG>xl;B+H&+XGy1w^6zFLtx!IBgdYVbLS&~3cGs#v<5@qlui&`0! zIH3Q>ncB9qDwNeuthDE5D>ZCr#@b?m&W{900+m-8l4a&feai3}hs$HQ)!_;l-sW&6 z3~zV10)}@uTpq)>I-F$qDTgb`ZZ*q$xuMB1S29VHC8=SMC4t@CXr6LqIZTNe)mlaY zQ(}^COA;_8Ch4#w0aIcU*Qh9itS5N+pu~aRyvEe=C0kd(Uq5Fa{nlKm!x=vLB&}}X z@)$nF;R5cOc}*}hIXZ($!j_~ayGxnmPgdw<46+b8I_Iy3dXi-vXljXhG~HaOsSKa( zaCr=uI$Qz6YYk3KVSLl*BV@SA;qn-6bvViJE5bl z3A1&}DyTLE(L-?qZg8k~E>*(}xVh*NX2b#ml`T__eq)Ii*y;m=ib=RmY$b7B9kx_p zoCQnOaw*r;z|aepigLBwix_&$i2DJkJB%c({v2W0f3DPfQ!Cfyni`m5xm`?(NoCU93aY9_XMu49z#ql?E}xcR5@h!{2te z0*3E*xI%_sG&l^K=RCf7$w$cWZym0H;g=mQkKtDwPBMJr6i@wAm1xlYa?AD?Y8=Mq z?+tj!B#Y93`wf<=VFoN6OpzIdETb9*S*9EY%e)^mV&pi#%p_bV#wOSG7h5VYHiM;V zxs+?_s9o>siZb}Tt*e?DjZD@`%Hea~0|{%1UK}*K`v(eR#;y^8QO6Q9Db{-T4xC|F zx0tI!4rJA*kh)FoH@hSWOF4?!|>@2m&foK z4p+c%k;4@-e4fKiW%#6%bzN`_SA_Vc&>&IqRE8%xTp`0#9Ik-jQyeaj;Sz_F4ELYn ztJpN$URVPiM&cat9FxqpBsC1Oc(9yPP0d_e4r5|QGcBWK4078sl7ox_a}P6GVi_%G z@IyunB*BA>R@-J9;3z}wN(BZ<%8(3N#sLy8%@tx4-#T!op=W(4WOn^IO5QOr94vXq zz&n-1V5-cnl5p=-PI;W{f;rvLRwLGp<{HLvM~1nPIW_~YFxK}ObIoC3L6X3Nfk{4P zxh%_W8IxRTNdj{clQ>xdjwDDD&8}#(so;yYqQDFgBnh;LNv^Y80xe>aEtVwEA|`RN z1X>g%3AAX3so-IAB{#@$`>DG9YOTRH-3Cd73~%%kX6uY=@C*@IfdQ9V)XEM6GOHXu zgc-eRbyCA%qh+)v$Y{-I68*w5TE<}1GO7N)Z-rC{N6{%@E;s5kKtDwPBQ#=KSRFp zPSaKa2@4nwIb5EF9WIdT;nv=5D#+!!&7&=rq=rFm2B!2snx|Hf;5!Rk*QYF_fIDQ8 zuUnFUJ7kitT9SY}WRe}0B+8&`XAOg_cX%Rh1ZysbbNZR#`J&|=2wj-VKTt)U>5`*; zUBmDR4wuL9sSa1b@Ph`YR-t_JJs%;%4>?>O!+RZ0GW?RCA>aJg5f(7~JBQ0-_!Wnf z48QGXnC-z>1u;XE!}6G9vL&fuklO~!`@VU~(gF3dL9qZpjaGeugZkmL$rcYkCcX+&{29ZWn79s9?JSfoi|0hDmd++|ogsz?9czXqc8(a?JB} z+mt|5^i}id4s)eq*{bJf_gOZ9-uaPv^t2@jaN$S3ZqKgBo2oG(b0t^K@Zk=Z$M8gl zD`5B=2B$_D-|X}eGQ7*-@)*9u;UvR9_A}(0#~on-!%sL|9>Y&NoMiY{eukr|V5uR> zG0Ip=<1I-IgWNWZpWDn+mJX;V4T=TGG0K>?w7dhOj7iS0B!N-JB&S%Cz$jyqLQ4{5 z&^5h=LGB+6DQ*{Q7^q;o0;86ko27Tq8dl%(ubCmnT zyC@gUQSRwLxnCKbU11bO=a3j?<%PYTLWb{M&kC*oR|B4HwO7wN=1wDS40E${WN}!C z9X=s$G4MBS53c44e`IB_oyyE}9Y%k5+*eLET&G&@RSfzn{6FSt*fzR~L8piJDc1Du z*^P#2{dU8Brb=!;wUJ?#OcAp7oie6x&$i1qO@Fg-jPZt_-VotCE(vyz2TX-~hkN7* zuh)wVc(U+hS$N8c+wU_S#Uf=r{)K4;Ybon-wwzZO{oZV@;V4rOPKrTSF2^Zlmh8vY0%{nnvaG7x49KiQSNGVy@{VXK|KIcE@p*%!X`&VaIZL zHp^V5^JrH8Vj|oz5ST7^+@(d>YpyiAFx+5<7lptc-?SPe5i-oyD+JN^s6oXu0j<-RA)zxry)t1p}uFf%9{mybPV@4mcj8-zED;??v z1Kw;=%NTUk1%^ma?&VzF63eKbt8cW)SWwEqCd<=VoDRiblGr+C#_8Lc-HV3c2yY`rV0l;IU*YN7SvXce*5hn} znd~=4II>!X$9_vw!)hP*_$JRFiICw*X3#6b(Q24>kA4F4X3#Ud;6}$8kXhyMtSstO z%czFIH!NypkkQJ~Bs$cVTE^fZR-!dQMgjlF5>2;^miHJ2U$%?_86_^2Z%frO_^L%! z2dl5nZpR!$&2`e;_Zd?!>oHfLaJMOUzqy7z;|YBgumhf9x|X_|;g3079>cR8u7KfE zhbv_Ge21IL@P+s4ieWy_d3>|bAW`vDh8Hp&k8EGUekUf?q z*%qjwf^A|OK^o;Hm_R5=K%xX}N-&*AD2hW(AcztmR6{7HBp65nj}-oW?pf>Xt9$MM z$^ZWM&j&v1th@I*`}A|~6kX&@iiBw>C$tKqyuf)C2sd|LW$SjS^Qs}--g$X5jb+hP zKH)&PmGklr7QR;ly>@Y4-bPQam59(BRf+F#QRfM#I;Gi!?2d%P-klJ5NQDSf5Hj~{ z@mCJl_HZ`xH3#55l}i)vr(A~kC(31sf2v%D_#)-f#6!xZh*v0=CB8kQb)fF)#zG8!+&RhE)4Kq>S+Csd@@)k>9XYV|76>w4$qy>YcaF41dj&=(N1 z5oJ9fq+&(TJv4?HHcrAZmL{JN!7w6Njnu3K#P=(gCjO0b8RCbO%My<$S4rG*hix?} zBS+k-TqW^5<+8*Jl*`m2zI*#=j{p?d(jvg|-`) zdXSn?MBJxbn)pQJGQ^9N%Mve9u9A2_xg7ELl&c~hzSEAj@KngmJs>5(D&l*U%MstN zTqW^?%4Lavqg;mgVdc`qBg&yp{Z&@s9wc*ZS%06jnveZ_`AwwiI*#vBEDF;Eb*XnUaPRoHrU9_COp+q zwS;Fls_sm{A33U)kmZS1xhkIEyo!WN9aT@L#T8kcYJ1H$1c6JDn&up$ zuT(Beyh^!B;-R~3&B8kvW-b9K1y>SZs$7=%a^*6_S16YzzEZgq@h#xOg5#~r7WgG1 zmJT3fJhCRor4p8D3f<#`iiE6$EYrS_wVTC5Z4UbmKNVEajkM0;$xIc6VFjDMZ7|}Eb&U^ zGQ`&^mnL4NT#EP|<+4HS#rnU9ddZj|WL0DU918_TBh=49Q9NOoQ2RlrT_j|a$S|Qc zYbBJg?Ts92KjgFvgs(ZuTLb9zh%>1nR4;G2rq^T6YbK$3d52Ycz3jXi2-Rz5tUH2r zXx4X;n(;{d7v<8#|E*kxc+xL}@D(ls%uEI;f*Inpa%tj>aw+1Yqk_!LRKpB$gK}x& zIm)Go&x;B&bG{m8h%ZnsO?;tp-hRdAn*tjd&c^_DDrK8T|D{)jGbs{om z8b{?>+}TQLK^C#NZJbGgUdJm{&g(E|QbWk%rEdc&EmAW=hGfj*FUEAJbDK%1>Ss@< z`e|xLsOtX51gQQs=hi?NQFm?k9W^72sCze)8JIITS?A-`3uwb)<%i@6qY=dY=*G5? zV?1HRZF)I3c91;kCR8`S6IdFDmE716(kx!PWl zej#LxvbCNHSxO02PUtNN$|xjc1IT9Y3wh6C7}0x9s6fbCjtNS>P^nx*tdC45Le@iW z!u=cGf1oMaP-*#07fZWRsd#Cx!s{*9kOe{tics8(O~k;YW}j|SOY6N{S$V=4pyc`K zm_cTmlpH(A%pxT#2AMfi$#H|s{6NVigUtLy$)$tLtWa{<;0?(93aKnYzeD@I?%FX= z_$DX`{NzDq{;qa}A4lz&*%(7yiXhy~je5~zW+$~H+$Czq%$L=U@GDU}W)4!jPwTdE z!TRGjA7nQj;o79YPCCX>vj}H9s>ohD!BI7Y{f=s2H-5`e1;Xz+sv+KmGF9UpD078< zd7X1Cut)E6)T~DUb+XLzC(A7M`-`qWXR(X_tQ325qHEPz?6~ceVju0L6uaXHrDgzf zrYAg)ngf%$NX_;}e7tgL;x6Sf#LMrs{Vu*);BBfcM;j4;AS9aT@r zP?O%@W31=6SPQ;*;US1pG2yp+D8!n|2q$ER$TI_0kRc^JM))2gxyVH{lkhrF6~Us^ zV7&Y2MSHATygOIc|`dos}Fv$jq)vE*)g% zi%KpVJQ$eIwe=svnL?Fhdb zwPU76?Fj3lcFfFIJ3@{CiEqrO_N86i*>}&n?yO{T-HJbqOka9WV70RWEUr;Vb zyhgbc@yE*L;;RGWxEwaJxc?0BCZ+BN9C1{h@DGlv`w)=jCEWe7xc_usMZ%vts-94T zDl(|MoK=zV8AsK>2>7<6ii8@JcMIVMRbWu(JE2-a4XVJPu6I@i!rwWn)(@)S2j$(4 z_(9dMxM8PV<7<0Q_RfGct7JZK>nr7bCGW{aaK9ZrQ;?c5OMJL;IpVx>DdH8%<%m}* z=iR@v%o(te@kyyUN)aw`R6XHNUiOO-2gtqZG;Fas=6agzLjk zDp(0fsf0RH=;uzTNI2OE)%!yJ&H{leoKS&qiW4gNLf*p|Ms$-Csv+FW2{rmcWqX0% z@`yOzjK4q`zjI~f3CFs!X0fcjl!^=e1On`Yu|a=8%<|2>7x8vZYBtrile|Y*)v!JY zsTn532P>B*K2*63@!`s4iH}gOl6Z!4IpTWds)*}<6B)h{cWX0s!GvOzd zxE2b3MVgW?-0U^AH$7oTG8?!m)O;RrU!>#Z9l{Aya^FVwbfgo4-tcpw%(Le5Y=v+# z#+%%8#wWuQh=illwD6apT#Yngc*ZMY+;)ID;|-twGX%Cy;#&ff;JJk>&^wf0fJ>K_ zHyJ`LFGXrrO5!V(OB1hDE<=2^a#`Z*l&d6OrCg5qCgrM#9~_A+M9e%4(yWxkzf~?r zJfd7B@ngzmiJwp|L;R$2Y2v4pOA)^TEmujI196Oj29Qfcm+0PjOMJeY{U)Ph$6WI>!P#`MZvq%}%~cDfZ{%O0nzK zD#c#0%kS`X?7ywEtJa4kW9z)2uWp&&hvXn|#FxfSmJE0=s>c?!UvZTKWxFH0EqV{7-eR_}u z2FXT~?UF(oq<8nqAn7f0gpgjc(EGpD?)%M5@bf>C;rlft`1#)_KEi9J(mh@mcsKbh z?M8T;vm^2Ct`G8r>A>xZxr+;S73pVwMzJ~$bJ|#^W5n1 z`p!40r}e4MD^GYaDA^{)3^KDy$+3gX+^=NCAT!S>Ic|`d=apPC$jqBcE*)g%10|OY zjzLRo;#wqs2s-mt9pQyhJ7%s{JHnqw z?U=bi?c#Gc-febaXE*%>4JD6a*-0xMHJk8SM-|y?!;Y#UyvI=u?8e6&RUmxQQ4R4f zlub0=fwDlbFaPNr3+&O&U60P*4v;fQwlsF~4A(fb*`F;+vFjEq#a{Y>QtXh+lw#Z8 zq14@gIz7FoUTJIwn;QFImnQz4av9?7l*1*bw&nUTckeSz&TsHVFGGkpM<;SDCTOyU4MZ&E>g*zBCyQv-F?om5t4pckBgQIrL z)TCLcsPufk5J$ELWOXeN>?LtSD2rqI}ksZ0pQ8k1& zIjVs@yV_9&!uuT65bss<_yJehr?ROL{>eEO*vaEvCzmz?>`;pRKH0TbiCsKZDfZ@m zO0naPQi^@ltQ5OriBcy6vRh;l6LPL4-z*Nn@lvE_t0TT#xis-g;&Y$2i$eHRkeLfWnyrrbLgjMAKT)od_#)-9#DmIZh%ZqtO}s+66!A5` zj|3QBz}TYqp=Pqx5i)Msp)Q3ir4nuyDfFNdDiX4?vO)Sn_2nXZ*a;N~*+Q}q`$FE@ z%!ueMbA*u1DqEc|?!ijrL>zmZmdMoFZC)^iQxa~1BUCFV7 z%#@U@7-XhL$#H|s^eee!keO4JTsp|iSxPP&ybzhIkjftS546N&*8_RNP29|p5AHKF zRqY6Oj@mJ^pV|@bAGKrVD77OjMD3VqRy)FZQ9EXiQ@i*`ig%k`WZ6x7xi%@VlMZxL ziSQ6d71?Vu9aTfv=%@yE<8h8E5OzAMA>M_u$HhBPrUv`+Jm*+ok6!Dj(k*~G#!H-e zkGf%BV!yBF+N;Da-bN|*<{nD1;|^7deRQl+?2bOA76R%j>OJpS1(PR{nhlOP|BUTV z*=SacVP+;sV@P~f)G$5H z9_AvR?MLh_Y!qUBIlK5xJ<%q9Qu8R1f zXWhUa37B~Vq&Yzmk0_TTeoVPa;wO~L5?Mlp!;Vd zO;`*EaOqT}W;rJQwsL9W?<$ueK2y0Y@mb1M5-(RSM|{3=Rm4X>Z`&<=2FJ`ykY-vD zHz=1QK32I(;#taNiA&05h?|s46E9FMMcfW943L=)HLN1;R4zx{tz0E>k8)Y!KIJmR zCn}dF9#Aet{H+%vEf^n!?DAXD^fK=W*|0Lnn<2}p2(=It)f1KiYTxCwi-c@=SqiAl zstQHz@1hJjMiFXpv&vQF5?5S-kbN(+m&LKQg<^54-5A%t2bvsMGI=P(t`zDluT8xB zLbl0fFg1H6@xHFQvl$WKR$~6Mlz0tFdP@Uc zfB?0LXUF6G5v*A~Q zP%cY6qFjpj*frYDUc12lcBIlS4+4&dn^4;TPEl%iz^^M6#9oYDwTslA=)8*5-dQPX zAE8tbdr|v(7k7d1Zb#L!IJQ7i=fRpmnsH4`cR30Z77&s#Bc^)NQTW=J{DkmFLl+HF zkG|uA6F&?FW0ef%ptLhwsS8uYUwg?~n>)3!%uEMqh6(XLFGmb5)PGsRRckCKolQ6u zTCxNm3`nVjV-|&;azaJIy`9i(3LWLBBB5%}*6=K%_T5gqK)9O|nni6DnpIBdLMK#1 zNG~}Hp0=!GbSFNtZ;i)l3q-Vxm^gESuY z%cv#;6P@MD>fsj=U+#(D4A1ppY=%2A)#MQ&A+?NIJcw$MDKrHN-Mmm+Re zE=@d7xm39_zYZH2)r2fYmV!E5rDDSBz~GN{LPf%oqw2~PuO{9j3A$_xU|NNEt1*_8 znLQFPlLcuEiD!?E7*a8w&Hy28K*(t1;1;)L{_D=GNH_@*$VqBzKn9R-vqGU(CsZKZ z*aB8~HKb$^&g%dbV@WP%TK!tR!BfT$*@5xfJpDl}i)< zP&se(vCQLPBNLji$5GxMK(9_`QY2(>GAb71D&r7}@N9KthsV>58vqMa#9vh|OI)p7 zinv3$ETET60wXo{u7Q~9Op1hGc2r|EAPY-4zrZ5kA}qTb;hs*Y-WT#t?7P7FKb%*d za9>B&5+3ZRJfQ~Z&A4t@FLGX9gACx(MM%xaB*t47LAbFnvnFCl{64tQ5ZEOHKr4_+ zuMpnjsM@CiDJ3Hcj7tW9E<`HZ5h1=UC(B2@FXS~jg)VhM1wwqpT!b2Zp+?xdWEId2 zNXG}^R>Lf#;#R}_<1n8P$i5`|2JDe*Bn<$qi z&M226{=9N&;$4;V)*NZK@HHN3(hS5UJsuPZ8Hx1$rm$k6LJ{ubw7t^^52okhfGQ(| z@G?*pL0^-%Jk#$v=T~Sy+16wcQkmcA1((okqBE)47VwKo`9d{L0pLay`=Kj-CWW;4 zndQ8G;k@#{0o=?LpQjMRNI3RCUcPws@`}G2URwJi%lfh_zDP)+u|ao0tabA`axW;% zbxL0Av#?#ANdqAZFonfm)vsCRAf#qi5Fe^sns~Z$8RBm!mnA-2xk}<0%H@dbm8&9t z_H`RmxO_7697qYUiuifua>OqxS4sSma#`X(D3>9ARk<|rI^|Nt+pLWQSgu7|P&1kH zgp6Be?`x2yRKohst~tdC6$!5cRT1TAI9Ya#?RWzS(cFH$n2x~#!lTkgHh-r7wAlSF@S{ML!cMSlm`QZY)080DKy3v z?`@B_qu3{qn!9x37hOoRuSWAf<+@>Zyh(hoSqFPwvp&shT(IB_mUV51jdUU*i%EF?;d>S7#X#gtO885s?QNZLAv1d~ zg89#!n|HV#!KG)MNgd$}j`9jygG(2WEuPep&UC*^|z8!F> zQrc)1bwFS#QZpORh53+k^S0o4Lm4;L_-?pKOWkoYGY^3@55|ZiO?rpdq#R5ayLRxF zgg+o=);!@U$Ql&;zN<TOIjZI|QHpfkx64mrx3QvJAeI@0jd=kd`njEfIDojSrt9p!Zzz3x*JLiO@GZ4Inn zMjCG5z;7s*CVo@74Dpx$Xlo$8S>pYb%MgD>xis-iK{7H1QXd^9Cu~?tQe03{pZigKWYzs3B`2)KrKvn53;5nuo(%?r{kV zjw(=lfup=(;Rjh@kViVNJfUhAsa;a5_&}x5#xOCvRNQ7;T-yifM)LP8&42o=GSIc1GDLI+ILP~vf)$#_1y>BVr7 z`^K9A$HP0}sT-|tSFhJ&Wp1e9O_(y>tIb_7f7U5@)B8MJVqxZq81YKy=53legnfVu zzmD)gM|neyUi+#Ep?Y~C=3(82)T}_nXDOE@K36$!MpCO6HZmg#zw4-4!gCzuZOFcm zS6iBNIh6w8sg9~A)UwJ7F;aPKM0lnXY9v%4uO)|Iy~=sj5#Hn|uXuW`R1-q=DqGeS z&Z|JEUf#GGf%P-atB&vmM|lyh!=;a$Ngd%o9p!li?_d{UD&uM_@OsLni6<(TA>Kf_ zEb%1eDv2j6mm}Unxhmp2*4dck)^tt4%$*=*;8zjfrCg49Sh-5#)yidw?@=y8e4lb@ z;`^2JCK4O35|xmNM92^mHZ6Mnhw~~D{>o9_`HNnAJCgz-Lru7qJP_73&MQyY;-~`Q zji{^KGu?J_e5v0Y7pEfKFjyi#2_S|OrkI}v_yXvCk;-jQ2jF*J86+YRUgJf$F^m|>2I0maKOi(gHc^rqjCWX#`%jMgo2`W!TE}|7j$Y5vOH1}l zMiBW6uBGY-Uv`u?cj@(%nh>g&wFa%tkfE0-Y--o>gBEX)#*QLd8s zXytOmGnK0(K1R7Laiek>;@QfjiJO)4CMfG#0UMd1@exRqjhso5kP*uqCY~ggZN`j&K?%`Elno zag{Uk#x0d-n$W)8@LuXv>IhG9l-CCII#Eps)vFNi%jK}X!g+bUM3Yr8F^zjC@M`Cl zFQ*)Ji`($pe?ewFIf0*G&hI3sj|)}X#1+=S^L-bH7e7rle9tw0{%M#B~E=Am~To%wv zwg4kh5#}6Ke=Oi}N&$Jv4$h=VSmUTh3NfUFr+}5PKG1pP2|2N3r6E)yZ!mU403R&~ zOw$qn4A+Fq60cG&MSPcXS>n5u^Hx%pc{*&QISDUuR4w63N7Y>gc(bEw30Yp!ssZce z&Z|iHQ%BVkYH>vtr`q1g8-c(JNKNw*uRq3;rum4|%B6^RQ!Wb`mrx(iCgj6Db%Yb( zCjGntAe9mhiWGVU((-h}K_^tt4=Yh{Jy~@2nksXfgqFau<%Nn9mxNlN*A!Pm!I{Uv zIOI(O67Q^BmUuViym6JowLKy>#9ve{P0WuUN|_nr>1vlHK1{g`@i&x96X%sn5nrxc zmiS8LGQ=yCOA~V_nl`~@m$0q}gOP!8IN)rhoH>B+RrI~QK~Ar)IN<^zt1fS^Qi#zf zyyLnz1n4b8gz#Szq8DpFRvuBYd_Dmdal+Xs*OvEpPFe1r>N79k}=yLesVVp1NZ=$8<}69|D5Ai<;tgOr0-Ob8?6Hy#f2 z=*92=M~vBNxHK`>6tn3Ob9WIgOFRj}!c`J)qFj!c=WMa7BIakrWrZ0In7LS;tB85K zA~i~1_J>YsbT8s%JCWXUaJ7O40fhcz6KP& zOw+i+09fWx@RL>`WHC}@Lj59H9U%)5E5eVRmUj=}LWzVl7I>0!Y2wMsWr&N)Wr^#Q z%Mc%}T$*^Ma$Zv~w#{K9O+iTaghwcGFS9`G358mx#9M)Q^9P%Qk;1%dAh<=!VT*7J z=jE-kR8bS})HxY8EL)zerij(8hDuDc0AE0w5Hd}6btXl^X^tu@tR`N_6lU4xVKA|} zd5uwxLJvY}W&rUK%B6{qR4zlzF)Y4W;yG$pNnDG$E_ONMqH>kQb;@Olk5(>2+@M^V zc#d)@;vVI42+JkaKpcM3WrQqR&I!jrfl3Lt+!Q(#f-)8fdCM(#xBlM~ryut*xd$Rl zp;U><55SuY>{^EZZ`XuE2e@X-4HD0A+zIJ;Oi53*c?x3J${HAVOV}@XW451b0P3J| z1NY0|49pZBSN^1c*v7_&coEd)@4l}Mn0d|hXMy3c5u~f)MJC+A#??)U6hGUE=XrY9 zQylxj)tSu_85e|l2h9oSc`^Egu}fj9j15lo*8cJ63zhNCZyUjcH|X-oAVT%>7Ov&+ z`XN%Y0ui65T$=cNbl zsR$F^;)H4mZ+BGPF97dx6z99^a0-2b$xqH9LN}@vp=x`l zP-<`Nyb6T~bAPLHUNBFVt`=is6$rvEm6(mad|CLb@evOaEiN;|qP3@#1@ZmJv)ZP9&)pp^hJ~ z>FLE`EKN_SUS8A3y-d?{{Qd?_Z8%~MWcffBA=Tw~zk@V4b~gy0h6t?_K1kb*weq`2 z%{oeawQ^bFYnAi%GHRU#8(CTjFLG2Z;Wdu(4w}ADkwTX`uX;ii@=hjaz?$A>7b3pW zDK!$Rl6NvnP^xn63~&<^e~+{x=wBN!v)MRnB?F3Z3s9k5TT4IM{ixG!BvkDhU)#F{U_CYfFkM5u8@TWt1ZMbP!x+*zo~{QXp`Bw zfeFuno7~%63P`1d`#B1I!+8}6f8eNEU&tFi6yoEMg!86v!olp-OI2pNYXH7V1FbJ` z5jXk~dy}gb*2g)oJmE!-n&k_5cLU2{eY*4VT4w~8{)E(w2jTgnTen%}N*7ig;W|gv^20xSK`G(c3x#--6}jK~ixaA+P?Zz%_A(0H z?!3HVCx!U4~WxcG`p{a*OVW<+?Sqv}@!QYm5a zq0n*8t4R2BN7ed5-t?l-NzTg~HNJ^AYJ3xK)c7V1Eb}&3cB3D$xA?pR>+$X&ou3T2 znNsnV{|>x(^D8$~gm=2)XZgi@OV-7(Ug^BNHs$RsBTV}Fxqrf)HVMZyny_{Wiw7@l z>niRAQ;kcrk(wb*%-bt7REckk*b!IaV`51|n)5! z^6^pLk4q=13E{Pln#JO^!Msua16XU&UYqjvmyst7&kvvypsN$!+xeSk;w{QKc<-sB zFh#t-a%tiNl*eg#}uNPOV2kG_m{ zmQ{f8F-JA-fCl<9(uDCqp?#c}cSfMebZ6pCX5Yk{%)W^?nSGN6mdT+ZgPxUQM+&tk znu^UX6hB7GR!o>JN1#3hSFb!FN1d#ZERJJDC>F;a70NHpn^v2k6DT+~I6GehZd2F) zXXiVC8M(2GcR#;}5YcL6Cr7jz6STZ#ZXL>d*Tt|fMf?}#(!_sPE<-#E=XEo|h-WL8 zAucJGCZ3}lkk*#5Rp5#Y^YMU`Oz2p8(KKPN_e~14W?TvTBfTQw5Pm{9tRO$OAdQqF zenBgrBVMaqiuiBJ<%s{T9FR5~%RC)dq~Qoh998=Vz&|Rb5*97PrR7M?muHB7=iKTE zUv^ZH;_o@in-Ztu5(Py(Mf{9&Ya~?h0>wX2t9ayWf;(Um{?!9uRmxL|t(oxDKfreb z#xj)-Bp#<+ns~f&8R7}bWr;Ubu9En9<#NO?C|61RqHE}qz zkRhIow{wKc5vP?)5$~#;H)N=PqYI(VLAc5Ih$|%w846wHgo=cJcT}w}*5PL&i60V3`wK)f@eYy&-ciBK@_CI8V5N6Po1GvbNX?KTzD~Iu@has~#J^U~8#2_dg^jE-gqJv~KCYB7WGM6v=T#*9siSIrp|UkT z#(8-|hGnUVH)MPhZ^-y24HUe>mEGt^>^ExVz2CPA98ke}JT$;FExeW2K%4LZgm8&G4qg;--MY$^C_raM?4Vd{LVo3a< zayjCUl&d8EyK-6Le=3(D4$`*sq!H4@W0Xq~uL2ha==vLgE!u|yWT_%#jIu7pr4p7Z zU#LhSRzkje=L>oBl|n0Am2-o1+tF1oH%NRSIC%te3?OTq@Kod+s8W4>`Q4)l^0S#! zhQqTqJCv&=9#$?#e2;Qf#2uU1C}lW~1k9WOQUa_Z z?olpB+^1Y6@rlZ1i5DrCAwEgDH1Ri;OA(&|E)1|-i@t`M$$TMXj50YWwG>ifMM(98 zDa77-(`gq88Luq&)IP;&7YS9nR4(r0HnvyH&DSE}1D(=r!s(!l84IL((tR7HPKBi0 zNnQ?kEmHZxi`?L&$UGAzMwS=N0J4OrHR2Rv}^XFNew5NX>L09#Sq% ze4TO`;*++pvB>CHGme?1AVn}kyiB}iK|~@0iIAEykWPjKr4q&# zg;qGBBH^u$sv%?@q#J#0Zy_2&@s~zwM|_!bY2quD%Mib$T$cD{N)t6Yk> zu%&HE>5(jPjdB^{dgao@M=R$&MPXfkjxwb~2-i5O_Eo^YDi!ZpU#LhS)>XQZLJT*d zXIaLFuB<#EE1vLN=Q>zFpkDC^_dqiogf!{-8GP`08}maHDPlZ(H(Z+d2-urmA?DmR zcEr4`FnYvSMtq5{RxVAvN;&s?5cevV1@w{wz(|i09tdhu&@DfcB|r7E zssoUhZ01aggc{1(3p{%eXmIlrTZGe9iRGWJ)HQ&sl>&0fZa~R(BCEyJvKY3j3?f1n zCnJLJE?2U*JdEJd)6S%h@Ht0$?@iI`Ni`uzjC$%OQwEBf$_qpj?iapHefGBYrJn=fVS^ zehD^G5yIOYRm(3fQYm3^p-{c^DiYr9sCr+hJ|5AxU`7;jRG^5MGT2AS1w0sd| zE0oI;U!`1z_!{NX#H*A`5w8Xp2FT2>)Ub;99_4bx_bFFN{D5*n4h^3E=PQw+Eo(svsYr5CB9MZGQ|82iP)uyZ&5pMjpy*w zFT>Umvh(DAgCCV;a|!h@YRv!>?nL1^*`y}buU*+Fi!*dpIS`U#`qK^J?0u-g?_B76qaDD~evb?=GQX|Vr3(n&Jn&EJq%68;SdvQ(AI z-isPNf^@V4*(dQKCt1#(1!TPwR=AB}!jEi8E2Pm%cOp$_n0kb~6sdV)b{e8$V;hcb z%vMNxvc^w*j?#keN~97v;SHeV$7D_(WJVjQJ}C?~9NWSCET-%KPm1kL6!s?nNlXU-)znng=e_-YK1>GO zSo99g&*9Scu0u+M?4xi-vX>U1mqIe$+!R~m%Bv&%2-LXX?BS(@%vHEj>j=9+SwrSd zQbWSuj51{I5j7;-4Ix`aR)h_2+4xwpY`OZ~%5di zxWJX4Cwv8z>`H5wu0>{j7gT;Lz$&E(+4P|+n~}pHB;zBBaj+dsjo1+Uc#q+TStav1 zsOc2pM*Fnk=u4 zxTnq6Zg11sNEaYoiF6gxYqS4v{GWvG%ShKD-F8ZHdFAY1-O<{=iS!+$?;$OxH@t)O z`*;0Mh5qSCFGsopX}lI|!2i4Dz4>{oIDIFZb|YPeG+tiU&X(y%x(?|_NaOaUO3Sn& zeH!VDNaOZHi!F0G(i@Q8c#`FBLwXO=HAuho&A5`y$Msf2??a?664HH_T8rsO z6~TO<5Z;o)Bca6oEMRHe@c1XsK?VtH-kOnjK}w{+7JE0DqN0q z1=6dLUW@bwr1A3BfzRGyuk4Jp0cqTR68OnTH$_VSxc$YrelyZxq-&9m+-W`5A^o5B zf8Z{wxZd41os4t~r1A3J`lV&YueRw%NS{XfGSXL(uKJa=E8Y`VviWj)kNhwBpMkh8 zLOO)BbgzwX71Cj(k0NcqFS$Pd(|W-}wwx`IZjE#Yr12=_;hR z#0`BmJ!YX#U_0`286v|8fDcF8NpOm!rLJMmmgi0iHWJVSs6MW>(KA-A?0u1#DCzXod0PXTfwuDUXS#*NMpqX{CNL)o7gKCAmyj%FGHRmhUdrp zp8)?1(p@&Q{sUXslpnQ^m-i6H^AkwTd4~rnPmp$-jNA zi{#&Vl96j&Elqt*!L-%|rFlI~9j&DWE#k{uFs-?-tEX2Aw8?SJa?v;#b@2@&Y3gWe zmeRXKQ~sG27Gy=|_KItBS4T%{r(A4lo!dXZ)YQ||Ilt9NhS|2xc}B%vnmf0r^+e{{ z+d5l`rEv(`yQDB{4<)a4|3zYJv0qRA$08B%lf+D?#`G|W9Xn0XUqAl1i~jtODAR4Q z3Ul$nBys*#g3KFw^iP{$0Z zCHrwC{@cE2uQQzsVaCsLnAVB;KO_FxFIj)4b8I$<#}7Ja5x{GP8-PF42T*^OAFqFB z%zygPMkNTCKCr3H8-Md&YTVx(j!c_OkpImqjqQvn+u2^Vu@alKSN@Os=itw@8mj?) z(f~}&;UntL(;CwYZlb46=|}e4G5^#TY!5TVdlWPe+uCIWoB@CKXBPfUPcsuF^2$cA zfj^Z0O^NhhG2NEW^zRt|#@4({Uq@dNa*07oP&kN!-bj{Bbl|Ff*)Do!j2 z(2wa$G5?|StpCt?)_)DwLzbTE6*MvL_yxY+s+Tx|XM)1h?B5+HqBQe&Bm@$}y{ z##>eEV=nzg{wEhTy$a~^Df}pyL|1-bD z!t*KnpE*Qx>_j7d=6BW~%aFSiFW=;2T^!n0uCe|fR$A97l6+VG=eXy-Vh+Jc~E$3(AJNW?s!jOHucxnndxF5r1$G(SGzIbk$EA>jT$nqSZD z@1yyY+pkCS6WxA1nqNQQ{yLi9AmF|^nx7PKKOD_(7;v8(&2JQN{~FCt4!AFk=F_j|nymhN`XMY4&okqhyofF=2=8 zkEeQTVQ-!;CE0&fc%vUo6JTCApqgXsm>?4jpmze z@a*3K;gjMyL-?@$&#?Yx-!QKqgAdNM`JHSMTm^m(cz$cfe7eWz4E(?vUIlxz9~eG& zmL={5{~Yy~TVf&jx2XgEaPX!*!Z^X-jrK`{Uw)1?d<^!V7k*5zX)yfl9YW?bG{hdT zA6RJ(&HOR1gTN18Yx50~H?L!$!*y~_$Ob_V_+XjUuLgf6`05yc3HSl<1F*k|IwxD5 zIpFUHKL>m@_-DZnfgb?>Hu&s-)gk{6+Jmo#{l+psO#7?>KL`9y;HyuuI>X?<3O+b> zbe!fdjvJjh;0IveMSbwq;LUH_oAE#AfH5JH1^;8%XTN3jtHH0LKKLQbtup+73vb5Ty7z5?yP@1MGG7g!{j((&gU<+`6wl{jKl~4C$fw+U3vcG>Fy?6* zItRmk;GdT0x6Kr^l+o{keRhmB+!8ti;H$w;2EQD99=r^X@O2sZIpFt1x#nAjroKaC zEkS$pr_Bt%3jBW1c^>?TxzUiAn@sptWG!VkETBC&Hid$o#4ASxAt>v5}XcxWD83?1O77b1JM7el?m>l{$y+T z3iubnuiM!2-<0uWUjGn&Ot588ebEkKz8diQwmepAP;E@T`{NV(lZHV`v!&CC3f zH|LaP?7zE~;is43=RiM)b%6V6H~4CELocs^@ZTW#7Wm~aTH-h0e^f^QhR_~Hk>noe z%vs;I^IBYczKqU0upj!9HQXHbAA=7bwZvq!kNJ*WQv2*&hTm6s)6Q$q4l z+hITSq_vxba=#h!aE>Gw!ajeOC1>E;)n)AO7CtHd-Fhv;gj@Buup$`wEl5r><7y5|5=8=qzr$9@FxCY z^dr}SVeoU-*m!Hm9)(4cvuJ;sB|C6!MH&0MV4uGl_R#+= z`2owzvLC*l1wVxI!{?;E%xj(SN%ft$0oo1i`5kK>Y!~v#M3Oy)PtrLUI>UEcSO)k`tZY0KN29I`Kj7af0ZSq`r+$l z@FQz&p68Z(%ji4}`|g*m{cN=VOW@N_SpGZU-=qC~mOslTK_Kt4ns|mTw8UJjSDOo; z)SkIA`~lEeH*9rQLcdtXzNrkq1Uk#n&YUl2hP?lL>1@~!57+`*QSL?Ht9P^=ez@!h z=5>|uN%gujw6`|Ve;+Ml|9TmF^X_z#zWEvv&umfs-OAYSAKJ@$C8r4UnhB=@`1JXf zcpH3k8J&}1zsfwomKWFUi@=Y(YXzh_;p@gSI`_jq{atH^?KyZNx*I|CqesAG7mive`Lpy{*Dd-Y4`vve>%=g{FzXiVga!b5}`TGy@XIP&5#YWN~ zN$s|s@TPr&OKkg$K>y3aoAw-e#S(jhKctLKLue19NYYWp{>(D`kIV2YLw)IA+^5`x zGKS08KVOFbD|F^uX$3BYj`{W6q$jkG?XRP5L(eJwnFaLS3FO}gBF2gqnZ`!$f zm6dt{iVMovFD}EM9qM@D1V0OT+22pK*S3Snb>P?G{`3OW>+Ul8Bd{O(r4`_lV)OH` zCjL41Sf1ZD`v>?{*IWKgl)L`M);{+qOR&wi1Rvl$Sp)ki;Hw8LF&_M$;Mcrm2^qoR z>tNx{cpkxg9|yh&`}}xY(FX8yzz<_UHDMn0hdhiT$?34Kh7Qbw^T7x2SmXQAo-3%2 zb%XW2l|0(>TnIfNyfmHnGCwnG+BuJQI~W!phP-DUY%B#O=}Z$o>zfA$l(9cdcvJ2w z{5IiwXwYNJ*qfhIHul+AeV3H6|B>(;%l-bqPj?8T!Z9wmDAe%-T~$Wsp3q+A(Sz3K zXvFzA^s9et^{dg&FT;M-@2x%WN8T%=pOS?%sXez6UR=D_ZXqw{!&~j88^+l5tKbK2 zw0Rsif+F}Ktp9kt5*!b{`&?^3i1<$ldCNurJqPx=GcCItE)EKx6#q44_*=^G_d~yX zqOB0NrQkX6)i2uucS5=El1IHJfUnrhj+1q#TY~RkZ7RH(zpG;V^^U?P#s7se{Nd0~ zUu5-ba9(W!Kj%A^$2JhOhdhFdBm-sm3!$@o7uyc|LjMZz-FH}#A@uvL!Y9T5cp3iH zGW-@a>TPYbf$(pGLd9I;gjMy3OXa-w#Lih(@@5~ zJLLWQ&?V4WbBYx>4?3rn(K(m)i2rEVn_pv2iqrf$Gus@dVe(uV`*+Il<~O3lec^hm zaw^0sB%W)t=xWV?|^BB(@Z(kNZDgMLD@TE`(g+-FSGWG+Zy_|=! z|H?5kd@TpR2Jy@Qe<}ENr&)sI^OiFD_m$zF3w0nGN&ZyEetkIzCH2>KAusodSZ}95 zYj^PJ*!{v+gimVEqhOz3YXy3sGq;R=FYM=h&l+xt_3)H3_7@6o)`wwy?ra70uM$2B z98K;D^`nf%PlmjVE7Z3hCa-`G!1EmVq3}ud9rrmqK6A15*%Um#y<*<4HLs~5Z*lbB zFAATee@GeohBEf8W%#a8N6v@1KjQl@-vK{__}TC0mC?B#_5-il=qI8QzoZT(ZVmX~ zmeF|%_9GWqLu>=V8)fV_lmmcS2h6)6<~1Dt8wA^eAI3V#`Mxvlan9r?UA_c<4aVpD zaL5av)c&oo&u?JMHSaf@*QsUfe_DqBIdq1%u{yU}nP7Dp`=@CC3u|~a>|YT++#fI8 zA!IoI{|ft6DXV`Q>^G8%n|51+bqUAbV5;y*_5CXB)2~^9U7>Rn_y8TX5`1$Ron@gt zj3UXo)Q>$!x)FT!`_{M-KC8ixth0n17sJ;h!Y9T5S{c4#8`}=uSclu8vzhQa0!Ncv zXzzcXZC~i*eqpUoh0_t>hY&yGJO=y-8Vny34vrH(DgMQweKZn_zYm?|cwhJcm|RSK zlxt>)d0kURe>Lpq+-~iDYm?xiGWJixe&}Iqco@#Hua>d@b7&9IXwux&-d>vD(bZY% z?Q81k3z~cSdi(n4&70O7luBPK&ZsFJaae7!RFd4mqjKN)TI5noS80BG*W9M|Qurm8 zQd9q;K)$om-QL>Q+A?k5efHWTFc(T~EsIQUufTp!rlr55V=>D)Dp*tl6eMDZhI`cgac_)YjQt>hG5C{j}OE z%}u>7e^N&now4o@B-6W~zptfhVW%Z#bk>D_HS?PHsM`07hxW9d5Rj`~&`~Q~98z*qb6?wu5~D3Sthw~9eCw&Ty}PxC z&DYd3-?V0EWP2!#KN!uow>I_ItD`TNwhq76G|If!lr!3JUTa_Tg3(kT#>obC*wP?!>u%TabIh1sk^7ExwW^~ zlx{|S+x*U^cBnL)9`5gy0wUKCzS#D(&X?wE?Qu?BoxOb`*F7y4+IM$#QK`SvWb8}| zuYs7?(;7}IDJ3*$ma);UP>I=Sp@~Ev@n`yROmV#=aw57e_0GBe!G+t8H*6V=smCEEYzu z%$Mc`rH&>U^>(IxakOe*S6@?muf0??`cfE&SvlPljaG18f2YiA>9*+b)w-5sX_YSR z>2K~!HaM|MzGi8fOr`BS;J+S zwgKnlYmgjOdxiEi3DEMQ=4m|R(uLY&AA2H*g1CJ=pIP}ok zLyD#1fd?INNGUj}ZJu4F>{@bCYiCQig~(uOXYJNcbjauJuMjD;SMHaVP0!z zZ)*@1)iw9H*5*DjG81opYhTF{vU9e!R#$)hh{F#0T4~Q|drsR&;+Hi!+Lg`yJw4{z zqD?K*;Jv+F%_Y-7>;<#5nyDgzhT+(89 zHvCTcnyj=$Z>t#Ry2Y8I7dG{Dwn}{uh_JPX~xn* z=>XT9GIl%7;O*;`uRI&m78`zhyG)jFxQ0ECiEj&$;oa2V-Y4U*yI;P(9LN^c(iiJb zQ=01(88tXi8QW4Ju()uAVpmiJo!eJ{QjJe%ZE5^UN8W>y9}ML?&IN zjlxrMRM`!T@F=0vS$3zAIi`fN5{^4V9wdukL_1pXAU{1{I`ZIs4sDaugKhBs&bi?b z3LCwrzZ?6EsfIL$td??s4@%*e=}lWLimZ(83>F4uhZk1_F>8+xiEu)hNhBxWe%X!f zDW@bo7B0dIjxWt?YHQan-P=ZJ7uQ}ax841HfoVN8GwZBfY{L5(vsv1i$WypIEJc@9%V@I=a-9U0%WiyJ-v4&!##}Cra3*j@AwvuRS5iknZa5k;TPW_H`ZK+G&%J)>hc2I0+$je3-5xQ5%?4>_;PZBM7PT6p`^)3wmq%c+bbRJ7bt#T4$gnU=18 z+;z>9lR~GtQS!s!fDb3>=tVQ!H+yB$^)6`YkyEHt+#FK7=Cw2}9xY_TJyC8Q`pwp2 z7l|-ZI}f|%mleW;I2tgV5;}>b_M?|Ji8Wl>Mr~x+yxZeTr@JvZHg+^(Dg{#Ez7tndh3q-Ga!8 zw>P1$xI2XVw`uckS-B*-R(U$m%0q-M7xst{?(W9e47%vK!p`32u6{XDM5ePD-t*de zWUktFYwn0mJfqX<)^vMwU>8s=I=Z@<#{qJflFsNdPXxl{I5IlI#Y$?f+joo9#}s0Q zrYonlL(fR2Hj%8cvsn|ec=pG4=x*u%=I+JremXKvd%_8tRL8JpZu#asaYNM*Qm6Qt zF}&FwJ+#ar&7Rl8!y9U5jvDMUS+2qZNb(pp4^YBY2PesJ50ILcB2S9sS&f;1T#HTf zxv3J?!L(Vp>y=u%WYo;FH-g%9VcVF>jaqW#@Xf9;b4c1y=g=N|2RL+_P0l@%Fhz5q z+5<~}DRMXCuG-`M=oLq{a6Qz7)nM5?J<9)LtfnrUqr zA@;cACLMQ%aIZD%o7ONq&g+97w+I|zPTgT2%k3&Q)n++$$qHibU;SgM8Q$71v50MB z$r{<(BzGIeEZm(VhY~qV@Ue`kwfsDeIlbs?GgFph!yIwUG#FLCQI92h`{&BI4eX2= zU0LB}o9Jy#obzm`NKFu<3CbHf3*-h256;ZUbd?S}P6{$7HXhFG)OI1u78VxL9hqNd zq$WKyu&p<@zgM1InmC-YJbCQv3b$w(npQ7tSB@y{54(GZ2QWkGVC^_w9-<^I4JH_~ zGTDvGG(UEYQmc7_JL*<0T;I&|I$7b&y{x;FY)QOJ!ro^BF{PMQ!szRP18c_Ujx#mK z(4{ihcVm_nnl_yX!4UrJx%6u81I?A zNaA;z=F}m_QtU4s;Z8g{MAO+aa^*17Wje{6^0AG$eh;4lO2rppxz;Z7Z`b2vA#7W_ zrG;V3U2b1fXS1AET!)$!tfTA1*aSz*w9D}*Y%$a7(X*93szyhR=?^!YdG8voR^csx z?Phz|*k&HO+h@D}{Zh13%vCN~X8OuWytyy7;+f{KOGD&YTu9he)2v|eosVOPHz(0D z-QGH{y{$WZ#u9`Fif}oRw+lp09-*|(x0@=4IBtYX-#D>UgQtvNGdIZcFxuQbBs~^z zal7$k&Loj0C_Go7vKD%*UVkSc9FQqiaPI9=#sSBUEn=qsXqX!=>4l@I~WJY;- zyX>9!&7GdEoP72>dXEZE#nItlsvXU92a8DD5~ z19>lF8YcXeuu*LiI|qdiFv2CsNZ5O%@cz;~X$)tAzdJ=AChDeQW{SCkm1i$4VL0ws z9iC?pAoo0p%s%FKR(6iN=UjH3o*$m<`bUo?uN!(=7n(;>rotS*dcR}ltGC(c5@vfN zyoELXwpjbvE?nW~nSvHu54OHeBS diff --git a/thinkphp/tests/extensions/5.6/apcu.so b/thinkphp/tests/extensions/5.6/apcu.so deleted file mode 100644 index fe952969ee5e3b7dae3305c44929714a4780e7c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 404405 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ⓈU(dm{;I@5ln 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

xj!FZKB|x6BnyYl(I<911{N`C}q(P zcz!jr#r?eLFA0j74R(g13jR3oLiW4E4inv6qE4{!WIC_ajVe z{GE&gKL$QT_Wyo}X4jjB0r?OaX#5z>fyOZ6HJy>bsc5zVR}&Y%{Ym0KOI-Z+CmBb6 zNL*C>Nyd?~BG_AZ@$4@bTl=dsu!7qOYr_$=alkxShWO)vHqW7UhFt5-Kh zzlUn&T)k`gkP{)$S42ZSYc1$Qv7xT979b4S76A38XlnihaVg@P#X#)_02c$@BH9ch zE(W?q478NE80Z!;&=%nNC*XZjvDZekVz(R!9;w(GUkW@w7%g?vQfo!-YY4*+-_AvC z>aDJU-PMF>6*g@94MMik2Vq%pcG$oZ#K3%2UHiZU5!GZclG~CB0h7cB#sSafyL755 z`h189iLo@yQLp57vgCF-qe^b4h^TvsOKzt~ZVwQb+)k0)egoVZbPKE4cTp z*JceIHcvhCKTk})4DC8@2T<-f=rAf;71V0pGV{bX#gh#-9VHHMAEIan7$qWJp@=am zwG||kMyqlYb9|$OUm7HoiiB?(B$SE--w2WLB-ZpYPN~Fq*21c1_}K{!j%mY`iX>flrU&KhJtEWl&UrnZ@d?w`0WO@ zW^P!AUE*7h!2z@myQFOXA}+qQOMGkQNR*9iY(FRT_ke3(+HHIZz9E~i&o}ypv`l-1 z|9^}xzVf2@%8*gO#TWJp{Xyd53wy;EekLxyuvdJc^JokQy<2n!GEGLLov4puJ5dX| zZYMPEx&ZA&Rk)p~mo(B4hTj+}(un9oX=SIr!=D8FS%6zD5YAj?9V?rHG0=2LQ&avg! z<5^0Pr4(06Q58(8f(hd{n&;dKOr+iB*#Y7vTnVMpK|BVeBo}~h98xO)Fp5A4fJFqx z0N6-i8i2P5%m#10LXAJ_%{s6FpfE%sNI|Tdy{sb_BqR%rT z!=iB*uK3?!r4(99iKUcQN=c=ZQo&>^s020T*|u^cuH81R>41rtfl<@3AYL;Gsm}qh zi@-7fstUk#06hT|UvDBOn8;-}fpQsH)&kfDAm4&#mu&%dkXR@MDLD=xFdf!C319+%${zt>VX^ctJj6us5y@iCK!!3nrGrg z7#A&q!ucTH1f*mbfOi0tT>v0^27svmW)Qd>KrMixViS9edDbKEWlKPHVp@&G0zfwy zQmqGhDMyonXDLONQd}uTRWPXvCQR*kl(E)CYWkprSsfv61+*J`H;8J~*lm1_u6%-z z^Go;OQF(}P`3T0gOssHhoMSBhcUURoO3YHmtf0gSO2=&D5O37bJ-U`a9 zpkyY`W0G|y(s>U_m}SjEs!To$#CbqU`T^Jnplk?$R+j=81>k%FlL6cUU>GF@jf5&D zALq%hVe*VqO8!#vR!~+2B{TWU@GLNqK7Uvz{{y7`%H)@TSbiCRwE#8(D60kV2Z2Wb z47?mgu?qkzY}v~Isu5CF58!D69|HJ}z}Eme%!cqW>XsBJwmeFmGHLzKJkiOXcU8C< zSuS1Vors~Ek>%1wKC2~M%7OglQObHmYwI;nNLbV$;c}7iQ-g%dMMB^TL`hrjg@6-Y zeJ1jEM9Ii6kPx16%#fo|C%iMjsZTPU@HU>0JmF>glg%$8s?TM&Jv+Y#;4i)1z@LqM z6;xqa{LcP~YW`P;U%|HPTQ5hu)@Yv5OfWjf?LY{AB~Xk<2TB%z_!y9qYXMx0@m$F& z00#&>03Z(Ikg^>B4iR_(Kpp$_*8n7-zo>i%fOGYUWtE=^P_um8uQ2_3liFT7#VX%} zOCYTa817^j(+0rL1eyXEiIs_K;!CEkk0U&Z?caR> zuvKG~+y#KGLdh)vx}pl_*HhMRVD|tkdlf(rI9AzP0LBpb1VBgpm3@nUH{%cKl^|*7 z;{@TFwCKaWF-)%#;Xi<7INx;$GgN~idSJ;c1O<>UbZCrzx{e?QM^EUds_{wmUSK(& z(f|1ugAp-FL|CJFQZ~Vq&C#c{jB7wETn0VPf_M^0N#gl9+X&6d+5)(hKsNv%66gh> z379Jf0N{+OYy^Nw44EJy+n1MJ4B#<@lwAp+)pC%o7Si*}%WefQ3n68919*zSHUQre zcmhECYN#|uo!=40xhP828x21;Pt=5KAy-c(E|QwC8!>cUx=3om$6CVklrSkuoiH)K zZIp1JLBb@F(Cq54gh?Wy7jSFz3()42iFCzt2*K|PQ1(~DK8Hcve+__>01~c+@}~e) z0;v2OfOB=t(n`-rvCq=7Ab>UG=?WnJIsiQZ93c<_;JF?^Ie-TMRE`JWT>Z$>vKatA zC21aj%{PElEu^}oWh()^jgYc+0CH~xuob{e0(AiH1u*`30KYyfT3clSAiY<>Y4^gX z$_@bA1gxwcK;caY=CPBqkAU3=Y#hBP!9<-6ifZfr6y+nH7=1HDPT&Ufc*F6udE%O* zB{U7Ul*_>-n>L#X@L0uu0LA}~(ztIErqm)ivu`6&xo^X$`SsM0Co8@LCi^xkO}cB% zQ}5e|@_S8?6$|Cl+?%Ktt5M1=P<{ln*V+_lg?XwbZsDjP2YzEz*ZzpR%cZIf$8F{b z4|LOCu0^v5I+uB`L?rEjyX0K(Itm%1wibh<&ZTNh%zGLo3~G>2Clcx#B-Dw7)08lp z=dWu`q?h+mEu14+iN>3b_XmheZw25Vg?dCF1;GCRl%)e0bQ>Hd7XVywd07E~hZ#~L zA*Ys=jR6q93L(=Z1a)>cfVl`MTLPe04M;15ggUzxz($0W)dCp08o(m}`ri&<7l0cH zybRzi0ORWcBs{OREq?0-4OlPgXW1E0m#+c8bF^hW1AvygCJ&aH=~ne7lb@R>Y<> zs%l8>Ra;tI^v#L?T?gj}(BH_LU z2}L5|6)l0EUsk={DjaieqlB{!5_*e-|20VHEfU(^DY>|+HzZ`cRkev(((a`%!aD%=;Q8T-_kyeyKS-8zkH>HRoL|VN4<j^}3dgK(l;B3ItaEXPNSN6m;SP~-tCp}h9TIMJ zsc_7X8YK*BkZ`L=IM5*BR*~>EC8T|eHcvfa-f%gFD0&3#L^ z(66lUeN44ehYxo{+EYF_sg?ak3&2nNxOtV6&5yaL*L?VIWuHb!7?#DW*X4vg8Y3RS zKVfo^@j7_%3$DWpI_NP<_JMc}kdh++UMKJ#fSd0I@CAVF>rvs)0=VfO0QLnK7;ONM z2*9@y#{n~AE$b!pXQjmm8Ajur+OJcn1_j69ORhlJ&tNUN5Ww(F04f1I2_XLjSjv_H z%i9d#CIC^j0PX;=oWK?UIa|>CB)qI;&N0uj$3Qs(O4%y_P5~%=4gh}x_*L`k(T!H# z1C20=Up9g7*S>FJ{%D?RN~{k|B`<^4^j-kZ0vJ!=F#y{DSVdhAh(xR0JiD-${uolv z2)W~{nw)Q*LrJa&xy5~q{mMa2K4G30ll%zCvV>OrKNFmONVAo_08$lWS_5j4gkV(Md6un&#DyeTMd7eh zhW7XhPRc+p8-;)OfJu&}h1ot1CtDmV1BDmBAOnTZ2yhJH-i8$a&E7a-2vhi>S~Fr0 z85}WCM!pq~v^io(haed->@#T|GEZ~TV;tW{`Nf1~B9>Yl>!Me$K=?#NE?ENL1cBKA zrrZx;8i11k@@tvO9l(}80ALG%-vB`Ky|3^AzcSCVESTZC?O;j;up0okZbsxGx#2FA z`8sh-K#%C>$DmKcNJlp_!=;hPd??&d4VOk@DexhE*hZAQW+2)t#BXg1e1xkT@SzU_ zmpNaB(2o+Ax5UmDdh#P!Taw+6kuIK6!nW!XeQGI;*DV?HR}k_>$tzaVz&}*pRvYbd zJJ8!RzMMtAz{OARIak*&2}z?dMqa~mu0Fg(FGp2seIG^ovK&<@uU+jRF3VAs^6J&M zz-8HJ-Vtqt6D*6_E(xnOVSMFWUGIYFo?=%Qz|n=T-xdl6x} zp9zR6zQ>WYn68uS?DK$YtywbrVE>@rI@N1lQV6q z6fxBgz_qDb{mWFX|7EH+qTeG=B0arwC#L$0xL&yvQ?=NEyr%up9u|m>lXoRlx0UE0 zx;rI=X9ClwPsP4vbR5G0V;kQSmqQ*YF*|O4Z#4H}0&g6>CtI@bi|a;MvL36$CEIa2 zT)ZVdj^3i*b4n06Q@p|-N3X~};D!!OG>>>s(>V4^^1^T+E}!BhXNhrZOMtjN!@Ki8 zzXmku#=(fY-l=L$S!Nsu2Y#E8-v@3Bm+5*ZN8LZ|443J8`AWi;r+~`_&Uz<1w)cRC zj&T&fLFib?S)w;^HafZ6?OeTgNvOsP`X=Fbu6|?5kb3fOcG3v`r(tv1(5aR9vx&dl z3G^+_(-Ie2b|n%cdkBYD$jOFeITYZ+9S5hw+)sM7mwKP7xzhsHwW zxAgO+Tj7R0GqTUgEu+QHA&zV0SUq0Dl9(PnwX}u!=}l{p7?LuQOULwZ^G3jhpp0Ps|#=Y4El+;%&iwVQ*U_b}9xA z37zP$w>VXSi8-iILYGxxf4xN{OmC2Ii%7VM5(dre0Re~cN|1@T@Du85S&x9K)`TS- zmRExQ_flAg!}4y=u>HWr;}1LN@z(;^9)DEmI8nP;d;A;n#vS_p#oEK`<$bu_;MX4h zrtr6T8Msva|HwOaJBds6e@pl`ppVow;FyCo;5u||x(2-MU=0}cDsZ%P_-2a4KTTYk zm3Jlny$6B+6$Jgbyj67bp>Qkto_t^G58$E4nu7km(SO%sU86n_`q9@wmnP^#`IHEz zwu?jWpsuQq9Oolh)ab>mQ6D>4qn>&lsSSbKt53u_Rfof_d%|H{cd@QF(h@ek@Epzhp*X@Gy^w%;c zPk%ipI8J{pbFwx66sR?k-?&-vk;u1hHcv1}!dnb}e`C0=hDjgj2zAWYa;H?yJQH?; zVb?kb1Or%JZ^%+_$&%+ylj7?iYXL{hQ}xyN`d!G^W0M2o8-FsrF^V5*QhOY##>Bj$jkv5`H}*ct+kw)?XUf zC2v7z^HvvpYlZUlh~T+c86DiuQNV5ucP9M2hULV>9xd~!)(GFD!=+hxQQoGOk;2|s z)=525*cZ!@g8q=fOFCQzG5h5u>%5g~Ft?(_3>5F2J^}$cZ5Y8j1+M&Ld3xc5eFMZ91M%- z01?m&Iv$c(R$irqP?gss3mM91-boM5M!wkq(uNJmYiZtwza-ghD*y%Q1XoyJJ-=tw#Gt4i<1auk!3 z-M=$R>f=~`G6Fw2u{st~65C`F%8avy*L1nvS5K#!PT zg-B&@0h=OWg1E~BKfOGY!1(jz6II*zOxmH3JR>liZy{N1u0CrQAX%bSis4NG- zM+hm)2XF~m@zS9H%0}bg7GPyl0Ness8*l=t{(uaX%|*yQgp@4@KwU8gXoh9^yAiY+ zK}}Dvw?|0XL%{NYl|2n$If0h|+(%#&fL8$^ay3}{Gx9NneaEl?^$429pu#(_xBMx9 zQUF5X_CU=^J;@>_nz)NmcndXP_m-0dWQ z?*LQ~I0#??fnxv;0k8&CA)PXEC*Fw@uW*Mlt{smia28C<2-paDm7XFag!v|o8pKp* zV)N@Mp*vV?C?On+zorftHzk4NhuHioJS+QvLsbsrNuZsEUPJnc*b1Hk(m#2_k~Px2 z>Lw>`>KpMf>Rq-<*=Tl5bMugSqC0PLPq@{|mR6?{`j{ncar-4S(ipYB6(n?as5%q# znMMgC8zgiV37Z=vbQTFOQNkqkUVljVuiWdl*F-+pD5S6YEeiB9CH;N9A*B3Q=kN=N zIKyOIZH0-0i!4}FzqeQ>A4?kvd?4So7%3tgt7nA%3WD2QU%z@*h!>2h(W)C{I#yTd zgR>XNS%Z}8|4FiuF~I?`UDa(_%|LWSX zJ8V!~rI>+|(C)B71n&T@8|6)czXM#4ayH9{3w48BtJoVZgZz+WWQ!<*4rD>7dl3@9 z*WlY14C(IzexGD+;kS^zJrnp=p&tjXJCJQkcOdmwhQvtsE8T(A&L6NB)nVW!{LR9f zwsjbcAbR;YzWh4}(fLbAM$it`6io8Ud){{dxXgMPfcyebWtsJ5V6x15vx#@Rd2*R` z7{3rxZvtjh;8Uuk#TdM!@I6|IcmVme6x0z=F@o?LC*A^~{M9qc&+04ca4pJeI(SMJ z0N6y}5&%U%0GI^e76ADPFn!r7V8?(}-U9&Z2Ma165TIs3(Fh}Vo_W3o!DY{Ydg+e< z_5)Z0z$%{klO%85Yo29qg0zbyvrqnu5m1f<)vwCl3@zlu#;GvJmC%5{YH~DnbP01z zAjg0@gnDX?`5lgDz0|aR{l9;p9N#eJN`$XL%#vyVpAeV_APef1%mA>M zzytvM0pw@4L}u0j^T9)h@nfHN7?HCKTfMk zd2_&YYph&Po?z5ZGEcPPRmznHhBcZYXb9*zjpo_s7u51C_~W%U zV9H0{_9Lvg>R*flXHP{n+Z4+e+Ew|Gcinhwma+05U}qcpC+l~a{t!^DiT$=ik!Yp- ziVpN%BqJXJDw7WZ9YvV_5Rk@y0zQz5jPS2RkANdnR}I(;3k4A`+ZTfHaegj;%I6eP z#9WZf-f5hF^48&aPUd+HTRshtUk*a!o=cd$7NL%fldpq^C}|0L{{}xfg-~e;<^YqH zV1yB0X`W`oWk5k|eHL8nGow+T_r(aPD_~GFBK2va_1OzTqdsAF3q|vP>QjKwbMq5EL1rOXGy0d}W?+n}R?4VbC@ISJ*bH1`Y9) zeBkO;magrrT82IdzbT;r0uSlH8R5Xc>F}?Ahe)=wIvjYIefWo(bG8YLc|8MK-DgH8 zO|8(gO~KS$%|npwJaLguBx*R&kOHFC$c6yYU#>}^99EEU=)$nr=IyXn6&CBTLfhJd z>z26JMQqgtM(j4AF=RavW<@gToxxfY_nWXmbaDvT%3hRh4tIG;mSzz4|cag9L#~9rTfrdKJWcS5gBc$3eiBdw} zC4%%|+(sc;m65TI!KSJ%ZkLd%!z77yx(i58$Gs(_6Je616=J^k#Qh+og2>E;E=vGu zZ=AhNO8y+u$xM*;$92%8u|^F^YYJQTLvi^++8ZWGT9>s4sXlJ3kP60`SS*fEC%Vqt zaaRhdHcS$Mf3p$(Ag)G87Tk zxKD+2VnU?yfmD!wjQd+i1rrTPlPU|68k2|s&}d*h!JQtde!KHe9kZShBh zwD%m+_9&3H$A2v(t52kP3zI;4INte?IKVliYAXL&d}|?{h!hyJ3+0uAaPhF-R%j4g z_?_|Xg|&KqTPeR7uCrB!xg1vZA*s*_7a}NX2>wkygeHE_gY#U7tfp>-j6n}+q>apg z)`CZFzP6^GfS)>2wjcm^E_tqF3?;=px3dSj_6U~*SE7pUCIy@wF>RFQ+aNXN7M>F9PVqu?x;@# zd}}G#9N9?Ud7FUU;AhS|2u6F{9tv?}Ajnm+ncz5hhWh|>3w>g!fy;FvWqMo>z||aM zL66FX@hwLWv^Y^csk&$EV0_af+OPJ)7WSV(h;AaI764^3T_tZjkYH` z$)E|g7yV*%vO$yVqq#s^7&K^K0NY2mG-$e=i*k%kF=(d!U!tuH+SBd@(?qv6Xo04&Cy|o~ni5xEkgqiYruWg&+6Kc2>ZLDmW_manUS4K@mO7;I+!`Nxa11xN0_^c&Wj0 z*X%&z!)2LAE}MM>MIT)*+B@6tRrY)gKcXvCP||-{Sur`x-qYSQDBh&#=V=n(i|EIq z_h{=_zC+Bx3)(my-wHplm*_G2mbOJeJPIe8tg87)t+;(9CdXQ!8FnaeEk) zkk}cX=t;W@Er4Gx7Wd1=;{F{m5bw9BqhBr-_shlNez{oO-?JA~@XN*G{%=EYLBCuq z?w^gUd;L$MF8KU%vAEv>M~(AuZ-;ioFBgmZ zKSjoy`Q>79e@9T0{9E&|J?od8`2&5h-07E##r<-zxL+<7_shlN{w*FfLH@0%D{cL9 zvABOq8@v(WkBP=QuzxDtBGq3HN9*X9i^cuVw#SB@-wCsK@^3`*)!9D`wYH02E*AIy z1v7W^%f;e;xmesU7mNGlVsU@O#p0fcePO1Ai?d-#yVHJJQZ5$vKZ_zz{=slBhd&yV zJEz}9JLdAs#p3?|1W}v)5f_WwJ#Ii;xmY}=@I8P{^u^-d^b};kcM)o;H>=RcVz+#M zA+~qGZGtHuFBbO>V$!%T(8r6#y@Ok@1lxOjyja{j?15NfJ$<}b+*|SyG{gN(zGyW6 z-qOW!#0q?MXo$VTH8$AyEXvGVwnsS2eY{xQTduK@K3**D9igR+@l8W{dn+_H-nSJk zw)cFERrz?axOb$+rulfWxObGsX84wO05)1STT-pe-$dfeqZNHu1^DCh~7j~9!3ulP~WuU$TVYR)@nrAR*I@@;@0 zd*?Pm+45p>A1@a7&bwWxE8M=F$g20sv4YmPeFsosyjLX)y3Xz6S9ZM1sszR7Y~(8I zm{1zB)I?up?Mr_Nh>urU`#Le_^d??q?d$xcU>+YozUS-GO|S$Xud?=arO9w@kB3#c{O-{)CUf53Kf1>m@vG5mFALpI z)8P+M30$Hj_aHZ!crA#yPYeGO6+Mn(n>Ff8Zp-^J(nx4pNU^?E$VJm4D#Fz1xJ`@6 z1;@3LRMUZ9f|AU8ked!7cHiDPktT^a?@cE3~mpdI!VQyM?V#MT+c>&@)POs z;a)nx+=I+cCQ13SSuG`kFXvwoe7O-3WFWx?PlgwNT3)#aIgoxBK|bDt9Oy(BW3G4) za-j2WD8%X*M57ewLeIvC#g~lXPM~WO;Y^bJ2fFF}2Q81>fSfo59sD`7!K-X5D!#Od8i_83d^q&DKmZMRU77 zOeaZsyRs)u<_*Z+ZV@JEQAE#aG(j?NK=x+n0Ny;CoX(~@QwPY+vq=tb4m;cAW?ez) z5h1K)8Upengz*Ms?|Biz9%j>S%8bI2zl7U+O_}iq?uG%u@2x3$jPJFJ%)4u^iWok%R7X9sV_iQzBEJitfZiK zN-UanA8$bRPGtlH`*;Jgcbaa&UB0yl^JXd#CH(D#6Daki8c*g$Uk&+;k}1 z0~1t=OiJ?3XFuuV4anXFI=bcSN24wbixzDb?GbG}z8%cyVn)(qYxb3Jk0l%wNe%HX z)mbt(ARh(2sks5U8a!^#CkSzS4&r}`3JilTiHc3)zvrS@{Qdy^t>m-EiBpjL_TTVY zrB7l&LF;v(RvWI5C(r*9oKc)F1UX-C{vc-pN(DJzZ~l-$IR8#E^Ka`DFgUCZP{K@! zb0L>gVoY4|4<`}uq8@*rbO58Ca60sa)2XM!F3(_)9eTFw(34`fo;yz_LC>8XdeRI! zoDAGDDR$^dGvab??9g*#x1Jl9fz7Sw#ss505X4Duv`lDSeznX2o&OACnA}9cA?OPp zPH0`t6^aI^$HNJ&E6Jb<9!_Xo$p%gGa6;>9VbGw56IxeGgQj~pp>?GgG}FTgt*ezm zdwMvbb+tBVfrk@XSJ0q?J)F?G+8VUn!wIdcok7QVIH7fQP|rhuNBb%dC$zY@=OsaB zcsQYTrJEeh_HaV$>T1w=9!_Xo-PP@q!G#`9XkFQADNs&mJ)F?Ga@2K#U!y#n(7JNf zLCEHW*24*{t0xWx6JMb`oY1-o)kfj3Q65fcT|?D&!PhAdC$z3%2Cr2fPH0^v2H&nc zoY1;T4PK{k10(R^YP7`Pr97O_y2?d+PG~)x(7GycY?$d|LThtE>v}pyCbX{SX%a6d zw5~ncI+m9cTGtEOI36!2w62$QX(wPddOaezJWn7wADxi-ik%FAq4W<4{UIFM)QVH% z;ND7?)W1Fa2h^ios1ET{z)=JlKb!%AuSW;rC|30!oVi)5EmOab2);@wNRvN-;JbG1 z7-u#Re>xLsPsWVDK*JTCg4_nA$>j|+$Ld)LQ!*{pf$=*2O(9|Is9@My6k5NtXgazx z-lU)l7UnO&`W`iZKlDwcIh(P*yC0;XlxoKM?tVxkRy-=V!y1N;&Q$Sgh^jHwdVdow z@K8rE{m3-RncMKHm8qZ?mw-@#!VE8dx#lutt5WfZ?&LqWT%Na8H6tuLhTcjso*ii@YA?iWLa%e%lve(<{zKE-97c*)xREVYmR2UJS# zeil&2e}GEi-OsWc4>W;gww*<`4Vb^Dln>EAm9qR&iVqPTgJskN7UaV$N8C_kHJL}7 zKFSnbtB?P4m47Gk#|8u6443wQPV{kBgzt#TS5%)MS`9yKI>H6&GG#?U8h(N5Hqb>1 zzMjdgM!3I%%Dl-a9uHC%S2#v=B~bs@l>aW7r@{bNj^1P-H z(P-og6VEYn92_XZ$P=2w$fIJkN-a@2J zc@6#ZC&beJc@6zDEh%iuYv`X7fLbk7khxkZ63dOGRi=qs1CFOK+t4CcQe;kxu*j7Z zxdv!UDV>!RsYb+0gC(>>p!r{;zN^Uk573m6$i&qqmCPVWw=2kRbu)r{v{Y8BWdOzy zm;+!Zf$0F=1rVqXVhndDuy`~>t+xR9oWP?1@{xAyT>x%u4d7*x2-E|(2p$-y4A>Cqz13I%KNA=Z zAQ7YQRz(1M0tnQ$g`hdWW&>-z6hKl305<{XLtrg{31~c9*8->}@Cbm90R&F9Mbu}3 zE$N8h0|4$#1Mnt*8 zo|)&~T-5e$-_P&;eE$E>|IhN=IWuR@oH=vm%$enxXCJlcAhJjr-EL=SUkcxl7`#Av zy=SbFKC(pjo(qU0z@F`&Zv@%+RFM29+d=D*WUr_6|86_Te)B@0$?YKfEiy>kLH4~A zr0t-3N~P_feg*eZkhX)k+zv7(4MOmFLgZV;(2MvL@6W(vI0b3y)ISvg4K;dUeb8VFjCYWKA2h@QlO5#W2Mx8r zR0sL@LBlLC+d=+)P_zZ+ILN;bim||X4)X7VMp&T7LH>QvNW5)IvR~mK{~m8y9FkzA zgZ%p---eZg{QDr^hLwZ-`yjWz6M`^eH#o?@4;rVJ0wn+5LH>Qvc>Nj)x9Se^?}H}j zkApV(_YU&!gHrXMO87e6LH>QvG<~1MZ`U29{6Tp-NuM^X94Q3nTkw9}kxFoZ1wWuW zrV?Ce!AEq*EQ0$stQ_Ru2lZ`OImo{cTA=sH@}GmjB>z6>X{Yq>gN~C(1o`(t&noF? zg8ciS6G}K-kbfWKw_#O-3^slTN|gr418p`i zHV1i)s|=6W!#nRiXZ>3+?)aum|%jzqk(7QuHNSJPY8 z;%5+~V+-jgx|2AI9FDE)(d%e=>85x<*UXoYL(~rd)VfhZk>Xa^568AA!HN+ZE!Kg6 zWBYKZ8de3xpNYzjPi0!N_(Kw)Yx8AVs@Q@4>A0>=LfK&zI9Bbr{y7Qdgw+#t!vP7+ z6Q>h^c_XQ>5$h4hplpttW=0aULM#UBj+>(-R4JTP!Y$Pjsufc(UvTVfme2Kh+WU7Jb-(immoGh&k{p>Bhbp& z?a;+Z^g_q2BP56|&uU`nN4H7JM|H7-%DrulOvQ%h2Tp*uZ)<><+v!Dp*;pVJvZD%> z$Fhy6L^lt)RyAv+_$nIEb(y3wu|ou(1?UEq7A-2W0o|yeks=vohTIe?X~v5w4nQ|6 zC|OJ+=oST~3JuB;vhzn+mN8U}A>3&HkRK`VIz!wGTNiSh0^1F-s6W8l6?mH= z22TRGPl5Xlu@ikJ~RT@q|(;uGTPzHSNL#>CYSZpi(wOK?9E3rYMB z4M6XJ8Zj}Sz=vr;60%}q<1~PWsj0AW&cur`03T7{aV9oX>Z64c`4kf`Q|e<1>|x?} z=yxHHFO;cgm`Ffh4|$?Qg6Ei+1m;6dobJbjy&L{Q$GBw!|g6`vd$|9BOAkjLX)<2e7o9!q~19(*b2o*PCa~ug&pJP@*^EBhv zSTzVAm;fU5xWJ!)ZinH&@frzV_ss7TJW*=W$9duz;Ezz z)!he(JMDm;rK@bnFodAW!6#H&r1*&o&`AXi5iwB3;8O~U7VV<}{X{_{#ZZ`#;Gfcn zL>7KMx)4;z1-6Q@2=j+(uNDIJQqlVuU_dvKi^fM3V+b>X{OZcBH~A1rO4TC5UY&`aDW-@n5LGKO-24xkeh8 zkp&LDw7_BVs0V2rDR%I13mh^hD#~>`f{x&L{XTE5F}_@-^$l9E3kMlVV90f4Jn%1n42aHJ1RbIK zNS2~^B1Z2!X28zUV0X^_mTST5s80`(l2{*r z&NO6GlNMYT)(teagnE zGuSvOoQ;zf*f_PDjgx<4<1}y@TS@hrss215_-g9cax4wrOjeF$%}A9jNEcgR@4S#9 zKJtT@HZ&mkDzXJbz-?Vz~9r>JvWD}yFAyBvoHQ*#Di zFJotrGT$JBJ76+{Z3*1P_$9 zWDve19vp0$6>N6aKt&z8-RhP$PAN=ciLYcbb>M zRG5SAM}nZ1Hlrv=Ds>*6*&M7OE`C%9XoxcD4pLFV3PWads0@CBb~cC8bkdoNf>O=6 zap>IQ8YqN0ih@M)3s^97w1T*x(wR| zG2_K7sGgais3e1x!-SQGLe0dVQSc+OLO+t4wA+o~Z4~TJRj&dczUoVI7vY|U4c&xz z=cfpI!ls-=IIO+_+tz8+F^O%edswu^E4+-9*{!~IJa>sS`89ZmN#vdj3r}5WqMMj*m@4)snA%O;mn$zYn2fhJZUIcz#5U~mvOQPpNB$RR$S2Iw*cMT#U6_e=#v zi)Tr8vlJ9B-lK}nRuDBSd3MHcNZ2|1h@r7)){xb4C?(p3pl-OxYb_(UFnSDvy3?2m zT@I%S3}hP0Lu&58FB$QWT4}^3 z?v;eAInRtkM+{l_9Ff;C+=r~EASuWmxMU%9FG`3`BoGHSzM0@x$04bns5%G3LyHV) zbYhrQ`J24?MC7}ROie3;=AUi4i%S{dST126Ogs6sLj+nF8D*4yYk%+nb zB@`)WRv9r*aU3mPfGv!euPPcZf-o72Sa3>WCX3&~szfYQP^!2bDipCuLD@p1(ibZz zNBkXii&%0_=9?$XY(Ps@2_8`enM8P$-C7}%u^1Oo{9B1xDQN7DxPpwL5nC&=se}>* zZ4jTLCr7OKBQWK}{x8tih|;O3JnjF=kuqW>)tANIqziIABUT-eU^|X0V|a*It&lO# zUx@gKGGd6%JVM&NPL!P49^x)^S(YnWmB5Lp)@Dp;9R0v2kJs+-zFnqM(KJ6)=~mWzWfFB@n$V~u*>iA)*_Z2UN+LTnP=+*2 zat7M*0BN$$HcpbX@hDKS@wa^0CJ~;@MuiQOAYl%irt)Us$4=t1@v$~m1R*eIIs+PIwmfWxXUFjEn9sDS2JG90os(!60HqS z#R9Ej`Jwu_*Nk?mZRTN#{{)^vI<0^8;cCYERA5YhMPj^;r=mzJVg6XRLG>MZUr4NP zBo-AyYhry^QtPDDG~*Qrz)={7bhI&^s?BIc?K}9Iu@3#!F>jtkU4mzjPK#@PXi7ly zU^pBLsV2rj7lKP#Wsd9c94>t^Hv=FDr7J_%INz4G&6{jWE zD-w(9L`wz(N!bQcZyP8<*__xrK#zp4h+HM#%3L-qq7B!n6AedbpnS-zaR5ZNHil4G+c*N7*)s zcLScvG|*b2C4p@)SdOZDCBnlJf%rN`2=qYtKf#Y(I!(7E0C(-HfNlH@JXKrK0%2bx zXvTvWHXYTp1a0I0@L|ycWgnJR_}ke)t)<2{o|}wdLn5$jd_10tc8)I>g^(nt`upH2 zI+}_kZix?fiw~EUo(4*g1dUwM{aAun$A+CU*It>6=JAjEa>P4Z}b%Y?^b64_ zB35^t8VPW|wf+#`=*9YmbAh};gH{JF12yMD-+IJ{;Mlpyw;n~KvvaYPH`7bF^xm5o`78LKG#aCys{*45a9lwTXoXaibRL2K!KAcxrV20xzRM1(X>(VL6c6>Dn zV5zl8kuzwK=3Hr^7C7E4K-wyOEyQcY&T|}qA#s*js2&GJJIgI_xnmTSTA}xobXPb6 z;5j-g^&kmWI>I4#=UQtbRO=vz$hppv#Rdm?M9%fHT)8_#K9RG=g16}o@`{|b5}ig{ z$G24Ul~y`-V+!CIIO`=VEOw8smf#wsRhPRn{fSgKIP-|)kfzc)&6zKQ>l@c;&H@S!eu5-WD1*NwWu8w#%}53f z=Mt*hP=|BbAMiT_r%jy8`-omnR!ejKc{qGwr)LQAiWK6iNb#YGSRzrZARY60=M|@w zM6haxOwJOb>bwC8%$@6}Q~n*Yb=A@yc({>tyLL2j^?R71cxU~Kg!KrusdwQ>B*L6K z8_^Vyb%3})?cbyzF5aQaH!Em>xQ`TXgMu8w0mJOvs324P8J@Cp6IC7SoZ^fN&{fuw zpJu#|!kt$a5+84&oE&G%g5lt!o!Hw-jFU(Gm;vY-5(7=0j!|D~BeP1IQcEy?JGXs; zI9jrdp?upFG)Byd26U||D_N9)1Lt)LN)>-h19ZKDvNhvvlJ^a-6CWSaVBvi50P%5@ z`p847CYtz&>P%;sQC2|M%DT0h^N@ltp(D$3SV34n{s=^zk6b<+&q?En-c!8@3nLd1 zPb*ny;#IOJKUPqHI8EB?o1y$1j+oOsL&3-jBF^r^pb@+T!ANIXniw z%|SCUr`rO#V*}L4nPizthhq+MIFl_f#L-Gcr07aoPRB1U131nCL$zT`smSsAKd4MM zIE{2p(tqPCbFyVetTI!5CRUa?<w)qw1$WqBoEL=2h9YXH|uIDnCze#r1KVCO(9d2{o5(+A2!!e z4{FdLiG7Lp^A>6}>@2G1Y}Z2(9+B+)k=$=l)x7P}YTkZnHTPXw%{wlw=AD;T^DgO9 z(aww<2|F*XX4j?F-0vL;!TH`1@M)+?oRds^VKFlHRYZvAra@`OEYzvHXyRoUg-92w z0VrEcL0u!qYBDWHGhTq+My9-tT>baq@iG2eOHjsJSk@Rc=&y(ge-pv@{!z2y<3Rl} zs7loAH({cP`l}NG<&B^s6th8yr{r{8a4NEm?7+H$PLb@`Cg;& zQZUjMSVlo44g|DFZFlB~1Lz)6ODIiFMN2_1%0qoePDNLv-cdygyj~Z7o&>O1fj8*l zIPtSwfj8=+6S<&f1tAVXXU zsYcb(Ta93Yi5p`9)+x%^-@G9PVErE?SJ>Z7=?}0`QQjXa_EPnmm&?58LdCh!05?F; zAoXsj_zT)CYNO)$!%%UG3fiQ=k3z*$P>iUn6!^!`Fxoqa+Dr?PEcRlk*qMRUEsCqJ zLdD(iYooSOtD_Z6xmz98My@7Y4pTfZ6RF#%rBOjsGiHGFps4XEFMK+J+#YrPUSt(N z?+3ga)LJDV$TsRm1vy0VI6$}jRq98y2n+zUv!7gmfXK=)Tt&4j5Sz_3g^$`r8x-(h z3_&xYs6Cdr4Z$GUs9S?nUM8Lo1bCZb4qL*bsGQpsc!()QyhEuMc8H}W-l;(B5J#eh zQFkd2Tf#$a0K3SmM$0kLmC|-erR9Thu}7DcGlH z;xxRZsQbt-fVdgnZwB~);_54a(EuN^ls-U|WC47bc59&Y0V0>geMq%jdw}Q%nMFOS zz>Wa%XGlEiX(f%@0>t~oBI>IzH1Xn@He7P(UJt-Dz%9*upCi8QT5$w7Y|MV_?)Wm zb#`$dbR+6{#YVeb%%M)+qw0H`UCbo#v;z0rMcpibFAkEDe84V(sFVNFCFOj?E@-_u z>Lr?bqEYPP?^GiTJYyH*DD`F9CPzoL3lEk1%5c>vc5yY;_f;Ah@S;IKalR1XuazWw z`iWOa&0bUB>3-sNs^D2wg){vGdDv0sRG&ZBPkc=s<~Is_yPvp|>icGrDyW~J@6|-T zHBo{e_7kUO1AOO*>@Xh+Ap!yZZlbKwML?wOzo+#%NK%OD@F}C-Co_)<2Fe|?s0+${ z|1eNxBZs)|GDXL0qhWT^T%>IFS3Zr64kR2z63t zKZrMS$XJrEXok3kB+&HJOK(UbRgwHb+7lV#R?q;^3^@-;QYB+un1jfWq(KOq~Yg9`SwrAsEdX6m7hx%vXzLt~q84qP z!%@_tZ=p^sLOFu-Vv=YClk2!K$!eg}#NDHDBS6YXv>M69i6Jp&oF!Qi zMbLN!MT!vwO;Av@JQWc$QBjE(`_LjWlN6LJbQr*x$?1}2s`xwQOI6a%7JnruO+lB5 zLl{?L(iM~=S6^e~kw_!90F|eCzVm5Vbw|u`8r#HvBK+($NmvUjt*g*tPAG98)Spz8G~VYq&Oo{S=`qtAi$kQf zaDO9a(JHX>0O&+VG|^hQS{iSzw3@iCtXhlMpdc>HY-HJ}ActCh-n2<#MxyLHkljvA zWaIZya2_6N-G!FO)hZo{2k8$ZB1r!gMbiT@#2MB_$Dajh~k>U*c&ePh8QX zCLTz3NG+I=*yQ3bHogGQAia+8XbACpP!4tO zl{-d+?*>L#y*47kQn#>DZA2uE@lZC+NKJ-kI*6zk$I!B|rL>4*9Y+f6N5!*ZngC)#-I6?i*`wHqCr!scA9{T481udV9FJ z9;P|M{AdPxqWLB);2^V#Oq-bq0S`9g1Wbl`1S}6VyU0+OH^J@?HwT47Nz9jEd}GYf zC~<`O))Z9K3Y&kmKgpPO4=5Wx&)%Hlcq9j2iQI%KV9qGH=4%UpLzkG&F;fMNLwCzfe=&X=2JdP0aVu$HPr|r-?aAO7|el?;vv> zIFB;rohGKd)5Mf_nwVtfhnezD6Z3B9MYJjJG%@9!CZ@d8#FTfMn5!V~I8)wfV#+&B z%x7XT7ck|WCZ@d8#FTfMnDR~&Q{HJ}{y0a|+@`$K#FTfMnAbrgQcS-)O-5hQ55gTO z?=*=Ya|=mQ-f3b!1D4NSwam}WpX_bZUG;!rjhup}9)14-+ z{8yl7xYI#|LlhIyOI-65 zv`EmMCN8-YMMrMwP7~JxHF_==GpawyAnz)J-v_Wj6x)&?xYC(6JxO{h-i2WG6UCYVru-I+7*hsux zenf)U?xQg{euMG4G`xY0I!Td z3&DX75Ok-BtL{lj`C@>eJ55~mX=q!z(?rmnCa#8VnF=?T?lf^Vwn`9g?$4tDUNudE zx7h^UY2w;)odl0qcbbg3tQS=ZS9h9>jlUVzM63b_W37E-P0*btV_ipOTXXRo${#xx z)&VW=5Ok->*aQ+8O^fMvkFkj>P-|K_qqC4>-MMI0S~;UTO~xiE%z5(E$=GBCc?8{Q zGB%|{=361T96PaG$_{s$M9Vu(qSc)y*G<>7F}Vl9WH<%e0}`fx3Boc@Le5`MGtz(3 zrqGE9 zr@SyGF`imedE{r(-;QJ(r#>t%j7d(SBcL|^Ii5j!e{?{VkFuzI^1_(pU7%BKilKB(Scl`1MPj7f3R$`$tie7Iz1ByCMz7?U!d&WqakS3U%?JgV?Y zDqM0vl2jMQq)ZxtbQ_PyQ^}jglJDTF3uDGDD@2mh9j$4}s$F+8zRjBZ0@`%Vt1 z26R4$NXPhTL{`v+G2^EbBUJhasM7cuiYCX)-{WTuL}_t!Va)j16uk7p7$D@4&d1Ts zC*$+|5Nw>3n(OY#q^C07o!XZkM;FGpr>F?)!WbICxjuFr**uwH?D+3w7(2l)gM5*P zMiV*X_!_%H7*OIT#D9(`K^MkM7(*&XwW14SCb-@QL)0CkVeu!7CCw&lO&7*YNJx`V zq^$phL{V`v$K3u7kwE{t)|g)tLX>vT*8L>(l!iDkYs&%@}#n2F^& zG2@gM#!Par0uecKO-iC5F-BsWBr63PXg4Z{>#hWHQ{w2t7+0d72%=!!UG6>+#L07+o0Sn(Rl6HeFm+n-Q@% zx-iCNwHaL)6Gs=uxYAS>x-ce=E{t)ds|dO6os&O1$7~{%R5p-cp9KE06 z%2E+@VN4ud7~`6%BIv@HIJz*#m8~M^!kD-_Ne^T>7VT`N%DB7RYi7t$BRiw+oEK-ZME{q|PJkr%fPKcljV_eNDyC&$u7}o{` z1t@MdDo>5e({!#)l!?|OY@8essK?dhampUz+N`Q%T^K{dezbLA%mcu|k#*?2jqgUj zkw1qM9gr}E`~fo#9+GDM0nMkIi!s6(=1Gh<%xsp^!XrSpp`e5rGz`mv5-izKL9*{A z%v2>)-;Imwhe1hmi@3X;2ldMR` z(69jWZD@c^bB;x8J&@Wq8JWciC|0VqajA)MsCDX&g|a*xR*V94t%4ll6%b0jPC=34 zIk+~d*FP>Xqs2^^&eR)dp^#j<&e?!&RB6d#6N*l~iF|9CN-TgjrP3}tpbYUSB$2vP z<;xbIh5~9=&@{1;O6XAK<%s8l0PRv~^F&83pxp|ZFERoF-Kxs-h|Qp#`XdFc5Vxa8 zr{1P8D@7V4m3oIts}*-aWT|)F0g2(IQ86_eP$#9yeU?ul_0%q6RPM9f4pW!9UxC;< z$%3k+9*9PtlT(7*Fo2{Uq*COR;9IKX!^ApG2{a=C0#7|eO~W0j-4!JFNzl90V>C2V z-^zksrXE*ZVol>1T%y!xrvuLzIZxB3jF!g|Kcry%b%?d`Tks6h58^3@Gj-$+JR!%l zIY1lps6=~8qCHP&bbinBU9Kh!*Q*la4LsG_&R+f08z1S5CB9THTFM$oXKDu0ayqioYNpCc1^FRKObe;R zheW*fAt66)KB@dvC6z?E2BKm_pEP;6+=Qh{%5=oi87AX$=uKMMS~PKJK-$&cAj*6M zBG%0RLdA9S94KJ$^yG&PVgMr?sBTM$Nj;0B#hkuZ^P3>rL`NBrp zc3Qq8HCRTN*Ah=8{%48YbqY!rv#4pVr|v{HVn1P8)+AeOMrmm`s=hHzT%g9kNtKr) z&;F;~qRN{m)`HWtowSx{#I6u`!>>qdS80{vGD_=E&<1fMmA;EG)eL6=m9g873i0-| z!)vFZVxJJoBPxR?1Z96zK@QPE>>g22wD^Y79#c@VXrQ#m6_hRRq_ig#G*3KE(31*U zA>O8HKBb^q(M;t%O%RzMZD@Pi!#9AB!GC~I(hkWWow-Q+@%!LXy)Uv4>C*AzTKH-d zdsI)`I|UY1>?{DHWe_znf<$H+L>@*hbemd9b%?FR(Cv@Q){7KNiS>O7iWW6gnq@2F z#qWsZo!<7kouIoElqz1P0;J`n1)(8Stu93+M;HX{SFJZs{E5oDTS4=~*42QQ1H>^c z2t7zN?@`bSv70at9+8|?idiI_dr39vsCEI-lv{^nw_hU6`-vB6w{Ir4A5b9HZs;&} z+Jnf5RGiJOAyyw!sW_WmL6nYCd&{+(UsGP{KLD|Ru;wVu*slZyOx@GsI!4 z?Q_@2g5EX66w3R&;`u{EI0*R##nnYa{ESHTDDZPbTtUb$UMur{Wr)8KSHDmNZN>gA zQU0X@uVF$b+a&<&Wllfai1h>iGDB-mFhSuqh!;2AaKVI%$kfxl9uu&cb6xUzN* zA7tWJRPJk}X7t`MEDar#adrbKGVMbWq1^6B`^an4yQmg_>_h_D^rwlSw z5pSQ0hmF%ngh_iglFAkU>vie`vC^>F_-#NLeSA35igk7jKzu!d#DzAdA_dXS5|MpE zN%T^z(VU1h7rnt`$TMYQ=~HaRMwul+|27Kzr^pEn(_?9F@H;2P9HC56D2Jucfa!{l zr67^g5_y3W{@%^o81Cf$fGG;kQ80xGJ8-`&ap5DVW?x0pu^17o>UU!hrDS6!` z<&~I-W(&Z#Pi58DAiJ#k6u+vg@0_ZtPmxtmqFq#EBD%>CLb{CACg|6qb@jcf9^UI^ zeofNGA6#V94e}FZ&GyQg>5C_}Q_c74q_Fy;iIvbOK&U$|B+@470R*2^^xn1TgyC`~ z`ZE_7e9*qcWJ&O(BzOnnQsu{nPfBr}Aei3I1re(5mw+eBB2UU92aVOWDN>|Aks{3i zJbnSZM*XKcO^m?8d}@d%6${Z;(dpLj3ZU=tvGAm1;Sk~!3s1@-U-1?3v@D_*Fvvbt z0J8gZiIQ!R9-?8h2mOAKk5MpZa)O zCVBci$y?QBk|$TPSK10*30O&cnUwYkz*DwCqxH)r&r!INMKO7WWO6mZDJ1U_o&4~h z5WgSap9oG;{OW622B&p&HfVDAiQ3myjx4tRY+tY?oPgCEa9!5PQ z>mIb59!+*LtA$vKp`MYIPNk1PC)ctT6P;M%BWn!>N6O&jaR|oA;A?Pj^-(e?B|Vxn zCQI@gPwYaXNu<9iN}{!vB&!A~iT(xLF3I<{a*CAb_K9AJrbvk%BUtKhiag^zf09?C zDN>@>1D^8x2oy42r>dL;oPKdI;0fwW3mp%%D2Y#$5??wQ>EA>neUe;cV;x6Zl!PZs z2|tB&CE-*l;ZFgNmlB>L=}jdS=ohXkpuvFZv-OuT8O;oYpl?h?htv>=z&CWVS0Hs- zIG}xiro|xe8U+#%s7pg&G6KWW5txp^ixenCpfCdg4+3W>unK{nU|KzGJpwDTsMw5m zp|FjSii1)AMDC;Bxn8|iSJV2F9<|V1sfNEGTn*v88ozbGe(buJ-RECKASA_ z{SpDnmpu;&(|!+V4l-YM5P`d`vL3X4jcwopX9M)pq!cTqSZl2&eU%1U{Mm-gv_ddT znx>Ux#Ls5y+AMPM^p&K3Yo`GuA5Vd|0Gur~do@}A=LnRFR7Q%l7q^t<;D$kYx$kcQ zsLydqkaaxJJo|GZR6z>dI78R++Fbx^aghP>qUGI3sXsdqrNI2HsNxJTl0%>7TthG8 zkG~AXJxHB@EsbFJ0?a{LHEGmE09yVj#3Tbp4I#|hJ9x~}K(}XgUu3woo8w|`w;64hZ zBVb^oB{La;D-pKt^TAb```x(d zlw%>~Ur5yOCyOqX9oRGi1=#5huSImJZ2E(AJD096qDy7dAF=@YqEnRhMW;n{qjZ#Y zqx51Y+A1woZwCXqzJ$KYq(_m{j1MuryE#Udvq*lPDNLbgdWar3Ff@=296S)$3Frr2xH(M}bDcL?sqn~~RW7-?42L@739dRPaMTI8AftLV${Q^+#M=~il7}%?df?~*D%EAB%8HEbOZDbXK)O#C5-0do z)a}-%4p3>TunDr=lB^7}xMVAX1XB8VQ)Q1ss$`a`IX)07JHba26;MbM`&&rpUzoxG zbF$ltQN?17vyU*TaCU#fn$pLI0STq~Q>_*<`QYw%}vz3;R(Z19! ztNOsH1E^E4?rQ`UQRW{(S<3yhP{jXrGi(`FS!=H$h8{^n+-Ecceb!Z)iUEDLg%E?h z7JH!AVh4MTlH*dN6ymkF&Pxq!sMpS!eI}A9hxM7laAoHsymmj*e+VHXY+0W^V;5!7 zvZ^!K-^LE{DGe-~rFc?p@XCSLMw3bpyR_pD?`scD!-ezSLRItqVB_=+i{23u!(xDU zShRU%Or{N2_t4nKPZ&e} zEA2qVtih0E5Yksq0-b&!iV3y)Vj%TJvo8&er-uCSzPRs-iF(YxbR_(ZgEI3rt3e!X$m@^<%us{7+IK7WhlxU_GCcv*v%`Vgf6{(r9z{+7?{ z^Lce%pHF%qemlIR zJF-%oYV=@h`!*$)o`!exHm2*8=X>hz6WvO2S@>X5$y zhG+K`O<<12zm@9s00{*DdH!ZR-|Jc8EVOSV08*hpU&Q|$uah;`Yux5t>Z$qrfM9(A z5g_?1$8sS_2|i#SqiTd$Y(+q2RKya04Cx2G8H4$!HlQC&l>W`YAUt(gd=3Bgq{^Cg zWl5_ltJc>f)mGLft}9!&s&rLl+3G||3 zlNvVG;towI$m)NI`S0K)VWX&V)jun^vb4T(ZB;`eioKNI`qKL9|FqU+8yZkr>H5{B zb4EwydtSp{CA1u6|u0T5EmV; zE-ObkK-0Wf;KLh)S!<|TSB7+0llrO(+;EOC5ReaF+_vJ&8rH0>P2%(Qc8>(s) zg5{*N|sbY%GG856+jk9MdGZgSyx+CO{IHd@CLOXR9#(l30&21i8#=N7Ppcb zL{e6|&M*6=^2JesMxS(1PgNyUTV}4Pu31@HU0<@UbX8rAzqqXgKe8xx)mjCY*EW`{ zs#)JqS5u7$OadgWb&b^xRVz0(TvD;Rvh}5YM9Malt!lgkqiTJXN++dKbs;{4Mby{q zCAEz!tE*Ni+^Y5Xg%w{}R$1CqRYN)flZ;MVy;3nrP|f=F&^IWoO0|>&DcGrQtg~Y4 z%j%lS>Pl8a;&oLk8~f0`s)EUFpQ=}CSYWf{j}WfXMV&#OVkIFJ_G3iiTfG8dZwgfr zl)-QfRS7{9Us0hnh9ELANPshHnE(aI4AeCM5@}cggo1q`#H}u?tt(qq+EBK-#7hMP zNxJ@q4DGkBR_YNtZ)06`N&Tu)$g8fTYy${7AllOUs#PWBjq9Zdi5El?6?E7>z$coL z+PbPH6pADelx?Z31tLPwmS_#?j?~@I#jFlQXnhpweHlOjQywFGBmKfNe;`_CQ97&a z%*@Yk%x}Y={I8z1Dh#fGDcs(XJKQX^Jtzb@#OG`jSY-WqM%yE-koSDRx3Zz_tcI6gNYCUW0}S@s`c|w~916*k;S4saofYS0 zRk14?0vPkOBKB1+1HngI2;*aou(yYlGe<95%^R4>8+Z+I!`2w^g2&+7!TD?lJJgl< z#;z%u1v|LOg85nG>{`n+fc2h9WV+V=dj)lyJP)NDHuEG;8_vt0LHv;XT}xuuSr|^A;KvKKD=3ehL*)Y4kJoe} z@pPD5hTC%iycm{|3FzrHp7cb3zYJ^GRhQNFNb~GvYz=RZo=ODl?e>c1jvoE_(F``O7BBV8Xq`Pd#%S&~(3B!>Ps|B}532{HiC{~xjgoNDsSy9?Mm8+%5q z-Ug-I@nTzg=D05YMq6%I;_o)e>PQyttVs%zyI3CY^tS2e5cH$9+znB@8cfakXzjn( zoDT(iPD^2L3kJ#aw)5hQ6Zy#sZxAb-;=95Ov*)Nr!Z9LEC z-|@w4R>htFBxSZ=$^|0t%kww=Y}l0Osce`#EsOQTX0TPBqBb_?5DRO~-?_HF@eLNoo$Mc5&{5k_;FnuG>^<#l2Yb4uvyr`|f%U{9 zq;Tg%wlR;14A$ImJ=^G>U%a*8OFn}7c&&#C?nLeEteHAWKRZ2b_6m9~rAPjFJas$I zzz_4-vreZhhMDYMOa1U!vjO4fWw_h)Fo%bb&{gvBYp}*%zUZ?=%D#`idNuDk;Mzlm zD+@0G7P$7Td2#=i%b%Rm{QS~oMWFKbdR`8aJ7e%);~{m?8a_(V+#fd zCfuwU0&Qi@ZYJ`ISz`tZ^c;my+nQLTXVNk@+!(JfWdq!N`^{uN>}+9=os3mKJ3DBS zDEqOu*HYiJwO!ZLb+_s%cJ8rTp$0pR2D-h$zJ33;B{F!{&hL?dL(n-#&u8iRMQ^;x zYR;FiIs7a?zKDgl^5bBGt>xYPIAOAN9t;ZYBWF!#n;J&C<`nZGy9!RQ0o|+-Y7^MN z8roTKUgI8#Tiw96w-_T(w_en0-c;7?DeCChT{v@ZK|T}4Se)$t*RX(QfZLAqy$wG|K8QfAOGaj10-V zhPsx)qR--o**X0LaHpNE?EUIX{$YXP4$0)hlm5ux2PSuYh3+f~iV-&s|o6yw8`Wtb&F)9+@PovgZr$+sL z?8C4gMD$~~t&xpGdaUPfKe3y?$un6^1`Ek!HK4&F+gV93i{Xl!)#usq7JfdI)qsHy zna`FT=aPUjOuvEA3uuj?(E(4|kV z=M89iU;jq-2O;C;M~@@A2CE?@F(z)#qg$vjn@TfzQifmHfOfPg^53 z8QXB4FWC3yELM5;pQU_t_1SyI+%xm7g;jf}K*Re(^}kp`#vr(rl|woBvwQ-7tcW$k zM?)_uV)Z;4w(>k{K%=Z6BXBevenb@%qMP*~_zZ#<1G|l}PT6L8)jY;XG}+2>qdpYD z73PWQY>F{iuQuGFiAl>@&z4r!4FmuDmONuzC=Z_pZQZ*FuFmO7X33H|FVMlZ&8eV_{8U6nN;;ZG7aev~5OG zXksJmW(M2WVyw{FhZ>xb?d%i|=|jz*tjGYV9=-iE$6_+O5JqmvG3Ll9NGM>UobA<( zd>v+!ci&RnwKS83wz4HgwxVLpb0F`}ssJNvYj}GmyAz*Z`%_&58_>xb-13=6BQI<4 ztlhQy+9~LOfpAxqm`Aj-g+>z04Py9O!);cSbTspd^vty#Mou^@X=Nkw8rcfoYQ#sd zh+ei44tOK0=wTE2A$A7xehl(%?q=r@d=SCEUfs=td)Srk26&`yc4hmrj$5CkBKuRH zhwU=5Leq=b!1mn3YdY@c#}F3fZx{&?Jd-y*+r`8owjSQ6krT!*dzQ`VL^&R`c>|kA z6^;a#sO^poy>IX&RQF;(p20H_^S7o99(NUs@}S}NN+0?Kt(BFQ1C-wN&$SFT;1UO$ zeX8}|si?Gao>A7A0y5t;_ukoc0faj_?_{$*Y$kYN-wuLc%VjmM#jNM+vOIQD?`A=6 zR-ea$&a!$phOXtXOUw4`ezYJdH|f^B#@L8kUou9(uqkW(iB`_qTX;ENTm8%HJML!P zEuHK&I1^KP*=#pUg6_=su%reyA1QjgK8;OL;5c2BT2-|A`~Wr6TWZ z!7pqlZ21>mtlCJ_*$q0)NB+KrWaglto0=EGuEfYO0jjW&QZS*TN4zfta4^N~Zs|qq zwS!ACvM)vI&`?w#E&e*fhbY|5-a+u76@3BWJ5}_b5!_=%e}V8#D*7J?ZnL7dL!N(! zJU`pg%{m~^ix4Ogza8NZ5pL>cIG4wMN73EvAq3w*aA%0>)X=Kt3@FV>wxN~5bV18c zY3J+P-dJAr8}{QCW3kS9xAab67qs*2NXz-QbRN?IHP~L^LA!n(>B*D;_3gh$dU(4^ZAHqY27mQ9LiFxN^TSG7Pj~a^epm?IW4ig|wr^MQrXN zXwKR4UN)-dzn|2#4Jv2RZZ^4>eY_=)Wup5t)=^GHT|X!@r3~z|myC(L8KdO9l(eD8dxVvzA@i*|p*K#u$@5+0pWVxXE#K(v!%7I&6pF)ce3BDH;ORpg>Q!5-k-a7O=*KKm|wi4spuSw zD1THA0p&E3>s)$nODl>lTv(b^v@{d{ivKI?%rSnLckSm*X~k{)J^nGxzjd}uO%>zX z_h1A_*1Iq=bvKiQcE)<7Q<_0e>Cd_67@!|FbEkh2!tY?tWMlU=_XN-qg3g}c(y!z< zu|z1@%`M%me?=z`6gtMgrH#rdobvgzt- zW3}Bg=VCe#j`84LS;lhdA)|<|F>l;ne?+A4|^#d{n%dz%ZUKHes!Me22ar`d_MvfXzYqe9u8n3J5x;?3=*yN!LY_7EZt74aAzb4^mwHAO|&WG-Kny(H_- z;+HS*&-iCu{2bJQ4Zz^fDtk_|H`j8{kzYIuhn<%b(8-RN%HR7I%L3>Zcx-PeS1#wN zExjzPldXk9hC%vk+dDc~VEgVpZ3Ri`6&QoY>R--oE-tQXJO;@Z)fZhMg&*H1d|GAc z$DSFgg#W@yYFC?dALkryUYw7GmgaIcAdfZVF-JS=-_E9cSQgDBbi2oX@1v{$9cOYL z%gtbuJ(tVqPWyqjgI%O^qMePEQejKDo8Nu>t~Tlw0W8rSz!B(&o{71a4E;=_g1Mbj zB>_(dCJ!Ef{VIpIsJG1>kZXgdX0=Gk$~O-myV* z{)ox@{Vlxxbb4k5ds*Y%n8zJ#X-{t~A|r77CI|qTFd*A{<*FeIlJjAm7Wi~>bdfZK zB&M@#R>|KYi?uq~4;epDF-Fp5spX$0e&`rF(xLkZci9O(iWY(-PEb!9I~2}6KVdIb9b(UfpJy*% z?($5y=XmbJywVsSx@>XdHE+~E%0GhzxPH-&x`!6?BL0hC6k~}ou?@m~b+ufn^x1Tj z`^w<*t(SLw!9!1;uX?Vz*#v-GT`j~e5`7pJr3ZWd4G@24<^$oBAH9u3^XH0sKl9b(=- zn!ygkWm9c?(pyfrq$(JJ;|Nv|2U3msjLsSeV2% zdP=IWa#4Ql6l*$!wTm}1D~Y}x3TD{Zi<>b#v13LLe21TJZe^=7*zndWL_K9RD1%*Zpl#Lq9Q?3hJO}Z&Qf3#ceJ#27_ozR&ZE~XZz(EfSDt0z zs;|ETlw^o}Hk`mzUGFjJ{tvsg|OdCYAPd3rt@T+UDPqNN4A za_ij6#mktZoQ1T5!Z(}SkI9M24g&@S5npe{1PUY{&>QC0uUcLVZ-VDlY|nXQ)&{Ve zC0CH9H&Bq4w?Db67s1~%GBll6pOsVqR_cJa11{6N>?rXoI^>aza|%J*&zt)=h3f^6>Z5oYW+ z68HWQoia=lz!$W<@2|9zjvkB2>qjTX?iP>&wP;Qvt>PmX9s z@~u~7d~fNVQhQ?ZG82urjZpTF&6t$D$S=shAK>{h+!hQ~yptc`FXOidI?;vy-~HQ# zTrc{?_TgL_-bRT7mPmq8K#-@drYGr&T{+%d%TABKA!*a=?*%n@qghMM&FqZ-#Ltbc?QIHY~x=a zZuo!gF^FP12J=rhMCEA)-|+!7n|BkHjt{6a1Ab=;aFD=vWB}3L!vP5THkoP5^9MJX zk>I6`a|OPAQ0$UoN8PuzjIejpSf$WLwLEg*mqOdKpyAz4M$m6NnILOB8N2Fz+sOd@ zx06B6+D^vCx)q{0Yr7Uz@;@3K+_(f?WE$c2y#8`|a#JO&k zOmh>1wibXs*Mo&%LVST9%djk(v9-8(^=ZR_)-|CchBgy5{100?sT>DjsyE>!0r{(B zOmb?sS#r8h*SDpOSb~Kw%!7y(xvyf#{SqU6Z$4X*ft|I&m6_~mox5{$r{2L{!GcFb zJC^z;7av?a{gLIwu-x*e{Q72kz`K$Q1(2;w&1GSpUAT>(x%1dU4@<;0S@*8Y+#(j3 zXT*l(bYY7v0~3XeEzcBSdDO%1$3pIJ@OxY@&)=U@oS9pYla+!6Q*65p@W8b`Tf{!! za+Zhs|D}R>Xa~>j;M4ZPlWEV)%*o7W;qAy5*3M?MPhXW;#GV85NA*1R`z^HGu{|?C zEi0k$b@m7B_ua9jfn7ks+qX0%r)5DTJzkN>CjFjB@>x1uuo4fCn*uqUz$Rt8Pd-6X z7ItHV)6O@r(bzS}lPl?VF86xusJiJUiR3STWLHsc8%xhK#)S6Cp(wZh`;s{RJxRP> zSixSy{6q@5(|*s-n4@zV3vB(2X64?$QZO+cd?^IO0(;q}y!p#n*r6rMSYUZpVo@f# z!O1qWDHEd01Qu=8M+G!ifkeissHQO?=IYW4usbH!iP~O)X?^Hs*Z%ex+ z)#QZ27cP8q%iDroFJ9JFYHZk(le#niwlNdl`0@7VKb= z4Olf`L-IP_WX^W%BSdzy*3BOFfsx1dZO&ug8r?6j$X52{)vfF%=4PK??e_it%{WxB zYe!~!7wf&cob6;iub(Kw`WJV$rL%BMbT?yx@V`K(b+a4iTRQVI^V`_{o7>qr#67S% zgS}~Z>e+X z7f)QmPzO7JHM_$wf>3)sH@&@TL^hZLoq{$D%bdg%eo@12X4Zqt80uKc?PT>V|P|F0ZYC12$~)q#J0 zP_@K+z)ZS$(sl9qQtSg(Vc7{|I^SvX%|0^d;Wl{g)ASuj~-$7D% zzkUukLH-9x0sB0A@{@nivqyrr;ouefd-gbq>GSLn_8l5U*soAZ@p}1wDdgpYp4ZDq z(9g>!$nx@W2(-`32jK7J6KQp56h}*~5aNE|&?pFAdOq`eCp@kGfzzj#p7+E-QLp<8 z9U(u?dkqoW%XE{)_s-`Rs%BTQHQj}Wm(Lo{d8*i*axZ3GZx?%cZx%3&JX*n@>y4U9s1Q4dv#2IRA2%Me%53L}+0FPVnWiaBSrE zvLI|mz#p5)uxz*q%cO-pJaWqH;$7G7HAaRmEjo$Z>^GY;_V9e3eG-I>Y&}X zs%{qH{?M2dRn&pSG`7ARe$QMS4lCML$v)RRakPd-oVAMiXfrmt@_7fl-r$G$=Q&w( zvKJ*`)o2|1?Pj=Mw;TLCn12wC;;6G&F;N@FuVRa~DR1>O-b7l)I;5??6 zr)RE^od16FS#=P#nC&#U^Ax)t8<~+Ddybnt2f@f8p0fM8yXNsW{_+wWoe9n46Yt7z zo6lp?*_d)17{alk)dlOOfb^rZB94vVyv6x|9%%tXv>~V%`p%y93tEQ%dC`xtgpPgP za_k>`YRDD0j?E1cparVGV$Cgpy~gqoK6Eu9y~cRn($lnnv~7!8a+}GWcVkWVaV+q5 z<1p>maBNx|VxtAYiZ7tY?D(Pe~ z8EvfbP;p{D3-T0U?VeWgaDE{WtH2p*_ z^$pWE=Ho&%np8&12VPp}vokouEl=5(l&{xTHda-yF2R*m$_PrUQi3!04O-#M!Wq+M zvc!8;;-C^P2HnKN_7qTIQ2N*2$_^^`1}J0pMQ zA`Q2%mC#LJeTbLkE?l%Aclu(9id+i;&z!SJE0N`wiE^R2SS19rYCEkC1vZRCD*EnwlcYRcc!{(Q&|ZSqcNkTY-MA)wyA1eNul>uv69l& ztChM~gB59#M(Txu4O#H=QB9q1^qGOzI;e4^B6x=+G)-R%=S*9eQ!-=m!bNinNut$K zAF(1;vZ@+-gV9pH+)`KKbqk<-zPK9M5cS&nT<XMNA3h~poS<`Y07B84d z!*Ejx)vjcE1V)!4YM1PZl|8ct~$wHrE8 z-Ns9CEefdd|KaUj;N+@`{P9i#p+$uTQAY(CK`^4|gqOj`nvhILB+2wl_Y9LbNt4GU z8A&q3Op-}LNbs?W$}U0N6-Di=tKzP&pdjLk21VCJ*I#_Bvf?9%E3Bes{Rsk!{J(Wh zeXDNYb0-Ad-#;JaesA46b*k#rsq?t!_F%I#_BDJrv0-q-FbG2kzENq@O&g%d>cLTb zV-cDgW^WqBr!E^~+m0+>IatD96;nj_`!(;fWZg^zn@G7)B2i3-^P3S!miw*j@ zgwIe$)-B&UI9eLpx_+a47KLZ{-VZ9Q*Dl-Wsy1rU^+uNuZNyg>gDVGD4Q^No!RR6Q zZfXo)vOtj%8e=1hiJ#YH96Le(Y+Tqm|NMD%{PjFSsa;wpk5P>1^5s&zoDfBUE>WxDy zFCIg~N{nm{Rab|{hC=GwgaP8rGf>>^?8IMA^t+b0SlBhEcfl+q zQVC3HzM++gImG}w2jrH!|P*;Ls!cV)J)!z@ezNe zO&er*jd^)hW*ms)f_@m72_Fd&6hlwm4CCph0_6}I=!$bX7tC5*VsZ^VCleC2(B)#f zN0SeZZa_E5JU5IO9o!hX7l^}=zs4|Z#X*guwSN31gH)IqWL?%fcW!47@k<|B>zE~ z>y9;SE-|ZFbSDAH%A{%CnjI7%lXBhD1 z`o{8+k&ME%-r2LI^)Z^G$f`3+V%vK3LkL1&-ZWSmAKJJUIZ*q1nD`+?mX9u9k70bB zgn695wRG(`BS7oQc!)+RNji+vlrUst!nPc9ZR`VJO6LQUk0+Y>`3W(mb&`PPyUX~Y zbU~dWZ7eqvXB)J};qZpWhQV>4ajeAhA!;Wp1?X$jRLoEZZF;CFO*@tjG}tuIsh3Qx z#xkz$o3)^~vn5NSZ@97O@wgkzdAq)LC@aH~vUXdwr?FuE!ujZrm?}9qrsP)9@ z9o%}!roqvzvQ+i1z~+kigRNGe!h)_@a~gAdx)wI(&c|CX+^ElA*xA)v*FKS19fS-~3dVwt5~ui(^~)_17-$e@yyuB;L4ULk266_7zp$bbgr1oZ9A1_+O;j_C zeu(SFrV*@02c_eLxp!DehV^NqF*Y5l$~2&%EsNyV*nsub#hFIeUS_LwEW<=zOpB!r z!|2uG;V`cq9+AaaW5poyyC}@*lZQ|k$mEN8v1N5ge(V#73n?8FwEX5mW33Fyt1;gm z9xHWi=naOTUE*YJ6iIgF<~Y?xq6wKZAL8?B^E>BdYzes^i6*W&Z5_;&z5QfDM$Vj0 zbkNzDf6kFb6{ZugU@NNLC@Y@zVIYx}9u}gKLDsB{>z8d|`K9&5{U4ajdIq ztTKDnf(7TzntefI;jI3a?tzfRK-{vk(b{X6t+6U-AWh41&&RpZO=HW~3^rtLfcQbG zTZO%(FpXD_#JvECmhr}hP3R3eqJ~T#Ib}tS#8z50jGv+y#Fhzq*zm|jO%zv&@6BSZ5c%2RevL_H{_sqVn88t-Y zCfU-J%(w~eZ(wFoq>-!!FX-&7qSN+umKq3;Frk#FLy$MHm_s@X8&BEAYV3PRg<*RL zyI-&x**}ijn44T2##ouyibUzQvKQ&&R9rb@O@TDLF`G1AQ$x$n>gmDSwAI_Fu_ydY z%0kSm(V#dZ7xtu(6lBk0Y|}{CH)>o5>l8Oh7APW$_-jej}6Xkbr`m5G2}=Bi{ona11C*f zN17W;qZpIu5-Nz*>L}8x3~r$lNg%m#7S+1%R1nylP|D=iy>Zy0-0Rl%>ndWJ+wv^_?Z=+WY|qv&9RNuDN`Iwwj>{5+P@{Z zXk=@tF%N@FSm(^w#S6yb5H6;^4>aPtkhh=!niA^SCjH74;@id=~llJ%6QNHN}{IJ<6Z_`A9=^J?u1F*;&k z$V@^K@5apyT(L%JnUaOYM2-gT8n*RjZQ8gt>>;}bnuTR=w^NqUJ@XgM?V3o#*w=Eh zEfS(~AvNLE2;TICg#qRU8-_8EVt>bvL1g35a^a#b>A@JiB#LwkMn=oHjFSZvqA0wE zL0{bxcJPoF!w@g46P>K(w1a@srUe+yS7*mcq@*flxERea#;+O-d#)lQ3~}1wMl`#* zuT0Z97?UhzhqY#0LTCJDyzxCPUKlN!)2Ja$WkcUGu-DPj9@rt}64yCGI+@)wTZZSM z)kARWHY~fax`@-s!OcVQ_rgjtC)MR{oX>?RF46+m`ys$3lv>_luE1y@n-8HGB()=C zLpL59U8%`P_fA|Vvlg?kM(-TFKxqldOlr%xNKKVJe!Kz~pQ?B?DYpLN?wfZ)2?d`} zhhf{(g>0S%g`;W>EJlSttcYbg==o;ly20feWHuv9!Z5SV##=~G*%dw}>&rK79G17g zr45UaUFTviu`|AMD>X`q$vERhb#u$Q(SiWy5@s!&)d=$q%<4xGIFbbMR;+=o z2U**+ydKsJj~ELBtSTa#qAS;8vaZ1v)*mr4Q~2w5#HW!$Y!SMys8aExt+&t+KVL&yj5`u zKwbikA!jmXWY?8lI(n?t$n0LH4!@WkjNQ~coQl!vhd@r?vOBR z#hd_JBMX^O^u={hXa-u((?L7}u))&|W*&$Qd8chtk5=y?L~3Dm5XZaFL1jIU*_w1X z?JDsFlPrrczm@$MdEQb>Y|XIgWi@SFDW`b`M~3jzr6rlmK^Hk7;nrCvlSr10jM=mB z{v<>g!Vhn1*g#`)i*q3=td?7=4*TjhWMV2cHnt+$xG}0d5W)dCYq%12 z1(svCBJ7;6G}S4uC2F`-mMt~WF`k_vD?-xVL&sToi1h3s0)%}yHiu(M`U<@&uRi5P z!Uowu9a^336JbX5n$ATR%wJS1t;fd5D0d$*EMo>FJ}THki`yUEH-4)%Xk}POhzFdLPc^ zAv7{EHn+1rdmfG;)aTA$G{1(EgVMwG%^=35Rrqsxz3sEx@dM#6In$a})+Bhx8^aE3 zMEpcKmXMho$fMWLb#xH#fDlkEN9J_b+F!)UzS<@`-V=9EW(ZJBjumbfZHhCX?95jRaRm^L=8!aMD?VzO+k zk4+CVjjYX>)SEM4aad)B`AexWjFYyy3Uib2-p?WiV*$?2g&%*{$REaZL?-wg z(tH@R35L$%?N}lm8aANM3x_Y!K$s+kJ!)~WY($MPEZrxb+#Ti`8_kDJ zw%93obUM6r$qGSEl;##&*l{y)W_mB`U3eZ|1$52jhF~qcoQTVtq44$&-8nm`s`2HjTTch#s6@!omjGDbD?HDo_{EI=qKXo0cOO zBXj(GhqplHEMiznOLrHemv2O%uoX0{V?XBcWcgFvIG4M8{qjuQ;f#p9s1Ye~Cq;Jq z!s}QW?8d^GNtl77iL&^#0g#jVoYv{_g}Jk8^#x00$k&&&aU>19-V&m2SQw`l_V(a^ zc6=_Ro(A%=Ot~|>@+PM-rwa!GG1@gc`*Dap^EAxy;ivliML6Y>f7vRlLB0dTbdxUg z4qnQ=$(I(F#gl9s*wn-Iwilx3ch+q`Tpr6Juin)=dtS+oUS^ccv?F#ZaX3PcQR^6> zt2Lb*g=Itt`M6q?m6I%YvZIf?7-yg4Wx0%Yu4Zsq@KlU=Jmo-Bl7)qAb|Al*KV*&( z24^lt8!f(yp(W!En78V6D(uK z{6&3uqc$g;BlNvpOvL1Tu?)v}wI};iZn(8i+|q8~^M~`#@9fENSaRSyyZLi)Mn%4L z539WJdLT|z;*392)P!R-KNsI!$N^ZKkc}rau%RAaA&33%xCh^|;>f%OYEAl?{;A<$ zc}8BEYvO2iFQ_tF4zCOci^KMOM$eX|m>ms>trqq{FlO?kdeQl{RZ0 zPS9a=4xNUxSbLYrT^<>v*2~HyY7r*zcr!1rj^o=p_Dn=#%l34rF|Kd2(aM!-<`YHu zM40teSSBR=YZ={uosAcX*y3g<#P$#pmYnI6jS3rbQnrBch_z!4i}MW11F9Vaxx zUuS7KOU6@E816BIhnW)mfbk56z3KiqI>%HO_Hbl36h{W)uBaV}LFygeG>Qh6DO}tE zm$`-xi>38z#hU4QJwvZ&s(zM|;`cAubHGk#9RIyBtoQZI?z0W;Yk{2nL2mJ*OQTbJN=(5sc4-N8vD2Qr|j%2GuIDe zcB`Ifik8VUW}NY4PRx(!6Z$2N7&Ih%6Y{p=A*j&Om;r=T7QT6rV8L22e$5xh=NO@J zL5Y({e)3hiH5{7k3|ai27mnm~>MiGoSZ1wCze+J%lg2GBL@o zMOu1n*!8td8M7ozVq&NCuFE%G#syQ52IEc4MwRFyetvE^OUW2tq z4^Bq)#W4YIptyU7D-YtynVO=4_=sWt+{Ixo5O$ct=?7`Gm}kP<0*ILbd2~Z$@ND_|6uU{Sb5NTt&0f&82%ha-6h2wigqqF5aRUrJIcH|e z^0KwJ!UOTeyc`I?pH5ndPXj_HP1x)m4v#!ZFv&`WuSKLMBlP1St3xo?MVSWINmXn* zX zM3yUB+ep(;Tw~aGg|dlY-5#e?k&@AOLxhH7H*%UT^euU@H2oYjpjQ~T=42x!%wz09 z32Qoj!xJ)F=B=URpVB6L6^E}|WOuTG&0{Rk*T_0v?%TtE(8&JcPUOl|8RKxPMHomz za7L4|nVtK%P?xWg<20*P07f>WCx$Pl+i z$KotGoIG|(_zcB%K+qAx2+$G++Ph>26WU=OixuKnOFxR!XOB7UFd$5D#2B-3oquTe9C4N704*OXg=tPBd>rv_VQ8(~Kf`45vcoyZha zperYwh3|_;SBiMBvB43WZq$QO){}!Lx&PQ2^yoFZ&mfzmhT=}#F2R7xnoR-JpP5vICE(VcY<@Ima4jaLr zO2kL+cvB-IHS(uy79u8wHsA?5&xQ?hKEa%iJZwWxc*!UkE1a&CIHZ5FTpXapwc$&q zYB)0BA%&)t2@DbyUk+pOjl&EQYT>{-CqsB^8qT)ZMzZ%BnT>}&qpK^)8So?rL)pCu zJJ32VS>@Vu{Cur?(BnYPjm7g-W}PlsVR^n|#E8 z6HNJN#rfWt6Qtc*wpf^Vb7b}LoXpmEE$)mrq?t1+SbxG+ww&gaeI9wuhR=uMPG(FW z@wYPgqR1_e^U8eT8QQgm^JE8h7dV6mVZTD}UOj>|p-A`l0>W!o;lKA*i{ zK7JrXC#ccd>@pDIczh|GHI{(Oc^ek#$F7*2!+hCCmUH4^;{uc7aO6sQ87i02R`&1Y zbPtZ1xF<8)!)M}GQ^HPyj%m8h<{vVJQLiO?hIsR3Q)xt&Ng3(fR-Dyye(yq6Vseh3|JCH+JiD`x(b@E`zp0Sv1^)4myv3$d;vOGbE`F;T zVkW;NvJjo!h410rW9MO0B!+BP-~2h4#Q7r~h~v3V-H8T6m>9_Cr*SltQ9phMX~{Z- zRG3fDzJqk7IM3jAp4ZMJxf)ZJQ2ZA+-0g9y zrfGNsgE-fXfOrTmezqKDq~YTV`9Q^$GjE1~yKp`Zxo7rvoe%S4JzV7~A#dVufn(;~ z+E?MCIdNkmNtt-H5{{zCo3ij_q>jrrEOU0EKZb&sTJ=l}7jk;DRabR#|ab%_?eC4m;wtoH? zSFn2Ygr8<%j?Z<6{Q5%p*%E6a%xNS6!8XP(M!%S8!z(G-kk-*fHp(Ra`Msp$!LnWE5J2j46RUsxCYSz>%^4bRB5#bQK10|gxu z*p(wVp@Ku2_^ardpWFm*{u6HgXfws=Ng??uXZfYZ4On?DUm@>~Wl(q=S@GA2^~Z|w zIrz$rqgV)pqdD=B&A_4g=D~IPbH-<&Q!zJ}*2=iBe8Wm?e&QtBHd#u}D4}kd(B*{a z{dAK`hK#uN;p?p-eEx^62)uX1)N0+fGrWYn*FkNvz(lt~vWkbHv}SzT6H83bst9S3 zE4*6APRCkI_l7SXl9N=JOiKWBfI_UxxWcBv2C(;pwHr6eN+Q1AmcvS6_#Ymzp9cwZ z38*)ULj|i>PM>kk%PeX{Cf>l{$l{oFHY_a3CJSZcpG$NNCrJaZr)9$JKg1N~2`CPK z4`J$pBUCNgg|qkZRk=>AvF9MCZZHv#GY%~M*W$Be{Qg>)`G_Vf>P9zzgwO_{f0nV)=?8d~k@b#NtQk z*wP87*rPwf(jAAF<)lSRt_ib(O&h|}WZm*@IEpSm!vu$+E3HHOgai4(rYKih&DI;? z&^UfoEn13Gv|(!l9NAEeIXNRD%oiBo*r1Z%Pe2)+78W$I?2)sbf*kof5Aq9O;ov&L z41+-YO)c$%E_`?mR+()7(AU9>bu+%c^wx$0kru7Xvvi0&oYUVHeJ#-vT0o+>wHZXg zOziQe;t(VjYuYLrZ7?^!FLZ0eL7C`4D!{307}T;3M5&gTMBkBb&Z5XT`?o9+rg1PY zyfsI?`7UR_)+K2~kJNac2yP8k594%;q+@i8aE#Q$A^hfq8^ZA?WW+Fwl-3QsQB;!; z$A!iEH^#Qd8;&S44ry8v!%{|(u-vh{8&YD>9aVD?2gnc10K?i%p2{xR`j8-EhL>!d zA?=mlb;ZBi;srnNJzggM$M~E5LaPve#A*1O60QIC>h0I`I;qr4$l{YqHNxvv61ZB$ zluCQ_(G8i(h=1y|3h_NoOO&Flo0aDv)j3O@kTpQ>ypji0;FIx_&hk$@M?6<)Q%d7| zOT4LO7>V~}8F};B3?uO`vW&4p|1VWJL78A9;h9FN5e^xtm+%8dsuA93q~4npQip>$ zg90a&>V)qzL4AZSyH43(F|InHSJ&sJMnr>I$D~p>;q@kHfY7V!POIxqs~dRy>Uvn+ z$E>=ggkD`wT3t_C-O|Ueu0Ivj|M;aAr==F>OEFHaR68b@&TLM^Lz}0RHnuf+!-7*v zo7*NVd9q4B3MJn;sXXKP3H{tJ%)JI6yp$AW-!Rc12hw$A-8X$BHdZ@u4oogc5G-*<)pQWfQNdKh*T*eUSBJ zg;b$n?4~DJEyixb`%HEptHYlH3;!mS`Y8LEMyeBfb;;P>uH4Vlt0Yb0nNF(^&vIIl zTq$ds@*?w>T})lCqX6540p?@d7Q$ zvdScUox%we~yAjAR`^mM<&IE1Tz$j}3zEfNW%+?#CCw4P zSMxGx9mKnxhCfvj+v_9vD?;*5_=rF5v?RN;&Yzp+y@U@aDP+i1Dr3D~3)3cru_VS~ z!nbP8=%4RX_}40`pv(SBtA5n9>Z1aeTdBmwEcLLKl020!R+QgZjm$J{hR*SqiOIh`hzl74@$ z3i!1PBBUOZOJm-kidc+11wDX|=#WETDe_rf%;Zw)jXi4TS1c08%fv6h-w>03NGI*Y z)10PeM;`evWqns=VX{bgj20`fN6C=V=rjY1YLuy90KHfAIfzrkr0;x{@i(SWkXl?NJl14KlY zON}L&8>TGD7Dmd_ldou(R&aGjU*dN=twP*%S{w0m@F(8nAEx^IOT0N=iD;@e;uD-! zA%3pY%EYh93XHP-zts48)db!nyh}-8Y@@Ijn6QF%0)??820TJ4h!KIJPEk?dBBZJX zvw`ocHa|5*YZP>*2}&|MOHmC;3i)D1iGt-=oA40-S~ZZFI`K1Ig(C6P(Cte!t*V4E zy-KGfuH$b3%D)g2yy;bRZW01?&Rxs|Rg1RZ_ zl_sc`3QF8^yK3?^)2K=~%LMhMf|A+LWaWOgl}d)MtF#Vkifv57C#Lj8TE_~#N)r*U zc3Oq_bxvy|zQk$m#4kH0wr1D`;LXdGh)UXtU*WVi;#WDXLi|@wOY$m>7*s_H@+w(& z7)zb-6Glo}A}!U;Qq;d-$e_SancylREiA|y+mxFXph*c2QrAp%%dCuhi03)2LfqxF zHsYI{)=s?FX>G)}Ijusx&uL}iyPVce{6nX;5&y_(72+Q|txUY%Y3;;!JFSiQr%tO7 zKj5@7@lnUd*px8zoD)$+pPlABW#WH#S_knromM7(>eEbq2l25^OTw3Ro};o5zJ#4h z3IiMEe?Lo{$N-kakVSaA$seGo|1eUW@KGZrON3YHqn*Z5qoDhpl-G!*sD=zsEOxIJ zD;n5XZb62JctB}WF-MAn9xfl!&key>3Nw*B|gPz72=mTt&R9iPU|3ki__YO zuW(w0_^nP$dI)u!t~><^o-C&sOP!Fl7NlyHI@?Nh=fn5;`Y6LfNYx9PX_uDTtydXW ziSKe+JMj;lRwh3BILjmL#K$=;@e=F&n972e2ya$W$Rm{hUs+<_YzkvZT}8>eTv2YCqp}wa+LA!T8??7NFHTB*<3%8 z?Dw?mvkv1KFB4zvw07ckPAd~Poz_nLL8m3n%{pJHJZNsh^OY2uoANhhiFqec7)zqL z3D=nXK8hMMQl0SaMoOA{wmw>6EHw&xvy<`~vD9mnMVgz%UZ0^IN;%3{s^!?+Me->7 zI;$gX?mhZ!uknnRiT~uZcH+mJRwh2<=}~i;g%H2YX-RXl&TptJG&kY*l@ywr^2;hK z5c5u=FqTAf6Fy?{`zUIviUJqmbB&ZV_jgpl116|OLC>;MwY)|w^#d&>&CO!RX|bYF zw5S|q98g(o?jm`V{SvDqZSK2O4&@c(`4&}V|` ztnQOeN(I#?GNqxVBua=W5feMYH)Pm|-((e532(}<5mOmRBcy>vp-G2kEX?apmWOZCQq{otd(tXPGZPR+ZO#FSPRfvD;v^L`VoYqeK`e#ISkfb_@-{7=%;x{_2 zjrgyfRv~_~)5^r(cUni@c-nP9bwijE{z*xN`Hki7wsLhss)tUT*Px(Z|4{{WsFDa| zminNR@@lixi_El+X1-Wa#IPJ|6CUDDleN8{_%c_aNIW&9hYNb)T9q(nl9Iiqsy<>3 zcoClPT#)i4bEN&sGv%2UQ)S{WDlKdm@n&y^k@&mMiiHDX-tDa6X<87`GF{l6pk6Gm+*Qc^?gU-T}J99+;615 z-zofqk$MSB>Ko{FtitCQsh6IW%FywQA9C8SBhmiO14sw2(E z1dxy_Pbw{Ai?QO#rI}5J7Ha`pUied0IJ@ZN(xwtITV---bBXu{<;NaAeMsF4w)Gb% zcaN1yR`&bV89y~gjhBgk>$D2-@0`{~{Gij?iGT03X~YjXt%LYaPMbme-DgKPA-^3c z@#a62h*5Y3@%Nn8L42pvrV;kREd#ZS?CgfFjsfviei7W_w1lT{Q*gc<3{ zx`5JeQB9EO2*0ePDW$QCnyiu57bL`^m4B9tA~$_?kWw$wQbp4wO3v~Svo@~zc+UpL zX`K?)IMv*IS>DT~e7Pe^h@`1gPp(kVu$#qZrKd7Z`+{->r}1W=7d-?&E>vzWHISA{ zcA%-|DzA%>F&=c{O@Z!Dw86J&RV;T{>FV7(Em9bek(&26%O0v4lvWTym#Z3V6*86jHB(g%JgPR9U5;5`V@dRV%6tB^7n&OO^ed zR;)%_SgfF#S?a2c0{LQxQk(Fw<`0;x?ft}eyH<1ytASR8RJ5o@K3k%`kaq#Z^%Jb+ z58x}Rc+;;}VI;mW%a{)l*05S@K!_0jLpB=Tq(c72gcXDcg|Q?;gs`gRFw5*!NWBV9 zEB{EVzT32_628&|^-<6zPRg72Efqi(If|Xb zH7U!nHsK+@#bj;oCw6;lw3pQ&hzO~uNF#RtCd%(syYA7egbQ)+bEAX8I+-^YDNz`S zXP=m1%sZ7e{L(zwOZX=x70%~a?g1-TCp=GeKuYOTNEHgQOq;U2P_;zM&&(_N5#{-` zNv;yISi$;WhH_I0iK&X#!eT{n_D418$yQs^E_s%s03y%PDn@vSPczzBKQYyXCDfR9 zgG7bhlLL7#Rn@j0^W=D$xZi0N;w4UNBOY*CJMmJdO(S0Bv<~7`PMblz?s-v51nK3I zc(Y!K2+|qE8=TfbJmR!z#G_7YC*J6^HsZ}rs}PSntxP=gq>O?Sd32pxhNMgQMkN(? z4z|Q)R<2Iy^EOyM zkjh?mnaaLOuh+rECkr=EN~Z|^nr8Vo7=28G$|cbGdHY^5hz zYc)!_e{=`65$zexY%K_9J!}JzKCAV3R5yOAB)SA#&(o^u5s(NErIoU39k1rMn;WWx zu4!MYY2Tq#$co5|c>4U#oUcl+*QUDNnyf~C8dK1bS?ZlyN?bgVoN>9zwsFkT3an)%R;y$Of5r182VJ^s< zZ)6yW|J`X7;%_>wOngsPVBR0pc$qR`SR~wT<%*Ua`moE&)d{H!CWv_z3g(ROQUPSe zEN)(2$xkcKtyWpGu-~SS-fAq#fS6|~>PO`H8x%~Lj17P+KB(;w07dhoHmWPbaHeV;;n;ts?%l=-=s9e)}Bec`Amk9_-3bd5Z~go zX~h5Hw07cKoz_PDMWj!FDUr*#nD;IwJPpLSY1@l8%^ zBfi;b72>^4D-%C(YDU3)oU+N!SIf|uE>O5uuVIc!YyZvpCK9#USn7nX!qu1WoTyyG z%5@XoV5Fr~;73O4COk)t#>|ZHvr0ljy=o_K?sh)HtIapy&F#6~+L0nF`71mM&4o)RygT)48hAU+ER1-lFhI zC%sGId!1C#3TXujE>KdpUO{Ro9CXsK!c9)f$MhNMF7_q7dVDc4`xU;KdJ6G6<(DO% z!i@i}Nc>0n^rIww`f{fFMrg#$Em+DkoY)0~jhMa%8zG}Z*ofHyz(z=Ig)Q%l*=o@y zGqOfq8KVVrD3*GImJ-SNVh5`&TaNhsCTpypm@dRXUnHIyGGl{{9;D3$Qv`+vy@)=Q zCce@OqNk41D;huVx|Ah3omSD(&zV?C%92QF*V5A_mXfk0QaZHsD<+nbvLsSwYU%Uz zDpOM8c}}YkFLYWPahKEDiEB=qMqGDV2k{c8%^?2WwAeHl%-ZS*!^Q>HzkkX;Tdv|_VpWonogf1U^dHGvZ)gPGqYBY@@ z3++?KB#R{qxv70ILQKbmUEX2w72qt6;kVsq)VXwM|QNN# zvGbMqeP+tjpEu+*<)L$sO(>G~gEUd8bG39)U{P|GhqznIF|b(WsL9*ZPrN0^o7d%X zeg1kYJ6id2zhtMJX zl#&WVhvlxaa&Vy}l4w%H} zRVbL(Z&v~T*UTwcp3POJQ_Q^SP2!hXbpx#K;~6&Mo1Kl2jww1I&Khsinx*ZDe`+>Y z30;XAm3W;g(b3$d`0q`LD&ZYQsu8+g>E0mq`tOWh#8XXFmGCqp^&LzvdPJ-w{#Pqn zC8UB#Lxcy@^$3+vaY^q|xZ6qjh23k{Pfnuy=$L|DUC|DCs$QkD62H-D9mH2StxWuHPD|!4ls`{-(5J6c_#r2K zO5t87<-J2eoyJlp+-9V{Hz}k_1%uRbWx3c&B~yo&>Z8BXtAt`+pCTUeFR*fB{lq)1 zx&bOlN1$2g3)efzzx!0ceiJ@kCO-A0Q9ZO?JMjygRwnLuT08MlrzO(>)_K1v-%I#= zC54Pk`5h{&File!OJYtzc#@Vwb5Ybwj8rF_Youf~_AJ*2POA_PJFSiQ zgHCHF{*cq!h(GMK3i0($D-(agY3;;cbXptnUZ+)vzvHwd5clh|0~sFT4ox}|{KV6p zRwiEIw07b(PMfgKKWd#wU4%zyu@L8!|MDy`A8Is!B@z6DFV=Dheu|o5q&i{MNJ$_} z(MK;ZmKp_J;H11pEJZaW&{=G*7Ap#VmOCoLL;P%|G5Cw*QTA$6t(sSDL?2zQSBY%m zy-sT*0o%r`oOIn+CUa352ZNhgcDYQ1_-;pIwWB^ObW}otZ-sJaD)Yptu zC){tOq_wZnM>iWwje_oSQeGpLq8ie&EcQJuR@B-o_x=nI@jok#tz9IKvL7_ns(IB) z(<5b?UZu5(Z&g}YSny_VhLQLm&xk?-<3u&QS_`6W2^&@cUPgUEZ@!ZyP9&_)gmn}C zvylcU>JB4y6H?WJ+1QYB@32x;LJAD8jDDogDXQ>25`|?-?%8>7S~5K+ezrREReF_U z84BO(q`YHhtLSy6e2rEAx04>PlmubESW#fIwh%>~K61zB!1mO3Fz;qR1fNhXtfmH!Samxw0I?Z#3kWT`^Y`;`9=dX?TqeC9c^ zHPC7HOybQ9B?=?)H_y#5=39_8EITtkLGL2mb{0u}mz*8p`}7K~v$Uq2dIgE_Z;jOV z9)+JYQtyKb7r)HJU#jraPC7xAzEQ6QO`57+r|QRBbxWz|HY3#u>6n7e1j=4wZs{gG z%mmda+XW^2rW8cYCY5>!yUdx5)W1D+^@p5`)xFI$=pnq%JlA+c;juI5-^Sl5yva$A zD7?k|+lcJ`-?wY~f8XL@*$)*`U%Zrmm+JRp({ma1yg>EDw+p*=HZRn>p`JSvzOmig{5xbq%1+G&&g^iePbvSux@p~`bF4?-A8?d^p&s?yWjc<8AQUC`m&F1 zrB8*8*!|n*0TdDa%RmmrlAsx&hl-TARD)HD5;LYT5ED`fVasd5-g}J&b1m;3?EK_C z0aD)Tg8iYqY{dKi9nHM>NX^#}srgDGbs`&>K#Fs9zFuTbR{F&9>vh^O*a1byq8F2|L^4<%FYZ0 zsoqa8qcfK9_0vR6!0M!<$Ysg9aXHTJ{niWu)$Qg|su1YCdjUy|k2Of-8-x zWJB;2)sIS{%Ur&*pmSZmlL?XX11D?9^tkkxD}9lvUXWG#qHOn8=6fHf(F{U}SENZ33R)=jwENCOo0T_bf9QdLA=UiQ_>&C+oE z6+4f3MP&QAUIXzMwRfZ04bHr{vvVbpV@}AGD@Z%TsS>+({z{3Dnmtv*j0(FF6$&ic zy|b3n3l{C(c~VZZK+IdTUQ7OsUXj)aZ!^+jLV65AN9ohG78E3;{so~~p#7emds6N9 z>^xWHF4HTtPuKdlYss&hs#QW)wQq4w6jaT-;RV_XE37qY3>h|5!NezDN-}%CSW&iT zxz$>m@DRVjXk-1v^ctozMdGO;y#Y2_Pt!r7BfYmIQ`KGSsQ2j=-8%0mvb@t+>Vzy+ zxRT$k{Qqp_647M&ps~~mS*lR<9_9a(UL}hW-{`ao@n@XYM*J^MYbXA^)20#M>a-5x zuR3i8@rV8@I!<=NOB25_Xaa>n5Zj*nr6ERj?<~qXJl~r0vT- zqg6lC>;W;a!UwhF$MrfD!|(Q~C%5tbE$Sdhyl*=-ImwIyah~2}>b`F~>ps@&zHfWJ z?uRux{#xsnzMiia16RIQkn(kc#OhhI2qQjxW~>@)n-y*|QZFHO1s7e$P$%h)o#X#y zd(fp|+FcY)yD#%H5gn$6Q9|&WDo@KW^sz-}sEQz^ExL@=vlT^H-YAr$NjJ@mI)Ld#VTPB*2hhoaPz)ul7_im^5?y;(Zy~U5d|j)9&2C z8~RofB5}sgckbZLP3mu9B>uM2kOm1e&2i@r-q2M=S(n;Vb2QnWodqi697Gxhdv+Go zn{Jp~e-KZxD$$LY&Ot6GWaUME0vo+Vb%c$WUH}{6!5mVb9fPT%R~$t8BjKF*2>z}s zT%?GY)gTelp5j32D^iU1GHM_#uPf8nwc5JyF<~a7r8%U4DNSa(wBbHr4VcUY$ns8O zsS~nP;ap&k@_*6FC8Ei4qp{QpS*lR5w78!MNHCd4oKa-6Z$30bO8bi4AOVdWBskmdQt zQYU1oLeVpozst%cqRBGHSn7ldn1+MNz^Bjg%}3Q}w&) zhYL*o8vQ`aFqRU!k==w{7etF>TvkZ?K_aC6*hC@xqk0EFR&iL9H&wH{Mo2GV_P1*X zZ|En;Bm9!tU88sY(@5Qf-nhw`k<>dq^v;>)on`dSjn=r!QX_k4!M~sD z)5n}^Wmk0PJ$l93C?5bI(ZFw;fjxvLYDWN9l;r>Yv34+8Bl8U68ERqplY_iD-^{Mk zYldvNwq4@M*=JcJBCDM`$x0UIH^maq}i z#b6_3cM~>Z8V@$w&fX?$#55CZf1Z^Csg(nVX63-4S(zl2Vk-v@&B`RtbaANXJ(!n$Wa+n4-mFZlgc7sQ^6i>^Hc=hSamcQOp6<-mv?G(|na)D4=FME| z<%#b z8ZoCDSno0NXoVasW-C%jDN5|ksK&T{3_)s9u;X{4DtexWq?eEAJ^JV=Hi*{Jv9Oko zg~^zm3K~cS4WxpSl$94G?+SJ_^Rgl}FD_E^Hr}7u*vPZw#TU#t->mb1rp*TuDPKsY z3<*o8`nkvaT_wCwNs~)E^XiqJtw zppk0ONHs{Jgc@*FaCm7)>DA9}^41$?S*qBwRIz2LV#`v+mZgd%bAHb6Iiti_b?uIC zYJ^d(Ks;E7lFu1Geg+5JMz^A&U{o9RJ^;W;@vwIrxows!HTc&F?RQk59v)t zo83j)>`n&M_v--pQJdLR3E3b;3Gi}dCr?2NIiQQ5-`XMwztpez_fD%2KkT$N;y*a8 zo%oMVn@0So(>jQ!>YHeJ6G?njJ+_8yh8)J5qm?L(#1*G?5FhKbX~f4lt)2K8PHQ7> zb6SPC-DzdwTa*?Q%tsDAdWu?x-5SDkl@wlCUaLa>!Gsn30xgBHB<6I4R1l5&EEPe$ z3flQuTJ=WrcSnhKw@=ytF0&lU9*74e-XCWX>B6 zJ6J=!(dz3vN(&xq^;HRnjnqdKKI0_9TZ~jqwdy+*A5T|pUTIp@*l!qV1w%SZb!sUI z#(c4&04*v<87ocJSU>Rrvu`QwV>MV<5K_^i8uw~<`Gs|x@iOtSZoeSQ?4QD$5hcpz zG4ZksEnn`Rl21ph;YqsTjdVnKf|5cyI!}dMV8RO05rwfN(h=cIRSeCM*Q=m~9#wm< zQx(KF#7)z*O87hz-k|XPP9mJ5s*5n)I87nlRn#8T>mwPxh(G3f5xQQ>QoWWP znqJGEh+ePD=tVs4dKK09M8t2&h$nvY|DO22&4?#{hl?kCnl)`7z4|v!x>s=6tcD&cbr6O?ZfBo2<+FiP_`@Ed~aJz(5oay;#E$o z5U+Mx8}VAFwG$6HZ5r`9r*#l-cG?W$w=VI7d^m63rbL;*62IMP9mId*v}wdwIjx=e zYNxdkU*oh2@wHAX6aPjRS~9d8o*yyj(aZYd6O0&yJ&Q@I5nim~v5MNi?VWn_L%kyN z6V7}seFDBMdh@+3@qWG8XUc(-H@{F~!B|3lKW6&Y3Ej@C@7y+#ouAhh#LGCsOu4;D zxm%R~VXaT1lK2_spk;Yq2wUEoqJXCO3sscx5N|N?wVet-=p@1$loWnP|1VYJC>17Z z5FcxGRtX!{;!BHaWE8B?HpcXbG4Nd74*}_kxQCt=y@;RddJ(!_g$+H0kf8p$$hEH%P$C55EI8)h72Wx|%^n+ur=8-u=dUTrc56 zEsVUIq}#|CnFxiinR|=OOlJ&v zRWQ`i%$XTQh#4_@yph6!u$LrG18B-SB{&5!mxX)C5H-*%mc^IKSa+X9&MOlv3t1JeIk8@gu_!&-X zBW`nAJMpueHjVh%PU|2(*=aL~PhSzW$69OmRNlNqiLw|ZeyP(sh^ISk8u6JG(Wb6SOXrqjyAGgfC5%sZVPy-Y2W#h}97dJWr$GgNTDUJJjQsZ5#O5xup^$KmDh-R-{9*c`+6n|aD%1Z3XGIN+( zF3cAbT8lBbVL8?&JjDNQvNrb<(@3aLBtCC8*yvT}@B-yIyJP#yAI04!TW2J228MVd zWH5xu7;kR5DB1_Ue6SZpEJ%5Gyi^5vh%KW@9!|;B10NHxA9)8!rWD{xgKk+~1Dae@ zO`s$pyFxITH}nVi2wUc<1%Aj^nICB|9N(9WvUw&fEjS##LQ^Srzwp~AygSblY@KkV zg^_pT&Pe#y7DnD(m2=hy`s6ktB@(FVA1}Q z$7i`G$1=4vS}ro@-W=cIkuR_3FO=vLsS2 z($a6!t87~kU%WONDBA~5;?0N>g^_saNQN=*6xMLx2WQ=Q8TK$w+lVm!0H6 z%Kk5Ft8PN~!BWb;+I+Ay^}$m5;2Y+arK!QmSnvn6ign1A^wv+R5x1H#RYHmkd~_r& z48-VT|L-2PjRwi!%i0#cF7gSDxLaw+O@xmasgXBaN-_`@ndOb83h5Ngg$R4K^`#`O zIa|X(Xv7Q+6eXmc!sZ4>bTBg;88eAjnoU(gnh7^vF@7k92FARpf%xYd8w&rW=8j~{ zCEnrY68_vs1BYTPmhpL0LHctIMbW?1%r|7rB>q2UQef#$n}wm``AVn6LPD4b&g#6-@iKG8P$aNWuAXe^ND`qQh$_muLEWeYj^sd?HH+ zh13`%1{3uKX(B=2@Y?onveQg;G9U@2h>$)JHkv2yNYV?ex0cy?bmEodPjO1eL@Ea zjpqMTW}qehg88mW_zNQ~IaY^Zs!`P63wq3*TRA(-^q4!h7W9}qw{nKa=^=c1=hjj6 zS*9D^xs_(H7YEL~*H6-*IY+Np)bH9VD+M~{UVShHD}!c5O?|Om12HeMz`*;947|U{ z!262~ynpLuse$(w8F+uPB7Q(seZ*R+O8BUe^dl;_grP#WNJA2P_)KpSueQF|O~?I8 zNm7*f_ePuEB!0PSA$-IhjWaD8sjcu4mo?sS5{aSre47c*Y!V+V9Dk+Di#D^MO3fyl zf08Up|FCBwLmcn~L-iw-aY!v9)qNe&ziSIW=G{Nf@&kRuO8@Mv{G(i5lksV0{@>jx zPdU#+g{U)L(55>EC3W!2Y#mo6ykAM^nY)s}eYrj)6Wq3Id}>~WJQsep9b6|Ts-C6N z=sRhIaqHyS1{=4C%Qo0}vR=qb6eIqEj1GOd z49ICxPPV*Cn!=CPs}`-~t6<8f(tmayeITbRx@XYU#x{;1_8_kc=bxNVltcQOTAp@1 zDNIe+#mGAlq`bU~bo3k2Yrzg=%91#8L`!d;SW3#0NZF;O->FyGSR}s7Y3;;6bXtuL^s^&etUmyL$^*~5P~oecv{WG_75I+^9d4!S6tuuesi36YN0j@$ zdX;u3UbHdlkDcc|NAjksL}4VpWmATcH+z*RjKp8k5iCf|JBO-#-VEp^eAr0cgpVpI z97mr>)OW00VmQkWjK#v(izd9tNZnm(?a68kxW1t9znygV<|yN{x;q1|M-(2Z7K3!0 z!c&~IP9gmQuDmJK^FK%96PZyzsQ3@2=u#@W)taZHN&I5dbSag;T}dL1_y{k$GOwH?8VAh*c2OUDG>$TJ;z52X{WsPNaK7`lq@w68u zsh#CkYk8~{c5iO-ZrplEosgX-GBR4(IU|(;`%(?qNafu*7RGf#Ms{SJ$Tn6zsdQn! zUXWNRWq~x2AZ9A$3qtx0tLxNjwTT41Mg1fFgV?ofP)kb0B!-ZQE&LXnI)qLH8;x12 zkA#hw1{Q_?F{;p6dWA!GrOUZIR|uB8jkC1sh1OhE!fqq=5cV6XK{#Nf-n{G^RlWbz zD|!kYa+H@MbiX7YT%D~c;T?K~Ai`UXlvMvJ&B08+lS}iO9DLYjLZhddZH1OMB`*se z-?urD7O8o8k@|QNF?i&a11T>Hq{kODkO~?|1tlB*c^lDhQbDy;P%W>~LUsJLdM((q z-*Mb(ladQ}HQ>b#eaK-Lz9+m|A5AJPA>6H`DWz?bn!Ndu^AX;i z<>Spg&PVu5BUK5Xt~Q}o!geE7U!t(#B*Jkc^$^}@r0Q1`-r=NQDg1+8gHgOGsT-jN z;ggJ1C48oldI(=(q-tFun?z(y@b3h3#PU4H_muDhW2qAU#z>2gR3nbkE83CJ-M4sa zqS4}fb-R^tlU^s6Ufv}BoYL^?3AZa`OM;X)S4t|ET~1LnO|MXskYR_QB-A%Qr75LN zlbXEIWtI>pH+QO>x4ArqNXQ3XKm+ky2YeDLv!b_zy718R+rK{I6a39oX zLVH;8bF9KTA%j8KOs<06dZoW7m(DQX->T2B2BPopa1uKnm6=rPPkT>4Tj)({p~xq8 zz0%zTzU<264ML_s3>t)N0JJS3lO4DS*#O`oWLg6kA^Rw}2&pKz)PB1hB)Xn&EzwJ* z{>4eu;2tNX)g{reKr3cxH0ee8VnQ?hazI-FaW`Hj<^Ts;h4^qS2U;63hbT$&#BI(u zjrd#@d>HmQADhCvmsa=#^k2|f6_>)en5btpsLo(;(Qt5e0L1sBs;h>X-Rl=2eJ;>BTPdJtE%YZD!`aw$S zRl<|4u5Lp57s~;<%d1aj+7!Ih1o4LiO0*+nNZz=by*i^R-Qz_G?^9AJ%9~$1adMM4 zPt#rj&M8gaoMK(2&Z*ISClUUWkroqv*`#gU(d5k!oVc^en?G9NUcxCFXi#NmlQ(oB zT8^;W`3`IHW`z?EZ}Mi$iBp@rVNygjM_7jZJLfDndGlc>KB>u@FFNtaCU2f@@l_{$ zsgV{F&NosoAwz9aX))n7&PDhhB?Zs$#-lSyUdL!lv-=~R(s`Gg^cvxtP5Ri*CU4k( z3oIF zn!MR)VbxE##ljDKyt&!=2pO)Bx6@+xznqVd!&j)+ZZs;OA0zh|3l!ALn=_n`Epn2z zNI&7J)*>j%o70>)xyc)b7V0H@h4W2n@}}1-AzYH>P<4=t2G!d&?}|^Usd>Zy|$G`N=H6+;qGGysCm-7|=}FG9$|eFZz9_ z%3)@d-Q^!E?IEjnF(JciN@=TS$-^zI785e!L>%#{&PMn`BUK4cSJGi{SbLNCjFBYr zh?&J;1t9~ZXpelKy5@&^eJU!*G%CsW=wq}YA%`#=g`Cvn4TmrgeLO3x$3UFYK4X}}L%t(s~uT~NcUhQb|<|9tr+2qYP ztZ*;kcZ?5<4&Kl;Xc5BG)LXC@voF0_%)8$GQ?8^w*iKdixOltCmoddIM!fn%#h&PMpK zk*b7`Dk&~;@(EDn<)cMtX|N=3SmtOWb?eoaIH6HV=IDqvB=mt2OPt%ZI0wQo>hNZt zK15-{?jbd0y zrK1>DQt2p$l@v#@Z@ZR9GEH&1IJiCAvI7+24TAyB z$oGH+>SShTe7&2W(#R1qHoz=Pjsu)8xMtNJRdSChTcxtkuq-o>4!Kn-IN!PQin5DR zQCSMTQI%(83GJEMH9D-<^yHNnwpXc&y{2lQK{A;JR5g%|`h4_D*Rwn-OlcMLK^EBe0 zIIW%d9;dYt-|Msr@d2lmiMJlZ>G7*iyus?(FcY=WM550& zwR;I?d)rQGzDaM~yk463G&8T4@Dw90?oxP>k$MT&C@BO5Z|E!#CpGD=uX8STFQ1ouT7gGSuj$zM?yE@JI#eXgx8r1F@59B^-i4J2@P8bvY(Dmyt8lFII?W*Yly^LGznT}e2Rx3kF`ri8RwKA|fP zS}h&&Z(c1SeH5yFJck?(+s{6wNvG^FKP{$V3?${G9RpVJVnP~lM36cC_$CRo2!jyY z_9I@LrciIKDBrvVBN$uvQq@{2mWH%Oq3-s8+EXKYkXOPUPHtH4G(8D~a)hrlQk8Iu zP6oh5_;e#Jo~`gRM(QQ}f{_*z{@6&>`xLqhl6P@GRMVX$8T-iMUg{>i+)U{qe2bF8 z#sF`wapL4AZ$9jWzoPIlClR_Ime3F5W?>KErAi95^5%_BoZRHiwO*Kz&cvujNM~Z- zp3ps%gxdbZiOJwZmOIVDe!?lHCiWnCbF``1|7wM>m$1JD4gcz&2E(k z;^Zc87-)DWG^I%&yj1PNvY&9Cl0wbAVUVC^+Iou@C1j99ON`Rqt9 zJ)*&+N&abS(R)c&n)B6K_RiO05Auqis+zq*uaoi0gqSMg zA68%60*H-ksPOqY!+_5W+`TfpR~s&y-bz(7ET05Tv#6W|aY z4wI0C1P?GI0U`!6WI}i*H9b8wnI=8mV|Pzpgk*Sl0YMo=0Was8;UOS!4~ZNkTtx#M zjsjN<8WlxlID9G(k%(N(1uxm)X+uc|_5L5=`L%=p$D9o7*4mE@#bII-*LTzKfjKz#BB{take>ofX9CAU!jfG9BqfI5!J(%@kv6h?q(W|ZJp{Qhx0HKenb*BA zly-{v4jiM5+$(j}2qsucnNO41C7uI*6{dE9XWQmvE2O7^ss>8_G>bKo|BS_&$bZ&i zIr6hCHjaFo#ahVEwb&H$qr;ommJEAL@cu+`a0>Y`5EQJ1{N5HDNB-j$%aL!gSQGjE zE!IdrXR!wIC1BFThCL=KR&WaWK8v-GuUc#z`MSk&5aVU_nH^wI}zfIRh5xbIEDP*EY?E)?-ml^XWjeqnBM@1J zOsl%S9p^M&nT_10D|(w(rueaWrR#^5q$doi22*_5yfVv|8SqKHmzX?*BFhNZ6@gqw z1ajRF$aO*>*9AU~5OIFZDpyZRv?kG&sLAJtRRbkICamN(vMi6-x;CwnuU+MqNf~qt zrLYw5u1$FNGlcZ`(35tuCjydTYt?EdR#`c+yd_D?F~MR;vq@GhMAzreXk5AtP`7nn#uupBCAaweZ>S@x0L2zDDvd0ZSS81Y(A~ zhfg4~3&I(ojcjKKCB~(TkWJaT&_LdXYko3Z^W7FEYhOl-VGt-;V~O*995Jr4E;Nz9 zFN{JvSvE%9l9-^YGRF)FGFd&7 z-2<9T5+o)?C33?r4;&GQ1?9X3C*{~1C)Z9f-gmsmsn0g-7y6l9nmy_$*f zVQ4PA66{YxsGV`JWo~Er@}Upy%-gn?_GIHobodwG*3rmL&G6(Wg)X#_y&!C|^Ifl$ zCOx#xcs@g8-J0(|tLvGNZOooXY?Mj(?Q*&86Gmj`tIa9jPZqrAL%S}4*+);8P)tQ|HU z*&wkdzQ$q1Ya?q1nFYzpNt|o^3q1Z6+Kj5^b?D_!g~Mn|ct1ga&ZFd*6SGm6TSD58 zw8<=y9pQqSa+feczog8rTLQ5O(<^~orv!2{ zqRdYgWqz_KiIHg$8UUX=kTJn6?H9IPgq11vopk4YHWX%WZNJZ=-imVEW7|BP+%23B z6Q!rL&3@ilkhWbev2dYbib_CO8SERfz#?m#TEb8xru=^bRSRA6&sZ!+{>K(WF>Q6y z){&4A56C_dLJ1G1350;iv2Ax-6fZFO@9{Hm}OYKQZiS@`DNUsG|MJE3(i#3w}w#Ayrzhki+`S&c= zME>smteKzQYpmk8!{t3WO2AvK{eOG=E zOW8)OJI)3DZ=kOH_aV=H=6@jVeZ=xVMm|3UeTVrv4rckct@_OvsK$d%1id0LfSHV^ z0zUz?6?FMWEYF8P&p1a;+m zfR{ikpm%@7@=IZV1?cVDncueRzq^+y@#wt`-2-%QP&XdiD}N2_+yc59^o|Vs+be(I zKE}gl&uQ?xCdeO=GwG8+w^{#iqj%OgLpwnq0euwo51>ZM{{8(ChJOomGw6GuR?=|W zE8lUH(OU)jCD09^u6!>S%!9;VQ6EUp%Xw& z%Kpu=H`}q-3VYK*+dd@wzlOgrgT4;>e)AiI-;J>Id-%Bpv}d*{`^%s^;K7H35)VKa zIoj!fy|)oZ>e)ydj&i+_{~YMepdVEJ-(ZLJyawgkS~=Zz@EFR$a=(#Le#Y&1#Eb1{ zTlFW-H6@-3`p=-#K@;%+9)R|MUIe-XbR}p)|2%_~K`#a!0=*0Leo$9`!375C1PwqJ zg1Yj=2XOp(&EG93MS4*pGoAIs^Fqi`?e zDBrymdCI*AJ=$d)9rNDXkb4L8JM4?$i3DR-wM_il##uYkV@`W9%Ge2Dj& zoJWD~2D&%sSkNOtCxW{EdcbLia%X4AZ!I6!{>89!Ip|%Wk7U??9e5M!^{=3fs7KfS zWE^+f!wlfBJ9b=s+TB`vIkeAcjsu+p>e@RVe!BK%0v`iC+H>{UKPb1g{3w4J>~Bq; zUv&On)#Us*D8DtmzTe>dfb+9R^CQ!)zqEG}?3@PbgMLu?LD;zg^fpj_yxFzCz4H8G z^PM$g$^D`*KOM}kiMsiHPL-sGr-hW42`Oz4Df%RSB?}46oi5n@C&eGoqy-`3%y0H40xR`BB?z+{NVZGtdv} zAIrnHp52Rb@f~1pdH90W7m@!3~<_Z2#BetnSV%Y$xk^j-N^0W_lD@TDA|LfVz*Lx0zy zU+@jajpz@2z;_5~K2OU>W%!uL*D~(s_^9pkIg#JOzn4H?0d>p!e&rv4y@x=VUzYuC zmFKP1ywf>{_QN~0-FvDN`Qg5uyFsbP+nxC=z%bg))w>%Dyn!&hTkvD9Wt09-*ySCI z>(TBvfHuG`Z(nrnx>jF>y+48e4RmsYD{0anmi#E#-vzW~JM-ICecsPA7xsB~FYo+x zL?Za!XE$gl4JB8M(hW3yv zSL#9Y!g7CeXMeHO^{HZ)r&B%oT94PRxlPT$I1{V5$7=mV_Lubmi-LuQ}-PyQ}%$!0+i2U8cO|LcLP0Nrr}8RFH#8L0K1F z?Mc43SdiQ+VpIM!>x_)i&YGweD!siySq^puo&5{_d^KNQ7$}oESuA%eE9OvVXEj*N zRH;}F$V+g@mMW5&k%uL>HnunY2~kiT6pJqJhnPi34|NP;5(&{};ojb|h3_}}>B_l6?M`eE&r?VO|7GIA`tnx`9}^V*pcEL z*D=w9BW1Mb`Xr8z^tkSb<2!m>PsH(29@hzRd?%0de;nUAoZsVkgU9(gj_=}e9**O? zdYoV5_~>xnjN`j`oDbvp?jGm4IR3G4{)*#!c$}Bwc%#R8CywvwaXyLTV?53iaeOb2 z<9{6A+vB(%$M^9#UdQo|dmM-3_`V*;*ErtfaomjKSbRo7;YWJ=JBUe+^qj>4q(*uN zWXNN&>Kq;E9q1q?Inp~Q1J5OJ)lYVil{ME<6j1$rNAJ&Dm?l*oj*wNETaRk|AK@kI zaf-&1^>~WlD&N7S!bE--2tUHJab`ch2>49QTO1#hy0X*As}iu4<-b`6HhNRAet@`l zy|%xHw`neOG)L4}G{Q^zf3M&w-%VrV@{bCh7Pn_1-wHq1N?QHikpId~%f&kBy<>>C zgP7I$3Ilu`+3XK|6RsktxTxPzz}KsVviy$6U^^YScd5Z&m$dqI0^f9*NwXT%azw>{ z0C65RhrO#I-*>qIuzm4X178DtFUWrfc*nH{C<1>T_@Jr?`Ryuc_1g@5=<_E1TQjYA zdr3J|95%oX)V!mCcYM*v6F&|3Cg4|^!(IXSz?TdF;;A=UD*KJs8GL8>a})5~puyjg zwEEpk{05Wei+BGWc+0;Sd=&iuCGdeEgY!+De*xZlyTMWY-e{TRlt1f%quAa-z}xOH z@;@=eI}v#6JqEZP{$BvR@jiq99UHe5#2+yD_rwqNyAk-N2Tl4?`2QgAq5oy@Lw7dx zS>VHune=RQ$hRoJ!Qg!R$?jrLm8B6Yw{H=N!C2_65q$dhT~1zc=vQxh7xs-@||p0q=nPWZ>R; zars%m2Y^%F2R`h`FVVQH2OK{?54^*{Z-kwW^G&|AudcG`asj9R>TJ2fTQ4y3jN7BY zhk(=0M&RCsarxf??*LAD_420?^8J7T$4~Vwd+iV8>5sY!sQsC5>|;3a#seP)PWvZN zeu0sv9rgK8Z67%0=L66Aarw^y9|BJKOM!bGarqm84*;k9oxq13`R@Sl$QwJ1^Hadr zJNR#b=Q@o%?Y{|pz`;jL|4`)}2F^Hq5_m@;?*B2A2hKR33Vfi;$P=FrJQu|MQ7@rU z`3?YY@yzcsjqmOaIrV-s7!w$X?xOe;ronaI5RiC?7?Jeiv>MDZ5 zTOIsB;2jP=1^9r2pAUSPM%z7qJbgI}+4nZ3JBJQ=suz*`-BE${*0Gg02h zfe$mH!;5i2$CwSVrYgz_=dIsJuxSFR1N11%r z$b6=LUBFv+G5AX|UaMb!hMg}$emH03zi-67+XPqZ1~C(`heoD(TWvTjJoO23N zA3Q6=P9a0So`I_`lc{nI-DdKXZl!;B0v`k}N&R~w!_G#^W4%E;uVu);C3spK)K&g8 z{GbeclHh6aIXwecZ#GM_U(Ud<%CPf|4Ecw&y!?5_#Ov!=2R;pa!z%`#Wr+6z@Rn~F zfN#tAEAWmXgG)2hKXtc*s;>=~n>3b>-ccHdP=w4CJgvOyYO=D^fql)v(5YqExfb$+ zkRJ#6)q?LS>&7l;-M9|&El(T4ClQAq6MxL$+}FGUeBi4FubXb>si7*(fAtlhG`vM{ zRj$D?#=x=g^VAIad0HMq5z-4gxxI`Xo>{mOxHr<^SEF3FWY}3Nc$%L-$iRnTf789j z8IBw8X!$>HX~FuLuBw+r>hhu?NVCzuCc)G4JzC3C+fwz~ptOE;0qnP3V`SC-S^X}_ zkiQD@EpHmRUPHV)GUU~pjMDu4Nd`Ww?Ih2qsrMJ9`TtG^zS|z@^0^HBp9N3zb5;i4 zlVN8?hWuAE}zbHd~RfhZx8XxTqqXBY$xi7=ccQWv2GVs@6-@DHgf&EAZH{HM5 zFkXq6{_Uf2BqHRH4E(eV{M-z@A~^GknD>@t$bUiOGLK_^k?B?cZq1N?G6VmO;A#23 zmLWev8jl)(a^E!hU5R}6);JOoawy~no$>z!!PD}coq=DFffr$)cTvBLyf4;x#1XJx z&9L+B4E*T~JHOJnobST*vI{XzzMf%cN16C?Nq4-x1Q(UW??}PZ;xk#x%lV(XjLO5% zoSk8(0QpVJjo`76UnY2({cAGtJG31rN614N@=t4dS+}6xWjfQp-(<+Yk%7OHf$y|; zdffIAJgr>EW#Ff0*y+&tXm4Pwsn{a?uV>h~6!INTJHHut8}<<=VZU>a#$hx<9?QUA z6g;h5TVQ{{8L#$~4NIE*L4v2Xx7G}NUIyNkf!8zem4c`FvpNI+eg^*24E%S3t8r<~ zZ6=ssL`+A?{S11%deZ>1P1e5yfDhem(ly}637+O>dj=k4;7eh@4c8a0hy9y?4;^gU z)h~eGqwV~8OApr7fW7;*JX4nbdj|e%*k9v}&+lZ&@3U`udpJ_#a{e6i3*$CP@U-}x zm|gw0!S{ot)GDAI*?|8uA0TnEY->zApi9 zdCmZwPe;fJs75(I;I6}W*Ep0TWIw@GdmH$I0iVIKlQkX@1bbeFol=JU)fw`G8S-~% zT&_#*XWCmH3#o5s*m+FwJ-vOs_5BBH579lmU((K3jN|G)5cPXA!_G*#l&j*f=}{xc zy4w$U+mOMzUY)FQgGK+ImVx_%(`Hn@k|BRnhWs}&pJC^X4E)^; z`+M%6?*HL}=a5&Fd|Gf7&moLslTi3J;Em4srrze3HqQ5F;MZi}cL|;r=SQ@>jJHm| zdp5()rVM-!*=VQP-%oH=-d60#e~4g=*LXBChM%5+cV*yL2%eVj%^CQu8TkDf_J5#p zX+JnGfzzMfFMtm}X#D2Bc7L69IP{FL#R&Au(L?; zv^Wf8$bU0K{_za_XWEX`<8#Il?&JQHVSkj|qLEhK{RB_*^RNv3cx^|uzy_!eouz|M`6Da11i@i!x?to&9JkV+^UimpCdBxX&RSShIYbn zY<`A(Jp;c^@U-~fk|F;$0D{-@<(kadH>a$8TNNQDBYj^GVrm2r^Riu#w9*C z8E-BhVQ4$>K71hg|Dpp28FuO!_;rG(#qHJ%T)kCNuOD78esCSK5%?Oc$Jmd4ukmOk z4gZedY5DG)OOJzB$d^j~!rn^RuhsL_x>u;yYxVx_?&gB$`_t#np5xE@O#58lm(+|{ z>h$T6LtPbrVX4xYFZuc*4nN<&)RSj2`bt4P=xUxk>Dcj}I^Y+(ma5dTo_P+WtG~B* z8S^>i%o#eHQ|Fv~#wk8iDjV`P7yZPD&ZV!X&+iR-3;9Bi^^yHBxnz+#eAu_JgA1ybaA&D)YM}xbC=1>YN+UU1@dG_Wtq3U*z2Fcocx7BeRf}6 zJrk3_=LEI>QvD3Em0uXKQx2ARp{IVO^P-?o_j~f?u97@lW3%h727%N?r5aO~NcH*M z{pEtMDy%bKSY$OMEVZC2kLZ+&wR-w-Jin8EP%6GI(W2dWd5X2Rs+d*J$s`V_hk|N# z_1sPTki^EsV0xu15&%#N zVy&8Q9)GNxiMEe}Q|&>T=*urFRq|a%V8VDSP{`LJsuL#IBjTO)9Ey=_RWk{qsuQiM z&b7N*>Gk9JPPQUaPc!5Ju4O@&iA)%EIbgGm$s56V2z|d$DN7&eFVwwKpnGGap%;Qk zB3N1obZzffU7m=|xCWCZbNMuTRX(_B7q~k)SgNHIE8LuaUrKzRFLq?Hmpr0mWwlb(V zNGRjlgkT(&_{fAKV{qtXh}Z~AH5j2;GNy)tAsV+R6IH7C=lbQ@OS-LxuxT=vtNDc> zYWoy52&XiD)e`hEJ#?oj$1S#T`$yL%Pw zmdKTshs<~x6wQJHM{Cx|KV_~z_vC4_PVteg&DHuIwqCz;nZHN|xcGP;_I0UJX|#1U z{go=^g^{tCy;m((T3b(>^_gkY{RzzznkRYEvV9q+D+M!i21~t~OzeJFr7VK&C%4a< z5HVwxEj3>^XUB_ZKaTqsIbwQ+Ety&-Id-J|nZY2e593*1y{Z?hI_hewkvb4Z7OE9Z z)$grz^_OJHBg2@?pVeBR{>r1vax6M0b?Vk7^;M6QN)O|zOtR)M7K$}rrbn0y^N3Di zwg_U&*CETxV#wFeIM-`cS=9<&Qp+@1=sHC-vj|&{X;r~eHH^dqXS+ijx8qwJS6x?+ zTY5;cE_Mbz`Nc(9Tq|F@B%f-rvtO-+rDe*ZsWV?I7Q$7yJX}uCOuVffv?8{`P)yZ^ zts5(EwivQj>T(JePMmT7^O1Qcek2@}bOqa0i3)O8(47x!4$JgfU6x4dxpvdb!%pRw zg2jQ%*L`}QQ7iXVWtrF=X$z(m__BzU>hG&5rl>X`ey!ML_bp+BOx@`rC1RvkxrMIk zYmZf&Ws^|#`}KClv@+RXh?CMn%d((Tl_Fg>UhL>R=m)xO#Ra57F>^{cF3ThQVz4V% zs(Vbtp|AmnV-XmIEd}L;^&Tf{kqqY+&O5T5;TRd#y(+4$4{1u#<)axdd^N@_DN65H z5)>Eq)Wa>@v`VGqN$2Sf{GeC1Gx8L_uiro*!4Rk71C?!7*c?R)qIN{`s)8Vp(O3Aw zBEQhH$nVYx-F`-qhU1Y+R>1!voi@LBj ze0t3hX_mU5*uzqCv*WWfgK3+p93m!7E*Tc3Ze~Hfr&SC6Wnne9o2JdZ{4AN8PCMoN zK;9Ig`$i=GsxQd)P466>n3=BNfM&pm1Vx;Sq{3$Jj(ZUq*tO-4DtWT`4NSwd0>(K^zy9z23ffBy~8{EaS}HvXJrF=;Mt=*QIsMY%$^@(Tzqp*LOgS2itk&d`j++k*yf2wQzoTSUUs);+oyM! z`LaxbY9V4w>r+?Ss4UpZkvdS_R}HpHszn)TZH_^2UwxV1ZS~A#>POCh$r-3nUe-Ob z!(xC{&&fO$#MP^`?0O|KNT_ZuC9n1L*Sji9$`M~wq;$WKrIECN?w0i7Ky9N;m~4o~ zPxNHcm7UQt38~!$$E!)TTpcDoRnT$quMcw+he&_L3#pr`f1ZlrslHXs{(c~OfV ze^lM-II6)wp9ZsG!zkTXk<*D%3#LaziXQE_PP3OW!Zdr#v(gASLs5F|7_^0OBsQ%Cd}l{0ZsXDrXW=^)i3l3!pMA4?w51BiP=J=!aIrbG1}9Xv$krXXbnpBvHz!V1b!CtlK+Ol~#jfb`7BSqE!E z&5!h4HQLD1Q>`%^E8KzU*qRYGc78g{-q90BXP9$-rla}3yg*4Ua-_4GvzuyAaSMYA zO4;UH|FQbRbS6vWaPug&uGXSf)K;EUusKcc2YTqSGGVQ#F{C2riehcS^iO|cOT?|N9o#?5VO=DyPE|db96K(O*ms@NA7=;qe z41_nUqa1kgR1v(H*Bg>ZMXc>7yEOtH=ZuF zClY#IQ_ZG7askFJ7bW8A9Iq`fn@4OwM0v`xvrdZ2nF-ln>Ai&N8hDvH4#kh})T{xvl=x|(o`YM_= zXJ6DjVaui#xEzaOElduWE+9Ede~V;km9f}x&tjOls!&lYKGiIpZA7$bn_d;$<5~ZE zD~kiayHZ_}uXZV~RogIUob()+Hs4{yixg1xEOix4ox+H~VXxE;xrU{Z&A~LhaH*@x z95xeqeVmN}yOchmF0nHEbYETQkg-;-<%Oa;C)HbIC9C+URf!tsWr$)okh4&;ZjDuFtrO#wTiXbqur;skJxE^tAoldRODJu#8hM+ zkSyi2GMl|WA-X7qHXEdx996*7Ng4Mts$2qEnpaBH{tJ6dS%Clm diff --git a/thinkphp/tests/extensions/7.0/redis.so b/thinkphp/tests/extensions/7.0/redis.so deleted file mode 100644 index e3aea8fcb15ca3b61d31dcedc298f7ae33ff39ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1541380 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

L#heBF9KImYV-??loSF1sjBNOsn#Ub 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∓e(x=!Bd{ljS09 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%0Du^0q=okxfPkxq<$4K+#KKv}7 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

)mv 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�abM0n`xn0WFhHg%}c>O>;~gH+O4g z>}YC*Vv?Y)N3KP@`l}gp(7gi<*-ABfbADzp`}$z=rHLtQE7onCE8L#C}$dWw0g1mQTi7OvlgL{ zL~eyD-Ow;NNY_xno6$EdncY>??I5v1Zz?=&X>FFJ&6cq$#4-sKT0PRPp2Vs4Oru_` zf$X!nr>8Tvw9tmtXB*b7MQI_HLTj)ob8`W;qZg}r6`8cs!TEx0^@*g&{J|9T(U?Nc z&wVg#u5_l#&}6Dv-xB-mWEP_KB&enoq63p-J4Go=T8T^-&x6vF18%0etIw9~EU5$@ zbNlT9>mmIWvbBL_hQO|n`2JOPkLI8*8RV?MP(QaE7T^Q!AD~ za>ztsx}pXX<1vhoJeij;l|YKO8nw0-S)PE>?Tf{3t``P8=x}jOPG+7L?~&>Oy<#3zz)FAlBtem zU>qr&3%aRR

nf9x6-v!s-{DCY0R_F9zWqO+8^^hWMi=89{gHkkuM^aK>D${<5Ao>L6NXcZ6ktz?dRK|vn$g}&;!R45BgS=}kL zQPcQM6??S(7-K(#9g7Fk?x+H98QPIG*ro!3*;lY}YDE7%p z4>cS}2mwHV$4#)<(CuacTygMo5WrfDeHz6ya4VKz-Fv;aEl0yx%|9V*2& zjMEmNT>Pa#^x-4#_8DltU<=UAm})=G&R}s%aOg)-Az7?iwokEpZeZ4_omd}JQ{D6_ zGlA%iZ1L)FqA93}i~^nq=p{e^O9$VQE$ux(2e8FcH9Did{;sg`a?sV&`P?`!gpQVpj-JD62 zrqtCrw;)+pu)_*J!>JnVfP^pwegMd%Fe>O&CLajq{?g|naA zvoT*LprL>}rd5UgshV7{v@k_sdI9xz z!BZ)hFg1MH=NXq;FE8C@N1ScdfP5m8*YF6C0&MP5!#gVKH0;sH9eYDT659)Q>@ zEU`E#%^#`rTr4yY!I5!kXHQ!!L7mN=5bCKgC8<729kEOv4v;i*NEuCNUYj7t|Fyve9>7Xb^q=|t=FSR|oS90ltp z3rQv9NHv5W0i=5-=IAtdu+T2S)oS^>wecq$>*AY*3+Ed%9pqDzHdH;pKU>bqIALh9$SAbcfy3^!zuh?1;@%P!?tn>iAh2 zH!?f21_?h`7nh=lvXHZc*d3dK)uzz1kxPy=B4>eCey}@@s{lO0F%#47%tj&H;WPwp zr(w~TUa0jMc-2guIcMagk%$>ld3=lqi?kow#Z$1s{6m{Ad=AL8h)i+AEj(5X!IQ;` zg0x4DNxHI)i!fGdyG+v>Y{hy(P`UDtd_} zLh8zGC{*$YEno)DA>*{p9-K-A*;a6{xgi1B%C^`w=#wW4EX03=o{42qP<@p%hN2*x zjugZ)p9jg-w#>~3#BQEPhkkCK4rxk72};4TNzyh=Rv4ii<50a4leVZ9~O+?yhe+WCT;sbI;$XT6Zs8yngpC&ZHgKO@Yv_it>tSeIU^M9#Zpr{W?n?Cwk57= za6Tg~IM6te@|~wOGSEd_SFMgzRQt%P7fU;qNB6Q&3)b`4!h~r;pP)cej-^7|4Y4Y9 zKq*4J*a*TC##TdZ_Ssno=ZNtM19zxas^|I)7ZY=0b8lzTf=KGZ8A0A1WYERSja!&( zK*2$?Tt~W=Y%b;ZP#>u-XzYbf4LG-lY!WKdPPJ0LW5BY;K?A^%EI->S>Nrl}AQB!? z3L+V!u7IYtHegWNA@y)M+xng0N+AfclnSgtLUN(+CVVWTG3(ag)&W}qpx`s_buuJY zaI~Do5s`yCiE#*%4wfSNh4kZ&z?)-G1qD!X0TQCj2!RQ?r8}1NShge(1mx;`Aq09d zHP@fm4Z;I;e9uA?vL{>8rQ+`P{$PzbdDnI=P}tf;Qra#D&S!vJ-9vo>v_>q5ZvqKD zFIZT}&8ZdHmfW%!oz!hBIF`&UiTRv>HYJMmn29k`0wWv~a>JNpvFFC@xRUe*EXfMz zgh8-(C7L^R-=SX=NS-zdO2l+%bEpxL4`B{n+O30&m*s7{Qrh)Dlm3UcI!p6^7PdLg zD_nBGL@7&jfp26uN|u^5eNJ8dl-c60KHEC^+KN~kpng{`7z0~xZMM4x@ghvb^~IU# z(^ZYe3-~VT>54@g7N4RJ3ueg~Y0$D}b2fwxrEnzT#7&UFWuU4ON?aJA4A6(m4xmp5 zMW7HVt=j>G?4=?6SlN%w+EVnhke>y9o{Vw|)7rRG1f&F)w$PVvXC8F)daPE}_ko9xwYgJ!zeOMu#j)MNosgetuB@Wvs*(-B(u;`u! zy9G}pay{@lmIFNPXwKx?7==EF2}_9x{GV(>i=uLgxyMZvM?;0c^(NL7P+temPLLm5 zp6P1ly&8**z7DvFwaTu+<$$W7UAn)yPJA?BjuiD$-P&ByinGl{aK*I=BIKIZkxZ_u zpH*957vpXLyo2~blNhW67Y;Ll8T!+9!W%$Pr@7>Zah z8PK|55X+8Iub7|ES6#jZF6>$VbXaz}fa`LaDNQA^gxo?9#Z=&J4RXZMSZ@qAeVOhA zRyvp(L>Zj)$H-bRdWf8^sqm^TLRz>NFnO4%X-tfzt#_y*uL@^PuC0QZrLTy1ZQHX{ zr6Fp@v37DEJ4CxI?67#G&x>w<2M$LU1P9^~jxy;Y?9B8qZ+7Q-CsKy%V3M;ddvqMm z5l{pBvLm{HZ%8#M6cA;2l(vE}Bw5RFA_ncIS~}dWs@Rz^v4Q-7j_Se8mC9t&WO^y4r;NeF|`#hqR(CRMpP?B$~zk$}>adRnvWDmFmd&DjJa%kP{W_ zu-e4&VvX7f1Z5F^TuDv{8?Y|-GG^GMdGzeA+}`@Eu?dtE%)@$yepWuXtf0EH1u{|EkY>JKd>W^4Ja;Z=hVg!>k~#!9u0N) z=kEn8krWI&#S;Gl6F1ca`w4V&@@P33jivm{6m5P=sFUs)A#V+O=UUrJ8mb!{(PZM_ zLKfJ4$hzPV+l9T4N+#?BV%qRoqKtYGmjN3HSe~E&3j&)9M1#=O&%jnDMkw25xJSiE z)ub7uk7!3gww9SPwbm}Ug1b2)zRO9FUr_W@H!TXaGBQj`z8^Fk0IHU@iqTKofD|HVBK zWB%xBt7eo~%7LZNju60uDdX-RwruOHDki9I?7P-S!L1@$k;>z+*)`F79ui_3IENEc z!mD`VG#`#hv%mq+7)1=4vK&xyI_+HGX`SixE6koauf%GKrEzH1y(G~N0S$f_A)XiB z$ijjJ#U?u=JlzXsN%1_Tu7JnNq7tRoPO;B}z}}Qd0&6o?EQCJs*1%NK9M6LqZ5qPU z^s4$Pc7qHV(Zh@&#wsH8QyP7R!MX$ou<^(+*W!)q&39*QZ1Cy;sdBeGnIG+Goak1Y58?c1Z zG#(7fQL8LX%AVTtRJbFNvSd|)t;sH1vKnU{#vQPX7Qc2qwuNv=W^gE}E4PqGA^vZs zDbovs0*Er%2F8b8c;7-;ZwPfxzOdaE%AmOxtbH6Kxu_0)&t!>ic*PQy9PiqVotM%V zacIGa9Pj3Kg@FifVFB4janmFV!I-fgcq-udd!niielsvFb4S8SR2E{fYcLJrPL4## z-D6qI2;0iy9L80qMJEZYp~0*~CBf7q+=5fz;a)83PoQ&V6)owU>!_Vj%(kXfNK(+y zxY6P?o&q+7dP*|564Z|M4(XlN0oorZG2{IMbOG0Q=>W3;ZsG(o{veK6_BZXEN@I$` z5S^`Q6((LtR`3X>jV+aFYLg?da9bkE%jkXEkPeq>f%?+0JsB_d%;2mKOj2%n$1Jve zt0=JE+{puDJ9UC-XZ3RDF*_$bTgAcP+q1$=*pvIJIvWS2n;1+;o&wH2GfV|=GyoY; zC}5(glXHrMTy&K)H;jVFqbLbmgSa%}ltGQXQhk}+;la5KHXX`9u%2~xq>`dwMMnu; z9FBApkTJ(Hm)*Ed0b4w}g-HgqibS5_45WV&G>@Hfh!!Eh7tUOwWvR-zf(N?jxJjQa z>S`f9#Oe?lJ27p_#K~gjshvJ?(iFgv<7Iryn*b8zN7MpLR97sCk-g(2mricPhPs%^ z5W~v?oSN?RjEccFtnaHdp_C}4?O9=%1jKeCzsXjroCTj9fJCAb!0SF(fIQ%mt_YJj z9N43iqFzx2dN}qr-l7EUw?KrYa}i*Z>j?#*Av0LEj-?B3#*8k&+vF+Jr_@hLOq@Pl ziQBTGHeM)&E!ql$Vl@!=g?zIUSEVsdD6RsF%88kVn?brgSWDJz5Pok|!6|G39eJ_V z3M-H`%i$zw&B%24qP|Q%jysjj2xVEnb9e*tMAk8?fNO@<4M`4`5s+M%K5!VAsH>k? zKc}vk9&|DxvI&z7W7Ey5_D4=30h{K@(H3uRw9Bp(?rGxW$pt-I46|2da@r#dD`3Lz ztl5zOC=#-iUDe8zu(0HEuPiha4{I$PIE`Eu4h-F{Um#nSFA3bOdhRpL3IC$fdvPX_ zB*2$u^AKsGxNBp$w7k%_#`<>`1QwAp3G30ulmE~$r~L`o%K`$n;u;YLNZ%$0J_JuG zp<$9#G>h*T};DM@cR`mXGI=^_B`Ny!fmOzCtMg$<%m!3=x5biEyi*J&v zP{1AlwhJHRfyM!h{1j`q2P;KApu#NcbIRo@hrJ4$t?ULXieR50q^Jd0A6*NbKn2g1 zW!;E6iXTF55pGO^q~Ju^IU%1WJ4|&qg~U(q z7)()?z8ozHcP-1yekhi!_4hcEx3B>bK{8;s`+gAS;oF9Q16_ zA>$kXK2#aJ1adr_vM8H?OF|C7aXlnP8#WJi=O&>-X3@!+E<|FbhF3k+HCxZRxyx7p zm49VI_vh4a(La0o@-5IMvozQ844roWu_TVE)?=#`ooF_72OBPEc>J)T205^?$ zvE}g{Ff@j!lMCC4Z-5pOvE8!eKteoEv>Egx017#C3A37WsR7)QEfd@fS6VsH)j6eb z%@b|_iUEXtr^y6pUG$Nvj5-)5yxLOfJU2Y266a zxFeU}*?U+-YsD@Ez*NmbZl3d?b$K? z6yhLR_Dg*q2T|C8?5YS4(%zZ@{u~N>$wn75p7#n^$&tDrm~>uM=aEI=W0?B_^AHs}J_ z=|6_>Fg8f04Ng(`ei;;Wk&vyiEG#VZegf13pNlZm5Lp`Lu6>$_B*JPe0bvc}0t6OM zGuOIow1q3lA($JcKYPRw^RdI?{x`TJS0ko^l8#$NWU6BK!~&Q(YxWG>m+`Shh8aeP z4ZT1Pxn#5k)|3-oaAnLlZi?~1tWcQ7%|+HP2iSB zK~#`Q&P|FQZ-K<7xgvP^GN0!5*(r_YbM7L!HtG|Yj2Hm1WSvy( z1oT?#h!QD4XR>H#;)fK?2DR{tccc*!{UPJg(lLV?vlZ+7a6Ye2#w zwML7Jsu1bG1-c8nC2QXWuB6fSlpnbv;Jr*mu2Jj;k^0t^mME9iEB~)M!5MQ8ChVqymrbxnbMAG4eB+T9b`FP`qw!K;TFXcjZ2kj~Rq6Spwv~ zz?n7*9>mI!BCV6d%_`D?b=U+_pfB2Dq&%ns3q4vv1;tVo5EjMFT#0(6 zX|)fkp}0Y_Cbj%%O$Z%wJ1p9xn7X1B0QXK-(N38Gq)@DOkU{YrQzdf2b0fdm^T%i% zOT^-pAN^5+tyu=;)&cd?62rEkF+iB&ml)|Bi0cx>xr+nQo`MKRk;-Ilg~lNztkO5{ z^;c`HEyj@zC?Dyh;9`E{S3Ty9{2+RPi0Pt|QUFq=(TY4g5Xbfa|9vQMI@sV5%&CX}!7aL|&EC*4L5fjzQ=+U2e(IuKo7wP8E<*i8$ zTrN$(&e$V60Z@<=fexh3DRiT@R5-0Z+AjnlGON;j+gUO3;6(`u){p*MjCmI#A_9`y zki(HoB85caRj}nmr!>ukSXRlk06s#)Wu*O3yeD!4(j;{{_zy*ja!R7PZj%Xxx6`ST zU^J0dLf28EjghS~lu(Y^D^HG9g)31M4vIZoLmC^G269*-N`vlHxCk^*4+_pQ6n3nN zol1JZ6CB`ajfymfpSZE(Y60C|=x2#D+LCKrFNV{FGujSFb!T0WiX;8n)v}Xau@g{5 zt2o0}q$wLiD3UGVs+2-N9d04P!4=fP5o!i!j^$|1i1y0MDejz4D~K&G(qHtLM5o3P zTw8Ldo3pzl6YV`q18Ovz7p9`Qk&`k7p!DXBG4F&i68$c2myUU-TpHBiUU$)=63=%h zG$esjBB*QMnUJiHH$-Z|v>6t|E~H8Q8nUts??;h^|U

q4_+O$Rr-0X@pB+e_5T(|#~5QD)n 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 o()Po>PmG7S@)%ll -// +---------------------------------------------------------------------- - -// 测试入口文件 -$_SERVER['REQUEST_METHOD'] = 'GET'; -// 定义项目测试基础路径 -define('TEST_PATH', __DIR__ . '/'); -// 定义项目路径 -define('APP_PATH', __DIR__ . '/application/'); -// 加载框架基础文件 -require __DIR__ . '/../base.php'; -\think\Loader::addNamespace('tests', TEST_PATH); diff --git a/thinkphp/tests/script/install.sh b/thinkphp/tests/script/install.sh deleted file mode 100644 index 0adee7ed..00000000 --- a/thinkphp/tests/script/install.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -if [ $(phpenv version-name) != "hhvm" ]; then - cp tests/extensions/$(phpenv version-name)/*.so $(php-config --extension-dir) - - if [ $(phpenv version-name) = "7.0" ]; then - phpenv config-add tests/conf/apcu_bc.ini - else - phpenv config-add tests/conf/apcu.ini - fi - - phpenv config-add tests/conf/memcached.ini - phpenv config-add tests/conf/redis.ini - - phpenv config-add tests/conf/timezone.ini -fi - -composer install --no-interaction --ignore-platform-reqs diff --git a/thinkphp/tests/thinkphp/baseTest.php b/thinkphp/tests/thinkphp/baseTest.php deleted file mode 100644 index 18f1d3dd..00000000 --- a/thinkphp/tests/thinkphp/baseTest.php +++ /dev/null @@ -1,39 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * 保证运行环境正常 - */ -class baseTest extends \PHPUnit_Framework_TestCase -{ - public function testConstants() - { - $this->assertNotEmpty(THINK_START_TIME); - $this->assertNotEmpty(THINK_START_MEM); - $this->assertNotEmpty(THINK_VERSION); - $this->assertNotEmpty(DS); - $this->assertNotEmpty(THINK_PATH); - $this->assertNotEmpty(LIB_PATH); - $this->assertNotEmpty(EXTEND_PATH); - $this->assertNotEmpty(CORE_PATH); - $this->assertNotEmpty(TRAIT_PATH); - $this->assertNotEmpty(APP_PATH); - $this->assertNotEmpty(RUNTIME_PATH); - $this->assertNotEmpty(LOG_PATH); - $this->assertNotEmpty(CACHE_PATH); - $this->assertNotEmpty(TEMP_PATH); - $this->assertNotEmpty(VENDOR_PATH); - $this->assertNotEmpty(EXT); - $this->assertNotEmpty(ENV_PREFIX); - $this->assertTrue(!is_null(IS_WIN)); - $this->assertTrue(!is_null(IS_CLI)); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/appTest.php b/thinkphp/tests/thinkphp/library/think/appTest.php deleted file mode 100644 index 016bbf9c..00000000 --- a/thinkphp/tests/thinkphp/library/think/appTest.php +++ /dev/null @@ -1,90 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * app类测试 - * @author Haotong Lin - */ - -namespace tests\thinkphp\library\think; - -use think\App; -use think\Config; -use think\Request; - -function func_trim($value) -{ - return trim($value); -} - -function func_strpos($haystack, $needle) -{ - return strpos($haystack, $needle); -} - -class AppInvokeMethodTestClass -{ - public static function staticRun($string) - { - return $string; - } - - public function run($string) - { - return $string; - } -} - -class appTest extends \PHPUnit_Framework_TestCase -{ - public function testRun() - { - $response = App::run(Request::create("http://www.example.com")); - - $expectOutputString = '

'; - - $this->assertEquals($expectOutputString, $response->getContent()); - $this->assertEquals(200, $response->getCode()); - - $this->assertEquals(true, function_exists('lang')); - $this->assertEquals(true, function_exists('config')); - $this->assertEquals(true, function_exists('input')); - - $this->assertEquals(Config::get('default_timezone'), date_default_timezone_get()); - - } - - // function调度 - public function testInvokeFunction() - { - $args1 = ['a b c ']; - $this->assertEquals( - trim($args1[0]), - App::invokeFunction('tests\thinkphp\library\think\func_trim', $args1) - ); - - $args2 = ['abcdefg', 'g']; - $this->assertEquals( - strpos($args2[0], $args2[1]), - App::invokeFunction('tests\thinkphp\library\think\func_strpos', $args2) - ); - } - - // 类method调度 - public function testInvokeMethod() - { - $result = App::invokeMethod(['tests\thinkphp\library\think\AppInvokeMethodTestClass', 'run'], ['thinkphp']); - $this->assertEquals('thinkphp', $result); - - $result = App::invokeMethod('tests\thinkphp\library\think\AppInvokeMethodTestClass::staticRun', ['thinkphp']); - $this->assertEquals('thinkphp', $result); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/behavior/One.php b/thinkphp/tests/thinkphp/library/think/behavior/One.php deleted file mode 100644 index 1ec6e66e..00000000 --- a/thinkphp/tests/thinkphp/library/think/behavior/One.php +++ /dev/null @@ -1,15 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * build测试 - * @author 刘志淳 - */ - -namespace tests\thinkphp\library\think; - -use think\Build; - -class buildTest extends \PHPUnit_Framework_TestCase -{ - public function testRun() - { - $build = [ - // Test run directory - '__dir__' => ['runtime/cache', 'runtime/log', 'runtime/temp', 'runtime/template'], - '__file__' => ['common.php'], - - // Test generation module - 'demo' => [ - '__file__' => ['common.php'], - '__dir__' => ['behavior', 'controller', 'model', 'view', 'service'], - 'controller' => ['Index', 'Test', 'UserType'], - 'model' => ['User', 'UserType'], - 'service' => ['User', 'UserType'], - 'view' => ['index/index'], - ], - ]; - Build::run($build); - - $this->buildFileExists($build); - } - - protected function buildFileExists($build) - { - foreach ($build as $module => $list) { - if ('__dir__' == $module || '__file__' == $module) { - foreach ($list as $file) { - $this->assertFileExists(APP_PATH . $file); - } - } else { - foreach ($list as $path => $moduleList) { - if ('__file__' == $path || '__dir__' == $path) { - foreach ($moduleList as $file) { - $this->assertFileExists(APP_PATH . $module . '/' . $file); - } - } else { - foreach ($moduleList as $file) { - if ('view' == $path) { - $file_name = APP_PATH . $module . '/' . $path . '/' . $file . '.html'; - } else { - $file_name = APP_PATH . $module . '/' . $path . '/' . $file . EXT; - } - $this->assertFileExists($file_name); - } - } - } - $this->assertFileExists(APP_PATH . ($module ? $module . DS : '') . 'config.php'); - } - } - } -} diff --git a/thinkphp/tests/thinkphp/library/think/cache/driver/cacheTestCase.php b/thinkphp/tests/thinkphp/library/think/cache/driver/cacheTestCase.php deleted file mode 100644 index 5b2f2a3e..00000000 --- a/thinkphp/tests/thinkphp/library/think/cache/driver/cacheTestCase.php +++ /dev/null @@ -1,207 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * 缓存抽象类,提供一些测试 - * @author simon - */ - -namespace tests\thinkphp\library\think\cache\driver; - -use think\Cache; - -abstract class cacheTestCase extends \PHPUnit_Framework_TestCase -{ - - /** - * 获取缓存句柄,子类必须有 - * @access protected - */ - abstract protected function getCacheInstance(); - - /** - * tearDown函数 - */ - protected function tearDown() - { - } - - /** - * 设定一组测试值,包括测试字符串、整数、数组和对象 - * @return mixed - * @access public - */ - public function prepare() - { - $cache = $this->getCacheInstance(); - $cache->clear(); - $cache->set('string_test', 'string_test'); - $cache->set('number_test', 11); - $cache->set('array_test', ['array_test' => 'array_test']); - return $cache; - } - - /** - * 测试缓存设置,包括测试字符串、整数、数组和对象 - * @return mixed - * @access public - */ - public function testSet() - { - $cache = $this->getCacheInstance(); - $this->assertTrue($cache->set('string_test', 'string_test')); - $this->assertTrue($cache->set('number_test', 11)); - $this->assertTrue($cache->set('array_test', ['array_test' => 'array_test'])); - } - - /** - * 测试缓存自增 - * @return mixed - * @access public - */ - public function testInc() - { - $cache = $this->getCacheInstance(); - $this->assertEquals(14, $cache->inc('number_test', 3)); - } - - /** - * 测试缓存自减 - * @return mixed - * @access public - */ - public function testDec() - { - $cache = $this->getCacheInstance(); - $this->assertEquals(8, $cache->dec('number_test', 6)); - } - - /** - * 测试缓存读取,包括测试字符串、整数、数组和对象 - * @return mixed - * @access public - */ - public function testGet() - { - $cache = $this->prepare(); - $this->assertEquals('string_test', $cache->get('string_test')); - $this->assertEquals(11, $cache->get('number_test')); - $array = $cache->get('array_test'); - $this->assertArrayHasKey('array_test', $array); - $this->assertEquals('array_test', $array['array_test']); - - $result = $cache->set('no_expire', 1, 0); - $this->assertTrue($result); - } - - /** - * 测试缓存存在情况,包括测试字符串、整数、数组和对象 - * @return mixed - * @access public - */ - public function testExists() - { - $cache = $this->prepare(); - $this->assertNotEmpty($cache->has('string_test')); - $this->assertNotEmpty($cache->has('number_test')); - $this->assertFalse($cache->has('not_exists')); - } - - /** - * 测试缓存不存在情况,包括测试字符串、整数、数组和对象 - * @return mixed - * @access public - */ - public function testGetNonExistent() - { - $cache = $this->getCacheInstance(); - $this->assertFalse($cache->get('non_existent_key', false)); - } - - /** - * 测试特殊值缓存,包括测试字符串、整数、数组和对象 - * @return mixed - * @access public - */ - public function testStoreSpecialValues() - { - $cache = $this->getCacheInstance(); - $cache->set('null_value', null); - //清空缓存后,返回null而不是false - $this->assertTrue(is_null($cache->get('null_value'))); - } - - /** - * 缓存过期测试 - * @return mixed - * @access public - */ - public function testExpire() - { - $cache = $this->getCacheInstance(); - $this->assertTrue($cache->set('expire_test', 'expire_test', 1)); - usleep(600000); - $this->assertEquals('expire_test', $cache->get('expire_test')); - usleep(800000); - $this->assertFalse($cache->get('expire_test')); - } - - /** - * 删除缓存测试 - * @return mixed - * @access public - */ - public function testDelete() - { - $cache = $this->prepare(); - $this->assertNotNull($cache->rm('number_test')); - $this->assertFalse($cache->get('number_test')); - } - - /** - * 获取并删除缓存测试 - * @return mixed - * @access public - */ - public function testPull() - { - $cache = $this->prepare(); - $this->assertEquals(11, $cache->pull('number_test')); - $this->assertFalse($cache->get('number_test')); - } - - /** - * 清空缓存测试 - * @return mixed - * @access public - */ - public function testClear() - { - $cache = $this->prepare(); - $this->assertTrue($cache->clear()); - $this->assertFalse($cache->get('number_test')); - } - - public function testStaticCall() - { - $this->assertTrue(Cache::set('a', 1)); - $this->assertEquals(1, Cache::get('a')); - $this->assertEquals(2, Cache::inc('a')); - $this->assertEquals(4, Cache::inc('a', 2)); - $this->assertEquals(4, Cache::get('a')); - $this->assertEquals(3, Cache::dec('a')); - $this->assertEquals(1, Cache::dec('a', 2)); - $this->assertEquals(1, Cache::get('a')); - $this->assertNotNull(Cache::rm('a')); - $this->assertNotNull(Cache::clear()); - } - -} diff --git a/thinkphp/tests/thinkphp/library/think/cache/driver/fileTest.php b/thinkphp/tests/thinkphp/library/think/cache/driver/fileTest.php deleted file mode 100644 index eb2099ce..00000000 --- a/thinkphp/tests/thinkphp/library/think/cache/driver/fileTest.php +++ /dev/null @@ -1,46 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * File缓存驱动测试 - * @author 刘志淳 - */ - -namespace tests\thinkphp\library\think\cache\driver; - -class fileTest extends cacheTestCase -{ - private $_cacheInstance = null; - - /** - * 基境缓存类型 - */ - protected function setUp() - { - \think\Cache::connect(['type' => 'File', 'path' => CACHE_PATH]); - } - - /** - * @return FileCache - */ - protected function getCacheInstance() - { - if (null === $this->_cacheInstance) { - $this->_cacheInstance = new \think\cache\driver\File(); - } - return $this->_cacheInstance; - } - - // skip testExpire - public function testExpire() - { - } -} diff --git a/thinkphp/tests/thinkphp/library/think/cache/driver/liteTest.php b/thinkphp/tests/thinkphp/library/think/cache/driver/liteTest.php deleted file mode 100644 index 19cbb9ef..00000000 --- a/thinkphp/tests/thinkphp/library/think/cache/driver/liteTest.php +++ /dev/null @@ -1,69 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Lite缓存驱动测试 - * @author 刘志淳 - */ - -namespace tests\thinkphp\library\think\cache\driver; - -use think\Cache; - -class liteTest extends \PHPUnit_Framework_TestCase -{ - protected function getCacheInstance() - { - return Cache::connect(['type' => 'Lite', 'path' => CACHE_PATH]); - } - - /** - * 测试缓存读取 - * @return mixed - * @access public - */ - public function testGet() - { - $cache = $this->getCacheInstance(); - $this->assertFalse($cache->get('test')); - } - - /** - * 测试缓存设置 - * @return mixed - * @access public - */ - public function testSet() - { - $cache = $this->getCacheInstance(); - $this->assertNotEmpty($cache->set('test', 'test')); - } - - /** - * 删除缓存测试 - * @return mixed - * @access public - */ - public function testRm() - { - $cache = $this->getCacheInstance(); - $this->assertTrue($cache->rm('test')); - } - - /** - * 清空缓存测试 - * @return mixed - * @access public - */ - public function testClear() - { - } -} diff --git a/thinkphp/tests/thinkphp/library/think/cache/driver/memcacheTest.php b/thinkphp/tests/thinkphp/library/think/cache/driver/memcacheTest.php deleted file mode 100644 index 8975fa20..00000000 --- a/thinkphp/tests/thinkphp/library/think/cache/driver/memcacheTest.php +++ /dev/null @@ -1,49 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Memcache缓存驱动测试 - * @author 刘志淳 - */ - -namespace tests\thinkphp\library\think\cache\driver; - -class memcacheTest extends cacheTestCase -{ - private $_cacheInstance = null; - - /** - * 基境缓存类型 - */ - protected function setUp() - { - if (!extension_loaded('memcache')) { - $this->markTestSkipped("Memcache没有安装,已跳过测试!"); - } - \think\Cache::connect(['type' => 'memcache', 'expire' => 2]); - } - - /** - * @return ApcCache - */ - protected function getCacheInstance() - { - if (null === $this->_cacheInstance) { - $this->_cacheInstance = new \think\cache\driver\Memcache(['length' => 3]); - } - return $this->_cacheInstance; - } - - // skip testExpire - public function testExpire() - { - } -} diff --git a/thinkphp/tests/thinkphp/library/think/cache/driver/memcachedTest.php b/thinkphp/tests/thinkphp/library/think/cache/driver/memcachedTest.php deleted file mode 100644 index d528dd22..00000000 --- a/thinkphp/tests/thinkphp/library/think/cache/driver/memcachedTest.php +++ /dev/null @@ -1,72 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Memcached缓存驱动测试 - * @author 7IN0SAN9 - */ - -namespace tests\thinkphp\library\think\cache\driver; - -class memcachedTest extends cacheTestCase -{ - private $_cacheInstance = null; - /** - * 基境缓存类型 - */ - protected function setUp() - { - if (!extension_loaded("memcached") && !extension_loaded('memcache')) { - $this->markTestSkipped("Memcached或Memcache没有安装,已跳过测试!"); - } - \think\Cache::connect(array('type' => 'memcached', 'expire' => 2)); - } - /** - * @return ApcCache - */ - protected function getCacheInstance() - { - if (null === $this->_cacheInstance) { - $this->_cacheInstance = new \think\cache\driver\Memcached(['length' => 3]); - } - return $this->_cacheInstance; - } - /** - * 缓存过期测试《提出来测试,因为目前看通不过缓存过期测试,所以还需研究》 - * @return mixed - * @access public - */ - public function testExpire() - { - } - - public function testStaticCall() - { - } - - /** - * 测试缓存自增 - * @return mixed - * @access public - */ - public function testInc() - { - } - - /** - * 测试缓存自减 - * @return mixed - * @access public - */ - public function testDec() - { - } -} diff --git a/thinkphp/tests/thinkphp/library/think/cache/driver/redisTest.php b/thinkphp/tests/thinkphp/library/think/cache/driver/redisTest.php deleted file mode 100644 index 839e5165..00000000 --- a/thinkphp/tests/thinkphp/library/think/cache/driver/redisTest.php +++ /dev/null @@ -1,66 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Redis缓存驱动测试 - * @author 7IN0SAN9 - */ - -namespace tests\thinkphp\library\think\cache\driver; - -class redisTest extends cacheTestCase -{ - private $_cacheInstance = null; - - protected function setUp() - { - if (!extension_loaded("redis")) { - $this->markTestSkipped("Redis没有安装,已跳过测试!"); - } - \think\Cache::connect(array('type' => 'redis', 'expire' => 2)); - } - - protected function getCacheInstance() - { - if (null === $this->_cacheInstance) { - $this->_cacheInstance = new \think\cache\driver\Redis(['length' => 3]); - } - return $this->_cacheInstance; - } - - public function testGet() - { - $cache = $this->prepare(); - $this->assertEquals('string_test', $cache->get('string_test')); - $this->assertEquals(11, $cache->get('number_test')); - $result = $cache->get('array_test'); - $this->assertEquals('array_test', $result['array_test']); - } - - public function testStoreSpecialValues() - { - $redis = new \think\cache\driver\Redis(['length' => 3]); - $redis->set('key', 'value'); - $redis->get('key'); - - $redis->handler()->setnx('key', 'value'); - $value = $redis->handler()->get('key'); - $this->assertEquals('value', $value); - - $redis->handler()->hset('hash', 'key', 'value'); - $value = $redis->handler()->hget('hash', 'key'); - $this->assertEquals('value', $value); - } - - public function testExpire() - { - } -} diff --git a/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.ini b/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.ini deleted file mode 100644 index 2a17cc0d..00000000 --- a/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.ini +++ /dev/null @@ -1 +0,0 @@ -inifile=1 \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.json b/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.json deleted file mode 100644 index 716ed064..00000000 --- a/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.json +++ /dev/null @@ -1 +0,0 @@ -{"jsonstring":1} \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.xml b/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.xml deleted file mode 100644 index 3c3266a1..00000000 --- a/thinkphp/tests/thinkphp/library/think/config/driver/fixtures/config.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - 1 - - \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/config/driver/iniTest.php b/thinkphp/tests/thinkphp/library/think/config/driver/iniTest.php deleted file mode 100644 index 2575157c..00000000 --- a/thinkphp/tests/thinkphp/library/think/config/driver/iniTest.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Ini配置测试 - * @author 7IN0SAN9 - */ - -namespace tests\thinkphp\library\think\config\driver; - -use think\config; - -class iniTest extends \PHPUnit_Framework_TestCase -{ - public function testParse() - { - Config::parse('inistring=1', 'ini'); - $this->assertEquals(1, Config::get('inistring')); - Config::reset(); - Config::parse(__DIR__ . '/fixtures/config.ini'); - $this->assertTrue(Config::has('inifile')); - $this->assertEquals(1, Config::get('inifile')); - Config::reset(); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/config/driver/jsonTest.php b/thinkphp/tests/thinkphp/library/think/config/driver/jsonTest.php deleted file mode 100644 index 9d438d40..00000000 --- a/thinkphp/tests/thinkphp/library/think/config/driver/jsonTest.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Xml配置测试 - * @author 7IN0SAN9 - */ - -namespace tests\thinkphp\library\think\config\driver; - -use think\config; - -class jsonTest extends \PHPUnit_Framework_TestCase -{ - public function testParse() - { - Config::parse('{"jsonstring":1}', 'json'); - $this->assertEquals(1, Config::get('jsonstring')); - Config::reset(); - Config::parse(__DIR__ . '/fixtures/config.json'); - $this->assertTrue(Config::has('jsonstring')); - $this->assertEquals(1, Config::get('jsonstring')); - Config::reset(); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/config/driver/xmlTest.php b/thinkphp/tests/thinkphp/library/think/config/driver/xmlTest.php deleted file mode 100644 index 9ab1d257..00000000 --- a/thinkphp/tests/thinkphp/library/think/config/driver/xmlTest.php +++ /dev/null @@ -1,33 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Xml配置测试 - * @author 7IN0SAN9 - */ - -namespace tests\thinkphp\library\think\config\driver; - -use think\config; - -class xmlTest extends \PHPUnit_Framework_TestCase -{ - public function testParse() - { - Config::parse('1', 'xml'); - $this->assertEquals(1, Config::get('xmlstring')); - Config::reset(); - Config::parse(__DIR__ . '/fixtures/config.xml'); - $this->assertTrue(Config::has('xmlfile.istrue')); - $this->assertEquals(1, Config::get('xmlfile.istrue')); - Config::reset(); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/configTest.php b/thinkphp/tests/thinkphp/library/think/configTest.php deleted file mode 100644 index 166f0f8a..00000000 --- a/thinkphp/tests/thinkphp/library/think/configTest.php +++ /dev/null @@ -1,169 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * 配置测试 - * @author Haotong Lin - */ - -namespace tests\thinkphp\library\think; - -use ReflectionClass; -use think\Config; - -class configTest extends \PHPUnit_Framework_TestCase -{ - public function testRange() - { - $reflectedClass = new ReflectionClass('\think\Config'); - $reflectedPropertyRange = $reflectedClass->getProperty('range'); - $reflectedPropertyRange->setAccessible(true); - $reflectedPropertyConfig = $reflectedClass->getProperty('config'); - $reflectedPropertyConfig->setAccessible(true); - // test default range - $this->assertEquals('_sys_', $reflectedPropertyRange->getValue()); - $config = $reflectedPropertyConfig->getValue(); - $this->assertTrue(is_array($config)); - // test range initialization - Config::range('_test_'); - $this->assertEquals('_test_', $reflectedPropertyRange->getValue()); - $config = $reflectedPropertyConfig->getValue(); - $this->assertEquals([], $config['_test_']); - } - - // public function testParse() - // { - // see \think\config\driver\...Test.php - // } - - public function testLoad() - { - $file = APP_PATH . 'config' . EXT; - $config = array_change_key_case(include $file); - $name = '_name_'; - $range = '_test_'; - - $reflectedClass = new ReflectionClass('\think\Config'); - $reflectedPropertyConfig = $reflectedClass->getProperty('config'); - $reflectedPropertyConfig->setAccessible(true); - $reflectedPropertyConfig->setValue([]); - - $this->assertEquals($config, Config::load($file, $name, $range)); - $this->assertNotEquals(null, Config::load($file, $name, $range)); - } - - public function testHas() - { - $range = '_test_'; - $this->assertFalse(Config::has('abcd', $range)); - $reflectedClass = new ReflectionClass('\think\Config'); - $reflectedPropertyConfig = $reflectedClass->getProperty('config'); - $reflectedPropertyConfig->setAccessible(true); - - // if (!strpos($name, '.')): - $reflectedPropertyConfig->setValue([ - $range => ['abcd' => 'value'], - ]); - $this->assertTrue(Config::has('abcd', $range)); - - // else ... - $this->assertFalse(Config::has('abcd.efg', $range)); - - $reflectedPropertyConfig->setValue([ - $range => ['abcd' => ['efg' => 'value']], - ]); - $this->assertTrue(Config::has('abcd.efg', $range)); - } - - public function testGet() - { - $range = '_test_'; - $reflectedClass = new ReflectionClass('\think\Config'); - $reflectedPropertyConfig = $reflectedClass->getProperty('config'); - $reflectedPropertyConfig->setAccessible(true); - // test all configurations - $reflectedPropertyConfig->setValue([$range => []]); - $this->assertEquals([], Config::get(null, $range)); - $this->assertEquals(null, Config::get(null, 'does_not_exist')); - $value = 'value'; - // test getting configuration - $reflectedPropertyConfig->setValue([$range => ['abcd' => 'efg']]); - $this->assertEquals('efg', Config::get('abcd', $range)); - $this->assertEquals(null, Config::get('does_not_exist', $range)); - $this->assertEquals(null, Config::get('abcd', 'does_not_exist')); - // test getting configuration with dot syntax - $reflectedPropertyConfig->setValue([$range => [ - 'one' => ['two' => $value], - ]]); - $this->assertEquals($value, Config::get('one.two', $range)); - $this->assertEquals(null, Config::get('one.does_not_exist', $range)); - $this->assertEquals(null, Config::get('one.two', 'does_not_exist')); - } - - public function testSet() - { - $range = '_test_'; - $reflectedClass = new ReflectionClass('\think\Config'); - $reflectedPropertyConfig = $reflectedClass->getProperty('config'); - $reflectedPropertyConfig->setAccessible(true); - $reflectedPropertyConfig->setValue([]); - // if (is_string($name)): - // without dot syntax - $name = 'name'; - $value = 'value'; - Config::set($name, $value, $range); - $config = $reflectedPropertyConfig->getValue(); - $this->assertEquals($value, $config[$range][$name]); - // with dot syntax - $name = 'one.two'; - $value = 'dot value'; - Config::set($name, $value, $range); - $config = $reflectedPropertyConfig->getValue(); - $this->assertEquals($value, $config[$range]['one']['two']); - // if (is_array($name)): - // see testLoad() - // ... - // test getting all configurations...? - // return self::$config[$range]; ?? - $value = ['all' => 'configuration']; - $reflectedPropertyConfig->setValue([$range => $value]); - $this->assertEquals($value, Config::set(null, null, $range)); - $this->assertNotEquals(null, Config::set(null, null, $range)); - } - - public function testReset() - { - $range = '_test_'; - $reflectedClass = new ReflectionClass('\think\Config'); - $reflectedPropertyConfig = $reflectedClass->getProperty('config'); - $reflectedPropertyConfig->setAccessible(true); - $reflectedPropertyConfig->setValue([$range => ['abcd' => 'efg']]); - - // clear all configurations - Config::reset(true); - $config = $reflectedPropertyConfig->getValue(); - $this->assertEquals([], $config); - // clear the configuration in range of parameter. - $reflectedPropertyConfig->setValue([ - $range => [ - 'abcd' => 'efg', - 'hijk' => 'lmn', - ], - 'a' => 'b', - ]); - Config::reset($range); - $config = $reflectedPropertyConfig->getValue(); - $this->assertEquals([ - $range => [], - 'a' => 'b', - ], $config); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/controller/.gitignore b/thinkphp/tests/thinkphp/library/think/controller/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/thinkphp/tests/thinkphp/library/think/controller/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/controllerTest.php b/thinkphp/tests/thinkphp/library/think/controllerTest.php deleted file mode 100644 index fba8d6c5..00000000 --- a/thinkphp/tests/thinkphp/library/think/controllerTest.php +++ /dev/null @@ -1,194 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * 控制器测试 - * @author Haotong Lin - */ - -namespace tests\thinkphp\library\think; - -use ReflectionClass; -use think\Controller; -use think\Request; -use think\View; - -require_once CORE_PATH . '../../helper.php'; - -class Foo extends Controller -{ - public $test = 'test'; - - public function _initialize() - { - $this->test = 'abcd'; - } - - public function assignTest() - { - $this->assign('abcd', 'dcba'); - $this->assign(['key1' => 'value1', 'key2' => 'value2']); - } - - public function fetchTest() - { - $template = dirname(__FILE__) . '/display.html'; - return $this->fetch($template, ['name' => 'ThinkPHP']); - } - - public function displayTest() - { - $template = dirname(__FILE__) . '/display.html'; - return $this->display($template, ['name' => 'ThinkPHP']); - } - public function test() - { - $data = [ - 'username' => 'username', - 'nickname' => 'nickname', - 'password' => '123456', - 'repassword' => '123456', - 'email' => 'abc@abc.com', - 'sex' => '0', - 'age' => '20', - 'code' => '1234', - ]; - - $validate = [ - ['username', 'length:5,15', '用户名长度为5到15个字符'], - ['nickname', 'require', '请填昵称'], - ['password', '[\w-]{6,15}', '密码长度为6到15个字符'], - ['repassword', 'confirm:password', '两次密码不一到致'], - ['email', 'filter:validate_email', '邮箱格式错误'], - ['sex', 'in:0,1', '性别只能为为男或女'], - ['age', 'between:1,80', '年龄只能在10-80之间'], - ]; - return $this->validate($data, $validate); - } -} - -class Bar extends Controller -{ - public $test = 1; - - public $beforeActionList = ['action1', 'action2']; - - public function action1() - { - $this->test += 2; - return 'action1'; - } - - public function action2() - { - $this->test += 4; - return 'action2'; - } -} - -class Baz extends Controller -{ - public $test = 1; - - public $beforeActionList = [ - 'action1' => ['only' => 'index'], - 'action2' => ['except' => 'index'], - 'action3' => ['only' => 'abcd'], - 'action4' => ['except' => 'abcd'], - ]; - - public function action1() - { - $this->test += 2; - return 'action1'; - } - - public function action2() - { - $this->test += 4; - return 'action2'; - } - - public function action3() - { - $this->test += 8; - return 'action2'; - } - - public function action4() - { - $this->test += 16; - return 'action2'; - } -} - -class controllerTest extends \PHPUnit_Framework_TestCase -{ - public function testInitialize() - { - $foo = new Foo(Request::instance()); - $this->assertEquals('abcd', $foo->test); - } - - public function testBeforeAction() - { - $obj = new Bar(Request::instance()); - $this->assertEquals(7, $obj->test); - - $obj = new Baz(Request::instance()); - $this->assertEquals(19, $obj->test); - } - - private function getView($controller) - { - $view = new View(); - $rc = new ReflectionClass(get_class($controller)); - $property = $rc->getProperty('view'); - $property->setAccessible(true); - $property->setValue($controller, $view); - return $view; - } - - public function testFetch() - { - $controller = new Foo(Request::instance()); - $view = $this->getView($controller); - $template = dirname(__FILE__) . '/display.html'; - $viewFetch = $view->fetch($template, ['name' => 'ThinkPHP']); - $this->assertEquals($controller->fetchTest(), $viewFetch); - } - - public function testDisplay() - { - $controller = new Foo; - $view = $this->getView($controller); - $template = dirname(__FILE__) . '/display.html'; - $viewFetch = $view->display($template, ['name' => 'ThinkPHP']); - - $this->assertEquals($controller->displayTest(), $viewFetch); - } - - public function testAssign() - { - $controller = new Foo(Request::instance()); - $view = $this->getView($controller); - $controller->assignTest(); - $expect = ['abcd' => 'dcba', 'key1' => 'value1', 'key2' => 'value2']; - $this->assertAttributeEquals($expect, 'data', $view); - } - - public function testValidate() - { - $controller = new Foo(Request::instance()); - $result = $controller->test(); - $this->assertTrue($result); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/cookieTest.php b/thinkphp/tests/thinkphp/library/think/cookieTest.php deleted file mode 100644 index 24cb153e..00000000 --- a/thinkphp/tests/thinkphp/library/think/cookieTest.php +++ /dev/null @@ -1,150 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Cookie测试 - * @author Haotong Lin - */ - -namespace tests\thinkphp\library\think; - -use ReflectionClass; -use think\Cookie; - -class cookieTest extends \PHPUnit_Framework_TestCase -{ - protected $ref; - - protected $default = [ - // cookie 名称前缀 - 'prefix' => '', - // cookie 保存时间 - 'expire' => 0, - // cookie 保存路径 - 'path' => '/', - // cookie 有效域名 - 'domain' => '', - // cookie 启用安全传输 - 'secure' => false, - // httponly设置 - 'httponly' => '', - // 是否使用 setcookie - 'setcookie' => false, - ]; - - protected function setUp() - { - $reflectedClass = new ReflectionClass('\think\Cookie'); - $reflectedPropertyConfig = $reflectedClass->getProperty('config'); - $reflectedPropertyConfig->setAccessible(true); - $reflectedPropertyConfig->setValue($this->default); - $this->ref = $reflectedPropertyConfig; - } - - public function testInit() - { - $config = [ - // cookie 名称前缀 - 'prefix' => 'think_', - // cookie 保存时间 - 'expire' => 0, - // cookie 保存路径 - 'path' => '/path/to/test/', - // cookie 有效域名 - 'domain' => '.thinkphp.cn', - // cookie 启用安全传输 - 'secure' => true, - // httponly设置 - 'httponly' => '1', - ]; - Cookie::init($config); - - $this->assertEquals( - array_merge($this->default, array_change_key_case($config)), - $this->ref->getValue() - ); - } - - public function testPrefix() - { - $this->assertEquals($this->default['prefix'], Cookie::prefix()); - - $prefix = '_test_'; - $this->assertNotEquals($prefix, Cookie::prefix()); - Cookie::prefix($prefix); - - $config = $this->ref->getValue(); - $this->assertEquals($prefix, $config['prefix']); - } - - public function testSet() - { - $value = 'value'; - - $name = 'name1'; - Cookie::set($name, $value, 10); - $this->assertEquals($value, $_COOKIE[$this->default['prefix'] . $name]); - - $name = 'name2'; - Cookie::set($name, $value, null); - $this->assertEquals($value, $_COOKIE[$this->default['prefix'] . $name]); - - $name = 'name3'; - Cookie::set($name, $value, 'expire=100&prefix=pre_'); - $this->assertEquals($value, $_COOKIE['pre_' . $name]); - - $name = 'name4'; - $value = ['_test_中文_']; - Cookie::set($name, $value); - $this->assertEquals('think:' . json_encode([urlencode('_test_中文_')]), $_COOKIE[$name]); - } - - public function testGet() - { - $_COOKIE = [ - 'a' => 'b', - 'pre_abc' => 'c', - 'd' => 'think:' . json_encode([urlencode('_test_中文_')]), - ]; - $this->assertEquals('b', Cookie::get('a')); - $this->assertEquals(null, Cookie::get('does_not_exist')); - $this->assertEquals('c', Cookie::get('abc', 'pre_')); - $this->assertEquals(['_test_中文_'], Cookie::get('d')); - } - - public function testDelete() - { - $_COOKIE = [ - 'a' => 'b', - 'pre_abc' => 'c', - ]; - $this->assertEquals('b', Cookie::get('a')); - Cookie::delete('a'); - $this->assertEquals(null, Cookie::get('a')); - - $this->assertEquals('c', Cookie::get('abc', 'pre_')); - Cookie::delete('abc', 'pre_'); - $this->assertEquals(null, Cookie::get('abc', 'pre_')); - } - - public function testClear() - { - $_COOKIE = []; - $this->assertEquals(null, Cookie::clear()); - - $_COOKIE = [ - 'a' => 'b', - 'pre_abc' => 'c', - ]; - Cookie::clear('pre_'); - $this->assertEquals(['a' => 'b'], $_COOKIE); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/db/driver/.gitignore b/thinkphp/tests/thinkphp/library/think/db/driver/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/thinkphp/tests/thinkphp/library/think/db/driver/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/dbTest.php b/thinkphp/tests/thinkphp/library/think/dbTest.php deleted file mode 100644 index 5724ee21..00000000 --- a/thinkphp/tests/thinkphp/library/think/dbTest.php +++ /dev/null @@ -1,352 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Db类测试 - * @author: 刘志淳 - */ - -namespace tests\thinkphp\library\think; - -use think\Db; - -class dbTest extends \PHPUnit_Framework_TestCase -{ - // 获取测试数据库配置 - private function getConfig() - { - return [ - // 数据库类型 - 'type' => 'mysql', - // 服务器地址 - 'hostname' => '127.0.0.1', - // 数据库名 - 'database' => 'test', - // 用户名 - 'username' => 'root', - // 密码 - 'password' => '', - // 端口 - 'hostport' => '', - // 连接dsn - 'dsn' => '', - // 数据库连接参数 - 'params' => [], - // 数据库编码默认采用utf8 - 'charset' => 'utf8', - // 数据库表前缀 - 'prefix' => 'tp_', - // 数据库调试模式 - 'debug' => true, - // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) - 'deploy' => 0, - // 数据库读写是否分离 主从式有效 - 'rw_separate' => false, - // 读写分离后 主服务器数量 - 'master_num' => 1, - // 指定从服务器序号 - 'slave_no' => '', - // 是否严格检查字段是否存在 - 'fields_strict' => true, - // 数据集返回类型 array 数组 collection Collection对象 - 'resultset_type' => 'array', - // 是否自动写入时间戳字段 - 'auto_timestamp' => false, - // 是否需要进行SQL性能分析 - 'sql_explain' => false, - ]; - } - - // 获取创建数据库 SQL - private function getCreateTableSql() - { - $sql[] = <<getConfig(); - $result = Db::connect($config)->execute('show databases'); - $this->assertNotEmpty($result); - } - - public function testExecute() - { - $config = $this->getConfig(); - $sql = $this->getCreateTableSql(); - foreach ($sql as $one) { - Db::connect($config)->execute($one); - } - $tableNum = Db::connect($config)->execute("show tables;"); - $this->assertEquals(4, $tableNum); - } - - public function testQuery() - { - $config = $this->getConfig(); - $sql = $this->getCreateTableSql(); - Db::connect($config)->batchQuery($sql); - - $tableQueryResult = Db::connect($config)->query("show tables;"); - - $this->assertTrue(is_array($tableQueryResult)); - - $tableNum = count($tableQueryResult); - $this->assertEquals(4, $tableNum); - } - - public function testBatchQuery() - { - $config = $this->getConfig(); - $sql = $this->getCreateTableSql(); - Db::connect($config)->batchQuery($sql); - - $tableNum = Db::connect($config)->execute("show tables;"); - $this->assertEquals(4, $tableNum); - } - - public function testTable() - { - $config = $this->getConfig(); - $tableName = 'tp_user'; - $result = Db::connect($config)->table($tableName); - $this->assertEquals($tableName, $result->getOptions()['table']); - } - - public function testName() - { - $config = $this->getConfig(); - $tableName = 'user'; - $result = Db::connect($config)->name($tableName); - $this->assertEquals($config['prefix'] . $tableName, $result->getTable()); - } - - public function testInsert() - { - $config = $this->getConfig(); - $data = [ - 'username' => 'chunice', - 'password' => md5('chunice'), - 'status' => 1, - 'create_time' => time(), - ]; - $result = Db::connect($config)->name('user')->insert($data); - $this->assertEquals(1, $result); - } - - public function testUpdate() - { - $config = $this->getConfig(); - $data = [ - 'username' => 'chunice_update', - 'password' => md5('chunice'), - 'status' => 1, - 'create_time' => time(), - ]; - $result = Db::connect($config)->name('user')->where('username', 'chunice')->update($data); - $this->assertEquals(1, $result); - } - - public function testFind() - { - $config = $this->getConfig(); - $mustFind = Db::connect($config)->name('user')->where('username', 'chunice_update')->find(); - $this->assertNotEmpty($mustFind); - $mustNotFind = Db::connect($config)->name('user')->where('username', 'chunice')->find(); - $this->assertEmpty($mustNotFind); - } - - public function testInsertAll() - { - $config = $this->getConfig(); - - $data = [ - ['username' => 'foo', 'password' => md5('foo'), 'status' => 1, 'create_time' => time()], - ['username' => 'bar', 'password' => md5('bar'), 'status' => 1, 'create_time' => time()], - ]; - - $insertNum = Db::connect($config)->name('user')->insertAll($data); - $this->assertEquals(count($data), $insertNum); - } - - public function testSelect() - { - $config = $this->getConfig(); - $mustFound = Db::connect($config)->name('user')->where('status', 1)->select(); - $this->assertNotEmpty($mustFound); - $mustNotFound = Db::connect($config)->name('user')->where('status', 0)->select(); - $this->assertEmpty($mustNotFound); - } - - public function testValue() - { - $config = $this->getConfig(); - $username = Db::connect($config)->name('user')->where('id', 1)->value('username'); - $this->assertEquals('chunice_update', $username); - $usernameNull = Db::connect($config)->name('user')->where('id', 0)->value('username'); - $this->assertEmpty($usernameNull); - } - - public function testColumn() - { - $config = $this->getConfig(); - $username = Db::connect($config)->name('user')->where('status', 1)->column('username'); - $this->assertNotEmpty($username); - $usernameNull = Db::connect($config)->name('user')->where('status', 0)->column('username'); - $this->assertEmpty($usernameNull); - - } - - public function testInsertGetId() - { - $config = $this->getConfig(); - $id = Db::connect($config)->name('user')->order('id', 'desc')->value('id'); - - $data = [ - 'username' => uniqid(), - 'password' => md5('chunice'), - 'status' => 1, - 'create_time' => time(), - ]; - $lastId = Db::connect($config)->name('user')->insertGetId($data); - $this->assertEquals($id + 1, $lastId); - - } - - public function testGetLastInsId() - { - $config = $this->getConfig(); - $data = [ - 'username' => uniqid(), - 'password' => md5('chunice'), - 'status' => 1, - 'create_time' => time(), - ]; - $lastId = Db::connect($config)->name('user')->insertGetId($data); - - $lastInsId = Db::connect($config)->name('user')->getLastInsID(); - $this->assertEquals($lastId, $lastInsId); - } - - public function testSetField() - { - $config = $this->getConfig(); - - $setFieldNum = Db::connect($config)->name('user')->where('id', 1)->setField('username', 'chunice_setField'); - $this->assertEquals(1, $setFieldNum); - - $setFieldNum = Db::connect($config)->name('user')->where('id', 1)->setField('username', 'chunice_setField'); - $this->assertEquals(0, $setFieldNum); - } - - public function testSetInc() - { - $config = $this->getConfig(); - $originCreateTime = Db::connect($config)->name('user')->where('id', 1)->value('create_time'); - Db::connect($config)->name('user')->where('id', 1)->setInc('create_time'); - $newCreateTime = Db::connect($config)->name('user')->where('id', 1)->value('create_time'); - $this->assertEquals($originCreateTime + 1, $newCreateTime); - - } - - public function testSetDec() - { - $config = $this->getConfig(); - $originCreateTime = Db::connect($config)->name('user')->where('id', 1)->value('create_time'); - Db::connect($config)->name('user')->where('id', 1)->setDec('create_time'); - $newCreateTime = Db::connect($config)->name('user')->where('id', 1)->value('create_time'); - $this->assertEquals($originCreateTime - 1, $newCreateTime); - } - - public function testDelete() - { - $config = $this->getConfig(); - Db::connect($config)->name('user')->where('id', 1)->delete(); - $result = Db::connect($config)->name('user')->where('id', 1)->find(); - $this->assertEmpty($result); - } - - public function testChunk() - { - // todo 暂未想到测试方法 - } - - public function testCache() - { - $config = $this->getConfig(); - $result = Db::connect($config)->name('user')->where('id', 1)->cache('key', 60)->find(); - $cache = \think\Cache::get('key'); - $this->assertEquals($result, $cache); - - $updateCache = Db::connect($config)->name('user')->cache('key')->find(1); - $this->assertEquals($cache, $updateCache); - } - -} diff --git a/thinkphp/tests/thinkphp/library/think/debugTest.php b/thinkphp/tests/thinkphp/library/think/debugTest.php deleted file mode 100644 index fc2fdd47..00000000 --- a/thinkphp/tests/thinkphp/library/think/debugTest.php +++ /dev/null @@ -1,179 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Debug测试 - * @author 大漠 - */ - -namespace tests\thinkphp\library\think; - -use think\Debug; - -class debugTest extends \PHPUnit_Framework_TestCase -{ - - /** - * - * @var Debug - */ - protected $object; - - /** - * Sets up the fixture, for example, opens a network connection. - * This method is called before a test is executed. - */ - protected function setUp() - { - $this->object = new Debug(); - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown() - {} - - /** - * @covers think\Debug::remark - * @todo Implement testRemark(). - */ - public function testRemark() - { - $name = "testremarkkey"; - Debug::remark($name); - } - - /** - * @covers think\Debug::getRangeTime - * @todo Implement testGetRangeTime(). - */ - public function testGetRangeTime() - { - $start = "testGetRangeTimeStart"; - $end = "testGetRangeTimeEnd"; - Debug::remark($start); - usleep(20000); - // \think\Debug::remark($end); - - $time = Debug::getRangeTime($start, $end); - $this->assertLessThan(0.03, $time); - //$this->assertEquals(0.03, ceil($time)); - } - - /** - * @covers think\Debug::getUseTime - * @todo Implement testGetUseTime(). - */ - public function testGetUseTime() - { - $time = Debug::getUseTime(); - $this->assertLessThan(20, $time); - } - - /** - * @covers think\Debug::getThroughputRate - * @todo Implement testGetThroughputRate(). - */ - public function testGetThroughputRate() - { - usleep(100000); - $throughputRate = Debug::getThroughputRate(); - $this->assertLessThan(10, $throughputRate); - } - - /** - * @covers think\Debug::getRangeMem - * @todo Implement testGetRangeMem(). - */ - public function testGetRangeMem() - { - $start = "testGetRangeMemStart"; - $end = "testGetRangeMemEnd"; - Debug::remark($start); - $str = ""; - for ($i = 0; $i < 10000; $i++) { - $str .= "mem"; - } - - $rangeMem = Debug::getRangeMem($start, $end); - - $this->assertLessThan(33, explode(" ", $rangeMem)[0]); - } - - /** - * @covers think\Debug::getUseMem - * @todo Implement testGetUseMem(). - */ - public function testGetUseMem() - { - $useMem = Debug::getUseMem(); - - $this->assertLessThan(35, explode(" ", $useMem)[0]); - } - - /** - * @covers think\Debug::getMemPeak - * @todo Implement testGetMemPeak(). - */ - public function testGetMemPeak() - { - $start = "testGetMemPeakStart"; - $end = "testGetMemPeakEnd"; - Debug::remark($start); - $str = ""; - for ($i = 0; $i < 100000; $i++) { - $str .= "mem"; - } - $memPeak = Debug::getMemPeak($start, $end); - $this->assertLessThan(500, explode(" ", $memPeak)[0]); - } - - /** - * @covers think\Debug::getFile - * @todo Implement testGetFile(). - */ - public function testGetFile() - { - $count = Debug::getFile(); - - $this->assertEquals(count(get_included_files()), $count); - - $info = Debug::getFile(true); - $this->assertEquals(count(get_included_files()), count($info)); - - $this->assertContains("KB", $info[0]); - } - - /** - * @covers think\Debug::dump - * @todo Implement testDump(). - */ - public function testDump() - { - if (strstr(PHP_VERSION, 'hhvm')) { - return; - } - - $var = []; - $var["key"] = "val"; - $output = Debug::dump($var, false, $label = "label"); - $array = explode("array", json_encode($output)); - if (IS_WIN) { - $this->assertEquals("(1) {\\n [\\\"key\\\"] => string(3) \\\"val\\\"\\n}\\n\\r\\n\"", end($array)); - } elseif (strstr(PHP_OS, 'Darwin')) { - $this->assertEquals("(1) {\\n [\\\"key\\\"] => string(3) \\\"val\\\"\\n}\\n\\n\"", end($array)); - } else { - $this->assertEquals("(1) {\\n 'key' =>\\n string(3) \\\"val\\\"\\n}\\n\\n\"", end($array)); - } - } -} diff --git a/thinkphp/tests/thinkphp/library/think/display.html b/thinkphp/tests/thinkphp/library/think/display.html deleted file mode 100644 index e99d3025..00000000 --- a/thinkphp/tests/thinkphp/library/think/display.html +++ /dev/null @@ -1 +0,0 @@ -{$name??'default'} \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/exceptionTest.php b/thinkphp/tests/thinkphp/library/think/exceptionTest.php deleted file mode 100644 index 66957ce6..00000000 --- a/thinkphp/tests/thinkphp/library/think/exceptionTest.php +++ /dev/null @@ -1,52 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * exception类测试 - * @author Haotong Lin - */ - -namespace tests\thinkphp\library\think; - -use ReflectionMethod; -use think\Exception as ThinkException; -use think\exception\HttpException; - -class MyException extends ThinkException -{ - -} - -class exceptionTest extends \PHPUnit_Framework_TestCase -{ - public function testGetHttpStatus() - { - try { - throw new HttpException(404, "Error Processing Request"); - } catch (HttpException $e) { - $this->assertEquals(404, $e->getStatusCode()); - } - } - - public function testDebugData() - { - $data = ['a' => 'b', 'c' => 'd']; - try { - $e = new MyException("Error Processing Request", 1); - $method = new ReflectionMethod($e, 'setData'); - $method->setAccessible(true); - $method->invokeArgs($e, ['test', $data]); - throw $e; - } catch (MyException $e) { - $this->assertEquals(['test' => $data], $e->getData()); - } - } -} diff --git a/thinkphp/tests/thinkphp/library/think/extend.html b/thinkphp/tests/thinkphp/library/think/extend.html deleted file mode 100644 index 922192dc..00000000 --- a/thinkphp/tests/thinkphp/library/think/extend.html +++ /dev/null @@ -1,2 +0,0 @@ -{extend name="extend2" /} -{block name="head"}header{/block} \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/extend2.html b/thinkphp/tests/thinkphp/library/think/extend2.html deleted file mode 100644 index eb22e1da..00000000 --- a/thinkphp/tests/thinkphp/library/think/extend2.html +++ /dev/null @@ -1,17 +0,0 @@ -{layout name="layout2" replace="[__REPLACE__]" /} -{block name="head"}{/block} -
- {include file="include" name="info" value="$info.value" /} -{block name="main"} -{block name="side"} - side -{/block} -{block name="mainbody"} - -{/block} -{/block} -{literal} - {$name} -{/literal} - -
\ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/hookTest.php b/thinkphp/tests/thinkphp/library/think/hookTest.php deleted file mode 100644 index 930ecf53..00000000 --- a/thinkphp/tests/thinkphp/library/think/hookTest.php +++ /dev/null @@ -1,67 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Hook类测试 - * @author liu21st - */ - -namespace tests\thinkphp\library\think; - -use think\Hook; - -class hookTest extends \PHPUnit_Framework_TestCase -{ - - public function testRun() - { - Hook::add('my_pos', '\tests\thinkphp\library\think\behavior\One'); - Hook::add('my_pos', ['\tests\thinkphp\library\think\behavior\Two']); - Hook::add('my_pos', '\tests\thinkphp\library\think\behavior\Three', true); - $data['id'] = 0; - $data['name'] = 'thinkphp'; - Hook::listen('my_pos', $data); - $this->assertEquals(2, $data['id']); - $this->assertEquals('thinkphp', $data['name']); - $this->assertEquals([ - '\tests\thinkphp\library\think\behavior\Three', - '\tests\thinkphp\library\think\behavior\One', - '\tests\thinkphp\library\think\behavior\Two'], - Hook::get('my_pos')); - } - - public function testImport() - { - Hook::import(['my_pos' => [ - '\tests\thinkphp\library\think\behavior\One', - '\tests\thinkphp\library\think\behavior\Three'], - ]); - Hook::import(['my_pos' => ['\tests\thinkphp\library\think\behavior\Two']], false); - Hook::import(['my_pos' => ['\tests\thinkphp\library\think\behavior\Three', '_overlay' => true]]); - $data['id'] = 0; - $data['name'] = 'thinkphp'; - Hook::listen('my_pos', $data); - $this->assertEquals(3, $data['id']); - - } - - public function testExec() - { - $data['id'] = 0; - $data['name'] = 'thinkphp'; - $this->assertEquals(true, Hook::exec('\tests\thinkphp\library\think\behavior\One')); - $this->assertEquals(false, Hook::exec('\tests\thinkphp\library\think\behavior\One', 'test', $data)); - $this->assertEquals('test', $data['name']); - $this->assertEquals('Closure', Hook::exec(function (&$data) {$data['name'] = 'Closure';return 'Closure';})); - - } - -} diff --git a/thinkphp/tests/thinkphp/library/think/include.html b/thinkphp/tests/thinkphp/library/think/include.html deleted file mode 100644 index e01ae9ef..00000000 --- a/thinkphp/tests/thinkphp/library/think/include.html +++ /dev/null @@ -1,2 +0,0 @@ - -{include file="include2" /} \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/include2.html b/thinkphp/tests/thinkphp/library/think/include2.html deleted file mode 100644 index 24bdacb3..00000000 --- a/thinkphp/tests/thinkphp/library/think/include2.html +++ /dev/null @@ -1 +0,0 @@ -{$info.value}: \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/lang/lang.php b/thinkphp/tests/thinkphp/library/think/lang/lang.php deleted file mode 100644 index 96880b15..00000000 --- a/thinkphp/tests/thinkphp/library/think/lang/lang.php +++ /dev/null @@ -1,4 +0,0 @@ -'加载', -]; diff --git a/thinkphp/tests/thinkphp/library/think/langTest.php b/thinkphp/tests/thinkphp/library/think/langTest.php deleted file mode 100644 index 360ee43d..00000000 --- a/thinkphp/tests/thinkphp/library/think/langTest.php +++ /dev/null @@ -1,76 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Lang测试 - * @author liu21st - */ - -namespace tests\thinkphp\library\think; - -use think\Config; -use think\Lang; - -class langTest extends \PHPUnit_Framework_TestCase -{ - - public function testSetAndGet() - { - Lang::set('hello,%s', '欢迎,%s'); - $this->assertEquals('欢迎,ThinkPHP', Lang::get('hello,%s', ['ThinkPHP'])); - Lang::set('hello,%s', '歡迎,%s', 'zh-tw'); - $this->assertEquals('歡迎,ThinkPHP', Lang::get('hello,%s', ['ThinkPHP'], 'zh-tw')); - Lang::set(['hello' => '欢迎', 'use' => '使用']); - $this->assertEquals('欢迎', Lang::get('hello')); - $this->assertEquals('欢迎', Lang::get('HELLO')); - $this->assertEquals('使用', Lang::get('use')); - - Lang::set('hello,{:name}', '欢迎,{:name}'); - $this->assertEquals('欢迎,liu21st', Lang::get('hello,{:name}', ['name' => 'liu21st'])); - } - - public function testLoad() - { - Lang::load(__DIR__ . DS . 'lang' . DS . 'lang.php'); - $this->assertEquals('加载', Lang::get('load')); - Lang::load(__DIR__ . DS . 'lang' . DS . 'lang.php', 'test'); - $this->assertEquals('加载', Lang::get('load', [], 'test')); - } - - public function testDetect() - { - - Config::set('lang_list', ['zh-cn', 'zh-tw']); - Lang::set('hello', '欢迎', 'zh-cn'); - Lang::set('hello', '歡迎', 'zh-tw'); - - Config::set('lang_detect_var', 'lang'); - Config::set('lang_cookie_var', 'think_cookie'); - - $_GET['lang'] = 'zh-tw'; - Lang::detect(); - $this->assertEquals('歡迎', Lang::get('hello')); - - $_GET['lang'] = 'zh-cn'; - Lang::detect(); - $this->assertEquals('欢迎', Lang::get('hello')); - - } - - public function testRange() - { - $this->assertEquals('zh-cn', Lang::range()); - Lang::set('hello', '欢迎', 'test'); - Lang::range('test'); - $this->assertEquals('test', Lang::range()); - $this->assertEquals('欢迎', Lang::get('hello')); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/layout.html b/thinkphp/tests/thinkphp/library/think/layout.html deleted file mode 100644 index be8d4a07..00000000 --- a/thinkphp/tests/thinkphp/library/think/layout.html +++ /dev/null @@ -1,2 +0,0 @@ -
{__CONTENT__} -
\ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/layout2.html b/thinkphp/tests/thinkphp/library/think/layout2.html deleted file mode 100644 index a5b75729..00000000 --- a/thinkphp/tests/thinkphp/library/think/layout2.html +++ /dev/null @@ -1,2 +0,0 @@ - \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/loader/test/Hello.php b/thinkphp/tests/thinkphp/library/think/loader/test/Hello.php deleted file mode 100644 index c1414561..00000000 --- a/thinkphp/tests/thinkphp/library/think/loader/test/Hello.php +++ /dev/null @@ -1,7 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Loader测试 - * @author liu21st - */ - -namespace tests\thinkphp\library\think; - -use think\Loader; - -class loaderTest extends \PHPUnit_Framework_TestCase -{ - - public function testAutoload() - { - $this->assertEquals(false, Loader::autoload('\think\Url')); - $this->assertEquals(false, Loader::autoload('think\Test')); - $this->assertEquals(false, Loader::autoload('my\HelloTest')); - } - - public function testAddClassMap() - { - Loader::addClassMap('my\hello\Test', __DIR__ . DS . 'loader' . DS . 'Test.php'); - } - - public function testAddNamespace() - { - Loader::addNamespace('top', __DIR__ . DS . 'loader' . DS); - $this->assertEquals(true, Loader::autoload('top\test\Hello')); - } - - public function testAddNamespaceAlias() - { - Loader::addNamespaceAlias('top', 'top\test'); - Loader::addNamespaceAlias(['top' => 'top\test', 'app' => 'app\index']); - //$this->assertEquals(true, Loader::autoload('top\Hello')); - } - - public function testTable() - { - Loader::db('mysql://root@127.0.0.1/test#utf8'); - } - - public function testImport() - { - $this->assertEquals(false, Loader::import('think.log.driver.MyTest')); - } - - public function testParseName() - { - $this->assertEquals('HelloTest', Loader::parseName('hello_test', 1)); - $this->assertEquals('hello_test', Loader::parseName('HelloTest', 0)); - } - - public function testParseClass() - { - $this->assertEquals('app\index\controller\User', Loader::parseClass('index', 'controller', 'user')); - $this->assertEquals('app\index\controller\user\Type', Loader::parseClass('index', 'controller', 'user.type')); - $this->assertEquals('app\admin\model\UserType', Loader::parseClass('admin', 'model', 'user_type')); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/log/driver/fileTest.php b/thinkphp/tests/thinkphp/library/think/log/driver/fileTest.php deleted file mode 100644 index ad6dd224..00000000 --- a/thinkphp/tests/thinkphp/library/think/log/driver/fileTest.php +++ /dev/null @@ -1,34 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Test File Log - */ -namespace tests\thinkphp\library\think\log\driver; - -use think\Log; - -class fileTest extends \PHPUnit_Framework_TestCase -{ - protected function setUp() - { - Log::init(['type' => 'file']); - } - - public function testRecord() - { - $record_msg = 'record'; - Log::record($record_msg, 'notice'); - $logs = Log::getLog(); - - $this->assertEquals([], $logs); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/logTest.php b/thinkphp/tests/thinkphp/library/think/logTest.php deleted file mode 100644 index e786b173..00000000 --- a/thinkphp/tests/thinkphp/library/think/logTest.php +++ /dev/null @@ -1,39 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Log测试 - * @author liu21st - */ -namespace tests\thinkphp\library\think; - -use think\Log; - -class logTest extends \PHPUnit_Framework_TestCase -{ - - public function testSave() - { - Log::init(['type' => 'test']); - Log::clear(); - Log::record('test'); - Log::record([1, 2, 3]); - $this->assertTrue(Log::save()); - } - - public function testWrite() - { - Log::init(['type' => 'test']); - Log::clear(); - $this->assertTrue(Log::write('hello', 'info')); - $this->assertTrue(Log::write([1, 2, 3], 'log')); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/model/.gitignore b/thinkphp/tests/thinkphp/library/think/model/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/thinkphp/tests/thinkphp/library/think/model/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/paginateTest.php b/thinkphp/tests/thinkphp/library/think/paginateTest.php deleted file mode 100644 index 8cd45507..00000000 --- a/thinkphp/tests/thinkphp/library/think/paginateTest.php +++ /dev/null @@ -1,40 +0,0 @@ - -// +---------------------------------------------------------------------- - -namespace tests\thinkphp\library\think; - -use think\paginator\driver\Bootstrap; - -class paginateTest extends \PHPUnit_Framework_TestCase -{ - public function testPaginatorInfo() - { - $p = Bootstrap::make($array = ['item3', 'item4'], 2, 2, 4); - - $this->assertEquals(4, $p->total()); - - $this->assertEquals(2, $p->listRows()); - - $this->assertEquals(2, $p->currentPage()); - - $p2 = Bootstrap::make($array2 = ['item3', 'item4'], 2, 2, 2); - $this->assertEquals(1, $p2->currentPage()); - } - - public function testPaginatorRender() - { - $p = Bootstrap::make($array = ['item3', 'item4'], 2, 2, 100); - $render = ''; - - $this->assertEquals($render, $p->render()); - } - -} diff --git a/thinkphp/tests/thinkphp/library/think/requestTest.php b/thinkphp/tests/thinkphp/library/think/requestTest.php deleted file mode 100644 index f86546e6..00000000 --- a/thinkphp/tests/thinkphp/library/think/requestTest.php +++ /dev/null @@ -1,187 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Db类测试 - */ - -namespace tests\thinkphp\library\think; - -use think\Config; -use think\Request; - -class requestTest extends \PHPUnit_Framework_TestCase -{ - protected $request; - - public function setUp() - { - //$request = Request::create('http://www.domain.com/index/index/hello/?name=thinkphp'); - - } - - public function testCreate() - { - $request = Request::create('http://www.thinkphp.cn/index/index/hello.html?name=thinkphp'); - $this->assertEquals('http://www.thinkphp.cn', $request->domain()); - $this->assertEquals('/index/index/hello.html?name=thinkphp', $request->url()); - $this->assertEquals('/index/index/hello.html', $request->baseurl()); - $this->assertEquals('index/index/hello.html', $request->pathinfo()); - $this->assertEquals('index/index/hello', $request->path()); - $this->assertEquals('html', $request->ext()); - $this->assertEquals('name=thinkphp', $request->query()); - $this->assertEquals('www.thinkphp.cn', $request->host()); - $this->assertEquals(80, $request->port()); - $this->assertEquals($_SERVER['REQUEST_TIME'], $request->time()); - $this->assertEquals($_SERVER['REQUEST_TIME_FLOAT'], $request->time(true)); - $this->assertEquals('GET', $request->method()); - $this->assertEquals(['name' => 'thinkphp'], $request->param()); - $this->assertFalse($request->isSsl()); - $this->assertEquals('http', $request->scheme()); - } - - public function testDomain() - { - $request = Request::instance(); - $request->domain('http://thinkphp.cn'); - $this->assertEquals('http://thinkphp.cn', $request->domain()); - } - - public function testUrl() - { - $request = Request::instance(); - $request->url('/index.php/index/hello?name=thinkphp'); - $this->assertEquals('/index.php/index/hello?name=thinkphp', $request->url()); - $this->assertEquals('http://thinkphp.cn/index.php/index/hello?name=thinkphp', $request->url(true)); - } - - public function testBaseUrl() - { - $request = Request::instance(); - $request->baseurl('/index.php/index/hello'); - $this->assertEquals('/index.php/index/hello', $request->baseurl()); - $this->assertEquals('http://thinkphp.cn/index.php/index/hello', $request->baseurl(true)); - } - - public function testbaseFile() - { - $request = Request::instance(); - $request->basefile('/index.php'); - $this->assertEquals('/index.php', $request->basefile()); - $this->assertEquals('http://thinkphp.cn/index.php', $request->basefile(true)); - } - - public function testroot() - { - $request = Request::instance(); - $request->root('/index.php'); - $this->assertEquals('/index.php', $request->root()); - $this->assertEquals('http://thinkphp.cn/index.php', $request->root(true)); - } - - public function testType() - { - $request = Request::instance(); - $request->server(['HTTP_ACCEPT' => 'application/json']); - - $this->assertEquals('json', $request->type()); - $request->mimeType('test', 'application/test'); - $request->mimeType(['test' => 'application/test']); - $request->server(['HTTP_ACCEPT' => 'application/test']); - - $this->assertEquals('test', $request->type()); - } - - public function testmethod() - { - $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'DELETE'; - - $request = Request::create('', ''); - $this->assertEquals('DELETE', $request->method()); - $this->assertEquals('GET', $request->method(true)); - - Config::set('var_method', '_method'); - $_POST['_method'] = 'POST'; - $request = Request::create('', ''); - $this->assertEquals('POST', $request->method()); - $this->assertEquals('GET', $request->method(true)); - $this->assertTrue($request->isPost()); - $this->assertFalse($request->isGet()); - $this->assertFalse($request->isPut()); - $this->assertFalse($request->isDelete()); - $this->assertFalse($request->isHead()); - $this->assertFalse($request->isPatch()); - $this->assertFalse($request->isOptions()); - } - - public function testCli() - { - $request = Request::instance(); - $this->assertTrue($request->isCli()); - } - - public function testVar() - { - Config::set('app_multi_module', true); - $request = Request::create(''); - $request->route(['name' => 'thinkphp', 'id' => 6]); - $request->get(['id' => 10]); - $request->post(['id' => 8]); - $request->put(['id' => 7]); - $request->request(['test' => 'value']); - $this->assertEquals(['name' => 'thinkphp', 'id' => 6], $request->route()); - //$this->assertEquals(['id' => 10], $request->get()); - $this->assertEquals('thinkphp', $request->route('name')); - $this->assertEquals('default', $request->route('test', 'default')); - $this->assertEquals(10, $request->get('id')); - $this->assertEquals(0, $request->get('ids', 0)); - $this->assertEquals(8, $request->post('id')); - $this->assertEquals(7, $request->put('id')); - $this->assertEquals('value', $request->request('test')); - $this->assertEquals('thinkphp', $request->param('name')); - $this->assertEquals(6, $request->param('id')); - $this->assertFalse($request->has('user_id')); - $this->assertTrue($request->has('test', 'request')); - $this->assertEquals(['id' => 6], $request->only('id')); - $this->assertEquals(['name' => 'thinkphp', 'lang' => 'zh-cn'], $request->except('id')); - $this->assertEquals('THINKPHP', $request->param('name', '', 'strtoupper')); - } - - public function testIsAjax() - { - $request = Request::create(''); - $_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest'; - $this->assertTrue($request->isAjax()); - } - - public function testIsPjax() - { - $request = Request::create(''); - $_SERVER['HTTP_X_PJAX'] = true; - $this->assertTrue($request->isPjax()); - } - - public function testIsMobile() - { - $request = Request::create(''); - $_SERVER['HTTP_VIA'] = 'wap'; - $this->assertTrue($request->isMobile()); - } - - public function testBind() - { - $request = Request::create(''); - $request->user = 'User1'; - $request->bind(['user' => 'User2']); - $this->assertEquals('User2', $request->user); - } - -} diff --git a/thinkphp/tests/thinkphp/library/think/responseTest.php b/thinkphp/tests/thinkphp/library/think/responseTest.php deleted file mode 100644 index 62d15747..00000000 --- a/thinkphp/tests/thinkphp/library/think/responseTest.php +++ /dev/null @@ -1,95 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Response测试 - * @author 大漠 - */ - -namespace tests\thinkphp\library\think; - -use think\Config; -use think\Request; -use think\Response; - -class responseTest extends \PHPUnit_Framework_TestCase -{ - - /** - * - * @var \think\Response - */ - protected $object; - - protected $default_return_type; - - protected $default_ajax_return; - - /** - * Sets up the fixture, for example, opens a network connection. - * This method is called before a test is executed. - */ - protected function setUp() - { - // 1. - // restore_error_handler(); - // Warning: Cannot modify header information - headers already sent by (output started at PHPUnit\Util\Printer.php:173) - // more see in https://www.analysisandsolutions.com/blog/html/writing-phpunit-tests-for-wordpress-plugins-wp-redirect-and-continuing-after-php-errors.htm - - // 2. - // the Symfony used the HeaderMock.php - - // 3. - // not run the eclipse will held, and travis-ci.org Searching for coverage reports - // **> Python coverage not found - // **> No coverage report found. - // add the - // /** - // * @runInSeparateProcess - // */ - if (!$this->default_return_type) { - $this->default_return_type = Config::get('default_return_type'); - } - if (!$this->default_ajax_return) { - $this->default_ajax_return = Config::get('default_ajax_return'); - } - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown() - { - Config::set('default_ajax_return', $this->default_ajax_return); - Config::set('default_return_type', $this->default_return_type); - } - - /** - * @covers think\Response::send - * @todo Implement testSend(). - */ - public function testSend() - { - $dataArr = []; - $dataArr["key"] = "value"; - - $response = Response::create($dataArr, 'json'); - $result = $response->getContent(); - $this->assertEquals('{"key":"value"}', $result); - $request = Request::instance(); - $request->get(['callback' => 'callback']); - $response = Response::create($dataArr, 'jsonp'); - $result = $response->getContent(); - $this->assertEquals('callback({"key":"value"});', $result); - } - -} diff --git a/thinkphp/tests/thinkphp/library/think/routeTest.php b/thinkphp/tests/thinkphp/library/think/routeTest.php deleted file mode 100644 index 31e1b861..00000000 --- a/thinkphp/tests/thinkphp/library/think/routeTest.php +++ /dev/null @@ -1,287 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Route测试 - * @author liu21st - */ - -namespace tests\thinkphp\library\think; - -use think\Config; -use think\Request; -use think\Route; - -class routeTest extends \PHPUnit_Framework_TestCase -{ - - protected function setUp() - { - Config::set('app_multi_module', true); - } - - public function testRegister() - { - $request = Request::instance(); - Route::get('hello/:name', 'index/hello'); - Route::get(['hello/:name' => 'index/hello']); - Route::post('hello/:name', 'index/post'); - Route::put('hello/:name', 'index/put'); - Route::delete('hello/:name', 'index/delete'); - Route::patch('hello/:name', 'index/patch'); - Route::any('user/:id', 'index/user'); - $result = Route::check($request, 'hello/thinkphp'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - $this->assertEquals(['hello' => true, 'user/:id' => true, 'hello/:name' => ['rule' => 'hello/:name', 'route' => 'index/hello', 'var' => ['name' => 1], 'option' => [], 'pattern' => []]], Route::rules('GET')); - Route::rule('type1/:name', 'index/type', 'PUT|POST'); - Route::rule(['type2/:name' => 'index/type1']); - Route::rule([['type3/:name', 'index/type2', ['method' => 'POST']]]); - Route::rule(['name', 'type4/:name'], 'index/type4'); - } - - public function testImport() - { - $rule = [ - '__domain__' => ['subdomain2.thinkphp.cn' => 'blog1'], - '__alias__' => ['blog1' => 'blog1'], - '__rest__' => ['res' => ['index/blog']], - 'bbb' => ['index/blog1', ['method' => 'POST']], - 'ddd' => '', - ['hello1/:ddd', 'index/hello1', ['method' => 'POST']], - ]; - Route::import($rule); - } - - public function testResource() - { - $request = Request::instance(); - Route::resource('res', 'index/blog'); - Route::resource(['res' => ['index/blog']]); - $result = Route::check($request, 'res'); - $this->assertEquals(['index', 'blog', 'index'], $result['module']); - $result = Route::check($request, 'res/create'); - $this->assertEquals(['index', 'blog', 'create'], $result['module']); - $result = Route::check($request, 'res/8'); - $this->assertEquals(['index', 'blog', 'read'], $result['module']); - $result = Route::check($request, 'res/8/edit'); - $this->assertEquals(['index', 'blog', 'edit'], $result['module']); - - Route::resource('blog.comment', 'index/comment'); - $result = Route::check($request, 'blog/8/comment/10'); - $this->assertEquals(['index', 'comment', 'read'], $result['module']); - $result = Route::check($request, 'blog/8/comment/10/edit'); - $this->assertEquals(['index', 'comment', 'edit'], $result['module']); - - } - - public function testRest() - { - $request = Request::instance(); - Route::rest('read', ['GET', '/:id', 'look']); - Route::rest('create', ['GET', '/create', 'add']); - Route::rest(['read' => ['GET', '/:id', 'look'], 'create' => ['GET', '/create', 'add']]); - Route::resource('res', 'index/blog'); - $result = Route::check($request, 'res/create'); - $this->assertEquals(['index', 'blog', 'add'], $result['module']); - $result = Route::check($request, 'res/8'); - $this->assertEquals(['index', 'blog', 'look'], $result['module']); - - } - - public function testMixVar() - { - $request = Request::instance(); - Route::get('hello-', 'index/hello', [], ['name' => '\w+']); - $result = Route::check($request, 'hello-thinkphp'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - Route::get('hello-', 'index/hello', [], ['name' => '\w+', 'id' => '\d+']); - $result = Route::check($request, 'hello-thinkphp2016'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - Route::get('hello-/[:id]', 'index/hello', [], ['name' => '\w+', 'id' => '\d+']); - $result = Route::check($request, 'hello-thinkphp/2016'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - } - - public function testParseUrl() - { - $result = Route::parseUrl('hello'); - $this->assertEquals(['hello', null, null], $result['module']); - $result = Route::parseUrl('index/hello'); - $this->assertEquals(['index', 'hello', null], $result['module']); - $result = Route::parseUrl('index/hello?name=thinkphp'); - $this->assertEquals(['index', 'hello', null], $result['module']); - $result = Route::parseUrl('index/user/hello'); - $this->assertEquals(['index', 'user', 'hello'], $result['module']); - $result = Route::parseUrl('index/user/hello/name/thinkphp'); - $this->assertEquals(['index', 'user', 'hello'], $result['module']); - $result = Route::parseUrl('index-index-hello', '-'); - $this->assertEquals(['index', 'index', 'hello'], $result['module']); - } - - public function testCheckRoute() - { - Route::get('hello/:name', 'index/hello'); - Route::get('blog/:id', 'blog/read', [], ['id' => '\d+']); - $request = Request::instance(); - $this->assertEquals(false, Route::check($request, 'test/thinkphp')); - $this->assertEquals(false, Route::check($request, 'blog/thinkphp')); - $result = Route::check($request, 'blog/5'); - $this->assertEquals([null, 'blog', 'read'], $result['module']); - $result = Route::check($request, 'hello/thinkphp/abc/test'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - } - - public function testCheckRouteGroup() - { - $request = Request::instance(); - Route::pattern(['id' => '\d+']); - Route::pattern('name', '\w{6,25}'); - Route::group('group', [':id' => 'index/hello', ':name' => 'index/say']); - $this->assertEquals(false, Route::check($request, 'empty/think')); - $result = Route::check($request, 'group/think'); - $this->assertEquals(false, $result['module']); - $result = Route::check($request, 'group/10'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - $result = Route::check($request, 'group/thinkphp'); - $this->assertEquals([null, 'index', 'say'], $result['module']); - Route::group('group2', function () { - Route::group('group3', [':id' => 'index/hello', ':name' => 'index/say']); - Route::rule(':name', 'index/hello'); - Route::auto('index'); - }); - $result = Route::check($request, 'group2/thinkphp'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - $result = Route::check($request, 'group2/think'); - $this->assertEquals(['index', 'group2', 'think'], $result['module']); - $result = Route::check($request, 'group2/group3/thinkphp'); - $this->assertEquals([null, 'index', 'say'], $result['module']); - Route::group('group4', function () { - Route::group('group3', [':id' => 'index/hello', ':name' => 'index/say']); - Route::rule(':name', 'index/hello'); - Route::miss('index/__miss__'); - }); - $result = Route::check($request, 'group4/thinkphp'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - $result = Route::check($request, 'group4/think'); - $this->assertEquals([null, 'index', '__miss__'], $result['module']); - - Route::group(['prefix' => 'prefix/'], function () { - Route::rule('hello4/:name', 'hello'); - }); - Route::group(['prefix' => 'prefix/'], [ - 'hello4/:name' => 'hello', - ]); - $result = Route::check($request, 'hello4/thinkphp'); - $this->assertEquals([null, 'prefix', 'hello'], $result['module']); - Route::group('group5', [ - [':name', 'hello', ['method' => 'GET|POST']], - ':id' => 'hello', - ], ['prefix' => 'prefix/']); - $result = Route::check($request, 'group5/thinkphp'); - $this->assertEquals([null, 'prefix', 'hello'], $result['module']); - } - - public function testControllerRoute() - { - $request = Request::instance(); - Route::controller('controller', 'index/Blog'); - $result = Route::check($request, 'controller/info'); - $this->assertEquals(['index', 'Blog', 'getinfo'], $result['module']); - Route::setMethodPrefix('GET', 'read'); - Route::setMethodPrefix(['get' => 'read']); - Route::controller('controller', 'index/Blog'); - $result = Route::check($request, 'controller/phone'); - $this->assertEquals(['index', 'Blog', 'readphone'], $result['module']); - } - - public function testAliasRoute() - { - $request = Request::instance(); - Route::alias('alias', 'index/Alias'); - $result = Route::check($request, 'alias/info'); - $this->assertEquals('index/Alias/info', $result['module']); - } - - public function testRouteToModule() - { - $request = Request::instance(); - Route::get('hello/:name', 'index/hello'); - Route::get('blog/:id', 'blog/read', [], ['id' => '\d+']); - $this->assertEquals(false, Route::check($request, 'test/thinkphp')); - $this->assertEquals(false, Route::check($request, 'blog/thinkphp')); - $result = Route::check($request, 'hello/thinkphp'); - $this->assertEquals([null, 'index', 'hello'], $result['module']); - $result = Route::check($request, 'blog/5'); - $this->assertEquals([null, 'blog', 'read'], $result['module']); - } - - public function testRouteToController() - { - $request = Request::instance(); - Route::get('say/:name', '@index/hello'); - $this->assertEquals(['type' => 'controller', 'controller' => 'index/hello', 'var' => []], Route::check($request, 'say/thinkphp')); - } - - public function testRouteToMethod() - { - $request = Request::instance(); - Route::get('user/:name', '\app\index\service\User::get', [], ['name' => '\w+']); - Route::get('info/:name', '\app\index\model\Info@getInfo', [], ['name' => '\w+']); - $this->assertEquals(['type' => 'method', 'method' => '\app\index\service\User::get', 'var' => []], Route::check($request, 'user/thinkphp')); - $this->assertEquals(['type' => 'method', 'method' => ['\app\index\model\Info', 'getInfo'], 'var' => []], Route::check($request, 'info/thinkphp')); - } - - public function testRouteToRedirect() - { - $request = Request::instance(); - Route::get('art/:id', '/article/read/id/:id', [], ['id' => '\d+']); - $this->assertEquals(['type' => 'redirect', 'url' => '/article/read/id/8', 'status' => 301], Route::check($request, 'art/8')); - } - - public function testBind() - { - $request = Request::instance(); - Route::bind('index/blog'); - Route::get('blog/:id', 'index/blog/read'); - $result = Route::check($request, 'blog/10'); - $this->assertEquals(['index', 'blog', 'read'], $result['module']); - $result = Route::parseUrl('test'); - $this->assertEquals(['index', 'blog', 'test'], $result['module']); - - Route::bind('\app\index\controller', 'namespace'); - $this->assertEquals(['type' => 'method', 'method' => ['\app\index\controller\Blog', 'read'], 'var' => []], Route::check($request, 'blog/read')); - - Route::bind('\app\index\controller\Blog', 'class'); - $this->assertEquals(['type' => 'method', 'method' => ['\app\index\controller\Blog', 'read'], 'var' => []], Route::check($request, 'read')); - } - - public function testDomain() - { - $request = Request::create('http://subdomain.thinkphp.cn'); - Route::domain('subdomain.thinkphp.cn', 'sub?abc=test&status=1'); - $rules = Route::rules('GET'); - Route::checkDomain($request, $rules); - $this->assertEquals('sub', Route::getbind('module')); - $this->assertEquals('test', $_GET['abc']); - $this->assertEquals(1, $_GET['status']); - - Route::domain('subdomain.thinkphp.cn', '\app\index\controller'); - $rules = Route::rules('GET'); - Route::checkDomain($request, $rules); - $this->assertEquals('\app\index\controller', Route::getbind('namespace')); - - Route::domain(['subdomain.thinkphp.cn' => '@\app\index\controller\blog']); - $rules = Route::rules('GET'); - Route::checkDomain($request, $rules); - $this->assertEquals('\app\index\controller\blog', Route::getbind('class')); - - } -} diff --git a/thinkphp/tests/thinkphp/library/think/session/.gitignore b/thinkphp/tests/thinkphp/library/think/session/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/thinkphp/tests/thinkphp/library/think/session/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/sessionTest.php b/thinkphp/tests/thinkphp/library/think/sessionTest.php deleted file mode 100644 index 5fd95f10..00000000 --- a/thinkphp/tests/thinkphp/library/think/sessionTest.php +++ /dev/null @@ -1,319 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Session测试 - * @author 大漠 - */ - -namespace tests\thinkphp\library\think; - -use think\Session; - -class sessionTest extends \PHPUnit_Framework_TestCase -{ - - /** - * - * @var \think\Session - */ - protected $object; - - /** - * Sets up the fixture, for example, opens a network connection. - * This method is called before a test is executed. - */ - protected function setUp() - { - // $this->object = new Session (); - // register_shutdown_function ( function () { - // } ); // 此功能无法取消,需要回调函数配合。 - set_exception_handler(function () {}); - set_error_handler(function () {}); - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown() - { - register_shutdown_function('think\Error::appShutdown'); - set_error_handler('think\Error::appError'); - set_exception_handler('think\Error::appException'); - } - - /** - * @covers think\Session::prefix - * - * @todo Implement testPrefix(). - */ - public function testPrefix() - { - Session::prefix(null); - Session::prefix('think_'); - - $this->assertEquals('think_', Session::prefix()); - } - - /** - * @covers think\Session::init - * - * @todo Implement testInit(). - */ - public function testInit() - { - Session::prefix(null); - $config = [ - // cookie 名称前缀 - 'prefix' => 'think_', - // cookie 保存时间 - 'expire' => 60, - // cookie 保存路径 - 'path' => '/path/to/test/session/', - // cookie 有效域名 - 'domain' => '.thinkphp.cn', - 'var_session_id' => 'sessionidtest', - 'id' => 'sess_8fhgkjuakhatbeg2fa14lo84q1', - 'name' => 'session_name', - 'use_trans_sid' => '1', - 'use_cookies' => '1', - 'cache_limiter' => '60', - 'cache_expire' => '60', - 'type' => '', // memcache - 'namespace' => '\\think\\session\\driver\\', // ? - 'auto_start' => '1', - ]; - - $_REQUEST[$config['var_session_id']] = $config['id']; - Session::init($config); - - // 开始断言 - $this->assertEquals($config['prefix'], Session::prefix()); - $this->assertEquals($config['id'], $_REQUEST[$config['var_session_id']]); - $this->assertEquals($config['name'], session_name()); - - $this->assertEquals($config['path'], session_save_path()); - $this->assertEquals($config['use_cookies'], ini_get('session.use_cookies')); - $this->assertEquals($config['domain'], ini_get('session.cookie_domain')); - $this->assertEquals($config['expire'], ini_get('session.gc_maxlifetime')); - $this->assertEquals($config['expire'], ini_get('session.cookie_lifetime')); - - $this->assertEquals($config['cache_limiter'], session_cache_limiter($config['cache_limiter'])); - $this->assertEquals($config['cache_expire'], session_cache_expire($config['cache_expire'])); - - // 检测分支 - $_REQUEST[$config['var_session_id']] = null; - session_write_close(); - session_destroy(); - - Session::init($config); - - // 测试auto_start - // PHP_SESSION_DISABLED - // PHP_SESSION_NONE - // PHP_SESSION_ACTIVE - // session_status() - if (strstr(PHP_VERSION, 'hhvm')) { - $this->assertEquals('', ini_get('session.auto_start')); - } else { - $this->assertEquals(0, ini_get('session.auto_start')); - } - - $this->assertEquals($config['use_trans_sid'], ini_get('session.use_trans_sid')); - - Session::init($config); - $this->assertEquals($config['id'], session_id()); - } - - /** - * 单独重现异常 - * @expectedException \think\Exception - */ - public function testException() - { - $config = [ - // cookie 名称前缀 - 'prefix' => 'think_', - // cookie 保存时间 - 'expire' => 0, - // cookie 保存路径 - 'path' => '/path/to/test/session/', - // cookie 有效域名 - 'domain' => '.thinkphp.cn', - 'var_session_id' => 'sessionidtest', - 'id' => 'sess_8fhgkjuakhatbeg2fa14lo84q1', - 'name' => 'session_name', - 'use_trans_sid' => '1', - 'use_cookies' => '1', - 'cache_limiter' => '60', - 'cache_expire' => '60', - 'type' => '\\think\\session\\driver\\Memcache', // - 'auto_start' => '1', - ]; - - // 测试session驱动是否存在 - // @expectedException 异常类名 - $this->setExpectedException('\think\exception\ClassNotFoundException', 'error session handler'); - - Session::init($config); - } - - /** - * @covers think\Session::set - * - * @todo Implement testSet(). - */ - public function testSet() - { - Session::prefix(null); - Session::set('sessionname', 'sessionvalue'); - $this->assertEquals('sessionvalue', $_SESSION['sessionname']); - - Session::set('sessionnamearr.subname', 'sessionvalue'); - $this->assertEquals('sessionvalue', $_SESSION['sessionnamearr']['subname']); - - Session::set('sessionnameper', 'sessionvalue', 'think_'); - $this->assertEquals('sessionvalue', $_SESSION['think_']['sessionnameper']); - - Session::set('sessionnamearrper.subname', 'sessionvalue', 'think_'); - $this->assertEquals('sessionvalue', $_SESSION['think_']['sessionnamearrper']['subname']); - } - - /** - * @covers think\Session::get - * - * @todo Implement testGet(). - */ - public function testGet() - { - Session::prefix(null); - - Session::set('sessionnameget', 'sessionvalue'); - $this->assertEquals(Session::get('sessionnameget'), $_SESSION['sessionnameget']); - - Session::set('sessionnamegetarr.subname', 'sessionvalue'); - $this->assertEquals(Session::get('sessionnamegetarr.subname'), $_SESSION['sessionnamegetarr']['subname']); - - Session::set('sessionnamegetarrperall', 'sessionvalue', 'think_'); - $this->assertEquals(Session::get('', 'think_')['sessionnamegetarrperall'], $_SESSION['think_']['sessionnamegetarrperall']); - - Session::set('sessionnamegetper', 'sessionvalue', 'think_'); - $this->assertEquals(Session::get('sessionnamegetper', 'think_'), $_SESSION['think_']['sessionnamegetper']); - - Session::set('sessionnamegetarrper.subname', 'sessionvalue', 'think_'); - $this->assertEquals(Session::get('sessionnamegetarrper.subname', 'think_'), $_SESSION['think_']['sessionnamegetarrper']['subname']); - } - - public function testPull() - { - Session::prefix(null); - Session::set('sessionnamedel', 'sessionvalue'); - $this->assertEquals('sessionvalue', Session::pull('sessionnameget')); - $this->assertNull(Session::get('sessionnameget')); - } - - /** - * @covers think\Session::delete - * - * @todo Implement testDelete(). - */ - public function testDelete() - { - Session::prefix(null); - Session::set('sessionnamedel', 'sessionvalue'); - Session::delete('sessionnamedel'); - $this->assertEmpty($_SESSION['sessionnamedel']); - - Session::set('sessionnamedelarr.subname', 'sessionvalue'); - Session::delete('sessionnamedelarr.subname'); - $this->assertEmpty($_SESSION['sessionnamedelarr']['subname']); - - Session::set('sessionnamedelper', 'sessionvalue', 'think_'); - Session::delete('sessionnamedelper', 'think_'); - $this->assertEmpty($_SESSION['think_']['sessionnamedelper']); - - Session::set('sessionnamedelperarr.subname', 'sessionvalue', 'think_'); - Session::delete('sessionnamedelperarr.subname', 'think_'); - $this->assertEmpty($_SESSION['think_']['sessionnamedelperarr']['subname']); - } - - /** - * @covers think\Session::clear - * - * @todo Implement testClear(). - */ - public function testClear() - { - Session::prefix(null); - - Session::set('sessionnameclsper', 'sessionvalue1', 'think_'); - Session::clear('think_'); - $this->assertNull($_SESSION['think_']); - - Session::set('sessionnameclsper', 'sessionvalue1', 'think_'); - Session::clear(); - $this->assertEmpty($_SESSION); - } - - /** - * @covers think\Session::has - * - * @todo Implement testHas(). - */ - public function testHas() - { - Session::prefix(null); - Session::set('sessionnamehas', 'sessionvalue'); - $this->assertTrue(Session::has('sessionnamehas')); - - Session::set('sessionnamehasarr.subname', 'sessionvalue'); - $this->assertTrue(Session::has('sessionnamehasarr.subname')); - - Session::set('sessionnamehasper', 'sessionvalue', 'think_'); - $this->assertTrue(Session::has('sessionnamehasper', 'think_')); - - Session::set('sessionnamehasarrper.subname', 'sessionvalue', 'think_'); - $this->assertTrue(Session::has('sessionnamehasarrper.subname', 'think_')); - } - - /** - * @covers think\Session::pause - * - * @todo Implement testPause(). - */ - public function testPause() - { - Session::pause(); - } - - /** - * @covers think\Session::start - * - * @todo Implement testStart(). - */ - public function testStart() - { - Session::start(); - } - - /** - * @covers think\Session::destroy - * - * @todo Implement testDestroy(). - */ - public function testDestroy() - { - Session::set('sessionnamedestroy', 'sessionvalue'); - Session::destroy(); - $this->assertEmpty($_SESSION['sessionnamedestroy']); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/template/driver/.gitignore b/thinkphp/tests/thinkphp/library/think/template/driver/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/thinkphp/tests/thinkphp/library/think/template/driver/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/template/taglib/cxTest.php b/thinkphp/tests/thinkphp/library/think/template/taglib/cxTest.php deleted file mode 100644 index 8aee392f..00000000 --- a/thinkphp/tests/thinkphp/library/think/template/taglib/cxTest.php +++ /dev/null @@ -1,575 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * 模板测试 - * @author Haotong Lin - */ - -namespace tests\thinkphp\library\think\tempplate\taglib; - -use think\Template; -use think\template\taglib\Cx; - -class cxTest extends \PHPUnit_Framework_TestCase -{ - public function testPhp() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testVolist() - { - $template = new template(); - $cx = new Cx($template); - - $content = <<\$vo): \$mod = (\$key % 2 );++\$key;?> - - -EOF; - $cx->parseTag($content); - $this->assertEquals($data, $content); - - $content = <<display($content, ['list' => [1, 2, 3, 4, 5]]); - $this->expectOutputString('234'); - } - - public function testForeach() - { - $template = new template(); - $cx = new Cx($template); - - $content = <<\$val} - -{/foreach} -EOF; - $data = <<\$val): ?> - - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = <<\$val): ?> - - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = <<display($content); - $this->expectOutputString('234'); - } - - public function testIf() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -one - -two - -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testSwitch() - { - $template = new template(); - $cx = new Cx($template); - - $content = << - -a - - -b - - -d - - -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testCompare() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << '0'): ?> -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = <<= '0'): ?> -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - } - - public function testRange() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = <<display($content); - $this->expectOutputString('yesno'); - } - - public function testPresent() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testEmpty() - { - $template = new template(); - $cx = new Cx($template); - - $content = <<isEmpty())): ?> -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = <<isEmpty()))): ?> -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testDefined() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -default - -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testImport() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testAssign() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testDefine() - { - $template = new template(); - $cx = new Cx($template); - - $content = << -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - - $content = << -EOF; - $cx->parseTag($content); - $this->assertEquals($content, $data); - } - - public function testFor() - { - $template = new template(); - - $content = <<display($content); - $this->expectOutputString('123456789'); - } - public function testUrl() - { - $template = new template(); - $content = <<display($content); - $this->expectOutputString(\think\Url::build('Index/index')); - } - - public function testFunction() - { - $template = new template(); - $data = [ - 'list' => ['language' => 'php', 'version' => ['5.4', '5.5']], - 'a' => '[', - 'b' => ']', - ]; - - $content = <<\$val} -{if is_array(\$val)} -{~\$func(\$val)} -{else} -{if !is_numeric(\$key)} -{\$key.':'.\$val.','} -{else} -{\$a.\$val.\$b} -{/if} -{/if} -{/foreach} -{/function} -EOF; - $template->display($content, $data); - $this->expectOutputString("language:php,[5.4][5.5]"); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/templateTest.php b/thinkphp/tests/thinkphp/library/think/templateTest.php deleted file mode 100644 index 27e49dbb..00000000 --- a/thinkphp/tests/thinkphp/library/think/templateTest.php +++ /dev/null @@ -1,414 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * 模板测试 - * @author oldrind - */ - -namespace tests\thinkphp\library\think; - -use think\Template; - -class templateTest extends \PHPUnit_Framework_TestCase -{ - public function testVar() - { - $template = new Template(); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = <<parse($content); - $this->assertEquals($data, $content); - - $content = <<parse($content); - $this->assertEquals($data, $content); - - } - - public function testVarFunction() - { - $template = new Template(); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << - -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - } - - public function testVarIdentify() - { - $config['tpl_begin'] = '<#'; - $config['tpl_end'] = '#>'; - $config['tpl_var_identify'] = ''; - $template = new Template($config); - - $content = << -EOF; - $data = <<a)) ? (is_array(\$info)?\$info['a']:\$info->a) : 'test'; ?> -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - $data = <<a)) echo 'test'; ?> -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - $data = <<a)==(is_array(\$info)?\$info['b']:\$info->b)) echo 'test'; ?> -EOF; - - $template->parse($content); - $this->assertEquals($data, $content); - - $content = << -EOF; - $data = <<a) ?: 'test')?'yes':'no'; ?> -EOF; - $template->parse($content); - $this->assertEquals($data, $content); - - $template2 = new Template(); - $template2->tpl_var_identify = 'obj'; - $content = <<b)?'yes':'no'; ?> -EOF; - $template2->parse($content); - $this->assertEquals($data, $content); - } - - public function testThinkVar() - { - $config['tpl_begin'] = '{'; - $config['tpl_end'] = '}'; - $template = new Template($config); - - $_SERVER['SERVER_NAME'] = 'server_name'; - $_GET['action'] = 'action'; - $_POST['action'] = 'action'; - $_COOKIE['name'] = 'name'; - $_SESSION['action'] = ['name' => 'name']; - define('SITE_NAME', 'site_name'); - - $content = << -{\$Think.GET.action}
-{\$Think.POST.action}
-{\$Think.COOKIE.action}
-{\$Think.COOKIE.action.name}
-{\$Think.SESSION.action}
-{\$Think.SESSION.action.name}
-{\$Think.ENV.OS}
-{\$Think.REQUEST.action}
-{\$Think.CONST.SITE_NAME}
-{\$Think.LANG.action}
-{\$Think.CONFIG.action.name}
-{\$Think.NOW}
-{\$Think.VERSION}
-{\$Think.LDELIM}
-{\$Think.RDELIM}
-{\$Think.SITE_NAME}
-{\$Think.SITE.URL} -EOF; - $data = <<server('SERVER_NAME'); ?>
-get('action'); ?>
-post('action'); ?>
-
-
-
-
-env('OS'); ?>
-request('action'); ?>
-
-
-
-
-
-
-
-
- -EOF; - $template->parse($content); - $this->assertEquals($data, $content); - } - - public function testFetch() - { - $template = new Template(); - $template->assign('name', 'name'); - $config = [ - 'strip_space' => true, - 'view_path' => dirname(__FILE__) . DS, - 'cache_id' => '__CACHE_ID__', - 'display_cache' => true, - ]; - $data = ['name' => 'value']; - $template->layout('layout')->fetch('display', $data, $config); - $this->expectOutputString('value'); - } - - public function testDisplay() - { - $config['view_path'] = dirname(__FILE__) . DS; - $config['view_suffix'] = '.html'; - $config['layout_on'] = true; - $config['layout_name'] = 'layout'; - $template = new Template($config); - $files = ['extend' => 'extend', 'include' => 'include']; - $template->assign('files', $files); - $template->assign('user', ['name' => 'name', 'account' => 100]); - $template->assign('message', 'message'); - $template->assign('info', ['value' => 'value']); - - $content = << -header -
- -value: - -main - - - side - - -value: - message{\$message} - - - mainbody - - - - {\$name} - - php code
- -EOF; - $template->display($content); - $this->expectOutputString($content2); -// $template->parse($content); - // var_dump($content); - } - - public function testVarAssign() - { - $template = new Template(); - $template->assign('name', 'value'); - $value = $template->get('name'); - $this->assertEquals('value', $value); - } - - public function testVarGet() - { - $template = new Template(); - $data = ['a' => 'a', 'b' => 'b']; - $template->assign($data); - $this->assertEquals($data, $template->get()); - } - - public function testIsCache() - { - $template = new Template(['cache_id' => '__CACHE_ID__', 'display_cache' => true]); - $this->assertTrue($template->isCache('__CACHE_ID__')); - $template->display_cache = false; - $this->assertTrue(!$template->isCache('__CACHE_ID__')); - } -} diff --git a/thinkphp/tests/thinkphp/library/think/urlTest.php b/thinkphp/tests/thinkphp/library/think/urlTest.php deleted file mode 100644 index 1cb64084..00000000 --- a/thinkphp/tests/thinkphp/library/think/urlTest.php +++ /dev/null @@ -1,127 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Url测试 - * @author liu21st - */ - -namespace tests\thinkphp\library\think; - -use think\Config; -use think\Route; -use think\Url; - -class urlTest extends \PHPUnit_Framework_TestCase -{ - - public function setUp() - { - Route::rules(['get' => [], - 'post' => [], - 'put' => [], - 'delete' => [], - 'patch' => [], - 'head' => [], - 'options' => [], - '*' => [], - 'alias' => [], - 'domain' => [], - 'pattern' => [], - 'name' => []]); - Route::name([]); - } - - public function testBuildModule() - { - - Route::get('blog/:name', 'index/blog'); - Route::get('blog/:id', 'index/blog'); - Config::set('pathinfo_depr', '/'); - Config::set('url_html_suffix', ''); - - $this->assertEquals('/blog/thinkphp', Url::build('index/blog?name=thinkphp')); - $this->assertEquals('/blog/thinkphp.html', Url::build('index/blog', 'name=thinkphp', 'html')); - $this->assertEquals('/blog/10', Url::build('index/blog?id=10')); - $this->assertEquals('/blog/10.html', Url::build('index/blog', 'id=10', 'html')); - - Route::get('item-', 'blog/item', [], ['name' => '\w+', 'id' => '\d+']); - $this->assertEquals('/item-thinkphp', Url::build('blog/item?name=thinkphp')); - $this->assertEquals('/item-thinkphp2016', Url::build('blog/item?name=thinkphp&id=2016')); - } - - public function testBuildController() - { - Config::set('url_html_suffix', ''); - Route::get('blog/:id', '@index/blog/read'); - $this->assertEquals('/blog/10.html', Url::build('@index/blog/read', 'id=10', 'html')); - - Route::get('foo/bar', '@foo/bar/index'); - $this->assertEquals('/foo/bar', Url::build('@foo/bar/index')); - - Route::get('foo/bar/baz', '@foo/bar.BAZ/index'); - $this->assertEquals('/foo/bar/baz', Url::build('@foo/bar.BAZ/index')); - } - - public function testBuildMethod() - { - Route::get('blog/:id', '\app\index\controller\blog@read'); - $this->assertEquals('/blog/10.html', Url::build('\app\index\controller\blog@read', 'id=10', 'html')); - } - - public function testBuildRoute() - { - Route::get('blog/:id', 'index/blog'); - Config::set('url_html_suffix', 'shtml'); - $this->assertNotEquals('/blog/10.html', Url::build('/blog/10')); - $this->assertEquals('/blog/10.shtml', Url::build('/blog/10')); - } - - public function testBuildNameRoute() - { - Route::get(['name', 'blog/:id'], 'index/blog'); - $this->assertEquals([['blog/:id', ['id' => 1], null, null]], Route::name('name')); - Config::set('url_html_suffix', 'shtml'); - $this->assertEquals('/blog/10.shtml', Url::build('name?id=10')); - } - - public function testBuildAnchor() - { - Route::get('blog/:id', 'index/blog'); - Config::set('url_html_suffix', 'shtml'); - $this->assertEquals('/blog/10.shtml#detail', Url::build('index/blog#detail', 'id=10')); - - Config::set('url_common_param', true); - $this->assertEquals('/blog/10.shtml?foo=bar#detail', Url::build('index/blog#detail', "id=10&foo=bar")); - } - - public function testBuildDomain() - { - Config::set('url_domain_deploy', true); - Route::domain('subdomain.thinkphp.cn', 'admin'); - $this->assertEquals('http://subdomain.thinkphp.cn/blog/10.shtml', Url::build('/blog/10')); - Route::domain('subdomain.thinkphp.cn', [ - 'hello/:name' => 'index/hello', - ]); - $this->assertEquals('http://subdomain.thinkphp.cn/hello/thinkphp.shtml', Url::build('index/hello?name=thinkphp')); - } - - public function testRoot() - { - Config::set('url_domain_deploy', false); - Config::set('url_common_param', false); - Url::root('/index.php'); - Route::get('blog/:id', 'index/blog/read'); - Config::set('url_html_suffix', 'shtml'); - $this->assertEquals('/index.php/blog/10/name/thinkphp.shtml', Url::build('index/blog/read?id=10&name=thinkphp')); - - } -} diff --git a/thinkphp/tests/thinkphp/library/think/validateTest.php b/thinkphp/tests/thinkphp/library/think/validateTest.php deleted file mode 100644 index 081a6f2b..00000000 --- a/thinkphp/tests/thinkphp/library/think/validateTest.php +++ /dev/null @@ -1,200 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * Validate类测试 - */ - -namespace tests\thinkphp\library\think; - -use think\File; -use think\Validate; - -class validateTest extends \PHPUnit_Framework_TestCase -{ - - public function testCheck() - { - $rule = [ - 'name' => 'require|max:25', - 'age' => 'number|between:1,120', - 'email' => 'email', - ]; - $msg = [ - 'name.require' => '名称必须', - 'name.max' => '名称最多不能超过25个字符', - 'age.number' => '年龄必须是数字', - 'age.between' => '年龄只能在1-120之间', - 'email' => '邮箱格式错误', - ]; - $data = [ - 'name' => 'thinkphp', - 'age' => 10, - 'email' => 'thinkphp@qq.com', - ]; - $validate = new Validate($rule, $msg); - $result = $validate->check($data); - $this->assertEquals(true, $result); - } - - public function testRule() - { - $rule = [ - 'name' => 'require|method:get|alphaNum|max:25|expire:2016-1-1,2026-1-1', - 'account' => 'requireIf:name,thinkphp|alphaDash|min:4|length:4,30', - 'age' => 'number|between:1,120', - 'email' => 'requireWith:name|email', - 'host' => 'activeUrl|activeUrl:A', - 'url' => 'url', - 'ip' => 'ip|ip:ipv4', - 'score' => 'float|gt:60|notBetween:90,100|notIn:70,80|lt:100|elt:100|egt:60', - 'status' => 'integer|in:0,1,2', - 'begin_time' => 'after:2016-3-18', - 'end_time' => 'before:2016-10-01', - 'info' => 'require|array|length:4|max:5|min:2', - 'info.name' => 'require|length:8|alpha|same:thinkphp', - 'value' => 'same:100|different:status', - 'bool' => 'boolean', - 'title' => 'chsAlpha', - 'city' => 'chs', - 'nickname' => 'chsDash', - 'aliasname' => 'chsAlphaNum', - 'file' => 'file|fileSize:20480', - 'image' => 'image|fileMime:image/png|image:80,80,png', - 'test' => 'test', - ]; - $data = [ - 'name' => 'thinkphp', - 'account' => 'liuchen', - 'age' => 10, - 'email' => 'thinkphp@qq.com', - 'host' => 'thinkphp.cn', - 'url' => 'http://thinkphp.cn/topic', - 'ip' => '114.34.54.5', - 'score' => '89.15', - 'status' => 1, - 'begin_time' => '2016-3-20', - 'end_time' => '2016-5-1', - 'info' => [1, 2, 3, 'name' => 'thinkphp'], - 'zip' => '200000', - 'date' => '16-3-8', - 'ok' => 'yes', - 'value' => 100, - 'bool' => true, - 'title' => '流年ThinkPHP', - 'city' => '上海', - 'nickname' => '流年ThinkPHP_2016', - 'aliasname' => '流年Think2016', - 'file' => new File(THINK_PATH . 'base.php'), - 'image' => new File(THINK_PATH . 'logo.png'), - 'test' => 'test', - ]; - $validate = new Validate($rule); - $validate->extend('test', function ($value) {return 'test' == $value ? true : false;}); - $validate->rule('zip', '/^\d{6}$/'); - $validate->rule([ - 'ok' => 'require|accepted', - 'date' => 'date|dateFormat:y-m-d', - ]); - $result = $validate->batch()->check($data); - $this->assertEquals(true, $result); - } - - public function testMsg() - { - $validate = new Validate(); - $validate->message('name.require', '名称必须'); - $validate->message([ - 'name.require' => '名称必须', - 'name.max' => '名称最多不能超过25个字符', - 'age.number' => '年龄必须是数字', - 'age.between' => '年龄只能在1-120之间', - 'email' => '邮箱格式错误', - ]); - } - - public function testMake() - { - $rule = [ - 'name' => 'require|max:25', - 'age' => 'number|between:1,120', - 'email' => 'email', - ]; - $msg = [ - 'name.require' => '名称必须', - 'name.max' => '名称最多不能超过25个字符', - 'age.number' => '年龄必须是数字', - 'age.between' => '年龄只能在1-120之间', - 'email' => '邮箱格式错误', - ]; - $validate = Validate::make($rule, $msg); - } - - public function testExtend() - { - $validate = new Validate(['name' => 'check:1']); - $validate->extend('check', function ($value, $rule) {return $rule == $value ? true : false;}); - $validate->extend(['check' => function ($value, $rule) {return $rule == $value ? true : false;}]); - $data = ['name' => 1]; - $result = $validate->check($data); - $this->assertEquals(true, $result); - } - - public function testScene() - { - $rule = [ - 'name' => 'require|max:25', - 'age' => 'number|between:1,120', - 'email' => 'email', - ]; - $msg = [ - 'name.require' => '名称必须', - 'name.max' => '名称最多不能超过25个字符', - 'age.number' => '年龄必须是数字', - 'age.between' => '年龄只能在1-120之间', - 'email' => '邮箱格式错误', - ]; - $data = [ - 'name' => 'thinkphp', - 'age' => 10, - 'email' => 'thinkphp@qq.com', - ]; - $validate = new Validate($rule); - $validate->scene(['edit' => ['name', 'age']]); - $validate->scene('edit', ['name', 'age']); - $validate->scene('edit'); - $result = $validate->check($data); - $this->assertEquals(true, $result); - } - - public function testSetTypeMsg() - { - $rule = [ - 'name|名称' => 'require|max:25', - 'age' => 'number|between:1,120', - 'email' => 'email', - ['sex', 'in:1,2', '性别错误'], - ]; - $data = [ - 'name' => '', - 'age' => 10, - 'email' => 'thinkphp@qq.com', - 'sex' => '3', - ]; - $validate = new Validate($rule); - $validate->setTypeMsg('require', ':attribute必须'); - $validate->setTypeMsg(['require' => ':attribute必须']); - $result = $validate->batch()->check($data); - $this->assertFalse($result); - $this->assertEquals(['name' => '名称必须', 'sex' => '性别错误'], $validate->getError()); - } - -} diff --git a/thinkphp/tests/thinkphp/library/think/view/driver/.gitignore b/thinkphp/tests/thinkphp/library/think/view/driver/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/thinkphp/tests/thinkphp/library/think/view/driver/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/think/view/theme/index/template.html b/thinkphp/tests/thinkphp/library/think/view/theme/index/template.html deleted file mode 100644 index 5f4548be..00000000 --- a/thinkphp/tests/thinkphp/library/think/view/theme/index/template.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - Document - - - - - diff --git a/thinkphp/tests/thinkphp/library/think/viewTest.php b/thinkphp/tests/thinkphp/library/think/viewTest.php deleted file mode 100644 index 5bb7de16..00000000 --- a/thinkphp/tests/thinkphp/library/think/viewTest.php +++ /dev/null @@ -1,76 +0,0 @@ - -// +---------------------------------------------------------------------- - -/** - * view测试 - * @author mahuan - */ - -namespace tests\thinkphp\library\think; - -class viewTest extends \PHPUnit_Framework_TestCase -{ - - /** - * 句柄测试 - * @return mixed - * @access public - */ - public function testGetInstance() - { - \think\Cookie::get('a'); - $view_instance = \think\View::instance(); - $this->assertInstanceOf('\think\view', $view_instance, 'instance方法返回错误'); - } - - /** - * 测试变量赋值 - * @return mixed - * @access public - */ - public function testAssign() - { - $view_instance = \think\View::instance(); - $view_instance->key = 'value'; - $this->assertTrue(isset($view_instance->key)); - $this->assertEquals('value', $view_instance->key); - $data = $view_instance->assign(array('key' => 'value')); - $data = $view_instance->assign('key2', 'value2'); - //测试私有属性 - $expect_data = array('key' => 'value', 'key2' => 'value2'); - $this->assertAttributeEquals($expect_data, 'data', $view_instance); - } - - /** - * 测试引擎设置 - * @return mixed - * @access public - */ - public function testEngine() - { - $view_instance = \think\View::instance(); - $data = $view_instance->engine('php'); - $data = $view_instance->engine(['type' => 'php', 'view_path' => '', 'view_suffix' => '.php', 'view_depr' => DS]); - $php_engine = new \think\view\driver\Php(['view_path' => '', 'view_suffix' => '.php', 'view_depr' => DS]); - $this->assertAttributeEquals($php_engine, 'engine', $view_instance); - //测试模板引擎驱动 - $data = $view_instance->engine(['type' => 'think', 'view_path' => '', 'view_suffix' => '.html', 'view_depr' => DS]); - $think_engine = new \think\view\driver\Think(['view_path' => '', 'view_suffix' => '.html', 'view_depr' => DS]); - $this->assertAttributeEquals($think_engine, 'engine', $view_instance); - } - - public function testReplace() - { - $view_instance = \think\View::instance(); - $view_instance->replace('string', 'replace')->display('string'); - } - -} diff --git a/thinkphp/tests/thinkphp/library/traits/controller/.gitignore b/thinkphp/tests/thinkphp/library/traits/controller/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/thinkphp/tests/thinkphp/library/traits/controller/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/thinkphp/tests/thinkphp/library/traits/model/.gitignore b/thinkphp/tests/thinkphp/library/traits/model/.gitignore deleted file mode 100644 index c96a04f0..00000000 --- a/thinkphp/tests/thinkphp/library/traits/model/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/thinkphp/tpl/dispatch_jump.tpl b/thinkphp/tpl/dispatch_jump.tpl index 18ee01bd..583376bb 100644 --- a/thinkphp/tpl/dispatch_jump.tpl +++ b/thinkphp/tpl/dispatch_jump.tpl @@ -2,6 +2,7 @@ + 跳转提示

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 diff --git a/thinkphp/tests/extensions/7.0/apcu.so b/thinkphp/tests/extensions/7.0/apcu.so deleted file mode 100644 index c2f0ad1402d0e709af094ee60ff617c1f0a34bd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 320965 zcmeFad3aRC_Aa~=0yKkmqoPq!TZ|eU69f$c+JOXiYeyr4_grf8EWqv-f&y zTD5A`s#U{o=H~i_Bqt>q_SMd~%pg@eULqb9Q1@txdNT}&(*yZaY%j#AkD7nWOzwViI*b4ngg354~!n(eAeN=U#VK<=(pQ*r}(#c-x|yP3{wz zvI_T1+%DYADx=Q=<7o4^jj!hBU$`{8*TPJ9pX6t%(>Hi3-Hs)Tk~%C)^0+)HOUzVv zXLoY@u2Wn~lZTw+a^G#7(Pzh)u|{og!~fv0G?&q_%HO%&Qukd(>gUNDI=k{63!d!b zbycT$D(9!TmQ*KahE96$uH1h27)i;VlzjI;LOmU+uIsxkBQLXY^O_?c#$5HRRL^;M z&R6gMRL_NYhH)>#9Z{J5xE(Kd;I74eC+@p&--G*J-1fB?FAw2<1oxx3m*Rc`_fxp- z>sh=!hx>WlFXDa)H?NoF!&rgmE4W`(^y_%Of%{F|YjCf{&1)U*^|&|U-h{gz_q({? z!~Fs74{?8t+rGBpbKGCx-hul+xOshv`z!Hg7(3Oo5znu2@522J?(cB( z`T@6vdp8MOO}O{q-ix~#_s_U_{et^f+y`(U#Leq>+=p=gf%{L~y#B)dH*VY9v`a$Y z!rcM4eL3*n33q4QT@`+mdfIW0R|?D$#tUH8SeCGAcgz4NuzCwIT@vw~w^ z_~eOc!#k~*yJy!cyHl^ZysPUUuQz@bzOrP(ec`%xb1Js~^+1`~x&7U5M1DH@>^Vb{ z=B~Wt(yMQK)O_dR_fMYIt;4{NFPo7(`n`U;FMq)Q)RMQ(s%Zb`j;7$y_eS(twEcGT zx`Na9+}-~B^7sGlnRDTtU-vtCS(gzVif^c&R<~#W?a|UFzl**!?5GoFS1dVrVd<80 zN6vn8dFS_DYX1I#zuI*RDYKv5yC5+2%jIt_ zJLCDKL%&^c?muq2zx?U}jjp>d{CG$CG5wYf`ryfPwtm0jZr8I<9@Ti`i(g)F=hxeI zSNFO1(fZqyjv2Xfr2E~qMSp%0XfA79wCCzCM{S;cV8D(C?y0Ewxnuu#hJHEf^P3BL z96jmFQGq93`{31XDZ_p^dg{yTe@lM2z%{Mx&c65VIRD?XEB2lJ`kvCue%f_O_YN;T zf9U%a-B(_cc4GPd9uNI=@cNp2uIZ3FZQ=BL-}<@lq^A0dE?TwfB=_-uOn-5I(&q)~ zA3pW?h%ZOIc;*{>mfq4_{zUI>C%^g4U9%Q^HgG|woB#E7)5rUcUUBforJua<(#e7K zJDwbw{ME)mKR&!MGH$?v!MUIOc*DaVJn64q)$7c6dSCe08#NDm$G`QDKW;QWFTCy9 z4X=$~vtwu9v&Ma};>z=f6g|A*?Vo2?d|+L_YTkR>M(3jJmt|%$! z*mbA(sGsxR|9(YE^#k>z$7NpGvTx&zeb+qnMCV2Qp1HNAK>(dEebJemMM8~y7@`MjQh&zlqQGXVqKk@E4iJ2HMxg8b(sklVZj`G1=r z{Jg8bJ)&PS@(r3v`FGJ!og3i3ZvK942nkKK^} zk@WVf1o}TKLAlo@&|8SjaN~}@j_Gvda!*Z=&qoRLb6)~JcPEJdp9K0jBoRLe@DCG| z`!4uDlKgK-Am_0O^yjz)a!BoVWVy|OfREIU4=2#uZ3+6t>I8N*lt7;6B#_VZ3G{YC zg808CkVA5U{?aZ1Kc^gZWclw*AkViG@cDFt_?&MXNzUE`@vl$NUcD0F;RO7oBxskj z66n=q3EKBe@bAVQe?6F>+>;WN`*DK!0}`}vX@Y+D5*Rs>JclIE+xZD_XM%C+aoFJ_ zXL&Lp{WG4#pSa zSb-4NTS(7qx5_`ClW1JS1UGe)#+)U6tFY%57Bqe}i@;pUscU43;T;gz!TkPsJeE6BpM|7(asxH@Hrf z594>FBkr!0z&{jzrsBU=@sHxf)m`C!h1+9avXaA+1{u$;?*vufhRqTODXx=j{<&y^ zYlM6lFW^ajmMA_4E8MU0FH&-bSj4px{ZYu_NlBlk4I*Qu;EqtELU=dxWsjW-R@kx!)3SovkG6{C}873`7pk>2->mTbIQ(N(FaK&8 zf2pe1H%k7l_axp$;iK(*lpa2+%DoYCV!cvTy=?w3Q|;cM^sT3gzX4C7hqp@LDTRNe z5QXgZ3l5>WV^B5IBTj^E9GZOGAe4DD5SUd%W>WFKDl7mOt z?JWvFp!)lAW&dscS*rA8x$3wtsQ4$^@fH6zpEs*|HK_KzUCA>A`oMbC?vfd(;*Dw~ zB<@o6JxS$n;z``C^cme*Tw_&zGnPqObu;5HL}2{7MH2r@mCNc7FH-%*)~j!o99*gc z<;!G7Q1RJdNx-4-6_CU6nx|vq`Dk~JQ*~LViVv`<4FGt&>0o z+h&R9EBPF++NEw^+k7q*?S7)sJm7Q@0Jg<727d+radw!=1wLEGQ`=<55LIr5 zDz~Q$Hg2%>^9>1%P<;Mm>xpgn6~57y|I0GIN8vxC9xT^CPvW+J6#z-RS@CJh=R4RR z>Zftp=`w-(`-YOgOSL1|(yf2jJkYq^vbhM;?Jn~Pb>Kt%D_M@;;K~q`#+L&k$e~rCg_j1sdDq* zk`bq(JYFjl|9-{4ZC5L7y;>ro3BQVOg~}e*DSK$gFHr5$SSjP5As@ysDt~ue{QDI@ zo`o{vOr@V)RQ%-|C0?ZR3E?T^d5Z+96dqA>tGz=4Sqi^Y<)6WXxa_^CJCxiSl-z9n z388_Rf1@Sik5>HjSL2s^zQohz!Ra@H1VD-_&u(8O|LYZQ6c$dHQZ}`4T3}3hps>&=9A7%M z6ku`17`~2~TspJFD7<2N;joekrPBf><%1`WnKrFtnlZ*-TGGBNm8f{)J(g2Rc}Z&-C0cni z#*|MjojO6}H?=HKS}aQ*S28vz!7+Y+$<%Qod|GfUG8eCbvPmUVSuFs?6D3w$UVKq+ z5juWyslRaIm}wJ@LRD5_-;0gHnbXHiF7yY=3&#b(ci~LrD`FKwTmeHTAtQ*b&|g+M z6|aTmCDTd*g(Vej(~K*rC=B|?jR}-!X{VG;FDV>fR*rg&V~W;XCm@UBV0n4T)IcE; zjfu-oU;zoHT6%MIHtTr%3S18Jh^1dRJ8pOqK{*Hmq`_oaZwN?(l)9rja3tI%K0}w zO8Gc}#v%z;<0H+GNn0ZYryeOUg~p#aX z)S4jFsI`9bt;|Y=Hp8O#V|#vH0&fari`skqbKA>Wh*baIf#x_7$}`0B`EVz3CEO| z%Qg=fW5$gugzYXXmd1<*#@1lykz~3xj*vCtv?Almf>c+9O)aSiAPo%}ZDVU*lS-&# z8U;qS-30cX^3&S} ziCSf+@yUm;xN@Z z8u#uaA|ZPc50DMrn@Ff>i@92!F76YH8?!86iRIF<5uKV&Lo8)0LZNBB2uawyQ^rh!icT&=w~Q%Cd5Q1J2|6qagc%92-zwb{1!zW5W~s;2xKoVK6fqA9 zw^%s~S~_U2OjG8+MH+@y#)b06gThY5gMtNV30v(CBnQJ6*RjS1r>O!(rx&WyTH?5p z@neFMS>JeZlyZd7g^#Euz+_Xln(@LhM#VE8Ci&4a^i6PQ`2>P%@#sG$8vM zxjZ5cJ(*;yqR3kSwyw1zvWv9R{vhUD8d;_qQX~(wp{U-iF$KGT{O~g;l}?^)V3;2x z#wosuA%&v=6Zo}BDF=<1?JgU86B-o?G)_+NW|pEKAVJItpu2vA5lxq9*VTkRhk$$U-tAMXb$97>c2@ zm-uo(SMO-B^Ku)@+Q{>dd%Fg&Sff{S8r zy)Wn+d(Z4+ukGL|my42P>swloz!;9DvsgH3I}PK?_trO?<})RhgC37@vB;>d!%Nn4 zXC%^gu9CK?cEIg-hS-;l>7mKkNcn&N{`VwMBi6>TM+5;MTUv@0))eD4V7!>4UkeYO zREibMcE&rg@MPmw70&qg+<6~XCfghTR+x;R9E)F|zK62cB{L2(m0>JSfNzh(vsC=l zvrZT3?0jrIBMu*+;+t{!y}ya%MnxQM=TjSpdsIH#<8agF=j;Uh#Nl~1KXJI7e?=S~ z<0lRurt(=9hhJ;+8HdOCOi#dP9Dbe6XB-}rTO7VYZFJSf;r~|nvN(LJ!t3JjulX?z zuEsdLziKZ>ueSUTRd{+F?p1h39Nw@%=AR#j+xht8@at?niNlLjK8xe<2`c`oIDC@A z8{_a<3OCMaTd#QvPmjYFDcp?1?^L)y4!=X;wQ=|Z3SSk6+wr%@;ZLae?sMDnxl-X~ z9B$_`F%I8o^Am^L@?Rc@f2!gijKhDh`8lsGKX$pEIQ)=`KQRus%UuwMJC*(~kHh;M zkowaQho7qAAB@A#Rk)$fnc4Qrraf_ZrOH1)4zH_`b z9KPmPiPy#9HHx3cIQ$-kH^<=~Wv`7(+P2G+D!wZYuT}DK$KkK3_!)6{rOMwEhp$)h z^W*S36~8DB|47C6$KlHrKb3L#S1NvO9B!!bU`ZSvRq>a{;YBKbT^#<4ir)~2*Qxl8 zak!!Mxj7zJ@eOrO#n!h@D!wZYH`F-cj>C^p@iXFZJH96lKUu}kkHd>p{zY+knu_m_ z!|PQ1$~Zhj#jlOS4K+?w_G_ze)9vvn4lh#im&D=oRs7{~c%wZ|#o-}^H^kv~{Kh!k z9><&Ga67)C&I#G=b*IYT6^GmL-EsJRDt<;BZpZh;;Sa0$`Ej@%zbFoWR>k+n;dcDW zIDDmwUmJ(p@h#O3NiaJ-r0EfV)0Lf%$NdR#L)qK-_+|q9pjPfmtz3^9mzj@_FGzql zB*0VExEY^MQ38Bf0=zi^o~6k_=d&^azBvKz(&VG(Q;+~(k^r|7;1e%AT}T&`fj07V zX>#Md)4uXGK6QL?0z6$SSC8*cfY)i|ns%XhIy5=!czyzWaRR(i!_U?7U#0P{{-TB#X!t!EUZmmbh>i&LYxq(veuakj*YHXWAE4n2H2ggcuhsA+8opS=uh8%% z8veD0FVpbR8opfNY;$$AOoXmdINM6c>$H4|L`?Z-vxbk=@CFT6uAvCsuHn#ow&q-)eY+hTo;(+co@v zhBs<>m4;gyu3Uc++N|MkYw-_i_#q89lz&3`+@|3U4OcF*2z6;V&vx2Zs)l#eaJPoP zVMoR@UBmCx@C*&#q2UWOyi&uLY50R0zFET;Yq+K1PieSA`7LDqB@Iv4aQnY} zhIi8RDqq7-)8ZFsxLd=EH2iK2pQzzdf-=yr;XSqZ6&ikqhF5C1S`reW3p6}Ui(jkZ zXKMIj4S!X`muUD|8oo@!&(`qe8vcleuhMXbCeJzzPuJpa*6{ymc!P%b((vsXevXDW zYWR5?ZfW@W8s4no-84QAYPfyoT_o!*TaUK(LMhT4ez7j`5OL~h8Jk~JsMu5;e9oHqK4aN>KW|U@Qbzh z6&l`IYnMt5U#G=ipyAJHc&&zCqT!1*{4ot*qTyK@zD&dWY4~ytzf{9lY4|`5uhZ~{ zG<>s$U#8&=8h*KkZ`W{-hBs<>wuW08{;Y;KYk0GUAJp(c8g5+Fs{eyE+@aw)8t&5Y zTn$gv@T0Z%b!+$#Eq=O&57qDt4fkqzmWCgr((vILUZ>$-YWQXiAEDt58a`6Pw`=%J4R6%&Yc<@`@KGAxtl=q|o*dNh0xiDL zr&a&|q2Ue7&e1e8=*6DH`t4@Gmsn)bLFjp0D9kHM~H>%QU=5!~GgQQN#CZxL?C>*6<1qFW2x&4L?rP z^933{O^aWv;Z807VhzU;qS&=W!virC^Ir`QYWQ*upRVDnG`zi*f1QSZs>R=|;lF8k zgND!0@a-D@u!c8kc!h>r8h(q0n^iwLtk-+s2WPK11%E!d7fT^k8yxFf`d;yg+h{q{ zhriC#Ja{85dRnxx1=pE_NV8_q20>p+I+=8xpnH>UM|!!S&mo;cdWoQWl5S7BR?sJr z?m)Uy(8rKwH;eiO-I=t5bdjKwNp~WhFX%(tKyxW3>JjwMq`Q#L5cF=+T}itIy^Hiw zq+Npkg7nd(4MA@u?Ihj&H-IzWCG8^JDCl*hyOC}X^lH+_kggN-3ev}tUM}e8NFPUf ziJ+H~?oPT^&<~P6o^++4?;?EyX}_Qsl1?REBM!WAq|xT6zo4%peJW`~(8EZdM!NYg*8d99Zqki{9z^0YGs1%2pa z(3}cKJ%aw3^tq%n1ihQ|d8FNf-bMO+(k?-NLHYvHhM>2S<`g&D{HJJt(ix;11-*`R zCg}!2uO{7_be*7AkiLlYazQ^wx)13kf?i6xFX>uAKS=sw(v^a~i}WR={eoUdnp3i9 zk)Y?3?ngRb&@)M2O4=jna?<@tX9)Tx(gR4l1wEGZK+-NjUq_l#uc#sDVWc_biZ=ft z+Ml$CbfcgLk3l&S+6wv#(jGzoO!`XF8G_zT+DF0zYn1igavaMH^K{T%5Lq?ZVKDd~}< zYX$uv>1#<>3i>Y6qe%M&y^u6r@o15t=ac>i>3l)YBu&>l>JfA~>CvP!1bq|f>q)x> zJ(lzhq+No(jx=50s3GWKr0McTn|~MWPr8V7qo44T zIi%@2MwbY>CuzEj(ON;DM0z~wN02^1pNhRx;Rlo&|68qygOi8cs& zHR*EFb%I_&dK&5Ff_{#4fb^mU}?kTwK8jPzX6&A*BECtXRp zQP6`(&m-L+=u1h@CtWA#-lVHYFBkMVq^n6U5p++|HKc0=eG=(^lCBi=F{E!J?H6=s z(hEoz2|Af{h;+W74>f>ZNZKRlpGk*FX9#*X=|!a7g5E_sLfR$hFG$}`+7R?s(sz(< zJ|NnkbS>#dL9ZiyC+P-3uO@vL={iBLAbmIK<$`{W^gX1P2zn{$dr8*{`a#n7k**Z< zU8L_P?HBYy(u+wK33@*12T11&dM4=yNqYocPWmCz8G^ov^uwgxf*woy5z;O}Uq|{; z(uSaik$#MH^RJ@)NiQMYDCj|?A1B=)=u1g2C0!@z-lU%(y}bLH|tpdD0nz-c9-i(r!WT zBK;z1m!Q8O{V&pnptq8KiFETXqWwuPC*3IMb);V=-5}`Iq*sux6Z8twuaI6Y=;uhk zN_vT)my&*sbgiHtB)yV!rJ(O3{W@vCpcj%}MY>4P^GUx!I$zK;Nv|gD5p+4}H%Vs* z`X(d&{(B!o3W@x`JG%l^t2f{K#fB8azv}RvuR@y;x-jCEj zGu*)!KF1r{W`;VN;UNw)G}LimNT-y*Q90p3=jGPaIcsP}oGS-As;mwJI!zyZAQz#X zvcoxP88vl5pBcVBZK4^ToaXn1$E8*H!Y`y%B7rabY8v~uFZ@;-`xTJcnchF}fn42eL{B+7(%)JF6=? z7{+g(hu$?K1J;>qe@M2@f@hW;9@+J`FG5?*wY!oL;6ll1-q389+3Pb^cp9Lt-tctS zZ`(t4X5_dAb8Ta?*=rM1Sl>YC+2On%HCvq3bJw8t} zl0r<^zH(NQ!w58kxwPojLW-iD1l!3$Pk6Ay3?HkjloJXS0AEl@L(MG5zM7!5I3-UKZxkmI|J6yB^q;7@TNvX(Fk*_bDo?QjSi@ps) z<^wfBqvVUS@KV4RDzUSgV~o-qhteFS7G~%RGZIKEFwukZg$h+)gMv-;fqWART;M~m znh$SKB47*&9mvl53*9PureIRmFLR3-Zh!vUF{)`y2`7ZeLh4!sUMat}! zk*VlD(YKIRq^V+>$>@G)H1?*hkZ}v1jBMc9gHLaLZn~n=5ZqGL*jTms80eY9jI^Hz zW8n?uy2L!|z}ggN^)X3EYOC4Tf7+UM1RV>#``Z^%14B^Qo+*%&t!t~{1;unNl2Qxh zf}Z8N^1^dm)P{QDX0_Cd*%o5v_Q>v+OU+L8hI3ucY9BfjG_Jib>5v&3k>+m75(-dn zhH}zUtwoTkH$2K^!YHPip?sHF?-5n@R@J-Bsyer?->fvZv-%EJB|OUE3;oS5bu?^D z<@YIpSFHROL)pM`!g6bWt->?r6GqO%}xE3$FAlHG)A1BzRD6Vp4_rDhXnj*QK@`XrpGh580ccoOyS*-#n6|2>`a*m_3vwAa9 zYr--^zBGq*9lUZgj5jH=@HMb~5L@`>RI_TW+YI?rv%8E$w-36^;;rF6_l5kDfGl%D z1MbVNs!uZe`O@5hmYJZwTWxBsDKQ1Tq-{ndCtx>rhwP8OX$! zR7d4-M{h?_?CL$x1~4tQSm<1up$~;*AO|1fx~#!aQy-KFk^trndmxr#nNPByHwnuDr0oDX%o2C~Y9ct*Os5RbVyeBAudHG-xrA+Grpm#-g~aaMnW9+{1C z(-+!Qbms-dGj_>A}+(W^!9@z79b&3VX0YUx_h z%gP^rNOMofuWsJ z(3t{jWDj~>^`Ms|Z`Ui{njQs_8xDPubczhw3M^^L|!?+BpeOyfvDtS)uGBS)pwlhW`&(A!qd>s7iovuRk2cnF707sNnImk&*$J7Ysies~%v|PBA!#pj zMJsTAAzPu&on2Lzr1AA0Y+j6iXU!yXEvzZ)a0A=m1LtXQJY@HOh4L4J)Y`Sy9sYS#)@DgW@?zfY`q-xe^Ce+W@zue)h>5I0B4ntA3lAa4=Ed8CR6R)VhufHGh z_Ci)sju$f8gG_cQ{>ada!D4i&$dr)_S)b_pBAA7I2+`FFK4t2!1l<{b?JfZ=xs3IV zT%8ns9AZJa96qY>s`cNc6j+=Q%E8c@YPDeCZtcW5P;V&4;RA_F4kUru|Epe{+wZEh zz%_R7&8}J->%8Ff9tcM7yu(BTiQ!}@UhNJ`m<=81BN}-yNH$Z`v!XHo`ay3@!Li*& z(ea2%!3H-)k79=O4rEt45k-rx#AP7aPBmKtWm=!-deD*k(vD_T;$iN`f7h1+`3d?_ zHAb%^_9L;+Wp|JX6bJfG;AGKv3T$yaSMQ-iZbXG4hEfK1M*E9eZ#vDaufto5FEZ3L z*Y0hHF2etP$1wZP@J#Q#U(Tz&p*qpj)R$!pOgiWbJAC~s9L9}6r;yVFp zTuqN~KT_3gJ@+p$^EiK%8#Cp)Kypii*uJbCSvjy^y&G(VzRMmlJUG^@8d!ulMxd)1 z9yoW6+psRBs}VWnp%>kTFLLH0JeUvC_1efg(T8@op}9VT)tJd?&6zv6JaZ5gmmc0<-q0`5iqLN@TOk26v_5dO z(BQphsNVXO{Uo%Vi!BgSk2Eg0xFDg__2b3WIzL7J&CI_w<3G&MuYt3z@^6{NZZou# zxu6BEM^+I(hJp>L(e~g{$S1Q-28bv}%75OE+o2WJU@(xDPS-z!ZXf1EIcXjr-ps%y z&R&?nI(zxjik!Vhr1_n_9!{%78fUL3#d?sl*9&P&1pR8-a`AjCtqxB!Qk~X_r!SI2 z&iZCz^~ntV&i^^bz(j*1p@|?jX2oLiif7jhrb9@owVo21w}H$-CT--=NI^s16pO{B z8_FgfZnZb`XCTA+$2XV@ZOn;GN%9u|WxdIKr2H>3i}(0K-$VXfl`8+frDapfxhPIF zgA^d!A=L+AVXn6!ef@ZhUjv`T;(tzPZ)Tk}cNa#_57|Ji{M57rx!QOD8R^@$U+7n>vlV0Lm^NjL=12MmklqyKIa%J0w≶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 E4+;+smjD0& diff --git a/thinkphp/tests/extensions/7.0/memcached.so b/thinkphp/tests/extensions/7.0/memcached.so deleted file mode 100644 index 544ba6d52ee89046ac2ddab0d4acfe2d95e8bfda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 323764 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 h1~w&V?BEM#C@~958OzT3EJU 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