From 72d388f642de1c466d31589fa820107bf8eb18c9 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 14 Jun 2026 14:00:24 +0800 Subject: [PATCH] feat: initial commit --- .gitignore | 5 + .htaccess | 24 + .install.lock | 1 + Mobile-Detect/LICENSE | 21 + Mobile-Detect/MobileDetect.json | 233 + Mobile-Detect/README.md | 321 + Mobile-Detect/composer.json | 40 + Mobile-Detect/docker-compose.yml | 16 + Mobile-Detect/src/MobileDetect.php | 1419 + admin/ConfigWriter.php | 101 + admin/bootstrap.php | 11 + admin_ip_manager.php | 538 + check_config/index_config.php | 40 + cloak_log.sql | 65 + cloaka.test.code-workspace | 11 + cloakjs.php | 173 + config/ConfigLoader.php | 69 + cong.php | 28 + cong.php.bak | 20 + dashboard.php | 1187 + datatable/countries.php | 250 + datatable/datalist.php | 172 + datatable/err.txt | 3 + datatable/export.php | 127 + datatable/log_analytics.php | 36 + datatable/sdatalist.php | 162 + deploy/baota/README.md | 90 + deploy/baota/hook/post_site.sh | 55 + deploy/baota/hook/post_site_del.sh | 5 + deploy/baota/install_bt.sh | 131 + deploy/baota/nginx/cloaka-admin.conf | 10 + deploy/baota/nginx/cloaka-site.conf | 14 + deploy/baota/site-stub/index.php | 5 + dist/bootstrap/4.5.2/css/bootstrap.min.css | 7 + .../4.5.2/js/bootstrap.bundle.min.js | 7 + dist/cloakjs | 217 + dist/device.js | 8 + dist/index.php | 199 + dist/jquery-2.2.4.min.js | 4 + dist/jquery.min.js | 6 + dist/layui.js | 2 + dist/layui.min.css | 8 + dist/mobiledetect.js | 3 + dist/ua.js | 1 + err.txt | 0 f_check.php | 157 + index.php | 4 + install.php | 429 + install/schema.sql | 63 + ip_black.txt | 23911 ++++++++++++++++ ip_check.php | 157 + jump.html | 43 + jump.txt | 95 + lib/Cloak/CloudflareClient.php | 170 + lib/Cloak/CloudflareConfig.php | 76 + lib/Cloak/ContentRewriter.php | 208 + lib/Cloak/DomainProvisioningService.php | 257 + lib/Cloak/DomainRepository.php | 241 + lib/Cloak/FpUrlHelper.php | 114 + .../Page/FingerprintRedirectRenderer.php | 21 + lib/Cloak/Page/FpPageRenderer.php | 54 + lib/Cloak/Page/RiskPageRenderer.php | 15 + lib/Cloak/Pipeline/CheckPipeline.php | 63 + lib/Cloak/Pipeline/RouteResolver.php | 137 + .../stages/apply_whitelist_blacklist.inc.php | 69 + .../stages/check_url_args_timeout.inc.php | 134 + .../resolve_session_fast_path_hit.inc.php | 9 + .../stages/run_ad_source_guard.inc.php | 71 + .../stages/run_main_api_fingerprint.inc.php | 197 + lib/Cloak/PipelineTimer.php | 101 + lib/Cloak/ReasonHelper.php | 54 + lib/Cloak/VisitorInfo.php | 320 + lib/Cloak/VisitorLogAnalytics.php | 441 + lib/Cloak/VisitorLogQueue.php | 218 + lib/Cloak/VisitorLogSchema.php | 92 + lib/Cloak/VisitorLogWorker.php | 226 + lib/Cloak/VisitorRepository.php | 355 + lib/CloakAdSourceGuard.php | 270 + lib/CloakDebugPage.php | 626 + lib/CloakHttpHelpers.php | 255 + lib/CloakPhpCompat.php | 139 + lib/DbHelper.php | 70 + lib/InstallSchema.php | 100 + lib/bootstrap.php | 25 + log_analytics.php | 271 + mdetect.php | 27 + nginx.conf | 12 + nt.txt | 9 + page_6.php | 100 + page_666.php | 148 + resources/cloakjs_enhanced.inc.php | 317 + resources/fingerprint_redirect.html.php | 42 + resources/virtual_device_detect.inc.php | 242 + share/cbwzs4usE6a8yawoq0y.php | 163 + share_log.php | 28 + slog.txt | 184 + storage/visitor_log_queue/.gitkeep | 0 storage/visitor_log_queue/pending.ndjson | 0 table.php | 477 + tem_link.php | 4 + tools/fixtures/regression_fp.php | 30 + tools/fixtures/regression_ip_check.php | 32 + tools/fixtures/regression_risk.php | 32 + tools/fixtures/regression_zp.php | 30 + tools/regression_test.php | 336 + tools/run_pipeline_fixture.php | 51 + tools/run_risk_route_fixture.php | 79 + tools/verify_ad_source_guard.php | 129 + tools/verify_baota_nginx.php | 17 + tools/verify_cloakjs_mode.php | 53 + tools/verify_cloudflare_domain.php | 120 + tools/verify_config_loader.php | 22 + tools/verify_fcheck_nt.php | 35 + tools/verify_pipeline_timer.php | 38 + tools/verify_request_url.php | 42 + tools/verify_session_real_visitor.php | 30 + tools/verify_virtual_detect.php | 53 + tools/visitor_log_worker.php | 30 + 118 files changed, 39015 insertions(+) create mode 100755 .gitignore create mode 100755 .htaccess create mode 100755 .install.lock create mode 100755 Mobile-Detect/LICENSE create mode 100755 Mobile-Detect/MobileDetect.json create mode 100755 Mobile-Detect/README.md create mode 100755 Mobile-Detect/composer.json create mode 100755 Mobile-Detect/docker-compose.yml create mode 100755 Mobile-Detect/src/MobileDetect.php create mode 100755 admin/ConfigWriter.php create mode 100755 admin/bootstrap.php create mode 100755 admin_ip_manager.php create mode 100755 check_config/index_config.php create mode 100755 cloak_log.sql create mode 100755 cloaka.test.code-workspace create mode 100755 cloakjs.php create mode 100755 config/ConfigLoader.php create mode 100755 cong.php create mode 100755 cong.php.bak create mode 100755 dashboard.php create mode 100755 datatable/countries.php create mode 100755 datatable/datalist.php create mode 100755 datatable/err.txt create mode 100755 datatable/export.php create mode 100644 datatable/log_analytics.php create mode 100755 datatable/sdatalist.php create mode 100755 deploy/baota/README.md create mode 100755 deploy/baota/hook/post_site.sh create mode 100755 deploy/baota/hook/post_site_del.sh create mode 100755 deploy/baota/install_bt.sh create mode 100755 deploy/baota/nginx/cloaka-admin.conf create mode 100755 deploy/baota/nginx/cloaka-site.conf create mode 100755 deploy/baota/site-stub/index.php create mode 100755 dist/bootstrap/4.5.2/css/bootstrap.min.css create mode 100755 dist/bootstrap/4.5.2/js/bootstrap.bundle.min.js create mode 100755 dist/cloakjs create mode 100755 dist/device.js create mode 100755 dist/index.php create mode 100755 dist/jquery-2.2.4.min.js create mode 100755 dist/jquery.min.js create mode 100755 dist/layui.js create mode 100755 dist/layui.min.css create mode 100755 dist/mobiledetect.js create mode 100755 dist/ua.js create mode 100755 err.txt create mode 100755 f_check.php create mode 100755 index.php create mode 100755 install.php create mode 100755 install/schema.sql create mode 100755 ip_black.txt create mode 100755 ip_check.php create mode 100755 jump.html create mode 100755 jump.txt create mode 100755 lib/Cloak/CloudflareClient.php create mode 100755 lib/Cloak/CloudflareConfig.php create mode 100755 lib/Cloak/ContentRewriter.php create mode 100755 lib/Cloak/DomainProvisioningService.php create mode 100755 lib/Cloak/DomainRepository.php create mode 100755 lib/Cloak/FpUrlHelper.php create mode 100755 lib/Cloak/Page/FingerprintRedirectRenderer.php create mode 100755 lib/Cloak/Page/FpPageRenderer.php create mode 100755 lib/Cloak/Page/RiskPageRenderer.php create mode 100755 lib/Cloak/Pipeline/CheckPipeline.php create mode 100755 lib/Cloak/Pipeline/RouteResolver.php create mode 100755 lib/Cloak/Pipeline/stages/apply_whitelist_blacklist.inc.php create mode 100755 lib/Cloak/Pipeline/stages/check_url_args_timeout.inc.php create mode 100755 lib/Cloak/Pipeline/stages/resolve_session_fast_path_hit.inc.php create mode 100755 lib/Cloak/Pipeline/stages/run_ad_source_guard.inc.php create mode 100755 lib/Cloak/Pipeline/stages/run_main_api_fingerprint.inc.php create mode 100755 lib/Cloak/PipelineTimer.php create mode 100755 lib/Cloak/ReasonHelper.php create mode 100755 lib/Cloak/VisitorInfo.php create mode 100644 lib/Cloak/VisitorLogAnalytics.php create mode 100644 lib/Cloak/VisitorLogQueue.php create mode 100755 lib/Cloak/VisitorLogSchema.php create mode 100644 lib/Cloak/VisitorLogWorker.php create mode 100755 lib/Cloak/VisitorRepository.php create mode 100755 lib/CloakAdSourceGuard.php create mode 100755 lib/CloakDebugPage.php create mode 100755 lib/CloakHttpHelpers.php create mode 100755 lib/CloakPhpCompat.php create mode 100755 lib/DbHelper.php create mode 100755 lib/InstallSchema.php create mode 100755 lib/bootstrap.php create mode 100644 log_analytics.php create mode 100755 mdetect.php create mode 100755 nginx.conf create mode 100755 nt.txt create mode 100755 page_6.php create mode 100755 page_666.php create mode 100755 resources/cloakjs_enhanced.inc.php create mode 100755 resources/fingerprint_redirect.html.php create mode 100644 resources/virtual_device_detect.inc.php create mode 100755 share/cbwzs4usE6a8yawoq0y.php create mode 100755 share_log.php create mode 100755 slog.txt create mode 100644 storage/visitor_log_queue/.gitkeep create mode 100644 storage/visitor_log_queue/pending.ndjson create mode 100755 table.php create mode 100755 tem_link.php create mode 100755 tools/fixtures/regression_fp.php create mode 100755 tools/fixtures/regression_ip_check.php create mode 100755 tools/fixtures/regression_risk.php create mode 100755 tools/fixtures/regression_zp.php create mode 100755 tools/regression_test.php create mode 100755 tools/run_pipeline_fixture.php create mode 100755 tools/run_risk_route_fixture.php create mode 100755 tools/verify_ad_source_guard.php create mode 100755 tools/verify_baota_nginx.php create mode 100755 tools/verify_cloakjs_mode.php create mode 100755 tools/verify_cloudflare_domain.php create mode 100755 tools/verify_config_loader.php create mode 100755 tools/verify_fcheck_nt.php create mode 100755 tools/verify_pipeline_timer.php create mode 100755 tools/verify_request_url.php create mode 100755 tools/verify_session_real_visitor.php create mode 100644 tools/verify_virtual_detect.php create mode 100644 tools/visitor_log_worker.php diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..72ea8d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# 忽略 Cursor 和 VS Code 的编辑器缓存 +.sidebar/ +.cursor/ +.vscode/ +*.log \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 100755 index 0000000..ed37935 --- /dev/null +++ b/.htaccess @@ -0,0 +1,24 @@ + + # 开启重写引擎 + RewriteEngine On + + # 对应:index index.html index.htm index.php; + DirectoryIndex index.html index.htm index.php + + # 1. 如果请求的是真实存在的目录或文件,直接跳过重写 + RewriteCond %{REQUEST_FILENAME} -d [OR] + RewriteCond %{REQUEST_FILENAME} -f + RewriteRule ^ - [L] + + # 2. 对应:location ~ \.php$ { try_files $uri =404; } + # 保护机制:如果请求以 .php 结尾但文件不存在,直接返回 404 (这也能防止下方的规则产生死循环) + RewriteCond %{REQUEST_URI} \.php$ + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ - [R=404,L] + + # 3. 对应:try_files $uri $uri/ @extensionless-php; 以及 rewrite ^(.*)$ $1.php last; + # 将所有找不到的请求追加 .php 后缀进行内部重定向 + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ $1.php [L] + \ No newline at end of file diff --git a/.install.lock b/.install.lock new file mode 100755 index 0000000..9e880e4 --- /dev/null +++ b/.install.lock @@ -0,0 +1 @@ +2026-05-24 21:55:43 installed \ No newline at end of file diff --git a/Mobile-Detect/LICENSE b/Mobile-Detect/LICENSE new file mode 100755 index 0000000..69d9874 --- /dev/null +++ b/Mobile-Detect/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Şerban Ghiţă, Nick Ilyin and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Mobile-Detect/MobileDetect.json b/Mobile-Detect/MobileDetect.json new file mode 100755 index 0000000..a4d1d22 --- /dev/null +++ b/Mobile-Detect/MobileDetect.json @@ -0,0 +1,233 @@ +{ + "version": "3.74.3", + "headerMatch": { + "HTTP_ACCEPT": { + "matches": [ + "application\/x-obml2d", + "application\/vnd.rim.html", + "text\/vnd.wap.wml", + "application\/vnd.wap.xhtml+xml" + ] + }, + "HTTP_X_WAP_PROFILE": null, + "HTTP_X_WAP_CLIENTID": null, + "HTTP_WAP_CONNECTION": null, + "HTTP_PROFILE": null, + "HTTP_X_OPERAMINI_PHONE_UA": null, + "HTTP_X_NOKIA_GATEWAY_ID": null, + "HTTP_X_ORANGE_ID": null, + "HTTP_X_VODAFONE_3GPDPCONTEXT": null, + "HTTP_X_HUAWEI_USERID": null, + "HTTP_UA_OS": null, + "HTTP_X_MOBILE_GATEWAY": null, + "HTTP_X_ATT_DEVICEID": null, + "HTTP_UA_CPU": { + "matches": [ + "ARM" + ] + } + }, + "uaHttpHeaders": [ + "HTTP_USER_AGENT", + "HTTP_X_OPERAMINI_PHONE_UA", + "HTTP_X_DEVICE_USER_AGENT", + "HTTP_X_ORIGINAL_USER_AGENT", + "HTTP_X_SKYFIRE_PHONE", + "HTTP_X_BOLT_PHONE_UA", + "HTTP_DEVICE_STOCK_UA", + "HTTP_X_UCBROWSER_DEVICE_UA" + ], + "uaMatch": { + "phones": { + "iPhone": "\\biPhone\\b|\\biPod\\b", + "BlackBerry": "BlackBerry|\\bBB10\\b|rim[0-9]+|\\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\\b-[0-9]+", + "Pixel": "; \\bPixel\\b", + "HTC": "HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel", + "Nexus": "Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 5X|Nexus 6", + "Dell": "Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b", + "Motorola": "Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092|XT1052", + "Samsung": "\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F|SM-G610F|SM-G981B|SM-G892A|SM-A530F|SM-G988N|SM-G781B|SM-A805N|SM-G965F", + "LG": "\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710", + "Sony": "SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533|SOV34|601SO|F8332", + "Asus": "Asus.*Galaxy|PadFone.*Mobile|ASUS_Z01QD|ASUS_X00TD", + "Xiaomi": "^(?!.*\\bx11\\b).*xiaomi.*$|POCOPHONE F1|\\bMI\\b 8|\\bMi\\b 10|Redmi Note 9S|Redmi 5A|Redmi Note 5A Prime|Redmi Note 7 Pro|N2G47H|M2001J2G|M2001J2I|M1805E10A|M2004J11G|M1902F1G|M2002J9G|M2004J19G|M2003J6A1G|M2012K11C|M2007J1SC", + "NokiaLumia": "Lumia [0-9]{3,4}", + "Micromax": "Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b", + "Palm": "PalmSource|Palm", + "Vertu": "Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature", + "Pantech": "PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790", + "Fly": "IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250", + "Wiko": "KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM", + "iMobile": "i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)", + "SimValley": "\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b", + "Wolfgang": "AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q", + "Alcatel": "Alcatel", + "Nintendo": "Nintendo (3DS|Switch)", + "Amoi": "Amoi", + "INQ": "INQ", + "OnePlus": "ONEPLUS", + "GenericPhone": "Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser" + }, + "tablets": { + "iPad": "iPad|iPad.*Mobile", + "NexusTablet": "Android.*Nexus[\\s]+(7|9|10)", + "GoogleTablet": "Android.*Pixel C", + "SamsungTablet": "SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V|SM-P610|SM-T290|SM-T515|SM-T590|SM-T595|SM-T725|SM-T817P|SM-P585N0|SM-T395|SM-T295|SM-T865|SM-P610N|SM-P615|SM-T970|SM-T380|SM-T5950|SM-T905|SM-T231|SM-T500|SM-T860|SM-T536|SM-T837A|SM-X200|SM-T220|SM-T870|SM-X906C|SM-X700|SM-X706|SM-X706B|SM-X706U|SM-X706N|SM-X800|SM-X806|SM-X806B|SM-X806U|SM-X806N|SM-X900|SM-X906|SM-X906B|SM-X906U|SM-X906N|SM-P613", + "Kindle": "Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk\/[0-9.]+ like Chrome\/[0-9.]+ (?!Mobile)", + "SurfaceTablet": "Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)", + "HPTablet": "HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10", + "AsusTablet": "^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K01A | K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b|\\bP024\\b|\\bP00C\\b", + "BlackBerryTablet": "PlayBook|RIM Tablet", + "HTCtablet": "HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410", + "MotorolaTablet": "xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617", + "NookTablet": "Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2", + "AcerTablet": "Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30|A3-A40", + "ToshibaTablet": "Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO", + "LGTablet": "\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b", + "FujitsuTablet": "Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b", + "PrestigioTablet": "PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002", + "LenovoTablet": "Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X|TB-X704F|TB-X104F|TB3-X70F|TB-X705F|TB-8504F|TB3-X70L|TB3-710F|TB-X704L|TB-J606F|TB-X606F|TB-X306X|YT-J706X|TB128FU", + "DellTablet": "Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7", + "XiaomiTablet": "21051182G", + "YarvikTablet": "Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b", + "MedionTablet": "Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB", + "ArnovaTablet": "97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2", + "IntensoTablet": "INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004", + "IRUTablet": "M702pro", + "MegafonTablet": "MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b", + "EbodaTablet": "E-Boda (Supreme|Impresspeed|Izzycomm|Essential)", + "AllViewTablet": "Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)", + "ArchosTablet": "\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b", + "AinolTablet": "NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark", + "NokiaLumiaTablet": "Lumia 2520", + "SonyTablet": "Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712", + "PhilipsTablet": "\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b", + "CubeTablet": "Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT", + "CobyTablet": "MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010", + "MIDTablet": "M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10", + "MSITablet": "MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b", + "SMiTTablet": "Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)", + "RockChipTablet": "Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A", + "FlyTablet": "IQ310|Fly Vision", + "bqTablet": "Android.*(bq)?.*\\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\\b|Maxwell.*Lite|Maxwell.*Plus", + "HuaweiTablet": "MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19|KOB2-L09|BG2-U01|BG2-W09|BG2-U03", + "NecTablet": "\\bN-06D|\\bN-08D", + "PantechTablet": "Pantech.*P4100", + "BronchoTablet": "Broncho.*(N701|N708|N802|a710)", + "VersusTablet": "TOUCHPAD.*[78910]|\\bTOUCHTAB\\b", + "ZyncTablet": "z1000|Z99 2G|z930|z990|z909|Z919|z900", + "PositivoTablet": "TB07STA|TB10STA|TB07FTA|TB10FTA", + "NabiTablet": "Android.*\\bNabi", + "KoboTablet": "Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build", + "DanewTablet": "DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b", + "TexetTablet": "NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE", + "PlaystationTablet": "Playstation.*(Portable|Vita)", + "TrekstorTablet": "ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab", + "PyleAudioTablet": "\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b", + "AdvanTablet": "Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ", + "DanyTechTablet": "Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1", + "GalapadTablet": "Android [0-9.]+; [a-z-]+; \\bG1\\b", + "MicromaxTablet": "Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b", + "KarbonnTablet": "Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b", + "AllFineTablet": "Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide", + "PROSCANTablet": "\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b", + "YONESTablet": "BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026", + "ChangJiaTablet": "TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503", + "GUTablet": "TX-A1301|TX-M9002|Q702|kf026", + "PointOfViewTablet": "TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10", + "OvermaxTablet": "OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027", + "HCLTablet": "HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync", + "DPSTablet": "DPS Dream 9|DPS Dual 7", + "VistureTablet": "V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10", + "CrestaTablet": "CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989", + "MediatekTablet": "\\bMT8125|MT8389|MT8135|MT8377\\b", + "ConcordeTablet": "Concorde([ ]+)?Tab|ConCorde ReadMan", + "GoCleverTablet": "GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042", + "ModecomTablet": "FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003", + "VoninoTablet": "\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b", + "ECSTablet": "V07OT2|TM105A|S10OT1|TR10CS1", + "StorexTablet": "eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab", + "VodafoneTablet": "SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400", + "EssentielBTablet": "Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2", + "RossMoorTablet": "RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711", + "iMobileTablet": "i-mobile i-note", + "TolinoTablet": "tolino tab [0-9.]+|tolino shine", + "AudioSonicTablet": "\\bC-22Q|T7-QC|T-17B|T-17P\\b", + "AMPETablet": "Android.* A78 ", + "SkkTablet": "Android.* (SKYPAD|PHOENIX|CYCLOPS)", + "TecnoTablet": "TECNO P9|TECNO DP8D", + "JXDTablet": "Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b", + "iJoyTablet": "Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)", + "FX2Tablet": "FX2 PAD7|FX2 PAD10", + "XoroTablet": "KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151", + "ViewsonicTablet": "ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a", + "VerizonTablet": "QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1", + "OdysTablet": "LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10", + "CaptivaTablet": "CAPTIVA PAD", + "IconbitTablet": "NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S", + "TeclastTablet": "T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi", + "OndaTablet": "\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+|V10 \\b4G\\b", + "JaytechTablet": "TPC-PA762", + "BlaupunktTablet": "Endeavour 800NG|Endeavour 1010", + "DigmaTablet": "\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b", + "EvolioTablet": "ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b", + "LavaTablet": "QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b", + "AocTablet": "MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712", + "MpmanTablet": "MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010", + "CelkonTablet": "CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b", + "WolderTablet": "miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b", + "MediacomTablet": "M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA", + "MiTablet": "\\bMI PAD\\b|\\bHM NOTE 1W\\b", + "NibiruTablet": "Nibiru M1|Nibiru Jupiter One", + "NexoTablet": "NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI", + "LeaderTablet": "TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100", + "UbislateTablet": "UbiSlate[\\s]?7C", + "PocketBookTablet": "Pocketbook", + "KocasoTablet": "\\b(TB-1207)\\b", + "HisenseTablet": "\\b(F5281|E2371)\\b", + "Hudl": "Hudl HT7S3|Hudl 2", + "TelstraTablet": "T-Hub2", + "GenericTablet": "Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b|WVT101|TM1088|KT107" + }, + "browsers": { + "Chrome": "\\bCrMo\\b|CriOS.*Mobile|Android.*Chrome\/[.0-9]* Mobile", + "Dolfin": "\\bDolfin\\b", + "Opera": "Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR\/[0-9.]+$|Coast\/[0-9.]+", + "Skyfire": "Skyfire", + "Edge": "EdgiOS.*Mobile|Mobile Safari\/[.0-9]* Edge", + "IE": "IEMobile|MSIEMobile", + "Firefox": "fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS.*Mobile", + "Bolt": "bolt", + "TeaShark": "teashark", + "Blazer": "Blazer", + "Safari": "Version((?!\\bEdgiOS\\b).)*Mobile.*Safari|Safari.*Mobile|MobileSafari", + "WeChat": "\\bMicroMessenger\\b", + "UCBrowser": "UC.*Browser|UCWEB", + "baiduboxapp": "baiduboxapp", + "baidubrowser": "baidubrowser", + "DiigoBrowser": "DiigoBrowser", + "Mercury": "\\bMercury\\b", + "ObigoBrowser": "Obigo", + "NetFront": "NF-Browser", + "GenericBrowser": "NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger", + "PaleMoon": "Android.*PaleMoon|Mobile.*PaleMoon" + }, + "os": { + "AndroidOS": "Android", + "BlackBerryOS": "blackberry|\\bBB10\\b|rim tablet os", + "PalmOS": "PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino", + "SymbianOS": "Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b", + "WindowsMobileOS": "Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;", + "WindowsPhoneOS": "Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;", + "iOS": "\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia", + "iPadOS": "CPU OS 13", + "SailfishOS": "Sailfish", + "MeeGoOS": "MeeGo", + "MaemoOS": "Maemo", + "JavaOS": "J2ME\/|\\bMIDP\\b|\\bCLDC\\b", + "webOS": "webOS|hpwOS", + "badaOS": "\\bBada\\b", + "BREWOS": "BREW" + } + } +} \ No newline at end of file diff --git a/Mobile-Detect/README.md b/Mobile-Detect/README.md new file mode 100755 index 0000000..51201c7 --- /dev/null +++ b/Mobile-Detect/README.md @@ -0,0 +1,321 @@ +![Mobile Detect](http://demo.mobiledetect.net/logo-github.png) + +# MobileDetect, PHP mobile detection class + +![Workflow status](https://img.shields.io/github/actions/workflow/status/serbanghita/Mobile-Detect/3.74.x-test.yml?style=flat-square) +![Latest tag](https://img.shields.io/github/v/tag/serbanghita/Mobile-Detect?filter=3.*&style=flat-square) +![Monthly Downloads](https://img.shields.io/packagist/dm/mobiledetect/mobiledetectlib?style=flat-square&label=installs) +![Total Downloads](https://img.shields.io/packagist/dt/mobiledetect/mobiledetectlib?style=flat-square&label=installs) +![MIT License](https://img.shields.io/packagist/l/mobiledetect/mobiledetectlib?style=flat-square) + +Mobile Detect is a lightweight PHP class for detecting mobile devices (including tablets). +It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment. + +- MobileDetect class is a +[server-side detection](http://www.w3.org/TR/mwabp/#bp-devcap-detection) PHP class that can help you with your RWD strategy, +it is not a replacement for CSS3 media queries or other forms of client-side feature detection. +- Can detect the difference between a mobile phone and a table by using regexes. +- The accuracy and relevance of the detection is kept by running [tests](./tests) to check for detection conflicts. + +```php +$detect = new \Detection\MobileDetect; +$deviceType = ($detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'phone') : 'computer'); +``` +## Installing + +### Download and include manually + +You need PHP >= `7.4`. + +- [Download the latest release](../../tags) +- Get the PHP class [MobileDetect.php](src/MobileDetect.php) and include it in your PHP source. + +### Composer + +- Install via [composer](https://packagist.org/packages/mobiledetect/mobiledetectlib). +`composer require mobiledetect/mobiledetectlib:3.74` +- Include the dependency in the `composer.json` file: + ```json + { + "require": { + "mobiledetect/mobiledetectlib": "^3.74" + } + } + ``` + +## Contribute + +- Go to * [:iphone: Live demo](https://demo.mobiledetect.net) +- Read [how to contribute](docs/CONTRIBUTING.md) guide. +- Submit a pull request. + +*Donate* + +|Paypal| +|------| +|[Donate :+1:](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=mobiledetectlib%40gmail%2ecom&lc=US&item_name=Mobile%20Detect¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted)| + + +I'm currently paying for hosting and spend a lot of my family time to maintain the project and planning the future releases. +I would highly appreciate any money donations that will keep the research going. + +Special thanks to the community :+1: for donations, JetBrains team for the continuous support and [Dragos Gavrila](https://twitter.com/grafician) who contributed with the logo. + +## Modules, plugins, ports + +[Submit new module, plugin, port](../../issues/new?title=New%203rd%20party%20module&body=Name,%20Link%20and%20Description%20of%20the%20module.) + +**JavaScript** + +* mobile-detect.js - A [JavaScript port](https://github.com/hgoebl/mobile-detect.js) of Mobile-Detect class. Made by [Heinrich Goebl](https://github.com/hgoebl). + +**Varnish Cache** + +* [Varnish Mobile Detect](https://github.com/willemk/varnish-mobiletranslate) - Drop-in varnish solution to mobile user +detection based on the Mobile-Detect library. Made by [willemk](https://github.com/willemk). +* [mobiledetect2vcl](https://github.com/carlosabalde/mobiledetect2vcl) - Python script to transform the Mobile +Detect JSON database into an UA-based mobile detection VCL subroutine easily integrable in any Varnish Cache +configuration. Made by [Carlos Abalde](https://github.com/carlosabalde). + +**LUA** + +* [mobile-detect.lua](https://github.com/yourpalmark/mobile-detect.lua) is a port of Mobile-Detect to Lua for +NGINX HTTP servers. Follows closely to mobile-detect.js. Supports all methods that server-side +mobile-detect.js supports. Fully unit-tested and synced with Travis CI (Build Passing badge included). +Made by [Mark Walters](https://github.com/yourpalmark). + +**PHP** + +**WordPress** + +* [Mobile Detect for WordPress](https://wordpress.org/plugins/tinywp-mobile-detect/) - WordPress has a built-in function +(`wp_is_mobile()`) to detect mobile devices. There is (at least) one catch, though. It considers iPad (iPad pro, +and any tablet) as a mobile. So, this 3rd party module changes the way `wp_is_mobile()` works with the help of +Mobile Detect PHP library! +Made by [Pothi Kalimuthu](https://github.com/pothi) + +* [WordPress Mobile Detect](https://wordpress.org/plugins/wp-mobile-detect/) - Gives you the ability to wrap that +infographic in a `[notdevice][/notdevice]` shortcode so at the server level WordPress will +decide to show that content only if the user is NOT on a phone or tablet. +Made by [Jesse Friedman](https://profiles.wordpress.org/professor44/). + +* [mobble](https://wordpress.org/plugins/mobble/) - provides mobile related conditional functions for your site. +e.g. `is_iphone()`, `is_mobile()` and `is_tablet()`. Made by Scott Evans. + +* [WordPress Responsage](https://github.com/iamspacehead/responsage) - A small WordPress theme plugin that allows +you to make your images responsive. Made by [Adrian Ciaschetti](https://github.com/iamspacehead). + +* [WP247 Body Classes](https://wordpress.org/plugins/wp247-body-classes/) - Add unique classes to the `body` tag for +easy styling based on various attributes (archive, user, post, mobile) and various WordPress "is" functions. +Mobile attributes include type of device, Operating System, Browser, etc. Examples: .is-mobile, .is-not-mobile, +.is-tablet, .is-ios, .is-not-ios, .is-androidos, .is-chromebrowser. +Made by [wescleveland56](https://github.com/wescleveland56). + +* [Adaptive Content](https://wordpress.org/plugins/addfunc-adaptive-content/) for WordPress provides the most +intuitive set of shortcodes for including/excluding content on mobile devices, tablets desktops and other +more specific device parameters. This lightweight plugin lets content writers and theme authors choose when +WordPress should or shouldn’t show any give content item using shortcodes and quicktags or theme elements using functions. +Made by [AddFunc](https://profiles.wordpress.org/addfunc). + +* [AddFunc Mobile Detect](https://wordpress.org/plugins/addfunc-mobile-detect/) for WordPress redirects +mobile traffic to your mobile website and, basically, gives you loads of control over your mobile redirects. +Made by [AddFunc](https://profiles.wordpress.org/addfunc). + +**Drupal** + +* [Drupal Mobile Switch](https://www.drupal.org/project/mobile_switch) - The Mobile Switch Drupal module provides a +automatic theme switch functionality for mobile devices, detected by Browscap or Mobile Detect. +Made by [Siegfried Neumann](https://www.drupal.org/user/45267). + +* [Drupal Context Mobile Detect](https://www.drupal.org/project/context_mobile_detect) - This is a Drupal context module +which integrates Context and PHP Mobile Detect library. +Created by [Artem Shymko](https://www.drupal.org/user/432492). + +* [Drupal Mobile Detect](https://www.drupal.org/project/mobile_detect) - Lightweight mobile detect module for Drupal + created by [Matthew Donadio](https://www.drupal.org/user/325244). + +**Joomla** + +* [yagendoo Joomla! Mobile Detection Plugin](http://www.yagendoo.com/en/blog/free-mobile-detection-plugin-for-joomla.html) - Lightweight PHP plugin for Joomla! +that detects a mobile browser using the Mobile Detect class. +Made by yagendoo media. + +* [User Agent Detector plugin](https://github.com/renekreijveld/UserAgentDetector) - This system plugin detects the user +agent of your website visitor and sets a session variable accordingly. Based on the user agent, the plugin detects if the +site is running on a desktop pc, tablet or smartphone. It can also detect if the visitor is a spider bot (search engine). +Session variable that is set: `ualayout`. Possible values: desktop, tablet, mobile, bot. +Made by @ReneKreijveld. + +**Magento** + +* [Magento helper](http://www.magentocommerce.com/magento-connect/catalog/product/view/id/16835/) from Optimise Web enables +the use of all functions provided by Mobile Detect. Made by [Kathir Vel](http://www.kathirvel.com). + +* [Magento 2 Mobile Detect Theme Change](https://github.com/EaDesgin/magento2-mobiledetect) is an extension for Magento 2 +that will change the theme or redirect to a different URL. Also containing a helper to check for the device type. + +**PrestaShop** + +* [PrestaShop](https://www.prestashop.com) is a free, secure and open source shopping cart platform. Mobile_Detect +is included in the default package since 1.5.x. + +**Laravel** + +* [Agent](https://github.com/jenssegers/agent) is a user agent class for Laravel based on Mobile Detect with some +additional functionality. +Made by [Jens Segers](https://github.com/jenssegers). + +* [Laravel Mobile Detect](https://github.com/riverskies/laravel-mobile-detect) is a package that enables you to use device detection right in your Laravel Blade templates. (Utilises the well-known, constantly updated PHP mobile detection library.) +Made by [Barnabas Kecskes](https://github.com/barnabaskecskes). + +* [BrowserDetect](https://github.com/hisorange/browser-detect) is a browser and mobile detection package, collects +and wrap together the best user-agent identifiers for Laravel. +Created by [Varga Zsolt](https://github.com/hisorange). + +**Zend Framework** + +* [ZF2 Mobile-Detect](https://github.com/neilime/zf2-mobile-detect.git) is a Zend Framework 2 module that provides +Mobile-Detect features (Mobile_Detect class as a service, helper for views and plugin controllers). +Made by [neilime](https://github.com/neilime). + +* [ZF2 MobileDetectModule](https://github.com/nikolaposa/MobileDetectModule) facilitates integration of a PHP MobileDetect +class with some ZF2-based application. Has similar idea like the existing ZF2 Mobile-Detect module, +but differs in initialization and provision routine of the actual Mobile_Detect class. +Appropriate view helper and controller plugin also have different conceptions. +Made by [Nikola Posa](https://github.com/nikolaposa). + +**Symfony** + +* [Symfony3 MobileDetectBundle](https://github.com/tattali/MobileDetectBundle) is a Symfony bundle to detect mobile devices, manage mobile view and redirect to the mobile and tablet version. Made by [Théo Attali](https://github.com/tattali). + +* [Symfony2 Mobile Detect Bundle](https://github.com/suncat2000/MobileDetectBundle) is a bundle for detecting mobile devices, +manage mobile view and redirect to the mobile and tablet version. +Made by [Nikolay Ivlev](https://github.com/suncat2000). + +* [Silex Mobile Detect Service Provider](https://github.com/jbinfo/MobileDetectServiceProvider) is a service provider to +interact with Mobile detect class methods. +Made by [Lhassan Baazzi](https://github.com/jbinfo). + +**Slim Framework** + +* [Slim_Mobile_Detect](https://github.com/zguillez/slim_mobile_detect) implements Mobile_Detect lib for different +responses write on Slim Framework App. + +**ExpressionEngine** + +* [EE2 Detect Mobile](https://github.com/garethtdavies/detect-mobile) is a lightweight PHP plugin for EE2 that detects + a mobile browser using the Mobile Detect class. Made by [Gareth Davies](https://github.com/garethtdavies). + +**Yii Framework** + +* [Yii Extension](https://github.com/iamsalnikov/MobileDetect) - Mobile detect plugin for Yii framework. +Made by [Alexey Salnikov](https://github.com/iamsalnikov). + +* [Yii Extension](https://github.com/candasm/yii1-mobile-detect-component) - Mobile detect component for Yii framework +1.x version which supports composer package manager. Made by [Candas Minareci](https://github.com/candasm). + +* [Yii2 Device Detect](https://github.com/alexandernst/yii2-device-detect/) - Yii2 extension for Mobile-Detect library. +Made by [Alexander Nestorov](https://github.com/alexandernst). + +**CakePHP** + +* [CakePHP MobileDetect](https://github.com/chronon/CakePHP-MobileDetectComponent-Plugin) is a plugin component for +CakePHP 2.x. Made by [Gregory Gaskill](https://github.com/chronon). + +**FuelPHP** + +* [Special Agent](https://github.com/rob-bar/special_agent) is a FuelPHP package which uses php-mobile-detect to +determine whether a device is mobile or not. It overrides the Fuelphp Agent class its methods. +Made by [Robbie Bardjin](https://github.com/rob-bar). + + +**TYPO3** + +* [px_mobiledetect](https://typo3.org/extensions/repository/view/px_mobiledetect) is an extension that helps to detect +visitor's mobile device class (if that’s tablet or mobile device like smartphone). Made by Alexander Tretyak. + +**Other** + +* [PageCache](https://github.com/mmamedov/page-cache) is a lightweight PHP library for full page cache, +with built-in Mobile-Detect support. Made by [Muhammed Mamedov](https://github.com/mmamedov). + +* [Statamic CMS Mobile Detect](https://github.com/haikulab/statamic-mobile-detect) is a plugin. +Made by [Sergei Filippov](https://github.com/haikulab/statamic-mobile-detect) of Haiku Lab. + +* [Kohana Mobile Detect](https://github.com/madeinnordeste/kohana-mobile-detect) is an example of implementation of +Mobile_Detect class with Kohana framework. +Written by [Luiz Alberto S. Ribeiro](https://github.com/madeinnordeste). + +* [MemHT](https://www.memht.com) is a Free PHP CMS and Blog that permit the creation and the management online +of websites with few and easy steps. Has the class included in the core. + +* [concrete5](https://www.concrete5.org) is a CMS that is free and open source. The library is included in the core. + +* [engine7](https://github.com/QOXCorp/exengine) is PHP Open Source Framework. The Mobile_Detect class is included in +the engine. + +* [Zikula](http://zikula.org) is a free and open-source Content Management Framework, which allows you to run +impressive websites and build powerful online applications. The core uses Mobile-Detect to switch to a special +Mobile theme, using jQueryMobile. + +* [UserAgentInfo](https://github.com/quentin389/UserAgentInfo) is a PHP class for parsing user agent strings +(HTTP_USER_AGENT). Includes mobile checks, bot checks, browser types/versions and more. +Based on browscap, Mobile_Detect and ua-parser. Created for high traffic websites and fast batch processing. +Made by [quentin389](https://github.com/quentin389). + +* [LJ Mobile Detect](https://github.com/lewisjenkins/craft-lj-mobiledetect) is a simple implementation of Mobile Detect +for Craft CMS. Made by [Lewis Jenkins](https://github.com/lewisjenkins). + +* [Detect Craft](https://github.com/mmikkel/Detect-Craft) is a Craft CMS wrapper for the Mobile_Detect library. Made by [Mikkel Rummelhoff](https://github.com/mmikkel). + +* [Grav Plugin Mobile Detect](https://github.com/dimitrilongo/grav-plugin-mobile-detect/) is a simple implementation +of Mobile Detect for Grav CMS. Made by [Dimitri Longo](https://github.com/dimitrilongo). + +* [Mobile_Detect module for UliCMS](https://github.com/derUli/ulicms-Mobile_Detect). +Made by [derUli](https://github.com/derUli). + +**Perl** + + * [MobileDetect.pm](https://www.buzzerstar.com/development/) is a Perl module for Mobile Detect. + Made by [Sebastian Enger](https://devop.tools/). + +**Python** + +* [pymobiledetect](https://pypi.python.org/pypi/pymobiledetect) - Mobile detect python package. +Made by Bas van Oostveen. + +**Ruby** + +* [mobile_detect.rb](https://github.com/ktaragorn/mobile_detect) is a Ruby gem using the JSON data exposed by the +php project and implementing a basic subset of the API (as much as can be done by the exposed data). +Made by [Karthik T](https://github.com/ktaragorn). + +**Go** + +* [GoMobileDetect](https://github.com/Shaked/gomobiledetect) is a Go port of Mobile Detect class. +Made by [https://github.com/Shaked](Shaked). + + +**LUA** + +* [ua-lua](https://github.com/robinef/ua-lua) is a small lib written in LUA providing device type detection. +ua-lua is detecting mobile or tablet devices based on user-agent inside nginx daemon. +Made by [Frédéric Robinet](https://github.com/robinef). + +**.Net** + +* [mobile-detect](https://github.com/validide/mobile-detect) is a .Net partial port written in C#. +Made by [Valentin Dide](https://github.com/validide). + +**ColdFusion** + +* [MobileDetect](https://github.com/GiancarloGomez/ColdFusion-MobileDetect) is a CFC port of the +Mobile_Detect PHP Library. Made by [Giancarlo Gomez](https://github.com/GiancarloGomez). + +**Experiments** :bulb: + +* [Mobile Detect Fast](https://bitbucket.org/lanaguani/mobile-detect-fast/) (See: [#474](https://github.com/serbanghita/Mobile-Detect/issues/474)) is a class to increase the performance of Mobile Detect lib. Made by [LanaGuani](https://github.com/lanaguanifw). + +## About + +See [the history](./docs/HISTORY.md) of the project. \ No newline at end of file diff --git a/Mobile-Detect/composer.json b/Mobile-Detect/composer.json new file mode 100755 index 0000000..0858949 --- /dev/null +++ b/Mobile-Detect/composer.json @@ -0,0 +1,40 @@ +{ + "name": "mobiledetect/mobiledetectlib", + "type": "library", + "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", + "keywords": ["mobile", "mobile detect", "mobile detector", "php mobile detect", "detect mobile devices"], + "homepage": "https://github.com/serbanghita/Mobile-Detect", + "license": "MIT", + "authors": [ + { + "name": "Serban Ghita", + "email": "serbanghita@gmail.com", + "homepage": "https://mobiledetect.net", + "role": "Developer" + } + ], + "require": { + "php": ">=7.4" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14", + "phpunit/phpunit": "^9.6", + "squizlabs/php_codesniffer": "^3.7" + }, + "autoload": { + "classmap": [ + "src/MobileDetect.php" + ], + "psr-4": { + "Detection\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "DetectionTests\\": "tests/" + } + }, + "archive": { + "exclude": ["docs", "scripts"] + } +} diff --git a/Mobile-Detect/docker-compose.yml b/Mobile-Detect/docker-compose.yml new file mode 100755 index 0000000..58ce75e --- /dev/null +++ b/Mobile-Detect/docker-compose.yml @@ -0,0 +1,16 @@ +app: + restart: 'on-failure' + image: php:7 + working_dir: /app + command: vendor/bin/phpunit -v -c tests/phpunit.xml --coverage-text --strict-coverage --stop-on-risky + ports: + - "8000:8000" + volumes: + - .:/app + +composer: + restart: 'no' + image: composer/composer:php7 + command: install + volumes: + - .:/app \ No newline at end of file diff --git a/Mobile-Detect/src/MobileDetect.php b/Mobile-Detect/src/MobileDetect.php new file mode 100755 index 0000000..8ee7f6d --- /dev/null +++ b/Mobile-Detect/src/MobileDetect.php @@ -0,0 +1,1419 @@ + (since 2012) + * @author Nick Ilyin + * @author: Victor Stanciu (original author) + * + * @version 3.74.3 + */ +namespace Detection; + +use BadMethodCallException; + +/** + * Auto-generated isXXXX() magic methods. + * php export/dump_magic_methods.php + * + * @method bool isiPhone() + * @method bool isBlackBerry() + * @method bool isPixel() + * @method bool isHTC() + * @method bool isNexus() + * @method bool isDell() + * @method bool isMotorola() + * @method bool isSamsung() + * @method bool isLG() + * @method bool isSony() + * @method bool isAsus() + * @method bool isXiaomi() + * @method bool isNokiaLumia() + * @method bool isMicromax() + * @method bool isPalm() + * @method bool isVertu() + * @method bool isPantech() + * @method bool isFly() + * @method bool isWiko() + * @method bool isiMobile() + * @method bool isSimValley() + * @method bool isWolfgang() + * @method bool isAlcatel() + * @method bool isNintendo() + * @method bool isAmoi() + * @method bool isINQ() + * @method bool isOnePlus() + * @method bool isGenericPhone() + * @method bool isiPad() + * @method bool isNexusTablet() + * @method bool isGoogleTablet() + * @method bool isSamsungTablet() + * @method bool isKindle() + * @method bool isSurfaceTablet() + * @method bool isHPTablet() + * @method bool isAsusTablet() + * @method bool isBlackBerryTablet() + * @method bool isHTCtablet() + * @method bool isMotorolaTablet() + * @method bool isNookTablet() + * @method bool isAcerTablet() + * @method bool isToshibaTablet() + * @method bool isLGTablet() + * @method bool isFujitsuTablet() + * @method bool isPrestigioTablet() + * @method bool isLenovoTablet() + * @method bool isDellTablet() + * @method bool isYarvikTablet() + * @method bool isMedionTablet() + * @method bool isArnovaTablet() + * @method bool isIntensoTablet() + * @method bool isIRUTablet() + * @method bool isMegafonTablet() + * @method bool isEbodaTablet() + * @method bool isAllViewTablet() + * @method bool isArchosTablet() + * @method bool isAinolTablet() + * @method bool isNokiaLumiaTablet() + * @method bool isSonyTablet() + * @method bool isPhilipsTablet() + * @method bool isCubeTablet() + * @method bool isCobyTablet() + * @method bool isMIDTablet() + * @method bool isMSITablet() + * @method bool isSMiTTablet() + * @method bool isRockChipTablet() + * @method bool isFlyTablet() + * @method bool isbqTablet() + * @method bool isHuaweiTablet() + * @method bool isNecTablet() + * @method bool isPantechTablet() + * @method bool isBronchoTablet() + * @method bool isVersusTablet() + * @method bool isZyncTablet() + * @method bool isPositivoTablet() + * @method bool isNabiTablet() + * @method bool isKoboTablet() + * @method bool isDanewTablet() + * @method bool isTexetTablet() + * @method bool isPlaystationTablet() + * @method bool isTrekstorTablet() + * @method bool isPyleAudioTablet() + * @method bool isAdvanTablet() + * @method bool isDanyTechTablet() + * @method bool isGalapadTablet() + * @method bool isMicromaxTablet() + * @method bool isKarbonnTablet() + * @method bool isAllFineTablet() + * @method bool isPROSCANTablet() + * @method bool isYONESTablet() + * @method bool isChangJiaTablet() + * @method bool isGUTablet() + * @method bool isPointOfViewTablet() + * @method bool isOvermaxTablet() + * @method bool isHCLTablet() + * @method bool isDPSTablet() + * @method bool isVistureTablet() + * @method bool isCrestaTablet() + * @method bool isMediatekTablet() + * @method bool isConcordeTablet() + * @method bool isGoCleverTablet() + * @method bool isModecomTablet() + * @method bool isVoninoTablet() + * @method bool isECSTablet() + * @method bool isStorexTablet() + * @method bool isVodafoneTablet() + * @method bool isEssentielBTablet() + * @method bool isRossMoorTablet() + * @method bool isiMobileTablet() + * @method bool isTolinoTablet() + * @method bool isAudioSonicTablet() + * @method bool isAMPETablet() + * @method bool isSkkTablet() + * @method bool isTecnoTablet() + * @method bool isJXDTablet() + * @method bool isiJoyTablet() + * @method bool isFX2Tablet() + * @method bool isXoroTablet() + * @method bool isViewsonicTablet() + * @method bool isVerizonTablet() + * @method bool isOdysTablet() + * @method bool isCaptivaTablet() + * @method bool isIconbitTablet() + * @method bool isTeclastTablet() + * @method bool isOndaTablet() + * @method bool isJaytechTablet() + * @method bool isBlaupunktTablet() + * @method bool isDigmaTablet() + * @method bool isEvolioTablet() + * @method bool isLavaTablet() + * @method bool isAocTablet() + * @method bool isMpmanTablet() + * @method bool isCelkonTablet() + * @method bool isWolderTablet() + * @method bool isMediacomTablet() + * @method bool isMiTablet() + * @method bool isNibiruTablet() + * @method bool isNexoTablet() + * @method bool isLeaderTablet() + * @method bool isUbislateTablet() + * @method bool isPocketBookTablet() + * @method bool isKocasoTablet() + * @method bool isHisenseTablet() + * @method bool isHudl() + * @method bool isTelstraTablet() + * @method bool isGenericTablet() + * @method bool isAndroidOS() + * @method bool isBlackBerryOS() + * @method bool isPalmOS() + * @method bool isSymbianOS() + * @method bool isWindowsMobileOS() + * @method bool isWindowsPhoneOS() + * @method bool isiOS() + * @method bool isiPadOS() + * @method bool isSailfishOS() + * @method bool isMeeGoOS() + * @method bool isMaemoOS() + * @method bool isJavaOS() + * @method bool iswebOS() + * @method bool isbadaOS() + * @method bool isBREWOS() + * @method bool isChrome() + * @method bool isDolfin() + * @method bool isOpera() + * @method bool isSkyfire() + * @method bool isEdge() + * @method bool isIE() + * @method bool isFirefox() + * @method bool isBolt() + * @method bool isTeaShark() + * @method bool isBlazer() + * @method bool isSafari() + * @method bool isWeChat() + * @method bool isUCBrowser() + * @method bool isbaiduboxapp() + * @method bool isbaidubrowser() + * @method bool isDiigoBrowser() + * @method bool isMercury() + * @method bool isObigoBrowser() + * @method bool isNetFront() + * @method bool isGenericBrowser() + * @method bool isPaleMoon() + * @method bool isWebKit() + * @method bool isConsole() + * @method bool isWatch() + */ +class MobileDetect +{ + /** + * A frequently used regular expression to extract version #s. + * + * @deprecated since version 2.6.9 + */ + const VER = '([\w._\+]+)'; + + /** + * Stores the version number of the current release. + */ + const VERSION = '3.74.3'; + + /** + * A type for the version() method indicating a string return value. + */ + const VERSION_TYPE_STRING = 'text'; + + /** + * A type for the version() method indicating a float return value. + */ + const VERSION_TYPE_FLOAT = 'float'; + + /** + * A cache for resolved matches + * @var array + */ + protected array $cache = []; + + /** + * The User-Agent HTTP header is stored in here. + * @var string|null + */ + protected ?string $userAgent = null; + + /** + * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE. + * @var array + */ + protected array $httpHeaders = []; + + /** + * CloudFront headers. E.g. CloudFront-Is-Desktop-Viewer, CloudFront-Is-Mobile-Viewer & CloudFront-Is-Tablet-Viewer. + * @var array + */ + protected array $cloudfrontHeaders = []; + + /** + * The matching Regex. + * This is good for debug. + * @var string|null + */ + protected ?string $matchingRegex = null; + + /** + * The matches extracted from the regex expression. + * This is good for debug. + * + * @var array|null + */ + protected ?array $matchesArray = null; + + /** + * HTTP headers that trigger the 'isMobile' detection + * to be true. + * + * @var array + */ + protected static array $mobileHeaders = [ + + 'HTTP_ACCEPT' => [ + 'matches' => [ + // Opera Mini + // @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/ + 'application/x-obml2d', + // BlackBerry devices. + 'application/vnd.rim.html', + 'text/vnd.wap.wml', + 'application/vnd.wap.xhtml+xml' + ]], + 'HTTP_X_WAP_PROFILE' => null, + 'HTTP_X_WAP_CLIENTID' => null, + 'HTTP_WAP_CONNECTION' => null, + 'HTTP_PROFILE' => null, + // Reported by Opera on Nokia devices (eg. C3). + 'HTTP_X_OPERAMINI_PHONE_UA' => null, + 'HTTP_X_NOKIA_GATEWAY_ID' => null, + 'HTTP_X_ORANGE_ID' => null, + 'HTTP_X_VODAFONE_3GPDPCONTEXT' => null, + 'HTTP_X_HUAWEI_USERID' => null, + // Reported by Windows Smartphones. + 'HTTP_UA_OS' => null, + // Reported by Verizon, Vodafone proxy system. + 'HTTP_X_MOBILE_GATEWAY' => null, + // Seen this on HTC Sensation. SensationXE_Beats_Z715e. + 'HTTP_X_ATT_DEVICEID' => null, + // Seen this on a HTC. + 'HTTP_UA_CPU' => ['matches' => ['ARM']], + ]; + + /** + * List of mobile devices (phones). + * + * @var array + */ + protected static array $phoneDevices = [ + 'iPhone' => '\biPhone\b|\biPod\b', // |\biTunes + 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+|\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\b-[0-9]+', + 'Google Pixel' => '; \bPixel\b', + 'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel', + 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 5X|Nexus 6', + // @todo: Is 'Dell Streak' a tablet or a phone? ;) + 'Dell' => 'Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b', + 'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\bMoto E\b|XT1068|XT1092|XT1052', + 'Samsung' => '\bSamsung\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F|SM-G610F|SM-G981B|SM-G892A|SM-A530F|SM-G988N|SM-G781B|SM-A805N|SM-G965F|SM-G955U', + 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710', + 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533|SOV34|601SO|F8332', + 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile|ASUS_Z01QD|ASUS_X00TD', + 'Xiaomi' => '^(?!.*\bx11\b).*xiaomi.*$|POCOPHONE F1|\bMI\b 8|\bMi\b 10|Redmi Note 9S|Redmi 5A|Redmi Note 5A Prime|Redmi Note 7 Pro|N2G47H|M2001J2G|M2001J2I|M1805E10A|M2004J11G|M1902F1G|M2002J9G|M2004J19G|M2003J6A1G|M2012K11C|M2007J1SC', + 'NokiaLumia' => 'Lumia [0-9]{3,4}', + // http://www.micromaxinfo.com/mobiles/smartphones + // Added because the codes might conflict with Acer Tablets. + 'Micromax' => 'Micromax.*\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\b', + // @todo Complete the regex. + 'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; + 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;) + // http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH) + // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android. + 'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790', + // http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones. + 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250', + // http://fr.wikomobile.com + 'Wiko' => 'KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM', + 'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)', + // Added simvalley mobile just for fun. They have some interesting devices. + // http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html + 'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b', + // Wolfgang - a brand that is sold by Aldi supermarkets. + // http://www.wolfgangmobile.com/ + 'Wolfgang' => 'AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q', + 'Alcatel' => 'Alcatel', + 'Nintendo' => 'Nintendo (3DS|Switch)', + // http://en.wikipedia.org/wiki/Amoi + 'Amoi' => 'Amoi', + // http://en.wikipedia.org/wiki/INQ + 'INQ' => 'INQ', + 'OnePlus' => 'ONEPLUS', + // @Tapatalk is a mobile app; http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039 + 'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser', + ]; + + /** + * List of tablet devices. + * + * @var array + */ + protected static array $tabletDevices = [ + // @todo: check for mobile friendly emails topic. + 'iPad' => 'iPad|iPad.*Mobile', + // Removed |^.*Android.*Nexus(?!(?:Mobile).)*$ + // @see #442 + // @todo Merge NexusTablet into GoogleTablet. + 'NexusTablet' => 'Android.*Nexus[\s]+(7|9|10)', + // https://en.wikipedia.org/wiki/Pixel_C + 'GoogleTablet' => 'Android.*Pixel C', + 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V|SM-P610|SM-T290|SM-T515|SM-T590|SM-T595|SM-T725|SM-T817P|SM-P585N0|SM-T395|SM-T295|SM-T865|SM-P610N|SM-P615|SM-T970|SM-T380|SM-T5950|SM-T905|SM-T231|SM-T500|SM-T860|SM-T536|SM-T837A|SM-X200|SM-T220|SM-T870|SM-X906C|SM-X700|SM-X706|SM-X706B|SM-X706U|SM-X706N|SM-X800|SM-X806|SM-X806B|SM-X806U|SM-X806N|SM-X900|SM-X906|SM-X906B|SM-X906U|SM-X906N|SM-P613', // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone. + // http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html + 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\b|Android.*Silk/[0-9.]+ like Chrome/[0-9.]+ (?!Mobile)', + // Only the Surface tablets with Windows RT are considered mobile. + // http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx + 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)', + // http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT + 'HPTablet' => 'HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10', + // Watch out for PadFone, see #132. + // http://www.asus.com/de/Tablets_Mobile/Memo_Pad_Products/ + 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|\bK00C\b|\bK00E\b|\bK00L\b|TX201LA|ME176C|ME102A|\bM80TA\b|ME372CL|ME560CG|ME372CG|ME302KL| K01A | K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\bME70C\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\bP027\b|\bP024\b|\bP00C\b', + 'BlackBerryTablet' => 'PlayBook|RIM Tablet', + 'HTCtablet' => 'HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410', + 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617', + 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2', + // http://www.acer.ro/ac/ro/RO/content/drivers + // http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer) + // http://us.acer.com/ac/en/US/content/group/tablets + // http://www.acer.de/ac/de/DE/content/models/tablets/ + // Can conflict with Micromax and Motorola phones codes. + 'AcerTablet' => 'Android.*; \b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\b|W3-810|\bA3-A10\b|\bA3-A11\b|\bA3-A20\b|\bA3-A30|A3-A40', + // http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/ + // http://us.toshiba.com/tablets/tablet-finder + // http://www.toshiba.co.jp/regza/tablet/ + 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO', + // http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html + // http://www.lg.com/us/tablets + 'LGTablet' => '\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\b', + 'FujitsuTablet' => 'Android.*\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\b', + // Prestigio Tablets http://www.prestigio.com/support + 'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002', + // http://support.lenovo.com/en_GB/downloads/default.page?# + 'LenovoTablet' => 'Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X|TB-X704F|TB-X104F|TB3-X70F|TB-X705F|TB-8504F|TB3-X70L|TB3-710F|TB-X704L|TB-J606F|TB-X606F|TB-X306X|YT-J706X|TB128FU', + // http://www.dell.com/support/home/us/en/04/Products/tab_mob/tablets + 'DellTablet' => 'Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7', + 'XiaomiTablet' => '21051182G', + // http://www.yarvik.com/en/matrix/tablets/ + 'YarvikTablet' => 'Android.*\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\b', + 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB', + 'ArnovaTablet' => '97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2', + // http://www.intenso.de/kategorie_en.php?kategorie=33 + // @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate + 'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004', + // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/ + 'IRUTablet' => 'M702pro', + 'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b', + // http://www.e-boda.ro/tablete-pc.html + 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)', + // http://www.allview.ro/produse/droseries/lista-tablete-pc/ + 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)', + // http://wiki.archosfans.com/index.php?title=Main_Page + // @note Rewrite the regex format after we add more UAs. + 'ArchosTablet' => '\b(101G9|80G9|A101IT)\b|Qilive 97R|Archos5|\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\b', + // http://www.ainol.com/plugin.php?identifier=ainol&module=product + 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark', + 'NokiaLumiaTablet' => 'Lumia 2520', + // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER + // Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser + // http://www.sony.jp/support/tablet/ + 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712', + // http://www.support.philips.com/support/catalog/worldproducts.jsp?userLanguage=en&userCountry=cn&categoryid=3G_LTE_TABLET_SU_CN_CARE&title=3G%20tablets%20/%20LTE%20range&_dyncharset=UTF-8 + 'PhilipsTablet' => '\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\b', + // db + http://www.cube-tablet.com/buy-products.html + 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT', + // http://www.cobyusa.com/?p=pcat&pcat_id=3001 + 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010', + // http://www.match.net.cn/products.asp + 'MIDTablet' => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10', + // http://www.msi.com/support + // @todo Research the Windows Tablets. + 'MSITablet' => 'MSI \b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\b', + // @todo http://www.kyoceramobile.com/support/drivers/ + // 'KyoceraTablet' => null, + // @todo http://intexuae.com/index.php/category/mobile-devices/tablets-products/ + // 'IntextTablet' => null, + // http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets) + // http://www.imp3.net/14/show.php?itemid=20454 + 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)', + // http://www.rock-chips.com/index.php?do=prod&pid=2 + 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A', + // http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/ + 'FlyTablet' => 'IQ310|Fly Vision', + // http://www.bqreaders.com/gb/tablets-prices-sale.html + 'bqTablet' => 'Android.*(bq)?.*\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\b|Maxwell.*Lite|Maxwell.*Plus', + // http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290 + // http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets) + 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19|KOB2-L09|BG2-U01|BG2-W09|BG2-U03', + // Nec or Medias Tab + 'NecTablet' => '\bN-06D|\bN-08D', + // Pantech Tablets: http://www.pantechusa.com/phones/ + 'PantechTablet' => 'Pantech.*P4100', + // Broncho Tablets: http://www.broncho.cn/ (hard to find) + 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)', + // http://versusuk.com/support.html + 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b', + // http://www.zync.in/index.php/our-products/tablet-phablets + 'ZyncTablet' => 'z1000|Z99 2G|z930|z990|z909|Z919|z900', // Removed "z999" because of https://github.com/serbanghita/Mobile-Detect/issues/717 + // http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/ + 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA', + // https://www.nabitablet.com/ + 'NabiTablet' => 'Android.*\bNabi', + 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build', + // French Danew Tablets http://www.danew.com/produits-tablette.php + 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b', + // Texet Tablets and Readers http://www.texet.ru/tablet/ + 'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE', + // Avoid detecting 'PLAYSTATION 3' as mobile. + 'PlaystationTablet' => 'Playstation.*(Portable|Vita)', + // http://www.trekstor.de/surftabs.html + 'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab', + // http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets + 'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b', + // http://www.advandigital.com/index.php?link=content-product&jns=JP001 + // because of the short codenames we have to include whitespaces to reduce the possible conflicts. + 'AdvanTablet' => 'Android.* \b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\b ', + // http://www.danytech.com/category/tablet-pc + 'DanyTechTablet' => 'Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1', + // http://www.galapad.net/product.html ; https://github.com/serbanghita/Mobile-Detect/issues/761 + 'GalapadTablet' => 'Android [0-9.]+; [a-z-]+; \bG1\b', + // http://www.micromaxinfo.com/tablet/funbook + 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b', + // http://www.karbonnmobiles.com/products_tablet.php + 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b', + // http://www.myallfine.com/Products.asp + 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide', + // http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr= + 'PROSCANTablet' => '\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\b', + // http://www.yonesnav.com/products/products.php + 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026', + // http://www.cjshowroom.com/eproducts.aspx?classcode=004001001 + // China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html) + 'ChangJiaTablet' => 'TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503', + // http://www.gloryunion.cn/products.asp + // http://www.allwinnertech.com/en/apply/mobile.html + // http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB) + // @todo: Softwiner tablets? + // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions. + 'GUTablet' => 'TX-A1301|TX-M9002|Q702|kf026', // A12R|D75A|D77|D79|R83|A95|A106C|R15|A75|A76|D71|D72|R71|R73|R77|D82|R85|D92|A97|D92|R91|A10F|A77F|W71F|A78F|W78F|W81F|A97F|W91F|W97F|R16G|C72|C73E|K72|K73|R96G + // http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118 + 'PointOfViewTablet' => 'TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10', + // http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/ + // @todo: add more tests. + 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027', + // http://hclmetablet.com/India/index.php + 'HCLTablet' => 'HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync', + // http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html + 'DPSTablet' => 'DPS Dream 9|DPS Dual 7', + // http://www.visture.com/index.asp + 'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10', + // http://www.mijncresta.nl/tablet + 'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989', + // MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309 + 'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b', + // Concorde tab + 'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan', + // GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/ + 'GoCleverTablet' => 'GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042', + // Modecom Tablets - http://www.modecom.eu/tablets/portal/ + 'ModecomTablet' => 'FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003', + // Vonino Tablets + 'VoninoTablet' => '\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\bQ8\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\b', + // ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0 + 'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1', + // Storex Tablets - http://storex.fr/espace_client/support.html + // @note: no need to add all the tablet codes since they are guided by the first regex. + 'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab', + // Generic Vodafone tablets. + 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400', + // French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb + // Aka: http://www.essentielb.fr/ + 'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2', + // Ross & Moor - http://ross-moor.ru/ + 'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711', + // i-mobile http://product.i-mobilephone.com/Mobile_Device + 'iMobileTablet' => 'i-mobile i-note', + // http://www.tolino.de/de/vergleichen/ + 'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine', + // AudioSonic - a Kmart brand + // http://www.kmart.com.au/webapp/wcs/stores/servlet/Search?langId=-1&storeId=10701&catalogId=10001&categoryId=193001&pageSize=72¤tPage=1&searchCategory=193001%2b4294965664&sortBy=p_MaxPrice%7c1 + 'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b', + // AMPE Tablets - http://www.ampe.com.my/product-category/tablets/ + // @todo: add them gradually to avoid conflicts. + 'AMPETablet' => 'Android.* A78 ', + // Skk Mobile - http://skkmobile.com.ph/product_tablets.php + 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)', + // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1 + 'TecnoTablet' => 'TECNO P9|TECNO DP8D', + // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3 + 'JXDTablet' => 'Android.* \b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\b', + // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/ + 'iJoyTablet' => 'Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)', + // http://www.intracon.eu/tablet + 'FX2Tablet' => 'FX2 PAD7|FX2 PAD10', + // http://www.xoro.de/produkte/ + // @note: Might be the same brand with 'Simply tablets' + 'XoroTablet' => 'KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151', + // http://www1.viewsonic.com/products/computing/tablets/ + 'ViewsonicTablet' => 'ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a', + // https://www.verizonwireless.com/tablets/verizon/ + 'VerizonTablet' => 'QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1', + // http://www.odys.de/web/internet-tablet_en.html + 'OdysTablet' => 'LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\bXELIO\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10', + // http://www.captiva-power.de/products.html#tablets-en + 'CaptivaTablet' => 'CAPTIVA PAD', + // IconBIT - http://www.iconbit.com/products/tablets/ + 'IconbitTablet' => 'NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S', + // http://www.teclast.com/topic.php?channelID=70&topicID=140&pid=63 + 'TeclastTablet' => 'T98 4G|\bP80\b|\bX90HD\b|X98 Air|X98 Air 3G|\bX89\b|P80 3G|\bX80h\b|P98 Air|\bX89HD\b|P98 3G|\bP90HD\b|P89 3G|X98 3G|\bP70h\b|P79HD 3G|G18d 3G|\bP79HD\b|\bP89s\b|\bA88\b|\bP10HD\b|\bP19HD\b|G18 3G|\bP78HD\b|\bA78\b|\bP75\b|G17s 3G|G17h 3G|\bP85t\b|\bP90\b|\bP11\b|\bP98t\b|\bP98HD\b|\bG18d\b|\bP85s\b|\bP11HD\b|\bP88s\b|\bA80HD\b|\bA80se\b|\bA10h\b|\bP89\b|\bP78s\b|\bG18\b|\bP85\b|\bA70h\b|\bA70\b|\bG17\b|\bP18\b|\bA80s\b|\bA11s\b|\bP88HD\b|\bA80h\b|\bP76s\b|\bP76h\b|\bP98\b|\bA10HD\b|\bP78\b|\bP88\b|\bA11\b|\bA10t\b|\bP76a\b|\bP76t\b|\bP76e\b|\bP85HD\b|\bP85a\b|\bP86\b|\bP75HD\b|\bP76v\b|\bA12\b|\bP75a\b|\bA15\b|\bP76Ti\b|\bP81HD\b|\bA10\b|\bT760VE\b|\bT720HD\b|\bP76\b|\bP73\b|\bP71\b|\bP72\b|\bT720SE\b|\bC520Ti\b|\bT760\b|\bT720VE\b|T720-3GE|T720-WiFi', + // Onda - http://www.onda-tablet.com/buy-android-onda.html?dir=desc&limit=all&order=price + 'OndaTablet' => '\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\b[\s]+|V10 \b4G\b', + 'JaytechTablet' => 'TPC-PA762', + 'BlaupunktTablet' => 'Endeavour 800NG|Endeavour 1010', + // http://www.digma.ru/support/download/ + // @todo: Ebooks also (if requested) + 'DigmaTablet' => '\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\b', + // http://www.evolioshop.com/ro/tablete-pc.html + // http://www.evolio.ro/support/downloads_static.html?cat=2 + // @todo: Research some more + 'EvolioTablet' => 'ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\bEvotab\b|\bNeura\b', + // @todo http://www.lavamobiles.com/tablets-data-cards + 'LavaTablet' => 'QPAD E704|\bIvoryS\b|E-TAB IVORY|\bE-TAB\b', + // http://www.breezetablet.com/ + 'AocTablet' => 'MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712', + // http://www.mpmaneurope.com/en/products/internet-tablets-14/android-tablets-14/ + 'MpmanTablet' => 'MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\bMPG7\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010', + // https://www.celkonmobiles.com/?_a=categoryphones&sid=2 + 'CelkonTablet' => 'CT695|CT888|CT[\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\bCT-1\b', + // http://www.wolderelectronics.com/productos/manuales-y-guias-rapidas/categoria-2-miTab + 'WolderTablet' => 'miTab \b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\b', + 'MediacomTablet' => 'M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA', + // http://www.mi.com/en + 'MiTablet' => '\bMI PAD\b|\bHM NOTE 1W\b', + // http://www.nbru.cn/index.html + 'NibiruTablet' => 'Nibiru M1|Nibiru Jupiter One', + // http://navroad.com/products/produkty/tablety/ + // http://navroad.com/products/produkty/tablety/ + 'NexoTablet' => 'NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI', + // http://leader-online.com/new_site/product-category/tablets/ + // http://www.leader-online.net.au/List/Tablet + 'LeaderTablet' => 'TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100', + // http://www.datawind.com/ubislate/ + 'UbislateTablet' => 'UbiSlate[\s]?7C', + // http://www.pocketbook-int.com/ru/support + 'PocketBookTablet' => 'Pocketbook', + // http://www.kocaso.com/product_tablet.html + 'KocasoTablet' => '\b(TB-1207)\b', + // http://global.hisense.com/product/asia/tablet/Sero7/201412/t20141215_91832.htm + 'HisenseTablet' => '\b(F5281|E2371)\b', + // http://www.tesco.com/direct/hudl/ + 'Hudl' => 'Hudl HT7S3|Hudl 2', + // http://www.telstra.com.au/home-phone/thub-2/ + 'TelstraTablet' => 'T-Hub2', + 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\bM6pro\b|CT1020W|arc 10HD|\bTP750\b|\bQTAQZ3\b|WVT101|TM1088|KT107' + ]; + + /** + * List of mobile Operating Systems. + * + * @var array + */ + protected static array $operatingSystems = [ + 'AndroidOS' => 'Android', + 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os', + 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino', + 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b', + // @reference: http://en.wikipedia.org/wiki/Windows_Mobile + 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;', + // @reference: http://en.wikipedia.org/wiki/Windows_Phone + // http://wifeng.cn/?r=blog&a=view&id=106 + // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx + // http://msdn.microsoft.com/library/ms537503.aspx + // https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx + 'WindowsPhoneOS' => 'Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;', + 'iOS' => '\biPhone.*Mobile|\biPod|\biPad|AppleCoreMedia', + // https://en.wikipedia.org/wiki/IPadOS + 'iPadOS' => 'CPU OS 13', + // @reference https://en.m.wikipedia.org/wiki/Sailfish_OS + // https://sailfishos.org/ + 'SailfishOS' => 'Sailfish', + // http://en.wikipedia.org/wiki/MeeGo + // @todo: research MeeGo in UAs + 'MeeGoOS' => 'MeeGo', + // http://en.wikipedia.org/wiki/Maemo + // @todo: research Maemo in UAs + 'MaemoOS' => 'Maemo', + 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135 + 'webOS' => 'webOS|hpwOS', + 'badaOS' => '\bBada\b', + 'BREWOS' => 'BREW', + ]; + + /** + * List of mobile User Agents. + * + * IMPORTANT: This is a list of only mobile browsers. + * Mobile Detect 2.x supports only mobile browsers, + * it was never designed to detect all browsers. + * The change will come in 2017 in the 3.x release for PHP7. + * + * @var array + */ + protected static array $browsers = [ + //'Vivaldi' => 'Vivaldi', + // @reference: https://developers.google.com/chrome/mobile/docs/user-agent + 'Chrome' => '\bCrMo\b|CriOS.*Mobile|Android.*Chrome/[.0-9]* Mobile', + 'Dolfin' => '\bDolfin\b', + 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+$|Coast/[0-9.]+', + 'Skyfire' => 'Skyfire', + // Added "Edge on iOS" https://github.com/serbanghita/Mobile-Detect/issues/764 + 'Edge' => 'EdgiOS.*Mobile|Mobile Safari/[.0-9]* Edge', + 'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+ + 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS.*Mobile', + 'Bolt' => 'bolt', + 'TeaShark' => 'teashark', + 'Blazer' => 'Blazer', + // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3 + // Excluded "Edge on iOS" https://github.com/serbanghita/Mobile-Detect/issues/764 + 'Safari' => 'Version((?!\bEdgiOS\b).)*Mobile.*Safari|Safari.*Mobile|MobileSafari', + // http://en.wikipedia.org/wiki/Midori_(web_browser) + //'Midori' => 'midori', + //'Tizen' => 'Tizen', + 'WeChat' => '\bMicroMessenger\b', + 'UCBrowser' => 'UC.*Browser|UCWEB', + 'baiduboxapp' => 'baiduboxapp', + 'baidubrowser' => 'baidubrowser', + // https://github.com/serbanghita/Mobile-Detect/issues/7 + 'DiigoBrowser' => 'DiigoBrowser', + // http://www.puffinbrowser.com/index.php + // https://github.com/serbanghita/Mobile-Detect/issues/752 + // 'Puffin' => 'Puffin', + // http://mercury-browser.com/index.html + 'Mercury' => '\bMercury\b', + // http://en.wikipedia.org/wiki/Obigo_Browser + 'ObigoBrowser' => 'Obigo', + // http://en.wikipedia.org/wiki/NetFront + 'NetFront' => 'NF-Browser', + // @reference: http://en.wikipedia.org/wiki/Minimo + // http://en.wikipedia.org/wiki/Vision_Mobile_Browser + 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger', + // @reference: https://en.wikipedia.org/wiki/Pale_Moon_(web_browser) + 'PaleMoon' => 'Android.*PaleMoon|Mobile.*PaleMoon', + ]; + + /** + * All possible HTTP headers that represent the + * User-Agent string. + * + * @var array + */ + protected static array $uaHttpHeaders = [ + // The default User-Agent string. + 'HTTP_USER_AGENT', + // Header can occur on devices using Opera Mini. + 'HTTP_X_OPERAMINI_PHONE_UA', + // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/ + 'HTTP_X_DEVICE_USER_AGENT', + 'HTTP_X_ORIGINAL_USER_AGENT', + 'HTTP_X_SKYFIRE_PHONE', + 'HTTP_X_BOLT_PHONE_UA', + 'HTTP_DEVICE_STOCK_UA', + 'HTTP_X_UCBROWSER_DEVICE_UA' + ]; + + /** + * The individual segments that could exist in a User-Agent string. VER refers to the regular + * expression defined in the constant self::VER. + * + * @var array + */ + protected static array $properties = [ + + // Build + 'Mobile' => 'Mobile/[VER]', + 'Build' => 'Build/[VER]', + 'Version' => 'Version/[VER]', + 'VendorID' => 'VendorID/[VER]', + + // Devices + 'iPad' => 'iPad.*CPU[a-z ]+[VER]', + 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]', + 'iPod' => 'iPod.*CPU[a-z ]+[VER]', + //'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'), + 'Kindle' => 'Kindle/[VER]', + + // Browser + 'Chrome' => ['Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'], + 'Coast' => ['Coast/[VER]'], + 'Dolfin' => 'Dolfin/[VER]', + // @reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox + 'Firefox' => ['Firefox/[VER]', 'FxiOS/[VER]'], + 'Fennec' => 'Fennec/[VER]', + // http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx + // https://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx + 'Edge' => 'Edge/[VER]', + 'IE' => ['IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];', 'Trident/[0-9.]+;.*rv:[VER]'], + // http://en.wikipedia.org/wiki/NetFront + 'NetFront' => 'NetFront/[VER]', + 'NokiaBrowser' => 'NokiaBrowser/[VER]', + 'Opera' => [' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]'], + 'Opera Mini' => 'Opera Mini/[VER]', + 'Opera Mobi' => 'Version/[VER]', + 'UCBrowser' => ['UCWEB[VER]', 'UC.*Browser/[VER]'], + 'MQQBrowser' => 'MQQBrowser/[VER]', + 'MicroMessenger' => 'MicroMessenger/[VER]', + 'baiduboxapp' => 'baiduboxapp/[VER]', + 'baidubrowser' => 'baidubrowser/[VER]', + 'SamsungBrowser' => 'SamsungBrowser/[VER]', + 'Iron' => 'Iron/[VER]', + // @note: Safari 7534.48.3 is actually Version 5.1. + // @note: On BlackBerry the Version is overwriten by the OS. + 'Safari' => ['Version/[VER]', 'Safari/[VER]'], + 'Skyfire' => 'Skyfire/[VER]', + 'Tizen' => 'Tizen/[VER]', + 'Webkit' => 'webkit[ /][VER]', + 'PaleMoon' => 'PaleMoon/[VER]', + 'SailfishBrowser' => 'SailfishBrowser/[VER]', + + // Engine + 'Gecko' => 'Gecko/[VER]', + 'Trident' => 'Trident/[VER]', + 'Presto' => 'Presto/[VER]', + 'Goanna' => 'Goanna/[VER]', + + // OS + 'iOS' => ' \bi?OS\b [VER][ ;]{1}', + 'Android' => 'Android [VER]', + 'Sailfish' => 'Sailfish [VER]', + 'BlackBerry' => ['BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'], + 'BREW' => 'BREW [VER]', + 'Java' => 'Java/[VER]', + // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx + // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases + 'Windows Phone OS' => ['Windows Phone OS [VER]', 'Windows Phone [VER]'], + 'Windows Phone' => 'Windows Phone [VER]', + 'Windows CE' => 'Windows CE/[VER]', + // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd + 'Windows NT' => 'Windows NT [VER]', + 'Symbian' => ['SymbianOS/[VER]', 'Symbian/[VER]'], + 'webOS' => ['webOS/[VER]', 'hpwOS/[VER];'], + ]; + + /** + * Construct an instance of this class. + * + * @param array|null $headers Specify the headers as injection. Should be PHP _SERVER flavored. + * If left empty, will use the global _SERVER['HTTP_*'] vars instead. + * @param string|null $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT + * from the $headers array instead. + */ + public function __construct(array $headers = null, string $userAgent = null) + { + $this->setHttpHeaders($headers); + $this->setUserAgent($userAgent); + } + + /** + * Get the current script version. + * This is useful for the demo.php file, + * so people can check on what version they are testing + * for mobile devices. + * + * @return string The version number in semantic version format. + */ + public static function getScriptVersion(): string + { + return self::VERSION; + } + + /** + * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers. + * + * @param array|null $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract + * the headers. The default null is left for backwards compatibility. + */ + public function setHttpHeaders(array $httpHeaders = null) + { + // use global _SERVER if $httpHeaders aren't defined + if (!is_array($httpHeaders) || !count($httpHeaders)) { + $httpHeaders = $_SERVER; + } + + // clear existing headers + $this->httpHeaders = array(); + + // Only save HTTP headers. In PHP land, that means only _SERVER vars that + // start with HTTP_. + foreach ($httpHeaders as $key => $value) { + if (substr($key, 0, 5) === 'HTTP_') { + $this->httpHeaders[$key] = $value; + } + } + + // In case we're dealing with CloudFront, we need to know. + $this->setCfHeaders($httpHeaders); + } + + /** + * Retrieves the HTTP headers. + * + * @return array + */ + public function getHttpHeaders(): array + { + return $this->httpHeaders; + } + + /** + * Retrieves a particular header. If it doesn't exist, no exception/error is caused. + * Simply null is returned. + * + * @param string $header The name of the header to retrieve. Can be HTTP compliant such as + * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the + * all-caps, HTTP_ prefixed, underscore separated awesomeness. + * + * @return string|null The value of the header. + */ + public function getHttpHeader(string $header): ?string + { + // are we using PHP-flavored headers? + if (strpos($header, '_') === false) { + $header = str_replace('-', '_', $header); + $header = strtoupper($header); + } + + // test the alternate, too + $altHeader = 'HTTP_' . $header; + + //Test both the regular and the HTTP_ prefix + if (isset($this->httpHeaders[$header])) { + return $this->httpHeaders[$header]; + } elseif (isset($this->httpHeaders[$altHeader])) { + return $this->httpHeaders[$altHeader]; + } + + return null; + } + + public function getMobileHeaders(): array + { + return static::$mobileHeaders; + } + + /** + * Get all possible HTTP headers that + * can contain the User-Agent string. + * + * @return array List of HTTP headers. + */ + public function getUaHttpHeaders(): array + { + return static::$uaHttpHeaders; + } + + + /** + * Set CloudFront headers + * http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device + * + * @param array|null $cfHeaders List of HTTP headers + * + * @return bool If there were CloudFront headers to be set + */ + public function setCfHeaders(array $cfHeaders = null): bool + { + // use global _SERVER if $cfHeaders aren't defined + if (!is_array($cfHeaders) || !count($cfHeaders)) { + $cfHeaders = $_SERVER; + } + + // clear existing headers + $this->cloudfrontHeaders = array(); + + // Only save CLOUDFRONT headers. In PHP land, that means only _SERVER vars that + // start with cloudfront-. + $response = false; + foreach ($cfHeaders as $key => $value) { + if (substr(strtolower($key), 0, 16) === 'http_cloudfront_') { + $this->cloudfrontHeaders[strtoupper($key)] = $value; + $response = true; + } + } + + return $response; + } + + /** + * Retrieves the cloudfront headers. + * + * @return array + */ + public function getCfHeaders(): array + { + return $this->cloudfrontHeaders; + } + + /** + * @param string $userAgent + * @return string + */ + private function prepareUserAgent(string $userAgent): string + { + $userAgent = trim($userAgent); + return substr($userAgent, 0, 500); + } + + /** + * Set the User-Agent to be used. + * + * @param string|null $userAgent The user agent string to set. + * + * @return string|null + */ + public function setUserAgent(string $userAgent = null): ?string + { + // Invalidate cache due to #375 + $this->cache = array(); + + if (false === empty($userAgent)) { + return $this->userAgent = $this->prepareUserAgent($userAgent); + } else { + $this->userAgent = null; + foreach ($this->getUaHttpHeaders() as $altHeader) { + // @todo: should use getHttpHeader(), but it would be slow. (Serban) + if (false === empty($this->httpHeaders[$altHeader])) { + $this->userAgent .= $this->httpHeaders[$altHeader] . " "; + } + } + + if (!empty($this->userAgent)) { + return $this->userAgent = $this->prepareUserAgent($this->userAgent); + } + } + + if (count($this->getCfHeaders()) > 0) { + return $this->userAgent = 'Amazon CloudFront'; + } + return $this->userAgent = null; + } + + /** + * Retrieve the User-Agent. + * + * @return string|null The user agent if it's set. + */ + public function getUserAgent(): ?string + { + return $this->userAgent; + } + + public function getMatchingRegex(): ?string + { + return $this->matchingRegex; + } + + public function getMatchesArray(): ?array + { + return $this->matchesArray; + } + + /** + * Retrieve the list of known phone devices. + * + * @return array List of phone devices. + */ + public static function getPhoneDevices(): array + { + return static::$phoneDevices; + } + + /** + * Retrieve the list of known tablet devices. + * + * @return array List of tablet devices. + */ + public static function getTabletDevices(): array + { + return static::$tabletDevices; + } + + /** + * Alias for getBrowsers() method. + * + * @return array List of user agents. + */ + public static function getUserAgents(): array + { + return static::getBrowsers(); + } + + /** + * Retrieve the list of known browsers. Specifically, the user agents. + * + * @return array List of browsers / user agents. + */ + public static function getBrowsers(): array + { + return static::$browsers; + } + + /** + * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*(). + * Retrieve the current set of rules. + * + * @return array + */ + public function getRules(): array + { + static $rules; + + if (!$rules) { + $rules = array_merge( + static::$phoneDevices, + static::$tabletDevices, + static::$operatingSystems, + static::$browsers + ); + } + + return $rules; + } + + /** + * Retrieve the list of mobile operating systems. + * + * @return array The list of mobile operating systems. + */ + public static function getOperatingSystems(): array + { + return static::$operatingSystems; + } + + /** + * Check the HTTP headers for signs of mobile. + * This is the fastest mobile check possible; it's used + * inside isMobile() method. + * + * @return bool + */ + public function checkHttpHeadersForMobile(): bool + { + + foreach ($this->getMobileHeaders() as $mobileHeader => $matchType) { + if (isset($this->httpHeaders[$mobileHeader])) { + if (isset($matchType['matches']) && is_array($matchType['matches'])) { + foreach ($matchType['matches'] as $_match) { + if (strpos($this->httpHeaders[$mobileHeader], $_match) !== false) { + return true; + } + } + + return false; + } else { + return true; + } + } + } + + return false; + } + + /** + * Magic overloading method. + * + * @method boolean is[...]() + * @param string $name + * @param array $arguments + * @return bool + * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is' + */ + public function __call(string $name, array $arguments) + { + // make sure the name starts with 'is', otherwise + if (substr($name, 0, 2) !== 'is') { + throw new BadMethodCallException("No such method exists: $name"); + } + + $key = substr($name, 2); + + return $this->matchUAAgainstKey($key); + } + + /** + * Find a detection rule that matches the current User-agent. + * + * @param string|null $userAgent deprecated + * @return bool + */ + protected function matchDetectionRulesAgainstUA(string $userAgent = null): bool + { + // Begin general search. + foreach ($this->getRules() as $_regex) { + if (empty($_regex)) { + continue; + } + + if ($this->match($_regex, $userAgent)) { + return true; + } + } + + return false; + } + + /** + * Search for a certain key in the rules array. + * If the key is found then try to match the corresponding + * regex against the User-Agent. + * + * @param string $key + * + * @return bool + */ + protected function matchUAAgainstKey(string $key): bool + { + // Make the keys lowercase, so we can match: isIphone(), isiPhone(), isiphone(), etc. + $key = strtolower($key); + if (false === isset($this->cache[$key])) { + // change the keys to lower case + $_rules = array_change_key_case($this->getRules()); + + if (false === empty($_rules[$key])) { + $this->cache[$key] = $this->match($_rules[$key]); + } + + if (false === isset($this->cache[$key])) { + $this->cache[$key] = false; + } + } + + return $this->cache[$key]; + } + + /** + * Check if the device is mobile. + * Returns true if any type of mobile device detected, including special ones + * @param string|null $userAgent deprecated + * @param array|null $httpHeaders deprecated + * @return bool + */ + public function isMobile(string $userAgent = null, array $httpHeaders = null): bool + { + + if ($httpHeaders) { + $this->setHttpHeaders($httpHeaders); + } + + if ($userAgent) { + $this->setUserAgent($userAgent); + } + + // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront' + if ($this->getUserAgent() === 'Amazon CloudFront') { + $cfHeaders = $this->getCfHeaders(); + if (array_key_exists('HTTP_CLOUDFRONT_IS_MOBILE_VIEWER', $cfHeaders) && + $cfHeaders['HTTP_CLOUDFRONT_IS_MOBILE_VIEWER'] === 'true' + ) { + return true; + } + } + + if ($this->checkHttpHeadersForMobile()) { + return true; + } else { + return $this->matchDetectionRulesAgainstUA(); + } + } + + /** + * Check if the device is a tablet. + * Return true if any type of tablet device is detected. + * + * @param string|null $userAgent deprecated + * @param array|null $httpHeaders deprecated + * @return bool + */ + public function isTablet(string $userAgent = null, array $httpHeaders = null): bool + { + // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront' + if ($this->getUserAgent() === 'Amazon CloudFront') { + $cfHeaders = $this->getCfHeaders(); + if (array_key_exists('HTTP_CLOUDFRONT_IS_TABLET_VIEWER', $cfHeaders) && + $cfHeaders['HTTP_CLOUDFRONT_IS_TABLET_VIEWER'] === 'true' + ) { + return true; + } + } + + foreach (static::$tabletDevices as $_regex) { + if ($this->match($_regex, $userAgent)) { + return true; + } + } + + return false; + } + + /** + * This method checks for a certain property in the + * userAgent. + * @param string $key + * @param string|null $userAgent deprecated + * @param array|null $httpHeaders deprecated + * @return bool + * + * @todo: The httpHeaders part is not yet used. + */ + public function is(string $key, string $userAgent = null, array $httpHeaders = null): bool + { + // Set the UA and HTTP headers only if needed (eg. batch mode). + if ($httpHeaders) { + $this->setHttpHeaders($httpHeaders); + } + + if ($userAgent) { + $this->setUserAgent($userAgent); + } + + return $this->matchUAAgainstKey($key); + } + + /** + * Some detection rules are relative (not standard), + * because of the diversity of devices, vendors and + * their conventions in representing the User-Agent or + * the HTTP headers. + * + * This method will be used to check custom regexes against + * the User-Agent string. + * + * @param string $regex + * @param string|null $userAgent + * @return bool + * + * @todo: search in the HTTP headers too. + */ + public function match(string $regex, string $userAgent = null): bool + { + if (!\is_string($userAgent) && !\is_string($this->userAgent)) { + return false; + } + + $match = (bool) preg_match( + sprintf('#%s#is', $regex), + (false === empty($userAgent) ? $userAgent : $this->userAgent), + $matches + ); + // If positive match is found, store the results for debug. + if ($match) { + $this->matchingRegex = $regex; + $this->matchesArray = $matches; + } + + return $match; + } + + /** + * Get the properties array. + * + * @return array + */ + public static function getProperties(): array + { + return static::$properties; + } + + /** + * Prepare the version number. + * + * @param string $ver The string version, like "2.6.21.2152"; + * + * @return float + * + * @todo Remove the error suppression from str_replace() call. + */ + public function prepareVersionNo(string $ver): float + { + $ver = str_replace(array('_', ' ', '/'), '.', $ver); + $arrVer = explode('.', $ver, 2); + + if (isset($arrVer[1])) { + $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions. + } + + return (float) implode('.', $arrVer); + } + + /** + * Check the version of the given property in the User-Agent. + * Will return a float number. (e.g. 2_0 will return 2.0, 4.3.1 will return 4.31) + * + * @param string $propertyName The name of the property. See self::getProperties() array + * keys for all possible properties. + * @param string $type Either self::VERSION_TYPE_STRING to get a string value or + * self::VERSION_TYPE_FLOAT indicating a float value. This parameter + * is optional and defaults to self::VERSION_TYPE_STRING. Passing an + * invalid parameter will default to the type as well. + * + * @return string|float|false The version of the property we are trying to extract. + */ + public function version(string $propertyName, string $type = self::VERSION_TYPE_STRING) + { + if (empty($propertyName)) { + return false; + } + + if (!\is_string($this->userAgent)) { + return false; + } + + // set the $type to the default if we don't recognize the type + if ($type !== self::VERSION_TYPE_STRING && $type !== self::VERSION_TYPE_FLOAT) { + $type = self::VERSION_TYPE_STRING; + } + + $properties = self::getProperties(); + + // Check if the property exists in the properties array. + if (true === isset($properties[$propertyName])) { + // Prepare the pattern to be matched. + // Make sure we always deal with an array (string is converted). + $properties[$propertyName] = (array) $properties[$propertyName]; + + foreach ($properties[$propertyName] as $propertyMatchString) { + $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString); + + // Identify and extract the version. + preg_match(sprintf('#%s#is', $propertyPattern), $this->userAgent, $match); + + if (false === empty($match[1])) { + return ($type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1]); + } + } + } + + return false; + } +} diff --git a/admin/ConfigWriter.php b/admin/ConfigWriter.php new file mode 100755 index 0000000..ef74ac5 --- /dev/null +++ b/admin/ConfigWriter.php @@ -0,0 +1,101 @@ +"; + } + + public static function save($checkName, array $data) + { + $str = self::buildDefineSource($checkName, $data); + $config_name = str_replace('.php', '', $checkName); + $config_file = 'check_config/' . $config_name . '_config.php'; + if (!file_exists($config_file)) { + copy('check_config/index_config.php', $config_file); + } + $f = fopen($config_file, 'w'); + rewind($f); + fwrite($f, $str); + fclose($f); + } +} diff --git a/admin/bootstrap.php b/admin/bootstrap.php new file mode 100755 index 0000000..c1dec36 --- /dev/null +++ b/admin/bootstrap.php @@ -0,0 +1,11 @@ + + + + + + + 登录 — IP 名单管理 + + + +

IP 名单管理

+

+
+ + + +
+

与 dashboard 使用相同登录密码;若已在后台登录可刷新本页。

+ + + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ]); +} catch (PDOException $e) { + http_response_code(500); + echo '错误

数据库连接失败。

'; + exit; +} + +/** 校验分组属于当前 type,返回 true 或 false */ +function groupBelongsToType(PDO $pdo, int $groupId, string $type): bool +{ + $st = $pdo->prepare('SELECT 1 FROM ip_groups WHERE id = ? AND type = ? LIMIT 1'); + $st->execute([$groupId, $type]); + return (bool) $st->fetchColumn(); +} + +// —— POST:新建分组 —— +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'create_group') { + $name = trim((string) ($_POST['group_name'] ?? '')); + $postType = ($_POST['list_type'] ?? '') === 'white' ? 'white' : 'black'; + if ($name === '') { + $flash = '分组名称不能为空'; + $flashOk = false; + } else { + $st = $pdo->prepare('INSERT INTO ip_groups (name, type) VALUES (?, ?)'); + $st->execute([$name, $postType]); + $flash = '分组已创建'; + header('Location: ' . $self . '?type=' . urlencode($postType) . '&msg=' . urlencode($flash) . '&ok=1'); + exit; + } +} + +// —— POST:批量导入 IP —— +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'bulk_import') { + $groupId = (int) ($_POST['import_group_id'] ?? 0); + $raw = (string) ($_POST['ip_lines'] ?? ''); + if ($groupId <= 0 || !groupBelongsToType($pdo, $groupId, $type)) { + $flash = '请选择有效的分组'; + $flashOk = false; + } else { + $lines = preg_split('/\R/u', $raw) ?: []; + $uniqueFromText = []; + foreach ($lines as $line) { + $ip = trim($line); + if ($ip === '') { + continue; + } + $uniqueFromText[$ip] = true; + } + $candidateIps = array_keys($uniqueFromText); + $exSt = $pdo->prepare('SELECT ip_address FROM ip_list WHERE group_id = ?'); + $exSt->execute([$groupId]); + $already = []; + while ($row = $exSt->fetch(PDO::FETCH_ASSOC)) { + $already[$row['ip_address']] = true; + } + $toInsert = []; + foreach ($candidateIps as $ip) { + if (!isset($already[$ip])) { + $toInsert[] = $ip; + } + } + $inserted = 0; + $stmt = $pdo->prepare('INSERT IGNORE INTO ip_list (group_id, ip_address) VALUES (?, ?)'); + $pdo->beginTransaction(); + try { + foreach ($toInsert as $ip) { + $stmt->execute([$groupId, $ip]); + $inserted += $stmt->rowCount(); + } + $pdo->commit(); + } catch (Throwable $e) { + $pdo->rollBack(); + $flash = '导入失败:' . $e->getMessage(); + $flashOk = false; + } + if ($flashOk) { + $skippedDupText = count($candidateIps) - count($toInsert); + $flash = '批量导入完成:新插入 ' . $inserted . ' 条;文本去重后 ' . count($candidateIps) . ' 条;本组已存在跳过 ' . $skippedDupText . ' 条'; + header('Location: ' . $self . '?type=' . urlencode($type) . '&msg=' . urlencode($flash) . '&ok=1'); + exit; + } + } +} + +// —— POST:按行批量删除 IP(当前 type 下;可选限定分组)—— +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'bulk_delete_ips') { + $scopeGroup = (int) ($_POST['bulk_delete_group_id'] ?? 0); + $raw = (string) ($_POST['bulk_delete_lines'] ?? ''); + if ($scopeGroup > 0 && !groupBelongsToType($pdo, $scopeGroup, $type)) { + $flash = '批量删除:分组无效'; + $flashOk = false; + } else { + $lines = preg_split('/\R/u', $raw) ?: []; + $ips = []; + foreach ($lines as $line) { + $ip = trim($line); + if ($ip !== '') { + $ips[$ip] = true; + } + } + $ips = array_keys($ips); + if ($ips === []) { + $flash = '批量删除:未填写任何 IP'; + $flashOk = false; + } else { + $sql = 'DELETE il FROM ip_list il + INNER JOIN ip_groups ig ON ig.id = il.group_id + WHERE ig.type = ? AND il.ip_address = ?'; + if ($scopeGroup > 0) { + $sql .= ' AND il.group_id = ?'; + } + $stmt = $pdo->prepare($sql); + $deleted = 0; + $pdo->beginTransaction(); + try { + foreach ($ips as $ip) { + if ($scopeGroup > 0) { + $stmt->execute([$type, $ip, $scopeGroup]); + } else { + $stmt->execute([$type, $ip]); + } + $deleted += $stmt->rowCount(); + } + $pdo->commit(); + } catch (Throwable $e) { + $pdo->rollBack(); + $flash = '批量删除失败:' . $e->getMessage(); + $flashOk = false; + } + if ($flashOk) { + $flash = '批量删除完成,共删除 ' . $deleted . ' 条记录(不存在的 IP 不计入)'; + header('Location: ' . $self . '?type=' . urlencode($type) . '&msg=' . urlencode($flash) . '&ok=1'); + exit; + } + } + } +} + +// —— POST:清空当前类型下所有 IP(保留分组)—— +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'clear_ips_only') { + $phrase = trim((string) ($_POST['clear_confirm_phrase'] ?? '')); + if ($phrase !== '清空IP') { + $flash = '清空失败:请在确认框中完整输入「清空IP」'; + $flashOk = false; + } else { + $del = $pdo->prepare( + 'DELETE il FROM ip_list il + INNER JOIN ip_groups ig ON ig.id = il.group_id + WHERE ig.type = ?' + ); + $del->execute([$type]); + $flash = '已清空当前类型下所有 IP(分组已保留),删除 ' . $del->rowCount() . ' 条'; + header('Location: ' . $self . '?type=' . urlencode($type) . '&msg=' . urlencode($flash) . '&ok=1'); + exit; + } +} + +// —— POST:清空当前类型下全部分组及 IP —— +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'clear_type_all') { + $phrase = trim((string) ($_POST['clear_confirm_phrase_all'] ?? '')); + if ($phrase !== '清空全部') { + $flash = '清空失败:请在确认框中完整输入「清空全部」'; + $flashOk = false; + } else { + $pdo->beginTransaction(); + try { + $pdo->prepare( + 'DELETE il FROM ip_list il + INNER JOIN ip_groups ig ON ig.id = il.group_id + WHERE ig.type = ?' + )->execute([$type]); + $pdo->prepare('DELETE FROM ip_groups WHERE type = ?')->execute([$type]); + $pdo->commit(); + $flash = '已清空当前类型下的所有分组及 IP'; + header('Location: ' . $self . '?type=' . urlencode($type) . '&msg=' . urlencode($flash) . '&ok=1'); + exit; + } catch (Throwable $e) { + $pdo->rollBack(); + $flash = '清空失败:' . $e->getMessage(); + $flashOk = false; + } + } +} + +// —— GET:删除分组 —— +if (isset($_GET['delete_group'])) { + $gid = (int) $_GET['delete_group']; + if ($gid > 0 && groupBelongsToType($pdo, $gid, $type)) { + $pdo->beginTransaction(); + try { + $pdo->prepare('DELETE FROM ip_list WHERE group_id = ?')->execute([$gid]); + $pdo->prepare('DELETE FROM ip_groups WHERE id = ? AND type = ?')->execute([$gid, $type]); + $pdo->commit(); + $flash = '分组及其 IP 已删除'; + } catch (Throwable $e) { + $pdo->rollBack(); + $flash = '删除分组失败'; + $flashOk = false; + } + } else { + $flash = '无效的分组'; + $flashOk = false; + } + header('Location: ' . $self . '?type=' . urlencode($type) . '&msg=' . urlencode($flash) . ($flashOk ? '&ok=1' : '')); + exit; +} + +// —— GET:删除单条 IP —— +if (isset($_GET['delete_ip'])) { + $ipId = (int) $_GET['delete_ip']; + if ($ipId > 0) { + $del = $pdo->prepare( + 'DELETE il FROM ip_list il + INNER JOIN ip_groups ig ON ig.id = il.group_id + WHERE il.id = ? AND ig.type = ?' + ); + $del->execute([$ipId, $type]); + $flash = $del->rowCount() > 0 ? '已删除该 IP 记录' : '未找到记录或无权删除'; + $flashOk = $del->rowCount() > 0; + } else { + $flash = '无效的 IP 记录'; + $flashOk = false; + } + header('Location: ' . $self . '?type=' . urlencode($type) . '&msg=' . urlencode($flash) . ($flashOk ? '&ok=1' : '')); + exit; +} + +if (isset($_GET['msg'])) { + $flash = (string) $_GET['msg']; + $flashOk = isset($_GET['ok']) && $_GET['ok'] === '1'; +} + +// 当前 type 下的分组 +$groupsStmt = $pdo->prepare('SELECT id, name FROM ip_groups WHERE type = ? ORDER BY id ASC'); +$groupsStmt->execute([$type]); +$groups = $groupsStmt->fetchAll(); + +$ipSearch = isset($_GET['ip_search']) ? trim((string) $_GET['ip_search']) : ''; +$ipSearchSql = ''; +$ipListBind = [$type]; +if ($ipSearch !== '') { + $ipSearchSql = ' AND il.ip_address LIKE ?'; + $ipListBind[] = '%' . addcslashes($ipSearch, '\\%_') . '%'; +} +$searchQuerySuffix = $ipSearch !== '' ? '&ip_search=' . rawurlencode($ipSearch) : ''; + +// IP 列表分页 +$perPage = 50; +$page = max(1, (int) ($_GET['page'] ?? 1)); +$offset = ($page - 1) * $perPage; + +$countSql = 'SELECT COUNT(*) FROM ip_list il INNER JOIN ip_groups ig ON ig.id = il.group_id WHERE ig.type = ?' . $ipSearchSql; +$totalStmt = $pdo->prepare($countSql); +$totalStmt->execute($ipListBind); +$totalIps = (int) $totalStmt->fetchColumn(); +$totalPages = max(1, (int) ceil($totalIps / $perPage)); +if ($page > $totalPages) { + $page = $totalPages; + $offset = ($page - 1) * $perPage; +} + +$listSql = 'SELECT il.id, il.ip_address, il.group_id, ig.name AS group_name + FROM ip_list il + INNER JOIN ip_groups ig ON ig.id = il.group_id + WHERE ig.type = ?' . $ipSearchSql . ' + ORDER BY il.id DESC + LIMIT ' . (int) $perPage . ' OFFSET ' . (int) $offset; +$listStmt = $pdo->prepare($listSql); +$listStmt->execute($ipListBind); +$ipRows = $listStmt->fetchAll(); + +function h(string $s): string +{ + return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); +} + +$typeParam = 'type=' . urlencode($type); +?> + + + + + + IP 名单管理 — <?php echo $type === 'white' ? '白名单' : '黑名单'; ?> + + + +

IP 黑白名单管理

+ + + + +
+ + +
+

新建分组

+
+ + + + + +
+
+ +
+

当前视图下的分组

+ +

暂无分组,请先创建。

+ + + + + + + + + + + + + + +
ID组名操作
+ 删除组 +
+ +
+ +
+

批量导入 IP

+

每行一个 IP;首尾空格与空行忽略;同一文本内重复只计一次;本组数据库中已存在的 IP 不会重复插入。

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

批量删除 IP

+

每行一个 IP;同一 IP 在文本中多次出现会去重后删除。选择「不限定分组」时,会删除当前名单类型下所有分组中匹配的 IP。

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

清空数据(危险操作)

+

以下操作仅影响当前视图类型(),不影响另一类型。

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

IP 列表(

+
+ +
+ + +
+
+ + + 清除 + +
+
+

条,每页

+ +

当前类型下暂无 IP。

+ + + + + + + + + + + + + + + +
IDIP分组操作
+ 删除 +
+ 1) { ?> +
+ 1) { ?> + 上一页 + + / + + 下一页 + +
+ + +
+ + diff --git a/check_config/index_config.php b/check_config/index_config.php new file mode 100755 index 0000000..d1ec441 --- /dev/null +++ b/check_config/index_config.php @@ -0,0 +1,40 @@ + 'https://www.google.com/', +) ); + define('COSTM_IP_SCORE', '20251108_emoUAVF6S' ); + define('BLACK_LIST', '0' ); + define('AUTO_BLACK', 'OFF' ); + define('IS_VIRTUAL', '0' ); + define('AUTO_BLACK_TIMES', '5' ); + define('WHITE_PARAMS', '' ); + define('IPHONE_MODEL', 0 ); + + define('SHOW_SITE_MOBILE', 0 ); + define('SHOW_SITE_OUTPUT', 1 ); + define('WRITE_LOG', 1 ); + define('CLOAK_ZH_ON', 'OFF'); + define('CLOAK_OS_ON', 'OFF'); + define('KEEP_PARAMS', 'OFF'); + define('CLOAK_REDIRECT_METHOD', 'curl'); + define('DB_ZP', 'https://worldhomenest.store'); + define('CLOAK_MOBILE_ON', 'OFF'); + define('CLOAK_V_REFERER', 'OFF'); + define('CLOAK_RISK_NUMBER', '51'); + define('CLOAK_RISK_ENHANCED', 'OFF'); + define('CLOAK_URL_ARGS_TIMEOUT', '0'); + + define('CLOAK_AD_FB', 'OFF'); + define('CLOAK_AD_GOOGLE', 'ON'); + define('CLOAK_AD_TIKTOK', 'ON'); + define('CLOAK_AD_STRICT', 'OFF'); + define('CLOAK_AD_SPM_ID', 't0tTw4MJ6r'); + + define('CLOAK_DEBUG_MODE', 'OFF'); + ?> \ No newline at end of file diff --git a/cloak_log.sql b/cloak_log.sql new file mode 100755 index 0000000..f257ad5 --- /dev/null +++ b/cloak_log.sql @@ -0,0 +1,65 @@ +-- phpMyAdmin SQL Dump +-- version 5.0.4 +-- https://www.phpmyadmin.net/ +-- +-- 主机: localhost +-- 生成日期: 2024-06-25 19:09:38 +-- 服务器版本: 5.7.44-log +-- PHP 版本: 7.4.33 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + +-- +-- 数据库: `cloak_log` +-- + +-- -------------------------------------------------------- + +-- +-- 表的结构 `visitor_logs` +-- + +CREATE TABLE `visitor_logs` ( + `id` int(11) UNSIGNED NOT NULL, + `campagin_id` varchar(20) NOT NULL COMMENT '策略ID', + `visit_md5_code` char(32) NOT NULL DEFAULT 'loss' COMMENT '客户端标记', + `domain` varchar(35) NOT NULL COMMENT '域名', + `visit_date` datetime NOT NULL COMMENT '访问日期', + `IP` varchar(150) NOT NULL COMMENT 'IP', + `country` varchar(10) DEFAULT NULL COMMENT '国家', + `result` char(5) DEFAULT NULL COMMENT '判断结果', + `reason` varchar(100) DEFAULT NULL COMMENT '判断理由', + `referer` text COMMENT '来源', + `vtimes` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '第几次访问', + `client` varchar(20) DEFAULT NULL COMMENT '客户端', + `browser` varchar(20) DEFAULT NULL COMMENT '浏览器', + `device` varchar(300) DEFAULT NULL COMMENT '设备', + `page` text COMMENT '浏览页面', + `fp_url` text COMMENT '跳转页面', + `language` varchar(300) DEFAULT NULL COMMENT '语言', + `add_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '日志记录时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- 转储表的索引 +-- + +-- +-- 表的索引 `visitor_logs` +-- +ALTER TABLE `visitor_logs` + ADD PRIMARY KEY (`id`), + ADD KEY `IP` (`IP`); + +-- +-- 在导出的表使用AUTO_INCREMENT +-- + +-- +-- 使用表AUTO_INCREMENT `visitor_logs` +-- +ALTER TABLE `visitor_logs` + MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT; +COMMIT; diff --git a/cloaka.test.code-workspace b/cloaka.test.code-workspace new file mode 100755 index 0000000..da9fd93 --- /dev/null +++ b/cloaka.test.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "../aizheye.test" + } + ], + "settings": {} +} \ No newline at end of file diff --git a/cloakjs.php b/cloakjs.php new file mode 100755 index 0000000..23fbd58 --- /dev/null +++ b/cloakjs.php @@ -0,0 +1,173 @@ + + diff --git a/config/ConfigLoader.php b/config/ConfigLoader.php new file mode 100755 index 0000000..8ef3200 --- /dev/null +++ b/config/ConfigLoader.php @@ -0,0 +1,69 @@ +window.location='{$current_name}';"); + exit(); +} + +// 重置临时链接参数 +if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "delUrlArgs") { + $check_name = strip_tags($_REQUEST['check_name']); + $dir = dirname(__FILE__) . '/args'; + $files = glob($dir . '/' . $check_name . "_*.txt"); + foreach ($files as $file) { + if (preg_match('/_(\d{10})\.txt$/', $file, $m)) { + unlink($file); + } + } + header('Location: ' . $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?action=edit_config&name=' . urlencode($check_name)); + exit; +} + +// 确定当前配置上下文(供表单回显用) +if (!empty($_REQUEST["name"])) { + $check_name = trim($_REQUEST["name"]); + $config_name = str_replace(".php", "", $check_name); + $config_file = "check_config/" . $config_name . "_config.php"; + if (!file_exists($config_file)) { + copy("check_config/index_config.php", $config_file); + } +} else { + $check_name = "index"; + $config_file = "check_config/index_config.php"; +} + include($config_file); + +// 密码处理 +if (!empty($_REQUEST['password'])) { + $_SESSION['password'] = $_REQUEST['password']; + $_SESSION["myaction"] = $_REQUEST['myaction']; +} + +// 设置测试访问状态(写入完整 Session 判定缓存,便于测试广告落地链接直达真实页) +if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "setuvi") { + require_once __DIR__ . '/lib/Cloak/VisitorRepository.php'; + if (!empty($_REQUEST["res"]) && $_REQUEST["res"] == "true") { + cloak_session_mark_real_visitor(); + } + if (!empty($_REQUEST["res"]) && $_REQUEST["res"] == "false") { + cloak_session_clear_real_visitor(); + } + echo(""); + exit(); +} + +// 保存配置 +if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "submit") { + $check_name = trim($_REQUEST["check_name"]); + $methods = trim($_REQUEST["methods"]); + $country = trim($_REQUEST["country"]); + $blacklist_group_id = (int)($_REQUEST["blacklist_group_id"] ?? 0); + $whitelist_group_id = (int)($_REQUEST["whitelist_group_id"] ?? 0); + try { + $pdoDash = new PDO( + 'mysql:host=127.0.0.1;dbname=' . DB_NAME . ';charset=utf8mb4', + DB_USERNAME, DB_PASSWORD, + [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] + ); + $chk = $pdoDash->prepare('SELECT 1 FROM ip_groups WHERE id = ? AND type = ? LIMIT 1'); + if ($blacklist_group_id > 0) { + $chk->execute([$blacklist_group_id, 'black']); + if (!$chk->fetchColumn()) $blacklist_group_id = 0; + } + if ($whitelist_group_id > 0) { + $chk->execute([$whitelist_group_id, 'white']); + if (!$chk->fetchColumn()) $whitelist_group_id = 0; + } + } catch (Throwable $e) { + $blacklist_group_id = $whitelist_group_id = 0; + } + $DB_fp = $_REQUEST["DB_fp"]; + $DB_zp = trim($_REQUEST["DB_zp"]); + $redirect_method = trim($_REQUEST["redirect_method"]); + $show_content = trim($_REQUEST["show_content"]); + $costm_ip_score = trim($_REQUEST["costm_ip_score"]); + $write_log = trim($_REQUEST["write_log"]); + $zh_on = trim($_REQUEST["zh_on"]); + $os_on = trim($_REQUEST["os_on"]); + $mobile_on = trim($_REQUEST["mobile_on"]); + $v_referer = trim($_REQUEST["v_referer"]); + $is_virtual = trim($_REQUEST["is_virtual"]); + $auto_black = trim($_REQUEST["auto_black"]); + $auto_black_times = trim($_REQUEST["auto_black_times"]); + $white_params = trim($_REQUEST["white_params"]); + $keep_params = trim($_REQUEST["keep_params"]); + $iphone_model = $_REQUEST["iphone_model"]; + $risk_number = $_REQUEST["risk_number"]; + $risk_enhanced = in_array(strtoupper(trim($_REQUEST["risk_enhanced"] ?? '')), ['ON']) ? 'ON' : 'OFF'; + $url_args_timeout = $_REQUEST["url_args_timeout"]; + $debug_mode = in_array(strtoupper(trim($_REQUEST["debug_mode"] ?? '')), ['ON']) ? 'ON' : 'OFF'; + $ad_fb = in_array(strtoupper(trim($_REQUEST["ad_fb"] ?? '')), ['ON']) ? 'ON' : 'OFF'; + $ad_google = in_array(strtoupper(trim($_REQUEST["ad_google"] ?? '')), ['ON']) ? 'ON' : 'OFF'; + $ad_tiktok = in_array(strtoupper(trim($_REQUEST["ad_tiktok"] ?? '')), ['ON']) ? 'ON' : 'OFF'; + $ad_strict = in_array(strtoupper(trim($_REQUEST["ad_strict"] ?? '')), ['ON']) ? 'ON' : 'OFF'; + + $config_name_submit = str_replace('.php', '', $check_name); + $existing_spm_id = ''; + $existing_cfg = 'check_config/' . $config_name_submit . '_config.php'; + if (file_exists($existing_cfg)) { + $existing_raw = file_get_contents($existing_cfg); + if (preg_match("/define\('CLOAK_AD_SPM_ID',\s*'([^']*)'\)/", $existing_raw, $spmM)) { + $existing_spm_id = $spmM[1]; + } + } + $ad_spm_id = CloakAdSourceGuard::isValidSpmId($existing_spm_id) ? $existing_spm_id : ''; + if (($ad_fb === 'ON' || $ad_google === 'ON' || $ad_tiktok === 'ON') && $ad_spm_id === '') { + $ad_spm_id = CloakAdSourceGuard::generateSpmId(); + } + + if (strtoupper($auto_black) === 'ON' && $blacklist_group_id <= 0) { + echo ""; + exit(); + } + + if (!empty($methods)) { + ConfigWriter::save($check_name, [ + 'methods' => $methods, + 'blacklist_group_id' => $blacklist_group_id, + 'whitelist_group_id' => $whitelist_group_id, + 'country' => $country, + 'show_content' => $show_content, + 'DB_fp' => $DB_fp, + 'costm_ip_score' => $costm_ip_score, + 'auto_black' => $auto_black, + 'is_virtual' => $is_virtual, + 'auto_black_times' => $auto_black_times, + 'white_params' => $white_params, + 'iphone_model' => $iphone_model, + 'write_log' => $write_log, + 'zh_on' => $zh_on, + 'os_on' => $os_on, + 'keep_params' => $keep_params, + 'redirect_method' => $redirect_method, + 'DB_zp' => $DB_zp, + 'mobile_on' => $mobile_on, + 'v_referer' => $v_referer, + 'risk_number' => $risk_number, + 'risk_enhanced' => $risk_enhanced, + 'url_args_timeout' => $url_args_timeout, + 'debug_mode' => $debug_mode, + 'ad_fb' => $ad_fb, + 'ad_google' => $ad_google, + 'ad_tiktok' => $ad_tiktok, + 'ad_strict' => $ad_strict, + 'ad_spm_id' => $ad_spm_id, + ]); + try { + $pdoBind = DomainRepository::pdo(); + DomainRepository::ensureTable($pdoBind); + $siteDomainId = (int) ($_REQUEST['site_domain_id'] ?? 0); + if ($siteDomainId > 0) { + DomainRepository::bindConfigToDomain($pdoBind, $check_name, $siteDomainId); + } else { + DomainRepository::clearConfigBinding($pdoBind, $check_name); + } + } catch (Throwable $e) { + } + echo(""); + exit(); + } +} + +function write_file($file_name, $text_str) { + $f = fopen($file_name, "w"); + rewind($f); + fwrite($f, $text_str); + fclose($f); +} + +function onoff_radio($name, $val, $label_on='开启', $label_off='关闭') { + $on = ($val == 'ON') ? 'active' : ''; + $off = ($val != 'ON') ? 'active' : ''; + return '
+ + +
'; +} + +function dash_truncate_attr($text, $maxLen = 52) { + $text = (string) $text; + $esc = htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); + if (function_exists('mb_strlen') && function_exists('mb_substr')) { + if (mb_strlen($text, 'UTF-8') <= $maxLen) { + return $esc; + } + return '' . htmlspecialchars(mb_substr($text, 0, $maxLen, 'UTF-8'), ENT_QUOTES, 'UTF-8') . '…'; + } + if (strlen($text) <= $maxLen) { + return $esc; + } + return '' . htmlspecialchars(substr($text, 0, $maxLen), ENT_QUOTES, 'UTF-8') . '…'; +} + +?> + + + + + +IPCLOAKAPI 多功能管理后台面板 v8.2.1 + + + + + + + + + + + + + alert('密码错误!');window.location='{$current_name}';"); + exit(); + } + +// 删除配置 +if (!empty($_REQUEST["action"]) && $_REQUEST["action"] == "delete_config" && !empty($_REQUEST["name"])) { + $name = trim($_REQUEST["name"]); + if ($name == "index") { + echo(""); + exit(); + } + $cfg = str_replace(".php", "", $name); + try { + DomainRepository::clearConfigBinding(DomainRepository::pdo(), $cfg); + } catch (Throwable $e) { + } + @unlink("check_config/{$cfg}_config.php"); + @unlink("{$cfg}.php"); + echo(""); + exit(); +} + +// 站点域名管理 +$cloakDomainMsg = ''; +$cloakDomainErr = ''; +$cloakCfEnabled = CloudflareConfig::isEnabled(); +if (!empty($_REQUEST['action']) && $_REQUEST['action'] === 'add_domain' && !empty($_POST['new_hostname'])) { + try { + $pdoDom = DomainRepository::pdo(); + $res = DomainProvisioningService::provisionOnAdd($pdoDom, $_POST['new_hostname']); + if ($res['ok']) { + $cloakDomainMsg = '域名「' . htmlspecialchars($res['hostname']) . '」已添加'; + if (!empty($res['nameservers'])) { + $nsHtml = implode('、', array_map('htmlspecialchars', $res['nameservers'])); + $cloakDomainMsg .= '。请到注册商将 NS 修改为:' . $nsHtml . ',然后点击「检测/刷新」。'; + } else { + $cloakDomainMsg .= ',请在编辑配置时关联此域名。'; + } + } else { + $cloakDomainErr = $res['error'] ?? '添加失败'; + } + } catch (Throwable $e) { + $cloakDomainErr = $e->getMessage(); + } +} +if (!empty($_REQUEST['action']) && $_REQUEST['action'] === 'check_domain') { + $domainId = (int) ($_POST['domain_id'] ?? $_REQUEST['domain_id'] ?? 0); + $jsonOut = isset($_REQUEST['format']) && $_REQUEST['format'] === 'json'; + try { + $res = DomainProvisioningService::checkAndProvision(DomainRepository::pdo(), $domainId); + if ($jsonOut) { + header('Content-Type: application/json; charset=utf-8'); + echo json_encode($res, JSON_UNESCAPED_UNICODE); + exit; + } + if ($res['ok']) { + $cloakDomainMsg = $res['message'] ?? '检测完成'; + } else { + $cloakDomainErr = $res['message'] ?? '检测失败'; + } + } catch (Throwable $e) { + if ($jsonOut) { + header('Content-Type: application/json; charset=utf-8'); + echo json_encode(['ok' => false, 'message' => $e->getMessage()], JSON_UNESCAPED_UNICODE); + exit; + } + $cloakDomainErr = $e->getMessage(); + } +} +if (!empty($_REQUEST['action']) && $_REQUEST['action'] === 'delete_domain' && !empty($_REQUEST['domain_id'])) { + try { + $res = DomainProvisioningService::deleteWithCloudflare(DomainRepository::pdo(), (int) $_REQUEST['domain_id']); + if ($res['ok']) { + $cloakDomainMsg = $res['message'] ?? '域名已删除。'; + if (!empty($res['warning'])) { + $cloakDomainErr = $res['warning']; + } + } else { + $cloakDomainErr = $res['message'] ?? '删除失败'; + } + } catch (Throwable $e) { + $cloakDomainErr = $e->getMessage(); + } +} + +// 系统状态检测(列表页用) +function dash_check_mysql() { + try { + $pdo = new PDO('mysql:host=127.0.0.1;dbname=' . DB_NAME . ';charset=utf8mb4', DB_USERNAME, DB_PASSWORD, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + return true; + } catch (Throwable $e) { return false; } +} +function dash_check_redis() { + if (!extension_loaded('redis') || strtoupper(REDIS_ENABLED) !== 'ON') return null; + try { + $r = new Redis(); + if (!@$r->connect(REDIS_HOST, (int)REDIS_PORT, 0.5)) return false; + $r->ping(); + return true; + } catch (Throwable $e) { return false; } +} + +function dash_cfg_get($raw, $name) +{ + if (preg_match("/define\('" . preg_quote($name, '/') . "',\s*'([^']*)'\)/", $raw, $m)) { + return $m[1]; + } + return ''; +} + +function dash_build_ad_links($pf, $protocol, $host) +{ + $path = __DIR__ . "/check_config/{$pf}_config.php"; + try { + $pdoDashHost = DomainRepository::pdo(); + DomainRepository::ensureTable($pdoDashHost); + $bound = DomainRepository::primaryHostnameForConfig($pdoDashHost, $pf); + if ($bound !== '') { + $host = $bound; + } + } catch (Throwable $e) { + } + $host = DomainRepository::normalizeHostname($host); + if ($host === '') { + $host = DomainRepository::normalizeHostname($_SERVER['HTTP_HOST'] ?? ''); + } + $base = rtrim($protocol . $host, '/') . '/' . (($pf != 'index') ? $pf : ''); + + if (!file_exists($path)) { + return [['label' => '落地链接', 'url' => $base]]; + } + + $raw = file_get_contents($path); + $enabled = []; + if (dash_cfg_get($raw, 'CLOAK_AD_FB') === 'ON') { + $enabled[] = CloakAdSourceGuard::PLATFORM_FB; + } + if (dash_cfg_get($raw, 'CLOAK_AD_GOOGLE') === 'ON') { + $enabled[] = CloakAdSourceGuard::PLATFORM_GOOGLE; + } + if (dash_cfg_get($raw, 'CLOAK_AD_TIKTOK') === 'ON') { + $enabled[] = CloakAdSourceGuard::PLATFORM_TIKTOK; + } + + if (empty($enabled)) { + return [['label' => '落地链接', 'url' => $base]]; + } + + $spmId = dash_cfg_get($raw, 'CLOAK_AD_SPM_ID'); + $query = CloakAdSourceGuard::buildAdLinkQuery($enabled, $spmId); + $url = $base . ($query !== '' ? '?' . $query : ''); + + return [['label' => '落地链接', 'url' => $url]]; +} + +// 遍历配置列表 +$products_file_ary = []; +$dd = opendir("check_config"); +while (false !== ($f = readdir($dd))) { + if ($f == "." || $f == "..") continue; + if (filetype("check_config/$f") == "dir" || $f == "index.php" || $f == "a.txt") continue; + $fname = str_replace("_config.php", "", $f); + $products_file_ary[] = $fname; + if (!file_exists($fname . ".php")) { + copy("tem_link.php", $fname . ".php"); + } +} +closedir($dd); +sort($products_file_ary); + +// 加载 IP 组(编辑页用) +$blackGroups = $whiteGroups = []; +try { + $pdoDash = new PDO('mysql:host=127.0.0.1;dbname=' . DB_NAME . ';charset=utf8mb4', DB_USERNAME, DB_PASSWORD, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]); + $stb = $pdoDash->prepare("SELECT id, name FROM ip_groups WHERE type = 'black' ORDER BY id ASC"); + $stb->execute(); $blackGroups = $stb->fetchAll(); + $stw = $pdoDash->prepare("SELECT id, name FROM ip_groups WHERE type = 'white' ORDER BY id ASC"); + $stw->execute(); $whiteGroups = $stw->fetchAll(); +} catch (Throwable $e) {} +$currentBlacklistGroupId = defined('BLACKLIST_GROUP_ID') ? (int)BLACKLIST_GROUP_ID : 0; +$currentWhitelistGroupId = defined('WHITELIST_GROUP_ID') ? (int)WHITELIST_GROUP_ID : 0; + +$action = $_REQUEST['action'] ?? ''; +$isEdit = in_array($action, ['edit_config', 'submit'], true); + +$cloakSiteDomains = []; +$selectedDomainId = 0; +$dashboardDefaultHost = DomainRepository::normalizeHostname($_SERVER['HTTP_HOST'] ?? ''); +try { + $pdoDash = $pdoDash ?? DomainRepository::pdo(); + DomainRepository::ensureTable($pdoDash); + $cloakSiteDomains = DomainRepository::listAll($pdoDash); + if ($isEdit) { + $selectedDomainId = DomainRepository::domainIdForConfig($pdoDash, $check_name); + } +} catch (Throwable $e) { + $cloakSiteDomains = []; +} + +// 视图判断 +$_d = function($name, $default) { return defined($name) ? constant($name) : $default; }; +?> + + +
+

IPCLOAKAPI 多功能管理后台面板 v8.2.1

+ +
+ +
+ + + + +
+

配置管理

+

管理 Cloak 配置、广告落地链接与站点域名

+
+ + +
+● MySQL ' . ($mysqlOk ? '已连接' : '连接失败') . ''; + if ($redisOk === null) { + echo '● Redis 未启用'; + } else { + echo '● Redis ' . ($redisOk ? '已连接' : '连接失败') . ''; + } +?> + ● 配置数: + ● 已登记域名: +
+ + +
+ + +
+ + + +
+
+
配置列表
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + +
配置名称绑定域名广告链接(广告后台填入的链接)真实页链接(客户到达的链接)操作
+ + 默认 + + ' . htmlspecialchars($pfHost) . ''; + } else { + echo '' . htmlspecialchars($dashboardDefaultHost) . '
(默认后台域)
'; + } + ?> +
+ + + + + ' . dash_truncate_attr($first, 48) . ''; + if (is_array($pfp) && count($pfp) > 1) { + echo '
+' . (count($pfp)-1) . ' 个链接
'; + } + } else { ?> + + +
+
+ 编辑 + 查看 + + + +
+
+
+
+ + +
+
+
站点域名
+
+
+ +
+ Cloudflare 已启用:添加域名后将自动创建 Zone 并显示 Nameserver;请到注册商修改 NS 后点击「检测/刷新」。NS 生效后将自动配置 proxied A 记录、Flexible SSL 与 Always HTTPS。 + 源站仍需在宝塔添加站点并监听 (Flexible:访客↔CF 为 HTTPS,CF↔源站为 HTTP)。 +
+ +
+ 使用前请先在宝塔完成:在宝塔面板 → 网站 → 添加站点(填写下方相同域名)→ 申请并开启 SSL 证书。完成后再在此添加域名并关联配置。 + 若在 cong.php 配置 Cloudflare API Token 与 Account ID,可自动创建 Zone 并管理 DNS/SSL。 +
+ +
+ + + +
+ +
尚未添加域名。未添加时,广告链接将使用当前后台访问域名:
+ +
+ + + + + + + + + + + + + + + + + + + + +
域名关联配置CloudflareNameserver操作
' . htmlspecialchars($dom['config_name']) . ''; + } else { + echo '未关联'; + } + ?> + + +
+ +
+ +
+ + + +
+
+ +
+ + + +
+ + 删除 +
+
+
+ +
+
+ + + + +← 返回配置列表 + +
+
+
编辑配置:
+ +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
配置名称 + + 示例:f123、d258 +
+ 关联域名
+ 请先在上方「站点域名」中添加并在宝塔创建该站点与 SSL +
+ + + 尚未添加任何域名,保存后广告链接将使用 + +
+ 是否开启 DEBUG 模式
+ 开启后访问落地链接将显示格式化调试页(判定结果、理由、代码行、访客信息),不会跳转真实页/安全页;生产环境请关闭 +
屏蔽模式 +
+ + + +
+
指定国家访问真实页(逗号分隔国家代码)
广告策略 ID
安全页跳转方式 + +
安全页链接(留空显示空白页)
真实页跳转方式 + +
真实页链接地址 + $link) { + if ($idx == 0) { + echo ' + 新增'; + } else { + echo '
删除'; + } + } + } else { + echo ' + 新增'; + } + ?> +
+
+
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ + +
+ + 重置 + 查看日志 + 数据分析 + 分享日志 +
+ +
+
+ + +
+ + + + diff --git a/datatable/countries.php b/datatable/countries.php new file mode 100755 index 0000000..a7271f5 --- /dev/null +++ b/datatable/countries.php @@ -0,0 +1,250 @@ + "无", +"AF" => "Afghanistan", +"AX" => "Aland Islands", +"AL" => "Albania", +"DZ" => "Algeria", +"AS" => "American Samoa", +"AD" => "Andorra", +"AO" => "Angola", +"AI" => "Anguilla", +"AQ" => "Antarctica", +"AG" => "Antigua and Barbuda", +"AR" => "Argentina", +"AM" => "Armenia", +"AW" => "Aruba", +"AU" => "Australia", +"AT" => "Austria", +"AZ" => "Azerbaijan", +"BS" => "Bahamas", +"BH" => "Bahrain", +"BD" => "Bangladesh", +"BB" => "Barbados", +"BY" => "Belarus", +"BE" => "Belgium", +"BZ" => "Belize", +"BJ" => "Benin", +"BM" => "Bermuda", +"BT" => "Bhutan", +"BO" => "Bolivia, Plurinational State of", +"BQ" => "Bonaire, Sint Eustatius and Saba", +"BA" => "Bosnia and Herzegovina", +"BW" => "Botswana", +"BV" => "Bouvet Island", +"BR" => "Brazil", +"IO" => "British Indian Ocean Territory", +"BN" => "Brunei Darussalam", +"BG" => "Bulgaria", +"BF" => "Burkina Faso", +"BI" => "Burundi", +"CV" => "Cabo Verde", +"KH" => "Cambodia", +"CM" => "Cameroon", +"CA" => "Canada", +"KY" => "Cayman Islands", +"CF" => "Central African Republic", +"TD" => "Chad", +"CL" => "Chile", +"CN" => "China", +"CC" => "Cocos (Keeling) Islands", +"CO" => "Colombia", +"KM" => "Comoros", +"CG" => "Congo", +"CD" => "Congo, The Democratic Republic of The", +"CK" => "Cook Islands", +"CR" => "Costa Rica", +"CI" => "Cote D'ivoire", +"HR" => "Croatia", +"CU" => "Cuba", +"CW" => "Curacao", +"CY" => "Cyprus", +"CZ" => "Czech Republic", +"DK" => "Denmark", +"DJ" => "Djibouti", +"DM" => "Dominica", +"DO" => "Dominican Republic", +"EC" => "Ecuador", +"EG" => "Egypt", +"SV" => "El Salvador", +"GQ" => "Equatorial Guinea", +"ER" => "Eritrea", +"EE" => "Estonia", +"ET" => "Ethiopia", +"FK" => "Falkland Islands (Malvinas)", +"FO" => "Faroe Islands", +"FJ" => "Fiji", +"FI" => "Finland", +"FR" => "France", +"GF" => "French Guiana", +"PF" => "French Polynesia", +"TF" => "French Southern Territories", +"GA" => "Gabon", +"GM" => "Gambia", +"GE" => "Georgia", +"DE" => "Germany", +"GH" => "Ghana", +"GI" => "Gibraltar", +"GR" => "Greece", +"GL" => "Greenland", +"GD" => "Grenada", +"GP" => "Guadeloupe", +"GU" => "Guam", +"GT" => "Guatemala", +"GG" => "Guernsey", +"GN" => "Guinea", +"GW" => "Guinea-Bissau", +"GY" => "Guyana", +"HT" => "Haiti", +"VA" => "Holy See", +"HN" => "Honduras", +"HK" => "Hong Kong", +"HU" => "Hungary", +"IS" => "Iceland", +"IN" => "India", +"ID" => "Indonesia", +"IR" => "Iran, Islamic Republic of", +"IQ" => "Iraq", +"IE" => "Ireland", +"IM" => "Isle of Man", +"IL" => "Israel", +"IT" => "Italy", +"JM" => "Jamaica", +"JP" => "Japan", +"JE" => "Jersey", +"JO" => "Jordan", +"KZ" => "Kazakhstan", +"KE" => "Kenya", +"KI" => "Kiribati", +"KP" => "Korea, Democratic People's Republic of", +"KR" => "Korea, Republic of", +"KW" => "Kuwait", +"KG" => "Kyrgyzstan", +"LA" => "Lao People's Democratic Republic", +"LV" => "Latvia", +"LB" => "Lebanon", +"LS" => "Lesotho", +"LR" => "Liberia", +"LY" => "Libya", +"LI" => "Liechtenstein", +"LT" => "Lithuania", +"LU" => "Luxembourg", +"MO" => "Macao", +"MK" => "Macedonia, The Former Yugoslav Republic of", +"MG" => "Madagascar", +"MW" => "Malawi", +"MY" => "Malaysia", +"MV" => "Maldives", +"ML" => "Mali", +"MT" => "Malta", +"MH" => "Marshall Islands", +"MQ" => "Martinique", +"MR" => "Mauritania", +"MU" => "Mauritius", +"YT" => "Mayotte", +"MX" => "Mexico", +"FM" => "Micronesia, Federated States of", +"MD" => "Moldova, Republic of", +"MC" => "Monaco", +"MN" => "Mongolia", +"ME" => "Montenegro", +"MS" => "Montserrat", +"MA" => "Morocco", +"MZ" => "Mozambique", +"MM" => "Myanmar", +"NA" => "Namibia", +"NR" => "Nauru", +"NP" => "Nepal", +"NL" => "Netherlands", +"NC" => "New Caledonia", +"NZ" => "New Zealand", +"NI" => "Nicaragua", +"NE" => "Niger", +"NG" => "Nigeria", +"NU" => "Niue", +"NF" => "Norfolk Island", +"MP" => "Northern Mariana Islands", +"NO" => "Norway", +"OM" => "Oman", +"PK" => "Pakistan", +"PW" => "Palau", +"PS" => "Palestine, State of", +"PA" => "Panama", +"PG" => "Papua New Guinea", +"PY" => "Paraguay", +"PE" => "Peru", +"PH" => "Philippines", +"PN" => "Pitcairn", +"PL" => "Poland", +"PT" => "Portugal", +"PR" => "Puerto Rico", +"QA" => "Qatar", +"RE" => "Reunion", +"RO" => "Romania", +"RU" => "Russian Federation", +"RW" => "Rwanda", +"BL" => "Saint Barthelemy", +"KN" => "Saint Kitts and Nevis", +"LC" => "Saint Lucia", +"MF" => "Saint Martin (French Part)", +"PM" => "Saint Pierre and Miquelon", +"VC" => "Saint Vincent and The Grenadines", +"WS" => "Samoa", +"SM" => "San Marino", +"ST" => "Sao Tome and Principe", +"SA" => "Saudi Arabia", +"SN" => "Senegal", +"RS" => "Serbia", +"SC" => "Seychelles", +"SL" => "Sierra Leone", +"SG" => "Singapore", +"SX" => "Sint Maarten (Dutch Part)", +"SK" => "Slovakia", +"SI" => "Slovenia", +"SB" => "Solomon Islands", +"SO" => "Somalia", +"ZA" => "South Africa", +"GS" => "South Georgia and The South Sandwich Islands", +"SS" => "South Sudan", +"ES" => "Spain", +"LK" => "Sri Lanka", +"SD" => "Sudan", +"SR" => "Suriname", +"SJ" => "Svalbard and Jan Mayen", +"SZ" => "Swaziland", +"SE" => "Sweden", +"CH" => "Switzerland", +"SY" => "Syrian Arab Republic", +"TW" => "Taiwan, Province of China", +"TJ" => "Tajikistan", +"TZ" => "Tanzania, United Republic of", +"TH" => "Thailand", +"TL" => "Timor-Leste", +"TG" => "Togo", +"TK" => "Tokelau", +"TO" => "Tonga", +"TT" => "Trinidad and Tobago", +"TN" => "Tunisia", +"TR" => "Turkey", +"TM" => "Turkmenistan", +"TC" => "Turks and Caicos Islands", +"TV" => "Tuvalu", +"UG" => "Uganda", +"UA" => "Ukraine", +"AE" => "United Arab Emirates", +"GB" => "United Kingdom", +"US" => "United States", +"UM" => "United States Minor Outlying Islands", +"UY" => "Uruguay", +"UZ" => "Uzbekistan", +"VU" => "Vanuatu", +"VE" => "Venezuela, Bolivarian Republic of", +"VN" => "Viet Nam", +"VG" => "Virgin Islands, British", +"VI" => "Virgin Islands, U.S.", +"WF" => "Wallis and Futuna", +"YE" => "Yemen", +"ZM" => "Zambia", +"ZW" => "Zimbabwe", +); \ No newline at end of file diff --git a/datatable/datalist.php b/datatable/datalist.php new file mode 100755 index 0000000..78a8434 --- /dev/null +++ b/datatable/datalist.php @@ -0,0 +1,172 @@ + "过滤无来源的访问", + "blacklisted_ptr" => "过滤黑名单主机名的访问者", + "proxy" => " 过滤代理和VPN", + "filter_isps" => "过滤不常见的服务提供商", + "switched_browsers" => "过滤多少分钟内切换浏览器", + "invalid_google_click_id" => "必须是有效的googleID", + "non_touch_device" => "过滤非接触设备", + "spoofed_browser" => "过滤浏览器欺骗设备", + "sticky_filtering" => "启用粘贴过滤", + "whitelisted_browser_ids" => "可访问的用户ID", + "blacklisted_browser_ids" => "不可访问的用户ID", + "whitelisted_urlrules" => "白名单链接参数", + "blacklisted_urlrules" => "黑名单链接参数", + "device_desktop" => "过滤电脑访问", + "device_mobile" => "过滤手机的访问", + "device_tablet" => "过滤平板的访问", + "device_no_accel" => "过滤没有加速度计/陀螺仪的设备", + "device_headless_browser" => "过滤没有浏览器头的访问", + "isp_type" => "过滤指定的ISP类型", + "browser_time_zone" => "可以访问的浏览器时区", + "whitelisted_language_codes" => "允许访问的浏览器语言", + "blacklisted_language_codes" => "不允许访问的浏览器语言", + "agent" => "代理商列表", + "ip_lists" => "IP列表", + "referrer" => "来源用户列表", + "org" => "组织机构列表", + "deadbolt" => "是否限制访问", + "global_db" => "全球IP数据库", + "org_isp" => "组织或者ISP", + "cross_campaign_ip_visits" => "每个IP最多可访问多少个", + "too_many_ip_visits" => "每个IP最多可访问多少次", + "too_many_browser_visits" => "每个浏览器最多可访问多少次", + "whitelisted_safe_page_url" => "仅允许页面地址包含", + "blacklisted_safe_page_url" => "过滤页面地址包含", + "time_of_day" => "不可访问的日期", +); + +if(empty($_SESSION['password']) || $_SESSION['password'] != LOGIN_PASSWORD) { + unset($_SESSION['password']); + unset($_SESSION['check_result']); + die("404 Not Found"); +} +$servername = "localhost"; +$username = DB_USERNAME; +$password = DB_PASSWORD; +$dbname = DB_NAME; + +// Create connection +$conn = new mysqli($servername, $username, $password, $dbname); +$jsonResult = array(); +// Check connection +if ($conn->connect_error) { + $error = "Connection failed: " . $conn->connect_error; + $handle = fopen(dirname(__FILE__) . "/err.txt", "a+"); + fwrite($handle, date("Y-m-d H:i:s") . ' | ' . $error . "\n"); + fclose($handle); + + $jsonResult["code"] = 1; + $jsonResult["msg"] = $error; + $jsonResult["count"] = 0; + $jsonResult["data"] = array(); +} else { + VisitorLogSchema::ensureColumns($conn); + if(isset($_GET['clear']) && $_GET['clear'] == "true") { //清除日志数据表 + $sql = "TRUNCATE `visitor_logs`"; + + // 执行查询并输出结果 + $result = mysqli_query($conn, $sql); + $jsonResult["code"] = 0; + $jsonResult["msg"] = "success"; + $jsonResult["count"] = 0; + $jsonResult["data"] = array(); + } else { // 默认分页数据 + // 获取当前页码(默认为第1页) + $pageNumber = isset($_GET['page']) ? (int) $_GET['page'] : 1; + + // 设置每页显示的记录条数 + $recordsPerPage = isset($_GET['limit']) ? (int) $_GET['limit'] : 50; + + // 计算起始位置 + $startPosition = ($pageNumber - 1) * $recordsPerPage; + $map = array(); + $where = 1; + + if(!empty($_GET['visit_date'])) { + $map[] = "DATE_FORMAT(`visit_date`, '%Y-%m-%d') LIKE '" . cloak_db_escape($conn, $_GET['visit_date']) . "'"; + } + + $where .= cloak_visitor_log_apply_result_filter($conn, $_GET['result'] ?? ''); + + if(!empty($_GET['country'])) { + $map[] = "country LIKE '" . cloak_db_escape($conn, $_GET['country']) . "'"; + } + + if(!empty($_GET['IP'])) { + $map[] = "IP LIKE '" . cloak_db_escape($conn, $_GET['IP']) . "'"; + } + + if(!empty($_GET['domain'])) { + $map[] = "domain LIKE '%" . cloak_db_escape($conn, $_GET['domain']) . "%'"; + } + + if(!empty($_GET['spage'])) { + $map[] = "page LIKE '%" . cloak_db_escape($conn, $_GET['spage']) . "%'"; + } + + if(!empty($map)) { + $where .= " AND " . join(" AND ", $map); + } + // SQL语句 + $sql = "SELECT `id`, `campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `fp_url`, `referer`, `vtimes`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `device`, `add_time` FROM `visitor_logs` WHERE {$where} ORDER BY `id` DESC LIMIT {$startPosition}, {$recordsPerPage}"; + + // 执行查询并输出结果 + $result = mysqli_query($conn, $sql); + $jsonData = array(); + + while ($row = mysqli_fetch_assoc($result)) { + //echo "

{$row["columnName"]}

"; // 根据需要修改列名 + if($row['vtimes'] == 0) { + $row['vtimes'] = 1; // 还未统计访问次数 + $sqlVtimes = mysqli_query($conn, "SELECT count(*) as `total` FROM `visitor_logs` WHERE `IP` = '" . cloak_db_escape($conn, $row["IP"]) . "' AND `domain` = '" . cloak_db_escape($conn, $row["domain"]) . "' AND id < " . (int)$row['id']); + $vtimesRow = mysqli_fetch_assoc($sqlVtimes); + $vtimes = $vtimesRow["total"]; // 如果之前此IP有访问记录 + if($vtimes > 0) { + $row['vtimes'] += $vtimes; // 访问次数叠加 + } + + // 更新访问次数 + $updateSql = "UPDATE `visitor_logs` SET `vtimes`=" . (int)$row['vtimes'] . " WHERE id = " . $row['id']; + mysqli_query($conn, $updateSql); + } + + if(!empty($row['country'])) { + $row['country'] = isset($countries[$row['country']])?$countries[$row['country']]:"无"; + } else { + $row['country'] = "无"; + } + if(isset($reasons[$row['reason']])) { + $row['reason'] = $reasons[$row['reason']]; + } + if ($row['result'] === 'wait') { + $row['result'] = '检测中'; + } + $row['judge_timing_text'] = cloak_visitor_log_format_timing($row['judge_timing'] ?? ''); + $jsonData[] = $row; + } + + $sqlCount = mysqli_query($conn, "SELECT count(*) as `total` FROM `visitor_logs` WHERE {$where}"); + $countRow = mysqli_fetch_assoc($sqlCount); + + $jsonResult["code"] = 0; + $jsonResult["msg"] = ""; + $jsonResult["count"] = $countRow['total']; + $jsonResult["data"] = $jsonData; + } +} + +// 关闭数据库连接 +mysqli_close($conn); + +header('Content-Type: application/json'); + +echo json_encode($jsonResult);exit; diff --git a/datatable/err.txt b/datatable/err.txt new file mode 100755 index 0000000..dc13f67 --- /dev/null +++ b/datatable/err.txt @@ -0,0 +1,3 @@ +2023-12-31 18:29:49 | Connection failed: Access denied for user 'root'@'localhost' (using password: YES) +2023-12-31 18:31:01 | Connection failed: Access denied for user 'root'@'localhost' (using password: YES) +2023-12-31 18:31:10 | Connection failed: Access denied for user 'root'@'localhost' (using password: YES) diff --git a/datatable/export.php b/datatable/export.php new file mode 100755 index 0000000..d7f3685 --- /dev/null +++ b/datatable/export.php @@ -0,0 +1,127 @@ + "过滤无来源的访问", + "blacklisted_ptr" => "过滤黑名单主机名的访问者", + "proxy" => " 过滤代理和VPN", + "filter_isps" => "过滤不常见的服务提供商", + "switched_browsers" => "过滤多少分钟内切换浏览器", + "invalid_google_click_id" => "必须是有效的googleID", + "non_touch_device" => "过滤非接触设备", + "spoofed_browser" => "过滤浏览器欺骗设备", + "sticky_filtering" => "启用粘贴过滤", + "whitelisted_browser_ids" => "可访问的用户ID", + "blacklisted_browser_ids" => "不可访问的用户ID", + "whitelisted_urlrules" => "白名单链接参数", + "blacklisted_urlrules" => "黑名单链接参数", + "device_desktop" => "过滤电脑访问", + "device_mobile" => "过滤手机的访问", + "device_tablet" => "过滤平板的访问", + "device_no_accel" => "过滤没有加速度计/陀螺仪的设备", + "device_headless_browser" => "过滤没有浏览器头的访问", + "isp_type" => "过滤指定的ISP类型", + "browser_time_zone" => "可以访问的浏览器时区", + "whitelisted_language_codes" => "允许访问的浏览器语言", + "blacklisted_language_codes" => "不允许访问的浏览器语言", + "agent" => "代理商列表", + "ip_lists" => "IP列表", + "referrer" => "来源用户列表", + "org" => "组织机构列表", + "deadbolt" => "是否限制访问", + "global_db" => "全球IP数据库", + "org_isp" => "组织或者ISP", + "cross_campaign_ip_visits" => "每个IP最多可访问多少个", + "too_many_ip_visits" => "每个IP最多可访问多少次", + "too_many_browser_visits" => "每个浏览器最多可访问多少次", + "whitelisted_safe_page_url" => "仅允许页面地址包含", + "blacklisted_safe_page_url" => "过滤页面地址包含", + "time_of_day" => "不可访问的日期", +); + +$servername = "localhost"; +$username = DB_USERNAME; +$password = DB_PASSWORD; +$dbname = DB_NAME; + +// Create connection +$conn = new mysqli($servername, $username, $password, $dbname); + +// Check connection +if ($conn->connect_error) { + $error = "Connection failed: " . $conn->connect_error; + $handle = fopen(dirname(__FILE__) . "/err.txt", "a+"); + fwrite($handle, date("Y-m-d H:i:s") . ' | ' . $error . "\n"); + fclose($handle); + + echo "数据库连接失败";exit; + +} else { + VisitorLogSchema::ensureColumns($conn); + $map = array(); + $where = 1; + + if(!empty($_GET['visit_date'])) { + $map[] = "DATE_FORMAT(`visit_date`, '%Y-%m-%d') LIKE '" . cloak_db_escape($conn, $_GET['visit_date']) . "'"; + } + + $where .= cloak_visitor_log_apply_result_filter($conn, $_GET['result'] ?? ''); + + if(!empty($_GET['country'])) { + $map[] = "country LIKE '" . cloak_db_escape($conn, $_GET['country']) . "'"; + } + + if(!empty($_GET['IP'])) { + $map[] = "IP LIKE '" . cloak_db_escape($conn, $_GET['IP']) . "'"; + } + + if(!empty($_GET['domain'])) { + $map[] = "domain LIKE '%" . cloak_db_escape($conn, $_GET['domain']) . "%'"; + } + + if(!empty($_GET['spage'])) { + $map[] = "page LIKE '%" . cloak_db_escape($conn, $_GET['spage']) . "%'"; + } + + if(!empty($map)) { + $where .= " AND " . join(" AND ", $map); + } + // SQL语句 + $sql = "SELECT `id`, `campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `fp_url`, `referer`, `vtimes`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `device`, `add_time` FROM `visitor_logs` WHERE {$where} ORDER BY `id` DESC"; + + // 执行查询并输出结果 + $result = mysqli_query($conn, $sql); + + + echo "\xEF\xBB\xBF"; + $fp = fopen('php://output', 'w'); + while ($row = mysqli_fetch_assoc($result)) { + $row['country'] = $countries[$row['country']]; + if(isset($reasons[$row['reason']])) { + $row['reason'] = $reasons[$row['reason']]; + } + if ($row['result'] === 'wait') { + $row['result'] = '检测中'; + } + $row['judge_timing_text'] = cloak_visitor_log_format_timing($row['judge_timing'] ?? ''); + fputcsv($fp, $row); + } + fclose($fp); + exit(""); +} \ No newline at end of file diff --git a/datatable/log_analytics.php b/datatable/log_analytics.php new file mode 100644 index 0000000..f81ec3e --- /dev/null +++ b/datatable/log_analytics.php @@ -0,0 +1,36 @@ + 1, 'msg' => '未授权', 'data' => null], JSON_UNESCAPED_UNICODE); + exit; +} + +$conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); +if ($conn->connect_error) { + echo json_encode(['code' => 1, 'msg' => '数据库连接失败', 'data' => null], JSON_UNESCAPED_UNICODE); + exit; +} + +$filters = [ + 'date_from' => $_GET['date_from'] ?? '', + 'date_to' => $_GET['date_to'] ?? '', + 'domain' => $_GET['domain'] ?? '', + 'campagin_id' => $_GET['campagin_id'] ?? '', +]; + +$data = VisitorLogAnalytics::buildReport($conn, $filters); +$conn->close(); + +echo json_encode([ + 'code' => 0, + 'msg' => 'success', + 'data' => $data, +], JSON_UNESCAPED_UNICODE); diff --git a/datatable/sdatalist.php b/datatable/sdatalist.php new file mode 100755 index 0000000..fdbe06c --- /dev/null +++ b/datatable/sdatalist.php @@ -0,0 +1,162 @@ + "过滤无来源的访问", + "blacklisted_ptr" => "过滤黑名单主机名的访问者", + "proxy" => " 过滤代理和VPN", + "filter_isps" => "过滤不常见的服务提供商", + "switched_browsers" => "过滤多少分钟内切换浏览器", + "invalid_google_click_id" => "必须是有效的googleID", + "non_touch_device" => "过滤非接触设备", + "spoofed_browser" => "过滤浏览器欺骗设备", + "sticky_filtering" => "启用粘贴过滤", + "whitelisted_browser_ids" => "可访问的用户ID", + "blacklisted_browser_ids" => "不可访问的用户ID", + "whitelisted_urlrules" => "白名单链接参数", + "blacklisted_urlrules" => "黑名单链接参数", + "device_desktop" => "过滤电脑访问", + "device_mobile" => "过滤手机的访问", + "device_tablet" => "过滤平板的访问", + "device_no_accel" => "过滤没有加速度计/陀螺仪的设备", + "device_headless_browser" => "过滤没有浏览器头的访问", + "isp_type" => "过滤指定的ISP类型", + "browser_time_zone" => "可以访问的浏览器时区", + "whitelisted_language_codes" => "允许访问的浏览器语言", + "blacklisted_language_codes" => "不允许访问的浏览器语言", + "agent" => "代理商列表", + "ip_lists" => "IP列表", + "referrer" => "来源用户列表", + "org" => "组织机构列表", + "deadbolt" => "是否限制访问", + "global_db" => "全球IP数据库", + "org_isp" => "组织或者ISP", + "cross_campaign_ip_visits" => "每个IP最多可访问多少个", + "too_many_ip_visits" => "每个IP最多可访问多少次", + "too_many_browser_visits" => "每个浏览器最多可访问多少次", + "whitelisted_safe_page_url" => "仅允许页面地址包含", + "blacklisted_safe_page_url" => "过滤页面地址包含", + "time_of_day" => "不可访问的日期", +); + +$servername = "localhost"; +$username = DB_USERNAME; +$password = DB_PASSWORD; +$dbname = DB_NAME; + +// Create connection +$conn = new mysqli($servername, $username, $password, $dbname); +$jsonResult = array(); +// Check connection +if ($conn->connect_error) { + $error = "Connection failed: " . $conn->connect_error; + $handle = fopen(dirname(__FILE__) . "/err.txt", "a+"); + fwrite($handle, date("Y-m-d H:i:s") . ' | ' . $error . "\n"); + fclose($handle); + + $jsonResult["code"] = 1; + $jsonResult["msg"] = $error; + $jsonResult["count"] = 0; + $jsonResult["data"] = array(); +} else { + VisitorLogSchema::ensureColumns($conn); + if(isset($_GET['clear']) && $_GET['clear'] == "true") { //清除日志数据表 + $sql = "TRUNCATE `visitor_logs`"; + + // 执行查询并输出结果 + $result = mysqli_query($conn, $sql); + $jsonResult["code"] = 0; + $jsonResult["msg"] = "success"; + $jsonResult["count"] = 0; + $jsonResult["data"] = array(); + } else { // 默认分页数据 + // 获取当前页码(默认为第1页) + $pageNumber = isset($_GET['page']) ? (int) $_GET['page'] : 1; + + // 设置每页显示的记录条数 + $recordsPerPage = isset($_GET['limit']) ? (int) $_GET['limit'] : 50; + + // 计算起始位置 + $startPosition = ($pageNumber - 1) * $recordsPerPage; + $map = array(); + $where = 1; + + if(!empty($_GET['visit_date'])) { + $map[] = "DATE_FORMAT(`visit_date`, '%Y-%m-%d') LIKE '" . cloak_db_escape($conn, $_GET['visit_date']) . "'"; + } + + $where .= cloak_visitor_log_apply_result_filter($conn, $_GET['result'] ?? ''); + + if(!empty($_GET['country'])) { + $map[] = "country LIKE '" . cloak_db_escape($conn, $_GET['country']) . "'"; + } + + if(!empty($_GET['IP'])) { + $map[] = "IP LIKE '" . cloak_db_escape($conn, $_GET['IP']) . "'"; + } + + if(!empty($_GET['domain'])) { + $map[] = "domain LIKE '%" . cloak_db_escape($conn, $_GET['domain']) . "%'"; + } + + if(!empty($_GET['spage'])) { + $map[] = "page LIKE '%" . cloak_db_escape($conn, $_GET['spage']) . "%'"; + } + + if(!empty($map)) { + $where .= " AND " . join(" AND ", $map); + } + // SQL语句 + $sql = "SELECT `id`, `campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `fp_url`, `referer`, `vtimes`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `device`, `add_time` FROM `visitor_logs` WHERE {$where} ORDER BY `id` DESC LIMIT {$startPosition}, {$recordsPerPage}"; + + // 执行查询并输出结果 + $result = mysqli_query($conn, $sql); + $jsonData = array(); + + while ($row = mysqli_fetch_assoc($result)) { + //echo "

{$row["columnName"]}

"; // 根据需要修改列名 + if($row['vtimes'] == 0) { + $row['vtimes'] = 1; // 还未统计访问次数 + $sqlVtimes = mysqli_query($conn, "SELECT count(*) as `total` FROM `visitor_logs` WHERE `IP` = '" . cloak_db_escape($conn, $row["IP"]) . "' AND `domain` = '" . cloak_db_escape($conn, $row["domain"]) . "' AND id < " . (int)$row['id']); + $vtimesRow = mysqli_fetch_assoc($sqlVtimes); + $vtimes = $vtimesRow["total"]; // 如果之前此IP有访问记录 + if($vtimes > 0) { + $row['vtimes'] += $vtimes; // 访问次数叠加 + } + + // 更新访问次数 + $updateSql = "UPDATE `visitor_logs` SET `vtimes`=" . (int)$row['vtimes'] . " WHERE id = " . $row['id']; + mysqli_query($conn, $updateSql); + } + + $row['country'] = $countries[$row['country']]; + if(isset($reasons[$row['reason']])) { + $row['reason'] = $reasons[$row['reason']]; + } + if ($row['result'] === 'wait') { + $row['result'] = '检测中'; + } + $row['judge_timing_text'] = cloak_visitor_log_format_timing($row['judge_timing'] ?? ''); + $jsonData[] = $row; + } + + $sqlCount = mysqli_query($conn, "SELECT count(*) as `total` FROM `visitor_logs` WHERE {$where}"); + $countRow = mysqli_fetch_assoc($sqlCount); + + $jsonResult["code"] = 0; + $jsonResult["msg"] = ""; + $jsonResult["count"] = $countRow['total']; + $jsonResult["data"] = $jsonData; + } +} + +// 关闭数据库连接 +mysqli_close($conn); + +header('Content-Type: application/json'); + +echo json_encode($jsonResult);exit; diff --git a/deploy/baota/README.md b/deploy/baota/README.md new file mode 100755 index 0000000..76fac27 --- /dev/null +++ b/deploy/baota/README.md @@ -0,0 +1,90 @@ +# IPCLOAKAPI 宝塔一键部署说明 + +## 适用场景 + +在一台宝塔服务器上**安装一次**,之后新建的 PHP 网站可通过钩子自动接入 Cloak 流量判定(需在后台绑定域名与配置)。 + +## 三步安装(客户向) + +### 第 1 步:上传并执行安装脚本 + +1. 将整个项目上传到服务器(或通过 Git 拉取)。 +2. SSH 登录服务器,执行: + +```bash +cd /path/to/cloaka +sudo bash deploy/baota/install_bt.sh +``` + +3. 按提示输入**管理后台域名**(例如 `cloak-admin.你的域名.com`)。脚本会把程序安装到 `/www/cloaka`(可改 `--root`)。 + +### 第 2 步:完成 Web 安装向导 + +浏览器打开: + +```text +https://cloak-admin.你的域名.com/install.php +``` + +填写 MySQL、后台密码、API 秘钥(CHECK_KEY),点击安装。 + +### 第 3 步:为每个业务站配置 + +对每个投流域名: + +1. **先在宝塔**:网站 → 添加站点 → 填写域名 → 申请 **SSL**(必须)。 +2. **再在后台**:`dashboard.php` → **站点域名** → 添加相同域名。 +3. **新建或编辑配置** → **关联域名** 选择该域名 → 填写仿品/正品链接 → 保存。 + +> 未添加域名时,广告链接默认使用**当前访问后台的域名**。 + +## 新建宝塔网站时会发生什么 + +安装脚本会在 `/www/server/panel/hook/` 注册 `cloaka_post_site.sh`: + +- 为新站点 Nginx 配置追加 Cloak 路由片段(请求走 `/www/cloaka/ip_check.php`)。 +- 尝试在数据库 `cloak_site_domains` 登记该域名(需已完成 install.php)。 + +## 手动绑定已有站点 + +编辑站点 Nginx 配置,在 `server { }` 内追加(注意修改 PHP 版本路径): + +```nginx +# BEGIN IPCLOAKAPI +# 内容见 /www/cloaka/deploy/baota/nginx/cloaka-site.conf.installed +# END IPCLOAKAPI +``` + +或重新运行: + +```bash +sudo CLOAK_ROOT=/www/cloaka bash /www/cloaka/deploy/baota/hook/post_site.sh 站点域名 /www/wwwroot/站点域名 +``` + +## 升级 + +```bash +sudo bash deploy/baota/install_bt.sh --upgrade --source /path/to/new/cloaka +``` + +不会覆盖 `cong.php`、`.install.lock` 及 `check_config/*_config.php`。 + +## 目录说明 + +| 路径 | 说明 | +|------|------| +| `/www/cloaka` | 程序主目录(默认) | +| `deploy/baota/nginx/cloaka-site.conf` | 业务站 Nginx 模板 | +| `deploy/baota/nginx/cloaka-admin.conf` | 管理站 Nginx 补充 | +| `deploy/baota/hook/post_site.sh` | 建站后钩子 | + +## 常见问题 + +**Q:访问业务站 502?** +检查 `cloaka-site.conf.installed` 中 PHP include 路径是否与站点 PHP 版本一致(安装脚本会按 82/83/81 检测)。 + +**Q:配置不生效?** +确认后台已为该域名**关联配置**,且 `check_config/配置名_config.php` 存在。 + +**Q:广告链接域名不对?** +在编辑配置中选择正确的「关联域名」;未选择时使用后台当前访问域名。 diff --git a/deploy/baota/hook/post_site.sh b/deploy/baota/hook/post_site.sh new file mode 100755 index 0000000..b091436 --- /dev/null +++ b/deploy/baota/hook/post_site.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# 宝塔建站完成后钩子:为站点启用 Cloak 路由 +# 用法:post_site.sh <域名> <网站根目录> + +set -euo pipefail + +if [[ -f /etc/cloaka.env ]]; then + # shellcheck disable=SC1091 + source /etc/cloaka.env +fi +CLOAK_ROOT="${CLOAK_ROOT:-/www/cloaka}" + +SITE_DOMAIN="${1:-}" +SITE_PATH="${2:-}" +MARK_BEGIN="# BEGIN IPCLOAKAPI" +MARK_END="# END IPCLOAKAPI" + +[[ -z "$SITE_DOMAIN" ]] && exit 0 + +VHOST="/www/server/panel/vhost/nginx/${SITE_DOMAIN}.conf" +SNIPPET_INST="${CLOAK_ROOT}/deploy/baota/nginx/cloaka-site.conf.installed" + +if [[ ! -f "$VHOST" ]]; then + exit 0 +fi + +if [[ ! -f "$SNIPPET_INST" ]]; then + exit 0 +fi + +if ! grep -qF "$MARK_BEGIN" "$VHOST" 2>/dev/null; then + { + echo "" + echo "$MARK_BEGIN" + cat "$SNIPPET_INST" + echo "$MARK_END" + } >> "$VHOST" +fi + +if [[ -f "${CLOAK_ROOT}/cong.php" ]]; then + php -r " +require '${CLOAK_ROOT}/cong.php'; +require '${CLOAK_ROOT}/lib/Cloak/DomainRepository.php'; +try { + \$pdo = DomainRepository::pdo(); + DomainRepository::ensureTable(\$pdo); + \$host = DomainRepository::normalizeHostname('${SITE_DOMAIN}'); + if (!DomainRepository::findByHostname(\$pdo, \$host)) { + DomainRepository::add(\$pdo, \$host); + } +} catch (Throwable \$e) {} +" 2>/dev/null || true +fi + +nginx -t 2>/dev/null && nginx -s reload 2>/dev/null || true diff --git a/deploy/baota/hook/post_site_del.sh b/deploy/baota/hook/post_site_del.sh new file mode 100755 index 0000000..68f1b86 --- /dev/null +++ b/deploy/baota/hook/post_site_del.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# 宝塔删站钩子(可选):不删除 check_config,仅清理 vhost 标记由面板完成 + +set -euo pipefail +exit 0 diff --git a/deploy/baota/install_bt.sh b/deploy/baota/install_bt.sh new file mode 100755 index 0000000..fcf8d55 --- /dev/null +++ b/deploy/baota/install_bt.sh @@ -0,0 +1,131 @@ +#!/bin/bash +# IPCLOAKAPI 宝塔一键安装脚本 +# 用法:sudo bash install_bt.sh [--upgrade] [--source /path/to/cloaka] +set -euo pipefail + +UPGRADE=0 +SOURCE_DIR="" +CLOAK_ROOT="/www/cloaka" +ADMIN_DOMAIN="" +PHP_VER="82" + +while [[ $# -gt 0 ]]; do + case "$1" in + --upgrade) UPGRADE=1; shift ;; + --source) SOURCE_DIR="${2:-}"; shift 2 ;; + --root) CLOAK_ROOT="${2:-}"; shift 2 ;; + *) echo "未知参数: $1"; exit 1 ;; + esac +done + +if [[ "$(id -u)" -ne 0 ]]; then + echo "请使用 root 运行:sudo bash install_bt.sh" + exit 1 +fi + +if [[ ! -d /www/server/panel ]]; then + echo "未检测到宝塔面板目录 /www/server/panel" + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [[ -z "$SOURCE_DIR" ]]; then + SOURCE_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" +fi + +detect_php() { + for v in 82 83 81 80 74; do + if [[ -f "/www/server/php/${v}/etc/php.ini" ]]; then + PHP_VER="$v" + return + fi + done + PHP_VER="82" +} + +detect_php +PHP_INCLUDE="/www/server/nginx/conf/enable-php-${PHP_VER}.conf" +if [[ ! -f "$PHP_INCLUDE" ]]; then + PHP_INCLUDE="enable-php.conf" +fi + +echo "=== IPCLOAKAPI 宝塔安装 ===" +echo "源码目录: $SOURCE_DIR" +echo "安装目录: $CLOAK_ROOT" +echo "PHP 版本: ${PHP_VER}" + +if [[ "$UPGRADE" -eq 0 ]]; then + read -r -p "管理后台域名(如 cloak-admin.example.com,可留空稍后手动建站): " ADMIN_DOMAIN +fi + +mkdir -p "$CLOAK_ROOT" +if command -v rsync >/dev/null 2>&1; then + rsync -a --delete \ + --exclude '.git' --exclude 'node_modules' --exclude '.cursor' \ + --exclude 'cong.php' --exclude '.install.lock' --exclude 'check_config/*_config.php' \ + "$SOURCE_DIR/" "$CLOAK_ROOT/" +else + cp -a "$SOURCE_DIR/." "$CLOAK_ROOT/" +fi + +chown -R www:www "$CLOAK_ROOT" +chmod -R u=rwX,g=rX,o=rX "$CLOAK_ROOT" +chmod -R u=rwX,g=rwX,o= "$CLOAK_ROOT/check_config" 2>/dev/null || mkdir -p "$CLOAK_ROOT/check_config" && chown www:www "$CLOAK_ROOT/check_config" +touch "$CLOAK_ROOT/jump.txt" "$CLOAK_ROOT/nt.txt" "$CLOAK_ROOT/err.txt" 2>/dev/null || true +chown www:www "$CLOAK_ROOT"/*.txt 2>/dev/null || true + +# 注册建站钩子 +HOOK_DIR="/www/server/panel/hook" +mkdir -p "$HOOK_DIR" +install -m 755 "$SCRIPT_DIR/hook/post_site.sh" "$HOOK_DIR/cloaka_post_site.sh" +install -m 755 "$SCRIPT_DIR/hook/post_site_del.sh" "$HOOK_DIR/cloaka_post_site_del.sh" + +# 环境变量供钩子使用 +ENV_FILE="/etc/cloaka.env" +echo "CLOAK_ROOT=${CLOAK_ROOT}" > "$ENV_FILE" +chmod 644 "$ENV_FILE" + +# 预处理 Nginx 片段 +SNIPPET_INST="${CLOAK_ROOT}/deploy/baota/nginx/cloaka-site.conf.installed" +sed -e "s|__CLOAK_ROOT__|${CLOAK_ROOT}|g" -e "s|__PHP_INCLUDE__|${PHP_INCLUDE}|g" \ + "$SCRIPT_DIR/nginx/cloaka-site.conf" > "$SNIPPET_INST" + +if [[ -n "$ADMIN_DOMAIN" && "$UPGRADE" -eq 0 ]]; then + if command -v bt >/dev/null 2>&1; then + echo "正在创建管理站点: $ADMIN_DOMAIN" + bt site add "$ADMIN_DOMAIN" "$CLOAK_ROOT" 2>/dev/null || true + fi + ADMIN_VHOST="/www/server/panel/vhost/nginx/${ADMIN_DOMAIN}.conf" + if [[ -f "$ADMIN_VHOST" ]] && ! grep -q 'cloaka-admin' "$ADMIN_VHOST" 2>/dev/null; then + cat "$SCRIPT_DIR/nginx/cloaka-admin.conf" >> "$ADMIN_VHOST" + fi +fi + +# 确保域名表(已安装 cong 时) +if [[ -f "$CLOAK_ROOT/cong.php" ]]; then + php -r " +require '${CLOAK_ROOT}/cong.php'; +require '${CLOAK_ROOT}/lib/Cloak/DomainRepository.php'; +\$pdo = DomainRepository::pdo(); +DomainRepository::ensureTable(\$pdo); +echo 'cloak_site_domains OK\n'; +" 2>/dev/null || true +fi + +nginx -t && nginx -s reload || true + +echo "" +echo "============================================" +echo "安装文件已就绪。" +if [[ ! -f "$CLOAK_ROOT/.install.lock" ]]; then + if [[ -n "$ADMIN_DOMAIN" ]]; then + echo "请浏览器访问: https://${ADMIN_DOMAIN}/install.php" + else + echo "请在宝塔新建站点,根目录指向: ${CLOAK_ROOT}" + echo "然后访问: https://你的管理域名/install.php" + fi +else + echo "已检测到安装锁,进入后台: ${ADMIN_DOMAIN:-你的管理域名}/dashboard.php" +fi +echo "新建业务站点后,请在后台「站点域名」添加域名并关联配置。" +echo "============================================" diff --git a/deploy/baota/nginx/cloaka-admin.conf b/deploy/baota/nginx/cloaka-admin.conf new file mode 100755 index 0000000..db57a82 --- /dev/null +++ b/deploy/baota/nginx/cloaka-admin.conf @@ -0,0 +1,10 @@ +# IPCLOAKAPI — 管理站点:不经过 ip_check 流量判定,直接走 PHP + +location / { + try_files $uri $uri/ /index.php?$query_string; +} + +location ~ \.php$ { + try_files $uri =404; + include enable-php.conf; +} diff --git a/deploy/baota/nginx/cloaka-site.conf b/deploy/baota/nginx/cloaka-site.conf new file mode 100755 index 0000000..240581e --- /dev/null +++ b/deploy/baota/nginx/cloaka-site.conf @@ -0,0 +1,14 @@ +# IPCLOAKAPI — 业务站点(占位符由 install_bt.sh / post_site.sh 替换) +# __CLOAK_ROOT__ __PHP_INCLUDE__ + +location @cloaka_entry { + include __PHP_INCLUDE__; + fastcgi_param SCRIPT_FILENAME __CLOAK_ROOT__/ip_check.php; + fastcgi_param SCRIPT_NAME /ip_check.php; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param QUERY_STRING $query_string; +} + +location / { + try_files $uri $uri/ @cloaka_entry; +} diff --git a/deploy/baota/site-stub/index.php b/deploy/baota/site-stub/index.php new file mode 100755 index 0000000..384a4ff --- /dev/null +++ b/deploy/baota/site-stub/index.php @@ -0,0 +1,5 @@ +code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/dist/bootstrap/4.5.2/js/bootstrap.bundle.min.js b/dist/bootstrap/4.5.2/js/bootstrap.bundle.min.js new file mode 100755 index 0000000..5b81567 --- /dev/null +++ b/dist/bootstrap/4.5.2/js/bootstrap.bundle.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.5.2 (https://getbootstrap.com/) + * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery)}(this,(function(t,e){"use strict";function n(t,e){for(var n=0;n=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};s.jQueryDetection(),e.fn.emulateTransitionEnd=r,e.event.special[s.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var a="alert",l=e.fn[a],c=function(){function t(t){this._element=t}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},n.dispose=function(){e.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){var n=s.getSelectorFromElement(t),i=!1;return n&&(i=document.querySelector(n)),i||(i=e(t).closest(".alert")[0]),i},n._triggerCloseEvent=function(t){var n=e.Event("close.bs.alert");return e(t).trigger(n),n},n._removeElement=function(t){var n=this;if(e(t).removeClass("show"),e(t).hasClass("fade")){var i=s.getTransitionDurationFromElement(t);e(t).one(s.TRANSITION_END,(function(e){return n._destroyElement(t,e)})).emulateTransitionEnd(i)}else this._destroyElement(t)},n._destroyElement=function(t){e(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.alert");o||(o=new t(this),i.data("bs.alert",o)),"close"===n&&o[n](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',c._handleDismiss(new c)),e.fn[a]=c._jQueryInterface,e.fn[a].Constructor=c,e.fn[a].noConflict=function(){return e.fn[a]=l,c._jQueryInterface};var h=e.fn.button,u=function(){function t(t){this._element=t}var n=t.prototype;return n.toggle=function(){var t=!0,n=!0,i=e(this._element).closest('[data-toggle="buttons"]')[0];if(i){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var r=i.querySelector(".active");r&&e(r).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),e(o).trigger("change")),o.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&e(this._element).toggleClass("active"))},n.dispose=function(){e.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.button");i||(i=new t(this),e(this).data("bs.button",i)),"toggle"===n&&i[n]()}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=t.target,i=n;if(e(n).hasClass("btn")||(n=e(n).closest(".btn")[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))t.preventDefault();else{var o=n.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();("LABEL"!==i.tagName||o&&"checkbox"!==o.type)&&u._jQueryInterface.call(e(n),"toggle")}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=e(t.target).closest(".btn")[0];e(n).toggleClass("focus",/^focus(in)?$/.test(t.type))})),e(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&e(this._element).is(":visible")&&"hidden"!==e(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(s.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var n=this;this._activeElement=this._element.querySelector(".active.carousel-item");var i=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)e(this._element).one("slid.bs.carousel",(function(){return n.to(t)}));else{if(i===t)return this.pause(),void this.cycle();var o=t>i?"next":"prev";this._slide(o,this._items[t])}},n.dispose=function(){e(this._element).off(d),e.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=o({},m,t),s.typeCheckConfig(f,t,g),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&e(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&e(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var n=function(e){t._pointerEvent&&_[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},i=function(e){t._pointerEvent&&_[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};e(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(e(this._element).on("pointerdown.bs.carousel",(function(t){return n(t)})),e(this._element).on("pointerup.bs.carousel",(function(t){return i(t)})),this._element.classList.add("pointer-event")):(e(this._element).on("touchstart.bs.carousel",(function(t){return n(t)})),e(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),e(this._element).on("touchend.bs.carousel",(function(t){return i(t)})))}},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},n._triggerSlideEvent=function(t,n){var i=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),r=e.Event("slide.bs.carousel",{relatedTarget:t,direction:n,from:o,to:i});return e(this._element).trigger(r),r},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));e(n).removeClass("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&e(i).addClass("active")}},n._slide=function(t,n){var i,o,r,a=this,l=this._element.querySelector(".active.carousel-item"),c=this._getItemIndex(l),h=n||l&&this._getItemByDirection(t,l),u=this._getItemIndex(h),f=Boolean(this._interval);if("next"===t?(i="carousel-item-left",o="carousel-item-next",r="left"):(i="carousel-item-right",o="carousel-item-prev",r="right"),h&&e(h).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(h,r).isDefaultPrevented()&&l&&h){this._isSliding=!0,f&&this.pause(),this._setActiveIndicatorElement(h);var d=e.Event("slid.bs.carousel",{relatedTarget:h,direction:r,from:c,to:u});if(e(this._element).hasClass("slide")){e(h).addClass(o),s.reflow(h),e(l).addClass(i),e(h).addClass(i);var p=parseInt(h.getAttribute("data-interval"),10);p?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=p):this._config.interval=this._config.defaultInterval||this._config.interval;var m=s.getTransitionDurationFromElement(l);e(l).one(s.TRANSITION_END,(function(){e(h).removeClass(i+" "+o).addClass("active"),e(l).removeClass("active "+o+" "+i),a._isSliding=!1,setTimeout((function(){return e(a._element).trigger(d)}),0)})).emulateTransitionEnd(m)}else e(l).removeClass("active"),e(h).addClass("active"),this._isSliding=!1,e(this._element).trigger(d);f&&this.cycle()}},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.carousel"),r=o({},m,e(this).data());"object"==typeof n&&(r=o({},r,n));var s="string"==typeof n?n:r.slide;if(i||(i=new t(this,r),e(this).data("bs.carousel",i)),"number"==typeof n)i.to(n);else if("string"==typeof s){if("undefined"==typeof i[s])throw new TypeError('No method named "'+s+'"');i[s]()}else r.interval&&r.ride&&(i.pause(),i.cycle())}))},t._dataApiClickHandler=function(n){var i=s.getSelectorFromElement(this);if(i){var r=e(i)[0];if(r&&e(r).hasClass("carousel")){var a=o({},e(r).data(),e(this).data()),l=this.getAttribute("data-slide-to");l&&(a.interval=!1),t._jQueryInterface.call(e(r),a),l&&e(r).data("bs.carousel").to(l),n.preventDefault()}}},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return m}}]),t}();e(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",v._dataApiClickHandler),e(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),n=0,i=t.length;n0&&(this._selector=a,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=t.prototype;return n.toggle=function(){e(this._element).hasClass("show")?this.hide():this.show()},n.show=function(){var n,i,o=this;if(!this._isTransitioning&&!e(this._element).hasClass("show")&&(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(n=null),!(n&&(i=e(n).not(this._selector).data("bs.collapse"))&&i._isTransitioning))){var r=e.Event("show.bs.collapse");if(e(this._element).trigger(r),!r.isDefaultPrevented()){n&&(t._jQueryInterface.call(e(n).not(this._selector),"hide"),i||e(n).data("bs.collapse",null));var a=this._getDimension();e(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[a]=0,this._triggerArray.length&&e(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(a[0].toUpperCase()+a.slice(1)),c=s.getTransitionDurationFromElement(this._element);e(this._element).one(s.TRANSITION_END,(function(){e(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[a]="",o.setTransitioning(!1),e(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(c),this._element.style[a]=this._element[l]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&e(this._element).hasClass("show")){var n=e.Event("hide.bs.collapse");if(e(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",s.reflow(this._element),e(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var r=0;r=0)return 1;return 0}();var D=C&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),S))}};function N(t){return t&&"[object Function]"==={}.toString.call(t)}function k(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function A(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function I(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=k(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:I(A(t))}function O(t){return t&&t.referenceNode?t.referenceNode:t}var x=C&&!(!window.MSInputMethodContext||!document.documentMode),j=C&&/MSIE 10/.test(navigator.userAgent);function L(t){return 11===t?x:10===t?j:x||j}function P(t){if(!t)return document.documentElement;for(var e=L(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===k(n,"position")?P(n):n:t?t.ownerDocument.documentElement:document.documentElement}function F(t){return null!==t.parentNode?F(t.parentNode):t}function R(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var s,a,l=r.commonAncestorContainer;if(t!==l&&e!==l||i.contains(o))return"BODY"===(a=(s=l).nodeName)||"HTML"!==a&&P(s.firstElementChild)!==s?P(l):l;var c=F(t);return c.host?R(c.host,e):R(t,F(e).host)}function H(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function M(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=H(e,"top"),o=H(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function B(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"])+parseFloat(t["border"+i+"Width"])}function q(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],L(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function Q(t){var e=t.body,n=t.documentElement,i=L(10)&&getComputedStyle(n);return{height:q("Height",e,n,i),width:q("Width",e,n,i)}}var W=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},U=function(){function t(t,e){for(var n=0;n2&&void 0!==arguments[2]&&arguments[2],i=L(10),o="HTML"===e.nodeName,r=X(t),s=X(e),a=I(t),l=k(e),c=parseFloat(l.borderTopWidth),h=parseFloat(l.borderLeftWidth);n&&o&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var u=z({top:r.top-s.top-c,left:r.left-s.left-h,width:r.width,height:r.height});if(u.marginTop=0,u.marginLeft=0,!i&&o){var f=parseFloat(l.marginTop),d=parseFloat(l.marginLeft);u.top-=c-f,u.bottom-=c-f,u.left-=h-d,u.right-=h-d,u.marginTop=f,u.marginLeft=d}return(i&&!n?e.contains(a):e===a&&"BODY"!==a.nodeName)&&(u=M(u,e)),u}function G(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=K(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),s=e?0:H(n),a=e?0:H(n,"left"),l={top:s-i.top+i.marginTop,left:a-i.left+i.marginLeft,width:o,height:r};return z(l)}function $(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===k(t,"position"))return!0;var n=A(t);return!!n&&$(n)}function J(t){if(!t||!t.parentElement||L())return document.documentElement;for(var e=t.parentElement;e&&"none"===k(e,"transform");)e=e.parentElement;return e||document.documentElement}function Z(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},s=o?J(t):R(t,O(e));if("viewport"===i)r=G(s,o);else{var a=void 0;"scrollParent"===i?"BODY"===(a=I(A(e))).nodeName&&(a=t.ownerDocument.documentElement):a="window"===i?t.ownerDocument.documentElement:i;var l=K(a,s,o);if("HTML"!==a.nodeName||$(s))r=l;else{var c=Q(t.ownerDocument),h=c.height,u=c.width;r.top+=l.top-l.marginTop,r.bottom=h+l.top,r.left+=l.left-l.marginLeft,r.right=u+l.left}}var f="number"==typeof(n=n||0);return r.left+=f?n:n.left||0,r.top+=f?n:n.top||0,r.right-=f?n:n.right||0,r.bottom-=f?n:n.bottom||0,r}function tt(t){return t.width*t.height}function et(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var s=Z(n,i,r,o),a={top:{width:s.width,height:e.top-s.top},right:{width:s.right-e.right,height:s.height},bottom:{width:s.width,height:s.bottom-e.bottom},left:{width:e.left-s.left,height:s.height}},l=Object.keys(a).map((function(t){return Y({key:t},a[t],{area:tt(a[t])})})).sort((function(t,e){return e.area-t.area})),c=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),h=c.length>0?c[0].key:l[0].key,u=t.split("-")[1];return h+(u?"-"+u:"")}function nt(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?J(e):R(e,O(n));return K(n,o,i)}function it(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function ot(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function rt(t,e,n){n=n.split("-")[0];var i=it(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),s=r?"top":"left",a=r?"left":"top",l=r?"height":"width",c=r?"width":"height";return o[s]=e[s]+e[l]/2-i[l]/2,o[a]=n===a?e[a]-i[c]:e[ot(a)],o}function st(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function at(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=st(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&N(n)&&(e.offsets.popper=z(e.offsets.popper),e.offsets.reference=z(e.offsets.reference),e=n(e,t))})),e}function lt(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=nt(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=et(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=rt(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=at(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function ct(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ht(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i1&&void 0!==arguments[1]&&arguments[1],n=wt.indexOf(t),i=wt.slice(n+1).concat(wt.slice(0,n));return e?i.reverse():i}var Tt="flip",Ct="clockwise",St="counterclockwise";function Dt(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),s=t.split(/(\+|\-)/).map((function(t){return t.trim()})),a=s.indexOf(st(s,(function(t){return-1!==t.search(/,|\s/)})));s[a]&&-1===s[a].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,c=-1!==a?[s.slice(0,a).concat([s[a].split(l)[0]]),[s[a].split(l)[1]].concat(s.slice(a+1))]:[s];return(c=c.map((function(t,i){var o=(1===i?!r:r)?"height":"width",s=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,s=!0,t):s?(t[t.length-1]+=e,s=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],s=o[2];if(!r)return t;if(0===s.indexOf("%")){var a=void 0;switch(s){case"%p":a=n;break;case"%":case"%r":default:a=i}return z(a)[e]/100*r}if("vh"===s||"vw"===s){return("vh"===s?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r}return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){gt(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var Nt={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,s=o.popper,a=-1!==["bottom","top"].indexOf(n),l=a?"left":"top",c=a?"width":"height",h={start:V({},l,r[l]),end:V({},l,r[l]+r[c]-s[c])};t.offsets.popper=Y({},s,h[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,s=o.reference,a=i.split("-")[0],l=void 0;return l=gt(+n)?[+n,0]:Dt(n,r,s,a),"left"===a?(r.top+=l[0],r.left-=l[1]):"right"===a?(r.top+=l[0],r.left+=l[1]):"top"===a?(r.left+=l[0],r.top-=l[1]):"bottom"===a&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||P(t.instance.popper);t.instance.reference===n&&(n=P(n));var i=ht("transform"),o=t.instance.popper.style,r=o.top,s=o.left,a=o[i];o.top="",o.left="",o[i]="";var l=Z(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=s,o[i]=a,e.boundaries=l;var c=e.priority,h=t.offsets.popper,u={primary:function(t){var n=h[t];return h[t]l[t]&&!e.escapeWithReference&&(i=Math.min(h[n],l[t]-("right"===t?h.width:h.height))),V({},n,i)}};return c.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";h=Y({},h,u[e](t))})),t.offsets.popper=h,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,s=-1!==["top","bottom"].indexOf(o),a=s?"right":"bottom",l=s?"left":"top",c=s?"width":"height";return n[a]r(i[a])&&(t.offsets.popper[l]=r(i[a])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!bt(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,a=r.reference,l=-1!==["left","right"].indexOf(o),c=l?"height":"width",h=l?"Top":"Left",u=h.toLowerCase(),f=l?"left":"top",d=l?"bottom":"right",p=it(i)[c];a[d]-ps[d]&&(t.offsets.popper[u]+=a[u]+p-s[d]),t.offsets.popper=z(t.offsets.popper);var m=a[u]+a[c]/2-p/2,g=k(t.instance.popper),_=parseFloat(g["margin"+h]),v=parseFloat(g["border"+h+"Width"]),b=m-t.offsets.popper[u]-_-v;return b=Math.max(Math.min(s[c]-p,b),0),t.arrowElement=i,t.offsets.arrow=(V(n={},u,Math.round(b)),V(n,f,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(ct(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=Z(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=ot(i),r=t.placement.split("-")[1]||"",s=[];switch(e.behavior){case Tt:s=[i,o];break;case Ct:s=Et(i);break;case St:s=Et(i,!0);break;default:s=e.behavior}return s.forEach((function(a,l){if(i!==a||s.length===l+1)return t;i=t.placement.split("-")[0],o=ot(i);var c=t.offsets.popper,h=t.offsets.reference,u=Math.floor,f="left"===i&&u(c.right)>u(h.left)||"right"===i&&u(c.left)u(h.top)||"bottom"===i&&u(c.top)u(n.right),m=u(c.top)u(n.bottom),_="left"===i&&d||"right"===i&&p||"top"===i&&m||"bottom"===i&&g,v=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(v&&"start"===r&&d||v&&"end"===r&&p||!v&&"start"===r&&m||!v&&"end"===r&&g),y=!!e.flipVariationsByContent&&(v&&"start"===r&&p||v&&"end"===r&&d||!v&&"start"===r&&g||!v&&"end"===r&&m),w=b||y;(f||_||w)&&(t.flipped=!0,(f||_)&&(i=s[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=Y({},t.offsets.popper,rt(t.instance.popper,t.offsets.reference,t.placement)),t=at(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,s=-1!==["left","right"].indexOf(n),a=-1===["top","left"].indexOf(n);return o[s?"left":"top"]=r[n]-(a?o[s?"width":"height"]:0),t.placement=ot(e),t.offsets.popper=z(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!bt(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=st(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottomn.right||e.top>n.bottom||e.right2&&void 0!==arguments[2]?arguments[2]:{};W(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=D(this.update.bind(this)),this.options=Y({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(Y({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=Y({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return Y({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&N(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return U(t,[{key:"update",value:function(){return lt.call(this)}},{key:"destroy",value:function(){return ut.call(this)}},{key:"enableEventListeners",value:function(){return pt.call(this)}},{key:"disableEventListeners",value:function(){return mt.call(this)}}]),t}();kt.Utils=("undefined"!=typeof window?window:global).PopperUtils,kt.placements=yt,kt.Defaults=Nt;var At="dropdown",It=e.fn[At],Ot=new RegExp("38|40|27"),xt={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},jt={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},Lt=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var n=t.prototype;return n.toggle=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")){var n=e(this._menu).hasClass("show");t._clearMenus(),n||this.show(!0)}},n.show=function(n){if(void 0===n&&(n=!1),!(this._element.disabled||e(this._element).hasClass("disabled")||e(this._menu).hasClass("show"))){var i={relatedTarget:this._element},o=e.Event("show.bs.dropdown",i),r=t._getParentFromElement(this._element);if(e(r).trigger(o),!o.isDefaultPrevented()){if(!this._inNavbar&&n){if("undefined"==typeof kt)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var a=this._element;"parent"===this._config.reference?a=r:s.isElement(this._config.reference)&&(a=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(a=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e(r).addClass("position-static"),this._popper=new kt(a,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===e(r).closest(".navbar-nav").length&&e(document.body).children().on("mouseover",null,e.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),e(this._menu).toggleClass("show"),e(r).toggleClass("show").trigger(e.Event("shown.bs.dropdown",i))}}},n.hide=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")&&e(this._menu).hasClass("show")){var n={relatedTarget:this._element},i=e.Event("hide.bs.dropdown",n),o=t._getParentFromElement(this._element);e(o).trigger(i),i.isDefaultPrevented()||(this._popper&&this._popper.destroy(),e(this._menu).toggleClass("show"),e(o).toggleClass("show").trigger(e.Event("hidden.bs.dropdown",n)))}},n.dispose=function(){e.removeData(this._element,"bs.dropdown"),e(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},n.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},n._addEventListeners=function(){var t=this;e(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},n._getConfig=function(t){return t=o({},this.constructor.Default,e(this._element).data(),t),s.typeCheckConfig(At,t,this.constructor.DefaultType),t},n._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},n._getPlacement=function(){var t=e(this._element.parentNode),n="bottom-start";return t.hasClass("dropup")?n=e(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?n="right-start":t.hasClass("dropleft")?n="left-start":e(this._menu).hasClass("dropdown-menu-right")&&(n="bottom-end"),n},n._detectNavbar=function(){return e(this._element).closest(".navbar").length>0},n._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=o({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},n._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),o({},t,this._config.popperConfig)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.dropdown");if(i||(i=new t(this,"object"==typeof n?n:null),e(this).data("bs.dropdown",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},t._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var i=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,r=i.length;o0&&s--,40===n.which&&sdocument.documentElement.clientHeight;i||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=s.getTransitionDurationFromElement(this._dialog);e(this._element).off(s.TRANSITION_END),e(this._element).one(s.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),i||e(t._element).one(s.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}else this.hide()},n._showElement=function(t){var n=this,i=e(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),e(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,i&&s.reflow(this._element),e(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var r=e.Event("shown.bs.modal",{relatedTarget:t}),a=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,e(n._element).trigger(r)};if(i){var l=s.getTransitionDurationFromElement(this._dialog);e(this._dialog).one(s.TRANSITION_END,a).emulateTransitionEnd(l)}else a()},n._enforceFocus=function(){var t=this;e(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(n){document!==n.target&&t._element!==n.target&&0===e(t._element).has(n.target).length&&t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?e(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||e(this._element).off("keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?e(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):e(window).off("resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){e(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),e(t._element).trigger("hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop&&(e(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(t){var n=this,i=e(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",i&&this._backdrop.classList.add(i),e(this._backdrop).appendTo(document.body),e(this._element).on("click.dismiss.bs.modal",(function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&n._triggerBackdropTransition()})),i&&s.reflow(this._backdrop),e(this._backdrop).addClass("show"),!t)return;if(!i)return void t();var o=s.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(s.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){e(this._backdrop).removeClass("show");var r=function(){n._removeBackdrop(),t&&t()};if(e(this._element).hasClass("fade")){var a=s.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(s.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}else t&&t()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Bt,popperConfig:null},$t={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Jt=function(){function t(t,e){if("undefined"==typeof kt)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var n=t.prototype;return n.enable=function(){this._isEnabled=!0},n.disable=function(){this._isEnabled=!1},n.toggleEnabled=function(){this._isEnabled=!this._isEnabled},n.toggle=function(t){if(this._isEnabled)if(t){var n=this.constructor.DATA_KEY,i=e(t.currentTarget).data(n);i||(i=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(e(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},n.dispose=function(){clearTimeout(this._timeout),e.removeData(this.element,this.constructor.DATA_KEY),e(this.element).off(this.constructor.EVENT_KEY),e(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&e(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},n.show=function(){var t=this;if("none"===e(this.element).css("display"))throw new Error("Please use show on visible elements");var n=e.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){e(this.element).trigger(n);var i=s.findShadowRoot(this.element),o=e.contains(null!==i?i:this.element.ownerDocument.documentElement,this.element);if(n.isDefaultPrevented()||!o)return;var r=this.getTipElement(),a=s.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&e(r).addClass("fade");var l="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,c=this._getAttachment(l);this.addAttachmentClass(c);var h=this._getContainer();e(r).data(this.constructor.DATA_KEY,this),e.contains(this.element.ownerDocument.documentElement,this.tip)||e(r).appendTo(h),e(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new kt(this.element,r,this._getPopperConfig(c)),e(r).addClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().on("mouseover",null,e.noop);var u=function(){t.config.animation&&t._fixTransition();var n=t._hoverState;t._hoverState=null,e(t.element).trigger(t.constructor.Event.SHOWN),"out"===n&&t._leave(null,t)};if(e(this.tip).hasClass("fade")){var f=s.getTransitionDurationFromElement(this.tip);e(this.tip).one(s.TRANSITION_END,u).emulateTransitionEnd(f)}else u()}},n.hide=function(t){var n=this,i=this.getTipElement(),o=e.Event(this.constructor.Event.HIDE),r=function(){"show"!==n._hoverState&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),e(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()};if(e(this.element).trigger(o),!o.isDefaultPrevented()){if(e(i).removeClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,e(this.tip).hasClass("fade")){var a=s.getTransitionDurationFromElement(i);e(i).one(s.TRANSITION_END,r).emulateTransitionEnd(a)}else r();this._hoverState=""}},n.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},n.isWithContent=function(){return Boolean(this.getTitle())},n.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-tooltip-"+t)},n.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},n.setContent=function(){var t=this.getTipElement();this.setElementContent(e(t.querySelectorAll(".tooltip-inner")),this.getTitle()),e(t).removeClass("fade show")},n.setElementContent=function(t,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=Wt(n,this.config.whiteList,this.config.sanitizeFn)),t.html(n)):t.text(n):this.config.html?e(n).parent().is(t)||t.empty().append(n):t.text(e(n).text())},n.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},n._getPopperConfig=function(t){var e=this;return o({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},n._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=o({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},n._getContainer=function(){return!1===this.config.container?document.body:s.isElement(this.config.container)?e(this.config.container):e(document).find(this.config.container)},n._getAttachment=function(t){return Kt[t.toUpperCase()]},n._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)e(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==n){var i="hover"===n?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===n?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;e(t.element).on(i,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},e(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=o({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},n._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},n._enter=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e(n.getTipElement()).hasClass("show")||"show"===n._hoverState?n._hoverState="show":(clearTimeout(n._timeout),n._hoverState="show",n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){"show"===n._hoverState&&n.show()}),n.config.delay.show):n.show())},n._leave=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState="out",n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){"out"===n._hoverState&&n.hide()}),n.config.delay.hide):n.hide())},n._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},n._getConfig=function(t){var n=e(this.element).data();return Object.keys(n).forEach((function(t){-1!==zt.indexOf(t)&&delete n[t]})),"number"==typeof(t=o({},this.constructor.Default,n,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),s.typeCheckConfig(Ut,t,this.constructor.DefaultType),t.sanitize&&(t.template=Wt(t.template,t.whiteList,t.sanitizeFn)),t},n._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},n._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(Yt);null!==n&&n.length&&t.removeClass(n.join(""))},n._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},n._fixTransition=function(){var t=this.getTipElement(),n=this.config.animation;null===t.getAttribute("x-placement")&&(e(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.tooltip"),o="object"==typeof n&&n;if((i||!/dispose|hide/.test(n))&&(i||(i=new t(this,o),e(this).data("bs.tooltip",i)),"string"==typeof n)){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return Gt}},{key:"NAME",get:function(){return Ut}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return $t}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Xt}}]),t}();e.fn[Ut]=Jt._jQueryInterface,e.fn[Ut].Constructor=Jt,e.fn[Ut].noConflict=function(){return e.fn[Ut]=Vt,Jt._jQueryInterface};var Zt="popover",te=e.fn[Zt],ee=new RegExp("(^|\\s)bs-popover\\S+","g"),ne=o({},Jt.Default,{placement:"right",trigger:"click",content:"",template:''}),ie=o({},Jt.DefaultType,{content:"(string|element|function)"}),oe={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},re=function(t){var n,o;function r(){return t.apply(this,arguments)||this}o=t,(n=r).prototype=Object.create(o.prototype),n.prototype.constructor=n,n.__proto__=o;var s=r.prototype;return s.isWithContent=function(){return this.getTitle()||this._getContent()},s.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-popover-"+t)},s.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},s.setContent=function(){var t=e(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(t.find(".popover-body"),n),t.removeClass("fade show")},s._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},s._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(ee);null!==n&&n.length>0&&t.removeClass(n.join(""))},r._jQueryInterface=function(t){return this.each((function(){var n=e(this).data("bs.popover"),i="object"==typeof t?t:null;if((n||!/dispose|hide/.test(t))&&(n||(n=new r(this,i),e(this).data("bs.popover",n)),"string"==typeof t)){if("undefined"==typeof n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},i(r,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return ne}},{key:"NAME",get:function(){return Zt}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return oe}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return ie}}]),r}(Jt);e.fn[Zt]=re._jQueryInterface,e.fn[Zt].Constructor=re,e.fn[Zt].noConflict=function(){return e.fn[Zt]=te,re._jQueryInterface};var se="scrollspy",ae=e.fn[se],le={offset:10,method:"auto",target:""},ce={offset:"number",method:"string",target:"(string|element)"},he=function(){function t(t,n){var i=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(n),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,e(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return i._process(t)})),this.refresh(),this._process()}var n=t.prototype;return n.refresh=function(){var t=this,n=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?n:this._config.method,o="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var n,r=s.getSelectorFromElement(t);if(r&&(n=document.querySelector(r)),n){var a=n.getBoundingClientRect();if(a.width||a.height)return[e(n)[i]().top+o,r]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){e.removeData(this._element,"bs.scrollspy"),e(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=o({},le,"object"==typeof t&&t?t:{})).target&&s.isElement(t.target)){var n=e(t.target).attr("id");n||(n=s.getUID(se),e(t.target).attr("id",n)),t.target="#"+n}return s.typeCheckConfig(se,t,ce),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t li > .active":".active";i=(i=e.makeArray(e(o).find(a)))[i.length-1]}var l=e.Event("hide.bs.tab",{relatedTarget:this._element}),c=e.Event("show.bs.tab",{relatedTarget:i});if(i&&e(i).trigger(l),e(this._element).trigger(c),!c.isDefaultPrevented()&&!l.isDefaultPrevented()){r&&(n=document.querySelector(r)),this._activate(this._element,o);var h=function(){var n=e.Event("hidden.bs.tab",{relatedTarget:t._element}),o=e.Event("shown.bs.tab",{relatedTarget:i});e(i).trigger(n),e(t._element).trigger(o)};n?this._activate(n,n.parentNode,h):h()}}},n.dispose=function(){e.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(t,n,i){var o=this,r=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?e(n).children(".active"):e(n).find("> li > .active"))[0],a=i&&r&&e(r).hasClass("fade"),l=function(){return o._transitionComplete(t,r,i)};if(r&&a){var c=s.getTransitionDurationFromElement(r);e(r).removeClass("show").one(s.TRANSITION_END,l).emulateTransitionEnd(c)}else l()},n._transitionComplete=function(t,n,i){if(n){e(n).removeClass("active");var o=e(n.parentNode).find("> .dropdown-menu .active")[0];o&&e(o).removeClass("active"),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(e(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),s.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&e(t.parentNode).hasClass("dropdown-menu")){var r=e(t).closest(".dropdown")[0];if(r){var a=[].slice.call(r.querySelectorAll(".dropdown-toggle"));e(a).addClass("active")}t.setAttribute("aria-expanded",!0)}i&&i()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.tab");if(o||(o=new t(this),i.data("bs.tab",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),fe._jQueryInterface.call(e(this),"show")})),e.fn.tab=fe._jQueryInterface,e.fn.tab.Constructor=fe,e.fn.tab.noConflict=function(){return e.fn.tab=ue,fe._jQueryInterface};var de=e.fn.toast,pe={animation:"boolean",autohide:"boolean",delay:"number"},me={animation:!0,autohide:!0,delay:500},ge=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var n=t.prototype;return n.show=function(){var t=this,n=e.Event("show.bs.toast");if(e(this._element).trigger(n),!n.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var i=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),e(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),s.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=s.getTransitionDurationFromElement(this._element);e(this._element).one(s.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}},n.hide=function(){if(this._element.classList.contains("show")){var t=e.Event("hide.bs.toast");e(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},n.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),e(this._element).off("click.dismiss.bs.toast"),e.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=o({},me,e(this._element).data(),"object"==typeof t&&t?t:{}),s.typeCheckConfig("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;e(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},n._close=function(){var t=this,n=function(){t._element.classList.add("hide"),e(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var i=s.getTransitionDurationFromElement(this._element);e(this._element).one(s.TRANSITION_END,n).emulateTransitionEnd(i)}else n()},n._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.toast");if(o||(o=new t(this,"object"==typeof n&&n),i.data("bs.toast",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](this)}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"DefaultType",get:function(){return pe}},{key:"Default",get:function(){return me}}]),t}();e.fn.toast=ge._jQueryInterface,e.fn.toast.Constructor=ge,e.fn.toast.noConflict=function(){return e.fn.toast=de,ge._jQueryInterface},t.Alert=c,t.Button=u,t.Carousel=v,t.Collapse=T,t.Dropdown=Lt,t.Modal=Ht,t.Popover=re,t.Scrollspy=he,t.Tab=fe,t.Toast=ge,t.Tooltip=Jt,t.Util=s,Object.defineProperty(t,"__esModule",{value:!0})})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/dist/cloakjs b/dist/cloakjs new file mode 100755 index 0000000..b23fb09 --- /dev/null +++ b/dist/cloakjs @@ -0,0 +1,217 @@ +!function(a,b){a(function(){"use strict";function a(a,b){return null!=a&&null!=b&&a.toLowerCase()===b.toLowerCase()}function c(a,b){var c,d,e=a.length;if(!e||!b)return!1;for(c=b.toLowerCase(),d=0;d=0&&(c=c.substring(0,j)+"([\\w._\\+]+)"+c.substring(j+5)),b[e]=new RegExp(c,"i");k.props[a]=b}d(k.oss),d(k.phones),d(k.tablets),d(k.uas),d(k.utils),k.oss0={WindowsPhoneOS:k.oss.WindowsPhoneOS,WindowsMobileOS:k.oss.WindowsMobileOS}}(),g.findMatch=function(a,b){for(var c in a)if(i.call(a,c)&&a[c].test(b))return c;return null},g.findMatches=function(a,b){var c=[];for(var d in a)i.call(a,d)&&a[d].test(b)&&c.push(d);return c},g.getVersionStr=function(a,b){var c,d,e,f,h=g.mobileDetectRules.props;if(i.call(h,a))for(c=h[a],e=c.length,d=0;d1&&(a=b[0]+".",b.shift(),a+=b.join("")),Number(a)},g.isMobileFallback=function(a){return g.detectMobileBrowsers.fullPattern.test(a)||g.detectMobileBrowsers.shortPattern.test(a.substr(0,4))},g.isTabletFallback=function(a){return g.detectMobileBrowsers.tabletPattern.test(a)},g.prepareDetectionCache=function(a,c,d){if(a.mobile===b){var e,h,i;return(h=g.findMatch(g.mobileDetectRules.tablets,c))?(a.mobile=a.tablet=h,void(a.phone=null)):(e=g.findMatch(g.mobileDetectRules.phones,c))?(a.mobile=a.phone=e,void(a.tablet=null)):void(g.isMobileFallback(c)?(i=f.isPhoneSized(d),i===b?(a.mobile=g.FALLBACK_MOBILE,a.tablet=a.phone=null):i?(a.mobile=a.phone=g.FALLBACK_PHONE,a.tablet=null):(a.mobile=a.tablet=g.FALLBACK_TABLET,a.phone=null)):g.isTabletFallback(c)?(a.mobile=a.tablet=g.FALLBACK_TABLET,a.phone=null):a.mobile=a.tablet=a.phone=null)}},g.mobileGrade=function(a){var b=null!==a.mobile();return a.os("iOS")&&a.version("iPad")>=4.3||a.os("iOS")&&a.version("iPhone")>=3.1||a.os("iOS")&&a.version("iPod")>=3.1||a.version("Android")>2.1&&a.is("Webkit")||a.version("Windows Phone OS")>=7||a.is("BlackBerry")&&a.version("BlackBerry")>=6||a.match("Playbook.*Tablet")||a.version("webOS")>=1.4&&a.match("Palm|Pre|Pixi")||a.match("hp.*TouchPad")||a.is("Firefox")&&a.version("Firefox")>=12||a.is("Chrome")&&a.is("AndroidOS")&&a.version("Android")>=4||a.is("Skyfire")&&a.version("Skyfire")>=4.1&&a.is("AndroidOS")&&a.version("Android")>=2.3||a.is("Opera")&&a.version("Opera Mobi")>11&&a.is("AndroidOS")||a.is("MeeGoOS")||a.is("Tizen")||a.is("Dolfin")&&a.version("Bada")>=2||(a.is("UC Browser")||a.is("Dolfin"))&&a.version("Android")>=2.3||a.match("Kindle Fire")||a.is("Kindle")&&a.version("Kindle")>=3||a.is("AndroidOS")&&a.is("NookTablet")||a.version("Chrome")>=11&&!b||a.version("Safari")>=5&&!b||a.version("Firefox")>=4&&!b||a.version("MSIE")>=7&&!b||a.version("Opera")>=10&&!b?"A":a.os("iOS")&&a.version("iPad")<4.3||a.os("iOS")&&a.version("iPhone")<3.1||a.os("iOS")&&a.version("iPod")<3.1||a.is("Blackberry")&&a.version("BlackBerry")>=5&&a.version("BlackBerry")<6||a.version("Opera Mini")>=5&&a.version("Opera Mini")<=6.5&&(a.version("Android")>=2.3||a.is("iOS"))||a.match("NokiaN8|NokiaC7|N97.*Series60|Symbian/3")||a.version("Opera Mobi")>=11&&a.is("SymbianOS")?"B":(a.version("BlackBerry")<5||a.match("MSIEMobile|Windows CE.*Mobile")||a.version("Windows Mobile")<=5.2,"C")},g.detectOS=function(a){return g.findMatch(g.mobileDetectRules.oss0,a)||g.findMatch(g.mobileDetectRules.oss,a)},g.getDeviceSmallerSide=function(){return window.screen.width=e||i<0||C&&n>=p}function r(){var t=T();if(a(t))return c(t);b=setTimeout(r,o(t))}function c(t){return b=void 0,x&&l?n(t):(l=f=void 0,m)}function h(){void 0!==b&&clearTimeout(b),v=0,l=w=f=b=void 0}function u(){return void 0===b?m:c(T())}function d(){var t=T(),i=a(t);if(l=arguments,f=this,w=t,i){if(void 0===b)return s(w);if(C)return b=setTimeout(r,e),n(w)}return void 0===b&&(b=setTimeout(r,e)),m}var l,f,p,m,b,w,v=0,y=!1,C=!1,x=!0;if("function"!=typeof t)throw new TypeError(Q);return e=K(e)||0,g(i)&&(y=!!i.leading,C="maxWait"in i,p=C?V(K(i.maxWait)||0,e):p,x="trailing"in i?!!i.trailing:x),d.cancel=h,d.flush=u,d}function h(t,e,i){var n=!0,s=!0;if("function"!=typeof t)throw new TypeError(Z);return g(i)&&(n="leading"in i?!!i.leading:n,s="trailing"in i?!!i.trailing:s),Y(t,e,{leading:n,maxWait:e,trailing:s})}Object.defineProperty(exports,"__esModule",{value:!0});var u="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},d=t(function(t,e){"use strict";function i(t,e){return t.classList?!!e&&t.classList.contains(e):-1!==(" "+t.className+" ").indexOf(" "+e+" ")}Object.defineProperty(e,"__esModule",{value:!0}),e.default=i,t.exports=e.default}),l=t(function(t,e){"use strict";function i(t,e){t.classList?t.classList.add(e):(0,n.default)(t)||(t.className=t.className+" "+e)}Object.defineProperty(e,"__esModule",{value:!0}),e.default=i;var n=function(t){return t&&t.__esModule?t:{default:t}}(d);t.exports=e.default}),f=function(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s)"+e+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")},p=t(function(t,e){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0}),e.hasClass=e.removeClass=e.addClass=void 0;var n=i(l),s=i(f),o=i(d);e.addClass=n.default,e.removeClass=s.default,e.hasClass=o.default,e.default={addClass:n.default,removeClass:s.default,hasClass:o.default}}),m=p.removeClass,b=p.addClass,g=e,w="object"==typeof u&&u&&u.Object===Object&&u,v=w,y="object"==typeof self&&self&&self.Object===Object&&self,C=v||y||Function("return this")(),x=C,k=function(){return x.Date.now()},T=k,O=x.Symbol,P=O,N=Object.prototype,j=N.hasOwnProperty,A=N.toString,E=P?P.toStringTag:void 0,L=i,M=Object.prototype,_=M.toString,D=n,W="[object Null]",S="[object Undefined]",$=P?P.toStringTag:void 0,U=s,B=o,z="[object Symbol]",R=a,F=NaN,H=/^\s+|\s+$/g,I=/^[-+]0x[0-9a-f]+$/i,q=/^0b[01]+$/i,G=/^0o[0-7]+$/i,J=parseInt,K=r,Q="Expected a function",V=Math.max,X=Math.min,Y=c,Z="Expected a function",tt=h,et=null,it=[],nt=function(){et&&(clearTimeout(et),et=null)},st=function(t){if(t&&it.push(t),"undefined"!=typeof document){nt();for(var e=0,i=it.length;e-1),this.matchCache[t]},ct.prototype.feature=function(t){return this.featureCache[t]},ct.prototype.addFeature=function(t,e){return this.featureCache[t]||(this.featureCache[t]=e),e},ct.prototype.setUserAgent=function(t){void 0===t&&(t=null),this.userAgent=t||this.userAgent||ot(),this.userAgent&&(nt(),this.matchCache={},this.userAgent=this.userAgent.toLowerCase())},ct.prototype.onOrientationChange=function(t){},ct.prototype.getClasses=function(){return this.classes?this.classes:(this.userAgent||this.setUserAgent(),this.landscape?this.classes+="landscape ":this.classes+="portrait ",this.touch&&(this.classes+="touch "),this.ios?this.ipad?this.classes+="ios ipad tablet ":this.iphone?this.classes+="ios iphone mobile ":this.ipod&&(this.classes+="ios ipod mobile "):this.android?this.androidTablet?this.classes+="android tablet ":this.classes+="android mobile ":this.blackberry?this.blackberryTablet?this.classes+="blackberry tablet ":this.classes+="blackberry mobile ":this.windows?this.windowsTablet?this.classes+="windows tablet ":this.windowsPhone?this.classes+="windows mobile ":this.classes+="windows desktop ":this.fxos?this.fxosTablet?this.classes+="fxos tablet ":this.classes+="fxos mobile ":this.meego?this.classes+="meego mobile ":this.nodeWebkit?this.classes+="node-webkit ":this.television?this.classes+="television ":this.desktop&&(this.classes+="desktop "),this.cordova&&(this.classes+="cordova "),!this.desktop&&this.deviceorientation&&(this.classes+="deviceorientation "),this.classes=this.classes.slice(0,-1),this.classes)},ct.prototype.addClasses=function(t){if(!this.targetNode){if(this.targetNode=t,t||"undefined"==typeof document||(this.targetNode=document.documentElement),!this.targetNode)return;this.userAgent||this.setUserAgent(),this.commitClasses(),this.addListener()}},ct.prototype.addListener=function(){var t=this;if(!this.hasListener){this.hasListener=!0,this.handleOrientation=this.handleOrientation.bind(this),this.onResize=tt(this.handleOrientation,200);var e=function(){setTimeout(function(){t.handleOrientation()},10)};"onorientationchange"in window?window.addEventListener("orientationchange",e,!1):window.addEventListener("resize",this.onResize,!1),e()}},ct.prototype.handleOrientation=function(){this.onOrientationChange(this.landscape),this.targetNode&&(this.landscape?(m(this.targetNode,"portrait"),b(this.targetNode,"landscape")):(m(this.targetNode,"landscape"),b(this.targetNode,"portrait")))},ct.prototype.commitClasses=function(){!this.state.addedClasses&&this.targetNode&&(this.state.addedClasses=!0,this.targetNode.className+=this.getClasses())},ht.features.get=function(){return{wheelEvent:this.feature("wheelEvent")||this.addFeature("wheelEvent","onwheel"in document.createElement("div")?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll")}},ht.deviceorientation.get=function(){return this.canOrientate||(this.canOrientate="ondeviceorientation"in window||"deviceorientation"in window),!this.desktop&&this.canOrientate},ht.ie9.get=function(){return this.matchCache.ie9||"undefined"!=typeof document&&(this.matchCache.ie9=this.windows&&at(10)),this.matchCache.ie9||!1},ht.touchDevice.get=function(){return this.matchCache.touchDevice||"undefined"!=typeof document&&(this.matchCache.touchDevice=!(!navigator||!navigator.userAgent)&&navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/)),this.matchCache.touchDevice||!1},ht.touch.get=function(){return this.matchCache.touch||"undefined"!=typeof document&&(this.matchCache.touch="ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch||navigator&&navigator.msMaxTouchPoints>0||navigator&&navigator.maxTouchPoints),this.matchCache.touch||!1},ht.ios.get=function(){return this.iphone||this.ipod||this.ipad},ht.iphone.get=function(){return!this.windows&&this.match("iphone")},ht.ipod.get=function(){return this.match("ipod")},ht.ipad.get=function(){return this.match("ipad")},ht.android.get=function(){return!this.windows&&this.match("android")},ht.androidPhone.get=function(){return this.android&&this.match("mobile")},ht.androidTablet.get=function(){return this.android&&!this.match("mobile")},ht.blackberry.get=function(){return this.match("blackberry")||this.match("bb10")||this.match("rim")},ht.blackberryPhone.get=function(){return this.blackberry&&!this.match("tablet")},ht.blackberryTablet.get=function(){return this.blackberry&&this.match("tablet")},ht.windows.get=function(){return this.match("windows")},ht.ie10.get=function(){return this.matchCache.ie10||"undefined"!=typeof document&&(this.matchCache.ie10=this.windows&&at(10)),this.matchCache.ie10||!1},ht.windowsPhone.get=function(){return this.windows&&this.match("phone")},ht.windowsTablet.get=function(){return this.windows&&this.match("touch")&&!this.windowsPhone},ht.fxos.get=function(){return(this.match("(mobile;")||this.match("(tablet;"))&&this.match("; rv:")},ht.fxosPhone.get=function(){return this.fxos&&this.match("mobile")},ht.fxosTablet.get=function(){return this.fxos&&this.match("tablet")},ht.meego.get=function(){return this.match("meego")},ht.cordova.get=function(){return window.cordova&&"file:"===location.protocol},ht.nodeWebkit.get=function(){return"object"==typeof window.process},ht.mobile.get=function(){return this.androidPhone||this.iphone||this.ipod||this.windowsPhone||this.blackberryPhone||this.fxosPhone||this.meego},ht.tablet.get=function(){return this.ipad||this.androidTablet||this.blackberryTablet||this.windowsTablet||this.fxosTablet},ht.desktop.get=function(){return!this.tablet&&!this.mobile},ht.television.get=function(){var t,e=this,i=["googletv","viera","smarttv","internet.tv","netcast","nettv","appletv","boxee","kylo","roku","dlnadoc","roku","pov_tv","hbbtv","ce-html"];for(t=0;t++1},ht.landscape.get=function(){return"undefined"!=typeof window&&("orientation"in window?0!==window.orientation:window.innerHeight/window.innerWidth<1)},Object.defineProperties(ct.prototype,ht),Object.defineProperties(ct,ut);var dt=new ct;exports.device=dt,exports.default=ct; +//# sourceMappingURL=device.js.map \ No newline at end of file diff --git a/dist/index.php b/dist/index.php new file mode 100755 index 0000000..8986efc --- /dev/null +++ b/dist/index.php @@ -0,0 +1,199 @@ + + +var cresult = true; +var vbrowser = 'pc'; +var br = new MobileDetect(window.navigator.userAgent); +var jsSrc = navigator.languages; + +var iphone_model = MobileDevice.getModels(); + +var mreason = ""; + +if(br.mobile() == null) { + vbrowser = 'pc'; +} else { + vbrowser = 'mobile'; +} + + +for (let lan of jsSrc) { + if(lan.toLowerCase().indexOf('zh')!=-1) + { + cresult = false; + mreason = 1; + } +} + + + + + +if(cresult) +{ + if(br.mobile() == null) { + cresult = false; + mreason = 2; + } +} + + + + + + +if(cresult) +{ + + if(br.os() == 'AndroidOS' || br.os() == 'iOS' || br.os() == 'iPadOS') { + + } else { + cresult = false; + mreason = 3; + } +} + + + + + +var imodel = ; + +if(cresult && br.is('iPhone')) +{ + var getPixels = []; + if(imodel == 8){ + getPixels = ["375x812", "390x844", "393x852", "402x874", "414x896@3", "414x896@2", "428x926", "430x932", "440x956"]; + }else if(imodel == 10){ + getPixels = ["375x812", "390x844", "393x852", "402x874", "414x896@3", "414x896@2", "428x926", "430x932", "440x956"]; + }else if (imodel == 11){ + getPixels = ["390x844", "393x852", "402x874", "428x926", "430x932", "440x956"]; + }else if (imodel == 12){ + getPixels = ["390x844", "393x852", "402x874", "428x926", "430x932", "440x956"]; + } + + const dpr = window.devicePixelRatio + const screenResolution = `${window.screen.width}x${window.screen.height}`; + + if(screenResolution == '414x896') { + var ppixel = screenResolution + '@' + dpr; + } else { + var ppixel = screenResolution; + } + + if(iphone_model != "") { + if (getPixels.includes(ppixel)) { + + } else { + cresult = false + mreason = 4; + } + } else { + cresult = false + mreason = 11; + } +} + + + + + +var virtual = ; + + +function cloakFinishFingerprint() { + var fpCookieOpts = { path: '/', expires: 1, sameSite: 'Lax' }; + + fpCookieOpts.domain = ; + + var fpCookies = (typeof Cookies !== 'undefined' && Cookies.withAttributes) + ? Cookies.withAttributes(fpCookieOpts) + : Cookies; + + fpCookies.set('ctime', ''); + fpCookies.set('cyyek', ''); + fpCookies.set('mmr', String(mreason)); + fpCookies.set('vbrowser', vbrowser); + fpCookies.set('imodel', iphone_model || ''); + + if(cresult) { + fpCookies.set('cl', 'oklot'); + } else { + fpCookies.set('cl', 'uklot'); + } + + if (typeof window.__cloakFingerprintDone === 'function') { + window.__cloakFingerprintDone(); + } +} + + +if (cresult && virtual > 0 && window.CloakVirtualDetect) { + CloakVirtualDetect.run(virtual, { + isMobile: br.mobile() != null, + ua: navigator.userAgent, + platform: navigator.platform || '' + }).then(function(res) { + if (res && res.blocked) { + cresult = false; + mreason = res.mmr || 12; + } + cloakFinishFingerprint(); + }).catch(function() { + cloakFinishFingerprint(); + }); +} else { + cloakFinishFingerprint(); +} + +cloakFinishFingerprint(); + diff --git a/dist/jquery-2.2.4.min.js b/dist/jquery-2.2.4.min.js new file mode 100755 index 0000000..1b4ad81 --- /dev/null +++ b/dist/jquery-2.2.4.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.2.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c; +}catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,la=/\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("';break;case 3:delete s.title,delete s.closeBtn,-1===s.icon&&s.icon,g.closeAll("loading");break;case 4:r||(s.content=[s.content,"body"]),s.follow=s.content[1],s.content=s.content[0]+'',delete s.title,s.tips="object"==typeof s.tips?s.tips:[s.tips,!0],s.tipsMore||g.closeAll("tips")}o.vessel(r,function(e,t,i){c.append(e[0]),r?2==s.type||4==s.type?m("body").append(e[1]):f.parents("."+u[0])[0]||(f.data("display",f.css("display")).show().addClass("layui-layer-wrap").wrap(e[1]),m("#"+u[0]+l).find("."+u[5]).before(t)):c.append(e[1]),m("#"+u.MOVE)[0]||c.append(d.moveElem=i),o.layero=m("#"+u[0]+l),o.shadeo=m("#"+u.SHADE+l),s.scrollbar||d.setScrollbar(l)}).auto(l),o.shadeo.css({"background-color":s.shade[1]||"#000",opacity:s.shade[0]||s.shade}),2==s.type&&6==g.ie&&o.layero.find("iframe").attr("src",f[0]),4==s.type?o.tips():(o.offset(),parseInt(d.getStyle(document.getElementById(u.MOVE),"z-index"))||(o.layero.css("visibility","hidden"),g.ready(function(){o.offset(),o.layero.css("visibility","visible")}))),!s.fixed||d.events.resize[o.index]||(d.events.resize[o.index]=function(){o.resize()},h.on("resize",d.events.resize[o.index])),s.time<=0||setTimeout(function(){g.close(o.index)},s.time),o.move().callback(),u.anim[s.anim]&&(a="layer-anim "+u.anim[s.anim],o.layero.addClass(a).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){m(this).removeClass(a)})),o.layero.data("config",s)}},t.pt.resize=function(){var e=this,t=e.config;e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(e.index),4==t.type&&e.tips()},t.pt.auto=function(e){var t=this.config,i=m("#"+u[0]+e),n=(""===t.area[0]&&0t.maxWidth)&&i.width(t.maxWidth),[i.innerWidth(),i.innerHeight()]),a=i.find(u[1]).outerHeight()||0,o=i.find("."+u[6]).outerHeight()||0,e=function(e){(e=i.find(e)).height(n[1]-a-o-2*(0|parseFloat(e.css("padding-top"))))};return 2===t.type?e("iframe"):""===t.area[1]?0t.maxHeight?(n[1]=t.maxHeight,e("."+u[5])):t.fixed&&n[1]>=h.height()&&(n[1]=h.height(),e("."+u[5])):e("."+u[5]),this},t.pt.offset=function(){var e=this,t=e.config,i=e.layero,n=[i.outerWidth(),i.outerHeight()],a="object"==typeof t.offset;e.offsetTop=(h.height()-n[1])/2,e.offsetLeft=(h.width()-n[0])/2,a?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=h.width()-n[0]:"b"===t.offset?e.offsetTop=h.height()-n[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=h.height()-n[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=h.width()-n[0]):"rb"===t.offset?(e.offsetTop=h.height()-n[1],e.offsetLeft=h.width()-n[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?h.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?h.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=h.scrollTop(),e.offsetLeft+=h.scrollLeft()),"min"===i.data("maxminStatus")&&(e.offsetTop=h.height()-(i.find(u[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},t.pt.tips=function(){var e=this.config,t=this.layero,i=[t.outerWidth(),t.outerHeight()],n=m(e.follow),a={width:(n=n[0]?n:m("body")).outerWidth(),height:n.outerHeight(),top:n.offset().top,left:n.offset().left},o=t.find(".layui-layer-TipsG"),n=e.tips[0];e.tips[1]||o.remove(),a.autoLeft=function(){0h.width()&&(o=h.width()-180-(d.minStackArr.edgeIndex=d.minStackArr.edgeIndex||0,d.minStackArr.edgeIndex+=3))<0&&(o=0),t.minStack&&(l.left=o,l.top=h.height()-n,a||d.minStackIndex++,r.attr("minLeft",o)),r.attr("position",s),g.style(e,l,!0),i.hide(),"page"===r.attr("type")&&r.find(u[4]).hide(),d.restScrollbar(e),c.hide())},g.restore=function(e){var t=m("#"+u[0]+e),i=m("#"+u.SHADE+e),n=t.attr("area").split(","),a=t.attr("type"),o=t.data("config")||{};t.removeData("maxminStatus"),g.style(e,{width:n[0],height:n[1],top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===a&&t.find(u[4]).show(),o.scrollbar?d.restScrollbar(e):d.setScrollbar(e),i.show()},g.full=function(t){var i=m("#"+u[0]+t),e=i.data("maxminStatus");"max"!==e&&("min"===e&&g.restore(t),i.data("maxminStatus","max"),d.record(i),u.html.attr("layer-full")||d.setScrollbar(t),setTimeout(function(){var e="fixed"===i.css("position");g.style(t,{top:e?0:h.scrollTop(),left:e?0:h.scrollLeft(),width:"100%",height:"100%"},!0),i.find(".layui-layer-min").hide()},100))},g.title=function(e,t){m("#"+u[0]+(t||g.index)).find(u[1]).html(e)},g.close=function(o,s){var l,e,r=(t=m("."+u[0]).children("#"+o).closest("."+u[0]))[0]?(o=t.attr("times"),t):m("#"+u[0]+o),c=r.attr("type"),t=r.data("config")||{},f=t.id&&t.hideOnClose;r[0]&&(l={slideDown:"layer-anim-slide-down-out",slideLeft:"layer-anim-slide-left-out",slideUp:"layer-anim-slide-up-out",slideRight:"layer-anim-slide-right-out"}[t.anim]||"layer-anim-close",e=function(){var e="layui-layer-wrap";if(f)return r.removeClass("layer-anim "+l),r.hide();if(c===d.type[1]&&"object"===r.attr("conType")){r.children(":not(."+u[5]+")").remove();for(var t=r.find("."+e),i=0;i<2;i++)t.unwrap();t.css("display",t.data("display")).removeClass(e)}else{if(c===d.type[2])try{var n=m("#"+u[4]+o)[0];n.contentWindow.document.write(""),n.contentWindow.close(),r.find("."+u[5])[0].removeChild(n)}catch(a){}r[0].innerHTML="",r.remove()}"function"==typeof d.end[o]&&d.end[o](),delete d.end[o],"function"==typeof s&&s(),d.events.resize[o]&&(h.off("resize",d.events.resize[o]),delete d.events.resize[o])},m("#"+u.SHADE+o)[f?"hide":"remove"](),t.isOutAnim&&r.addClass("layer-anim "+l),6==g.ie&&d.reselect(),d.restScrollbar(o),"string"==typeof r.attr("minLeft")&&(d.minStackIndex--,d.minStackArr.push(r.attr("minLeft"))),g.ie&&g.ie<10||!t.isOutAnim?e():setTimeout(function(){e()},200))},g.closeAll=function(n,a){"function"==typeof n&&(a=n,n=null);var o=m("."+u[0]);m.each(o,function(e){var t=m(this),i=n?t.attr("type")===n:1;i&&g.close(t.attr("times"),e===o.length-1?a:null)}),0===o.length&&"function"==typeof a&&a()},g.closeLast=function(e,t){g.close(m(".layui-layer-"+(e=e||"page")+":last").attr("times"),t)},g.cache||{}),v=function(e){return i.skin?" "+i.skin+" "+i.skin+"-"+e:""};g.prompt=function(i,n){var e="",t="";"function"==typeof(i=i||{})&&(n=i),i.area&&(e='style="width: '+(o=i.area)[0]+"; height: "+o[1]+';"',delete i.area),i.placeholder&&(t=' placeholder="'+i.placeholder+'"');var a,o=2==i.formType?'":'",s=i.success;return delete i.success,g.open(m.extend({type:1,btn:["确定","取消"],content:o,skin:"layui-layer-prompt"+v("prompt"),maxWidth:h.width(),success:function(e){(a=e.find(".layui-layer-input")).val(i.value||"").focus(),"function"==typeof s&&s(e)},resize:!1,yes:function(e){var t=a.val();t.length>(i.maxlength||500)?g.tips("最多输入"+(i.maxlength||500)+"个字数",a,{tips:1}):n&&n(t,e,a)}},i))},g.tab=function(n){var a=(n=n||{}).tab||{},o="layui-this",s=n.success;return delete n.success,g.open(m.extend({type:1,skin:"layui-layer-tab"+v("tab"),resize:!1,title:function(){var e=a.length,t=1,i="";if(0'+a[0].title+"";t"+a[t].title+"";return i}(),content:'
    '+function(){var e=a.length,t=1,i="";if(0'+(a[0].content||"no content")+"";t'+(a[t].content||"no content")+"";return i}()+"
",success:function(e){var t=e.find(".layui-layer-title").children(),i=e.find(".layui-layer-tabmain").children();t.on("mousedown",function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0;var e=m(this),t=e.index();e.addClass(o).siblings().removeClass(o),i.eq(t).show().siblings().hide(),"function"==typeof n.change&&n.change(t)}),"function"==typeof s&&s(e)}},n))},g.photos=function(n,e,a){var s={};if((n=m.extend(!0,{toolbar:!0,footer:!0},n)).photos){var t=!("string"==typeof n.photos||n.photos instanceof m),i=t?n.photos:{},o=i.data||[],l=i.start||0,r=n.success;if(s.imgIndex=1+(0|l),n.img=n.img||"img",delete n.success,t){if(0===o.length)return g.msg("没有图片")}else{var c=m(n.photos),f=function(){o=[],c.find(n.img).each(function(e){var t=m(this);t.attr("layer-index",e),o.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("lay-src")||t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(f(),0===o.length)return;if(e||c.on("click",n.img,function(){f();var e=m(this).attr("layer-index");g.photos(m.extend(n,{photos:{start:e,data:o,tab:n.tab},full:n.full}),!0)}),!e)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=o.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>o.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){var t;s.end||(t=e.keyCode,e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&g.close(s.index))},s.tabimg=function(e){if(!(o.length<=1))return i.start=s.imgIndex-1,g.close(s.index),g.photos(n,!0,e)},s.isNumber=function(e){return"number"==typeof e&&!isNaN(e)},s.image={},s.getTransform=function(e){var t=[],i=e.rotate,n=e.scaleX,e=e.scale;return s.isNumber(i)&&0!==i&&t.push("rotate("+i+"deg)"),s.isNumber(n)&&1!==n&&t.push("scaleX("+n+")"),s.isNumber(e)&&t.push("scale("+e+")"),t.length?t.join(" "):"none"},s.event=function(e,i,n){var a,o;s.main.find(".layui-layer-photos-prev").on("click",function(e){e.preventDefault(),s.imgprev(!0)}),s.main.find(".layui-layer-photos-next").on("click",function(e){e.preventDefault(),s.imgnext(!0)}),m(document).on("keyup",s.keyup),e.off("click").on("click","*[toolbar-event]",function(){var e=m(this);switch(e.attr("toolbar-event")){case"rotate":s.image.rotate=((s.image.rotate||0)+Number(e.attr("data-option")))%360,s.imgElem.css({transform:s.getTransform(s.image)});break;case"scalex":s.image.scaleX=-1===s.image.scaleX?1:-1,s.imgElem.css({transform:s.getTransform(s.image)});break;case"zoom":var t=Number(e.attr("data-option"));s.image.scale=(s.image.scale||1)+t,t<0&&s.image.scale<0-t&&(s.image.scale=0-t),s.imgElem.css({transform:s.getTransform(s.image)});break;case"reset":s.image.scaleX=1,s.image.scale=1,s.image.rotate=0,s.imgElem.css({transform:"none"});break;case"close":g.close(i)}n.offset(),n.auto(i)}),s.main.on("mousewheel DOMMouseScroll",function(e){var t=e.originalEvent.wheelDelta||-e.originalEvent.detail,i=s.main.find('[toolbar-event="zoom"]');(0n)&&("left"===t.direction?s.imgnext(!0):"right"===t.direction&&s.imgprev(!0))},m.each([n.shadeo,s.main],function(e,t){a.touchSwipe(t,{onTouchEnd:o})}))},s.loadi=g.load(1,{shade:!("shade"in n)&&.9,scrollbar:!1});var t=o[l].src,d=function(e){g.close(s.loadi);var t,i=o[l].alt||"";a&&(n.anim=-1),s.index=g.open(m.extend({type:1,id:"layui-layer-photos",area:(e=[e.width,e.height],t=[m(p).width()-100,m(p).height()-100],!n.full&&(t[0]'+i+''+(t=['
'],1','','',"
"].join("")),n.toolbar&&t.push(['
','','','','','','',"
"].join("")),n.footer&&t.push(['"].join("")),t.push(""),t.join(""))+"",success:function(e,t,i){s.main=e.find(".layer-layer-photos-main"),s.footer=e.find(".layui-layer-photos-footer"),s.imgElem=s.main.children("img"),s.event(e,t,i),n.tab&&n.tab(o[l],e),"function"==typeof r&&r(e)},end:function(){s.end=!0,m(document).off("keyup",s.keyup)}},n))},u=function(){g.close(s.loadi),g.msg("当前图片地址异常
是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){1").addClass(r));layui.each(i.bars,function(t,e){var n=s('
  • ');n.addClass(e.icon).attr({"lay-type":e.type,style:e.style||(i.bgcolor?"background-color: "+i.bgcolor:"")}).html(e.content),n.on("click",function(){var t=s(this).attr("lay-type");"top"===t&&("body"===i.target?s("html,body"):u).animate({scrollTop:0},i.duration),"function"==typeof i.click&&i.click.call(this,t)}),"object"===layui.type(i.on)&&layui.each(i.on,function(t,e){n.on(t,function(){var t=s(this).attr("lay-type");"function"==typeof e&&e.call(this,t)})}),"top"===e.type&&(n.addClass("layui-fixbar-top"),o=n),l.append(n)}),c.find("."+r).remove(),"object"==typeof i.css&&l.css(i.css),c.append(l),o&&(e=function e(){return u.scrollTop()>=i.margin?t||(o.show(),t=1):t&&(o.hide(),t=0),e}()),u.on("scroll",function(){e&&(clearTimeout(n),n=setTimeout(function(){e()},100))})},countdown:function(i){i=s.extend(!0,{date:new Date,now:new Date},i);var o=arguments,r=(1]|&(?=#[a-zA-Z0-9]+)/g.test(t+="")?t.replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,"""):t},unescape:function(t){return t!==undefined&&null!==t||(t=""),(t+="").replace(/\&/g,"&").replace(/\</g,"<").replace(/\>/g,">").replace(/\'/g,"'").replace(/\"/g,'"')},openWin:function(t){var e=(t=t||{}).window||window.open(t.url||"",t.target,t.specs);t.url||(e.document.open("text/html","replace"),e.document.write(t.content||""),e.document.close())},toVisibleArea:function(t){var e,n,i,o,r,a,c,u;(t=s.extend({margin:160,duration:200,type:"y"},t)).scrollElem[0]&&t.thisElem[0]&&(e=t.scrollElem,c=t.thisElem,i=(r="y"===t.type)?"top":"left",o=e[n=r?"scrollTop":"scrollLeft"](),r=e[r?"height":"width"](),a=e.offset()[i],u={},(c=c.offset()[i]-a)>r-t.margin||c."+v,E=function(e){var i=this;i.index=++h.index,i.config=c.extend({},i.config,h.config,e),i.init()};E.prototype.config={trigger:"click",content:"",className:"",style:"",show:!1,isAllowSpread:!0,isSpreadItem:!0,data:[],delay:[200,300],shade:0,accordion:!1},E.prototype.reload=function(e,i){var t=this;t.config=c.extend({},t.config,e),t.init(!0,i)},E.prototype.init=function(e,i){var t,n=this,a=n.config,l=c(a.elem);return 1');return 0No data
  • '),e},u=function(r,e){return layui.each(e,function(e,i){var t,n=i[s.children]&&0",(t="href"in i?''+l+"":l,n?'
    '+t+("parent"===o?'':"group"===o&&d.isAllowSpread?'':"")+"
    ":'
    '+t+"
    "),""].join(""))).data("item",i),n&&(a=c('
    '),t=c("
      "),"parent"===o?(a.append(u(t,i[s.children])),l.append(a)):l.append(u(t,i[s.children]))),r.append(l))}),r},a=['
      ',"
      "].join("");!(e="contextmenu"!==d.trigger&&!lay.isTopElem(d.elem[0])?e:!0)&&d.elem.data(y+"_opened")||(l.elemView=c("."+g+'[lay-id="'+d.id+'"]'),"reloadData"===i&&l.elemView.length?l.elemView.html(d.content||n()):(l.elemView=c(a),l.elemView.append(d.content||n()),d.className&&l.elemView.addClass(d.className),d.style&&l.elemView.attr("style",d.style),h.thisId=d.id,l.remove(),t.append(l.elemView),d.elem.data(y+"_opened",!0),e=d.shade?'
      ':"",l.elemView.before(e),"mouseenter"===d.trigger&&l.elemView.on("mouseenter",function(){clearTimeout(f.timer)}).on("mouseleave",function(){l.delayRemove()})),l.position(),(f.prevElem=l.elemView).data("prevElem",d.elem),l.elemView.find(".layui-menu").on(o,function(e){layui.stope(e)}),l.elemView.find(".layui-menu li").on("click",function(e){var i=c(this),t=i.data("item")||{},n=t[s.children]&&0n.width()&&(t.addClass(x),(i=t[0].getBoundingClientRect()).left<0)&&t.removeClass(x),i.bottom>n.height())&&t.eq(0).css("margin-top",-(i.bottom-n.height()+5))}).on("mouseleave",t,function(e){var i=c(this).children("."+C);i.removeClass(x),i.css("margin-top",0)}),h.close=function(e){e=f.getThis(e);return e?(e.remove(),f.call(e)):this},h.reload=function(e,i,t){e=f.getThis(e);return e?(e.reload(i,t),f.call(e)):this},h.reloadData=function(){var t=c.extend([],arguments),n=(t[2]="reloadData",new RegExp("^("+["data","templet","content"].join("|")+")$"));return layui.each(t[1],function(e,i){n.test(e)||delete t[1][e]}),h.reload.apply(null,t)},h.render=function(e){e=new E(e);return f.call(e)},e(r,h)});layui.define(["jquery","lay"],function(e){"use strict";var g=layui.$,x=layui.lay,c={config:{},index:layui.slider?layui.slider.index+1e4:0,set:function(e){var t=this;return t.config=g.extend({},t.config,e),t},on:function(e,t){return layui.onevent.call(this,i,e,t)}},i="slider",v="layui-disabled",b="layui-slider-bar",T="layui-slider-wrap",w="layui-slider-wrap-btn",M="layui-slider-tips",L="layui-slider-input-txt",E="layui-slider-hover",t=function(e){var t=this;t.index=++c.index,t.config=g.extend({},t.config,c.config,e),t.render()};t.prototype.config={type:"default",min:0,max:100,value:0,step:1,showstep:!1,tips:!0,input:!1,range:!1,height:200,disabled:!1,theme:"#16baaa"},t.prototype.render=function(){var n=this,a=n.config,e=g(a.elem);if(1a.max&&(a.value=a.max),i=Math.floor((a.value-a.min)/(a.max-a.min)*100)+"%");var l,e=a.disabled?"#c2c2c2":a.theme,t='
      '+(a.tips?'
      ':"")+'
      '+(a.range?'
      ':"")+"
      ",i=g(a.elem),s=i.next(".layui-slider");if(s[0]&&s.remove(),n.elemTemp=g(t),a.range?(n.elemTemp.find("."+T).eq(0).data("value",a.value[0]),n.elemTemp.find("."+T).eq(1).data("value",a.value[1])):n.elemTemp.find("."+T).data("value",a.value),i.html(n.elemTemp),"vertical"===a.type&&n.elemTemp.height(a.height+"px"),a.showstep){for(var o=(a.max-a.min)/a.step,r="",u=1;u<1+o;u++){var d=100*u/o;d<100&&(r+='
      ')}n.elemTemp.append(r)}a.input&&!a.range&&(e=g('
      '),i.css("position","relative"),i.append(e),i.find("."+L).children("input").val(a.value),"vertical"===a.type?e.css({left:0,top:-48}):n.elemTemp.css("margin-right",e.outerWidth()+15)),a.disabled?(n.elemTemp.addClass(v),n.elemTemp.find("."+w).addClass(v)):n.slide(),n.elemTemp.find("."+w).on("mouseover",function(){var e="vertical"===a.type?a.height:n.elemTemp[0].offsetWidth,t=n.elemTemp.find("."+T),i=("vertical"===a.type?e-g(this).parent()[0].offsetTop-t.height():g(this).parent()[0].offsetLeft)/e*100,t=g(this).parent().data("value"),e=a.setTips?a.setTips(t):t;n.elemTemp.find("."+M).html(e),clearTimeout(l),l=setTimeout(function(){"vertical"===a.type?n.elemTemp.find("."+M).css({bottom:i+"%","margin-bottom":"20px",display:"inline-block"}):n.elemTemp.find("."+M).css({left:i+"%",display:"inline-block"})},300)}).on("mouseout",function(){clearTimeout(l),n.elemTemp.find("."+M).css("display","none")})},t.prototype.slide=function(e,t,i){var u=this,d=u.config,c=u.elemTemp,v=function(){return"vertical"===d.type?d.height:c[0].offsetWidth},m=c.find("."+T),o=c.next(".layui-slider-input"),r=o.children("."+L).children("input").val(),p=100/((d.max-d.min)/Math.ceil(d.step)),f=function(e,t,i){e=(e=100<(e=100n[1]&&n.reverse(),u.value=d.range?n:l,d.change&&d.change(u.value),"done"===i&&d.done&&d.done(u.value)},h=function(e){var t=e/v()*100/p,i=Math.round(t)*p;return i=e==v()?Math.ceil(t)*p:i},y=g(['
      v()?v():t)/v()*100/p;f(t,o),r.addClass(E),c.find("."+M).show(),e.preventDefault()},n=function(e){r.removeClass(E),setTimeout(function(){c.find("."+M).hide()},e)},a=function(){n&&n(x.touchEventsSupported()?1e3:0),y.remove(),d.done&&d.done(u.value),x.touchEventsSupported()&&(t[0].removeEventListener("touchmove",i,!!x.passiveSupported&&{passive:!1}),t[0].removeEventListener("touchend",a),t[0].removeEventListener("touchcancel",a))},g("#LAY-slider-moving")[0]||g("body").append(y),y.on("mousemove",i),y.on("mouseup",a).on("mouseleave",a),x.touchEventsSupported()&&(t[0].addEventListener("touchmove",i,!!x.passiveSupported&&{passive:!1}),t[0].addEventListener("touchend",a),t[0].addEventListener("touchcancel",a))})}),c.on("click",function(e){var t=g("."+w),i=g(this);!t.is(event.target)&&0===t.has(event.target).length&&t.length&&(i=(t=(t=(t="vertical"===d.type?v()-e.clientY+i.offset().top-g(window).scrollTop():e.clientX-i.offset().left-g(window).scrollLeft())<0?0:t)>v()?v():t)/v()*100/p,t=d.range?"vertical"===d.type?Math.abs(t-parseInt(g(m[0]).css("bottom")))>Math.abs(t-parseInt(g(m[1]).css("bottom")))?1:0:Math.abs(t-m[0].offsetLeft)>Math.abs(t-m[1].offsetLeft)?1:0:0,f(i,t,"done"),e.preventDefault())}),o.children(".layui-slider-input-btn").children("i").each(function(t){g(this).on("click",function(){r=o.children("."+L).children("input").val();var e=((r=1==t?r-d.stepd.max?d.max:Number(r)+d.step)-d.min)/(d.max-d.min)*100/p;f(e,0,"done")})});var n=function(){var e=this.value,e=(e=(e=(e=isNaN(e)?0:e)d.max?d.max:e,((this.value=e)-d.min)/(d.max-d.min)*100/p);f(e,0,"done")};o.children("."+L).children("input").on("keydown",function(e){13===e.keyCode&&(e.preventDefault(),n.call(this))}).on("change",n)},t.prototype.events=function(){this.config},c.render=function(e){e=new t(e);return function(){var i=this,n=i.config;return{setValue:function(e,t){return e=(e=e>n.max?n.max:e)',"",'','',"","","
      "].join("")),t=i.elem=k(i.elem);i.size&&o.addClass("layui-colorpicker-"+i.size),t.addClass("layui-inline").html(e.elemColorBox=o),i.id="id"in i?i.id:t.attr("id")||e.index,e.color=e.elemColorBox.find("."+C)[0].style.background,e.events()},d.prototype.renderPicker=function(){var o,e=this,i=e.config,t=e.elemColorBox[0],r=e.elemPicker=k(['
      ','
      ','
      ','
      ','
      ','
      ',"
      ",'
      ','
      ',"
      ","
      ",'
      ','
      ','
      ',"
      ","
      ",i.predefine?(o=['
      '],layui.each(i.colors,function(e,i){o.push(['
      ','
      ',"
      "].join(""))}),o.push("
      "),o.join("")):"",'
      ','
      ','',"
      ",'
      ','','',"","
      "].join(""));e.elemColorBox.find("."+C)[0];k(a)[0]&&k(a).data("index")==e.index?e.removePicker(d.thisElemInd):(e.removePicker(d.thisElemInd),k("body").append(r)),n.thisId=i.id,d.thisElemInd=e.index,d.thisColor=t.style.background,e.position(),e.pickerEvents()},d.prototype.removePicker=function(e){var i=this.config,e=k("#layui-colorpicker"+(e||this.index));return e[0]&&(e.remove(),delete n.thisId,"function"==typeof i.close)&&i.close(this.color),this},d.prototype.position=function(){var e=this,i=e.config;return r.position(e.bindElem||e.elemColorBox[0],e.elemPicker[0],{position:i.position,align:"center"}),e},d.prototype.val=function(){var e,i=this,o=(i.config,i.elemColorBox.find("."+C)),t=i.elemPicker.find("."+M),r=o[0].style.backgroundColor;r?(e=Y(F(r)),o=o.attr("lay-type"),i.select(e.h,e.s,e.b),"torgb"===o?t.find("input").val(r):"rgba"===o?(o=F(r),3===(r.match(/[0-9]{1,3}/g)||[]).length?(t.find("input").val("rgba("+o.r+", "+o.g+", "+o.b+", 1)"),i.elemPicker.find("."+D).css("left",280)):(t.find("input").val(r),r=280*r.slice(r.lastIndexOf(",")+1,r.length-1),i.elemPicker.find("."+D).css("left",r)),i.elemPicker.find("."+T)[0].style.background="linear-gradient(to right, rgba("+o.r+", "+o.g+", "+o.b+", 0), rgb("+o.r+", "+o.g+", "+o.b+"))"):t.find("input").val("#"+j(e))):(i.select(0,100,100),t.find("input").val(""),i.elemPicker.find("."+T)[0].style.background="",i.elemPicker.find("."+D).css("left",280))},d.prototype.side=function(){var n=this,l=n.config,c=n.elemColorBox.find("."+C),a=c.attr("lay-type"),s=n.elemPicker.find(".layui-colorpicker-side"),e=n.elemPicker.find("."+B),d=n.elemPicker.find("."+I),t=n.elemPicker.find("."+E),u=n.elemPicker.find("."+T),f=n.elemPicker.find("."+D),p=e[0].offsetTop/180*360,h=100-(t[0].offsetTop+3)/180*100,g=(t[0].offsetLeft+3)/260*100,v=Math.round(f[0].offsetLeft/280*100)/100,y=n.elemColorBox.find("."+w),i=n.elemPicker.find(".layui-colorpicker-pre").children("div"),m=function(e,i,o,t){n.select(e,i,o);var r=X({h:e,s:i,b:o}),e=j({h:e,s:i,b:o}),i=n.elemPicker.find("."+M).find("input");y.addClass(x).removeClass(P),c[0].style.background="rgb("+r.r+", "+r.g+", "+r.b+")","torgb"===a?i.val("rgb("+r.r+", "+r.g+", "+r.b+")"):"rgba"===a?(f.css("left",280*t),i.val("rgba("+r.r+", "+r.g+", "+r.b+", "+t+")"),c[0].style.background="rgba("+r.r+", "+r.g+", "+r.b+", "+t+")",u[0].style.background="linear-gradient(to right, rgba("+r.r+", "+r.g+", "+r.b+", 0), rgb("+r.r+", "+r.g+", "+r.b+"))"):i.val("#"+e),l.change&&l.change(k.trim(n.elemPicker.find("."+M).find("input").val()))},o=k(['
      '].join("")),b=function(e){k("#LAY-colorpicker-moving")[0]||k("body").append(o),o.on("mousemove",e),o.on("mouseup",function(){o.remove()}).on("mouseleave",function(){o.remove()})};e.on("mousedown",function(e){var t=this.offsetTop,r=e.clientY;b(function(e){var i=t+(e.clientY-r),o=s[0].offsetHeight,o=(i=o<(i=i<0?0:i)?o:i)/180*360;m(p=o,g,h,v),e.preventDefault()}),e.preventDefault()}),s.on("click",function(e){var i=e.clientY-k(this).offset().top+L.scrollTop(),i=(i=(i=i<0?0:i)>this.offsetHeight?this.offsetHeight:i)/180*360;m(p=i,g,h,v),e.preventDefault()}),t.on("mousedown",function(e){var n=this.offsetTop,l=this.offsetLeft,c=e.clientY,a=e.clientX;layui.stope(e),b(function(e){var i=n+(e.clientY-c),o=l+(e.clientX-a),t=d[0].offsetHeight-3,r=d[0].offsetWidth-3,r=((o=r<(o=o<-3?-3:o)?r:o)+3)/260*100,o=100-((i=t<(i=i<-3?-3:i)?t:i)+3)/180*100;m(p,g=r,h=o,v),e.preventDefault()}),e.preventDefault()}),d.on("mousedown",function(e){var i=e.clientY-k(this).offset().top-3+L.scrollTop(),o=e.clientX-k(this).offset().left-3+L.scrollLeft(),o=((i=i<-3?-3:i)>this.offsetHeight-3&&(i=this.offsetHeight-3),((o=(o=o<-3?-3:o)>this.offsetWidth-3?this.offsetWidth-3:o)+3)/260*100),i=100-(i+3)/180*100;m(p,g=o,h=i,v),layui.stope(e),e.preventDefault(),t.trigger(e,"mousedown")}),f.on("mousedown",function(e){var t=this.offsetLeft,r=e.clientX;b(function(e){var i=t+(e.clientX-r),o=u[0].offsetWidth,o=(o<(i=i<0?0:i)&&(i=o),Math.round(i/280*100)/100);m(p,g,h,v=o),e.preventDefault()}),e.preventDefault()}),u.on("click",function(e){var i=e.clientX-k(this).offset().left,i=((i=i<0?0:i)>this.offsetWidth&&(i=this.offsetWidth),Math.round(i/280*100)/100);m(p,g,h,v=i),e.preventDefault()}),i.each(function(){k(this).on("click",function(){k(this).parent(".layui-colorpicker-pre").addClass("selected").siblings().removeClass("selected");var e=this.style.backgroundColor,i=Y(F(e)),o=e.slice(e.lastIndexOf(",")+1,e.length-1);p=i.h,g=i.s,h=i.b,3===(e.match(/[0-9]{1,3}/g)||[]).length&&(o=1),v=o,m(i.h,i.s,i.b,o)})}),r.touchEventsSupported()&&layui.each([{elem:s,eventType:"click"},{elem:u,eventType:"click"},{elem:d,eventType:"mousedown"}],function(e,t){r.touchSwipe(t.elem,{onTouchMove:function(e){var i,o;e=e,i=t.eventType,e=e.touches[0],(o=document.createEvent("MouseEvent")).initMouseEvent(i,!0,!0,window,1,e.screenX,e.screenY,e.clientX,e.clientY,!1,!1,!1,!1,0,null),e.target.dispatchEvent(o)}})})},d.prototype.select=function(e,i,o,t){this.config;var r=j({h:e,s:100,b:100}),e=(j({h:e,s:i,b:o}),e/360*180),o=180-o/100*180-3,i=i/100*260-3;this.elemPicker.find("."+B).css("top",e),this.elemPicker.find("."+I)[0].style.background="#"+r,this.elemPicker.find("."+E).css({top:o,left:i})},d.prototype.pickerEvents=function(){var c=this,a=c.config,s=c.elemColorBox.find("."+C),d=c.elemPicker.find("."+M+" input"),o={clear:function(e){s[0].style.background="",c.elemColorBox.find("."+w).removeClass(x).addClass(P),c.color="",a.done&&a.done(""),c.removePicker()},confirm:function(e,i){var o,t,r,n,l=k.trim(d.val());-1>16,g:(65280&r)>>8,b:255&r},t=Y(n),s[0].style.background=o="#"+j(t),c.elemColorBox.find("."+w).removeClass(P).addClass(x)),"change"===i?(c.select(t.h,t.s,t.b,i),a.change&&a.change(o)):(c.color=l,a.done&&a.done(l),c.removePicker())}};c.elemPicker.on("click","*[colorpicker-events]",function(){var e=k(this),i=e.attr("colorpicker-events");o[i]&&o[i].call(this,e)}),d.on("keyup",function(e){var i=k(this);o.confirm.call(this,i,13===e.keyCode?null:"change")})},d.prototype.events=function(){var e=this;e.config;e.elemColorBox.on("click",function(){e.renderPicker(),k(a)[0]&&(e.val(),e.side())})},s.on(i,function(e){var i,o,t;n.thisId&&(i=l.getThis(n.thisId))&&(o=i.config,t=i.elemColorBox.find("."+C),k(e.target).hasClass(c)||k(e.target).parents("."+c)[0]||k(e.target).hasClass(a.replace(/\./g,""))||k(e.target).parents(a)[0]||i.elemPicker&&(i.color?(e=Y(F(i.color)),i.select(e.h,e.s,e.b)):i.elemColorBox.find("."+w).removeClass(x).addClass(P),t[0].style.background=i.color||"","function"==typeof o.cancel&&o.cancel(i.color),i.removePicker()))}),L.on("resize",function(){if(n.thisId){var e=l.getThis(n.thisId);if(e)return!(!e.elemPicker||!k(a)[0])&&void e.position()}}),l.that={},l.getThis=function(e){var i=l.that[e];return i||o.error(e?t+" instance with ID '"+e+"' not found":"ID argument required"),i},n.render=function(e){e=new d(e);return l.call(e)},e(t,n)});layui.define("jquery",function(t){"use strict";var u=layui.$,d=(layui.hint(),layui.device()),c="element",r="layui-this",h="layui-show",o=".layui-tab-title",i=function(){this.config={}},y=(i.prototype.set=function(t){return u.extend(!0,this.config,t),this},i.prototype.on=function(t,i){return layui.onevent.call(this,c,t,i)},i.prototype.tabAdd=function(t,i){var a,e=u(".layui-tab[lay-filter="+t+"]"),l=e.children(o),n=l.children(".layui-tab-bar"),e=e.children(".layui-tab-content"),s=""+(i.title||"unnaming")+"";return n[0]?n.before(s):l.append(s),e.append('
      '+(i.content||"")+"
      "),i.change&&this.tabChange(t,i.id),l.data("LAY_TAB_CHANGE",i.change),C.tabAuto(i.change?"change":null),this},i.prototype.tabDelete=function(t,i){t=u(".layui-tab[lay-filter="+t+"]").children(o).find('>li[lay-id="'+i+'"]');return C.tabDelete(null,t),this},i.prototype.tabChange=function(t,i){t=u(".layui-tab[lay-filter="+t+"]").children(o).find('>li[lay-id="'+i+'"]');return C.tabClick.call(t[0],{liElem:t}),this},i.prototype.tab=function(a){a=a||{},e.on("click",a.headerElem,function(t){var i=u(this).index();C.tabClick.call(this,{index:i,options:a})})},i.prototype.progress=function(t,i){var a="layui-progress",t=u("."+a+"[lay-filter="+t+"]").find("."+a+"-bar"),a=t.find("."+a+"-text");return t.css("width",function(){return/^.+\/.+$/.test(i)?100*new Function("return "+i)()+"%":i}).attr("lay-percent",i),a.text(i),this},".layui-nav"),f="layui-nav-item",p="layui-nav-bar",b="layui-nav-tree",v="layui-nav-child",m="layui-nav-more",g="layui-anim layui-anim-upbit",C={tabClick:function(t){var i=(t=t||{}).options||{},a=t.liElem||u(this),e=i.headerElem?a.parent():a.parents(".layui-tab").eq(0),i=i.bodyElem?u(i.bodyElem):e.children(".layui-tab-content").children(".layui-tab-item"),l=a.find("a"),l="javascript:;"!==l.attr("href")&&"_blank"===l.attr("target"),n="string"==typeof a.attr("lay-unselect"),s=e.attr("lay-filter"),t="index"in t?t.index:a.parent().children("li").index(a);l||n||(a.addClass(r).siblings().removeClass(r),i.eq(t).addClass(h).siblings().removeClass(h)),layui.event.call(this,c,"tab("+s+")",{elem:e,index:t})},tabDelete:function(t,i){var i=i||u(this).parent(),a=i.parent().children("li").index(i),e=i.closest(".layui-tab"),l=e.children(".layui-tab-content").children(".layui-tab-item"),n=e.attr("lay-filter");i.hasClass(r)&&(i.next()[0]&&i.next().is("li")?C.tabClick.call(i.next()[0],{index:a+1}):i.prev()[0]&&i.prev().is("li")&&C.tabClick.call(i.prev()[0],null,a-1)),i.remove(),l.eq(a).remove(),setTimeout(function(){C.tabAuto()},50),layui.event.call(this,c,"tabDelete("+n+")",{elem:e,index:a})},tabAuto:function(l){var n="layui-tab-more",s="layui-tab-bar",o="layui-tab-close",c=this;u(".layui-tab").each(function(){var t,i=u(this),a=i.children(".layui-tab-title"),e=(i.children(".layui-tab-content").children(".layui-tab-item"),'lay-stope="tabmore"'),e=u('');c===window&&d.ie,i.attr("lay-allowclose")&&a.find("li").each(function(){var t,i=u(this);i.find("."+o)[0]||((t=u('')).on("click",C.tabDelete),i.append(t))}),"string"!=typeof i.attr("lay-unauto")&&(a.prop("scrollWidth")>a.outerWidth()+1||a.find("li").length&&a.height()>(t=a.find("li").eq(0).height())+t/2?("change"===l&&a.data("LAY_TAB_CHANGE")&&a.addClass(n),a.find("."+s)[0]||(a.append(e),i.attr("overflow",""),e.on("click",function(t){var i=a.hasClass(n);a[i?"removeClass":"addClass"](n)}))):(a.find("."+s).remove(),i.removeAttr("overflow")))})},hideTabMore:function(t){var i=u(".layui-tab-title");!0!==t&&"tabmore"===u(t.target).attr("lay-stope")||(i.removeClass("layui-tab-more"),i.find(".layui-tab-bar").attr("title",""))},clickThis:function(){var t=u(this),i=t.closest(y),a=i.attr("lay-filter"),e=t.parent(),l=t.siblings("."+v),n="string"==typeof e.attr("lay-unselect");if("javascript:;"!==t.attr("href")&&"_blank"===t.attr("target")||n||l[0]||(i.find("."+r).removeClass(r),e.addClass(r)),i.hasClass(b)){var n=f+"ed",s=!e.hasClass(n),o=function(){u(this).css({display:""}),i.children("."+p).css({opacity:0})};if(l.is(":animated"))return;l.removeClass(g),l[0]&&(s?(l.slideDown(200,o),e.addClass(n)):(e.removeClass(n),l.show().slideUp(200,o)),"string"!=typeof i.attr("lay-accordion")&&"all"!==i.attr("lay-shrink")||((s=e.siblings("."+n)).removeClass(n),s.children("."+v).show().stop().slideUp(200,o)))}layui.event.call(this,c,"nav("+a+")",t)},collapse:function(){var t=u(this),i=t.find(".layui-colla-icon"),a=t.siblings(".layui-colla-content"),e=t.parents(".layui-collapse").eq(0),l=e.attr("lay-filter"),n="none"===a.css("display");"string"==typeof e.attr("lay-accordion")&&((e=e.children(".layui-colla-item").children("."+h)).siblings(".layui-colla-title").children(".layui-colla-icon").html(""),e.removeClass(h)),a[n?"addClass":"removeClass"](h),i.html(n?"":""),layui.event.call(this,c,"collapse("+l+")",{title:t,content:a,show:n})}},a=(i.prototype.render=i.prototype.init=function(t,i){var a=i?'[lay-filter="'+i+'"]':"",i={tab:function(){C.tabAuto.call({})},nav:function(){var s={},o={},c={},r="layui-nav-title";u(y+a).each(function(t){var i=u(this),a=u(''),e=i.find("."+f);i.find("."+p)[0]||(i.append(a),(i.hasClass(b)?e.find("dd,>."+r):e).on("mouseenter",function(){!function(t,i,a){var e,l=u(this),n=l.find("."+v);i.hasClass(b)?n[0]||(e=l.children("."+r),t.css({top:l.offset().top-i.offset().top,height:(e[0]?e:l).outerHeight(),opacity:1})):(n.addClass(g),n.hasClass("layui-nav-child-c")&&n.css({left:-(n.outerWidth()-l.width())/2}),n[0]?t.css({left:t.position().left+t.width()/2,width:0,opacity:0}):t.css({left:l.position().left+parseFloat(l.css("marginLeft")),top:l.position().top+l.height()-t.height()}),s[a]=setTimeout(function(){t.css({width:n[0]?0:l.width(),opacity:n[0]?0:1})},d.ie&&d.ie<10?0:200),clearTimeout(c[a]),"block"===n.css("display")&&clearTimeout(o[a]),o[a]=setTimeout(function(){n.addClass(h),l.find("."+m).addClass(m+"d")},300))}.call(this,a,i,t)}).on("mouseleave",function(){i.hasClass(b)?a.css({height:0,opacity:0}):(clearTimeout(o[t]),o[t]=setTimeout(function(){i.find("."+v).removeClass(h),i.find("."+m).removeClass(m+"d")},300))}),i.on("mouseleave",function(){clearTimeout(s[t]),c[t]=setTimeout(function(){i.hasClass(b)||a.css({width:0,left:a.position().left+a.width()/2,opacity:0})},200)})),e.find("a").each(function(){var t=u(this);t.parent();t.siblings("."+v)[0]&&!t.children("."+m)[0]&&t.append(''),t.off("click",C.clickThis).on("click",C.clickThis)})})},breadcrumb:function(){u(".layui-breadcrumb"+a).each(function(){var t=u(this),i="lay-separator",a=t.attr(i)||"/",e=t.find("a");e.next("span["+i+"]")[0]||(e.each(function(t){t!==e.length-1&&u(this).after(""+a+"")}),t.css("visibility","visible"))})},progress:function(){var e="layui-progress";u("."+e+a).each(function(){var t=u(this),i=t.find(".layui-progress-bar"),a=i.attr("lay-percent");i.css("width",function(){return/^.+\/.+$/.test(a)?100*new Function("return "+a)()+"%":a}),t.attr("lay-showpercent")&&setTimeout(function(){i.html(''+a+"")},350)})},collapse:function(){u(".layui-collapse"+a).each(function(){u(this).find(".layui-colla-item").each(function(){var t=u(this),i=t.find(".layui-colla-title"),t="none"===t.find(".layui-colla-content").css("display");i.find(".layui-colla-icon").remove(),i.append(''+(t?"":"")+""),i.off("click",C.collapse).on("click",C.collapse)})})}};return i[t]?i[t]():layui.each(i,function(t,i){i()})},new i),e=u(document);u(function(){a.render()}),e.on("click",".layui-tab-title li",C.tabClick),u(window).on("resize",C.tabAuto),t(c,a)});layui.define(["lay","layer"],function(e){"use strict";var x=layui.$,a=layui.lay,i=layui.layer,b=layui.device(),t="upload",r="layui_"+t+"_index",o={config:{},index:layui[t]?layui[t].index+1e4:0,set:function(e){var i=this;return i.config=x.extend({},i.config,e),i},on:function(e,i){return layui.onevent.call(this,t,e,i)}},l=function(){var i=this,e=i.config.id;return{upload:function(e){i.upload.call(i,e)},reload:function(e){i.reload.call(i,e)},config:(l.that[e]=i).config}},u="layui-upload-file",f="layui-upload-form",F="layui-upload-iframe",w="layui-upload-choose",L="UPLOADING",j=function(e){var i=this;i.index=++o.index,i.config=x.extend({},i.config,o.config,e),i.render()};j.prototype.config={accept:"images",exts:"",auto:!0,bindAction:"",url:"",force:"",field:"file",acceptMime:"",method:"post",data:{},drag:!0,size:0,number:0,multiple:!1,text:{"cross-domain":"Cross-domain requests are not supported","data-format-error":"Please return JSON data format","check-error":"",error:"","limit-number":null,"limit-size":null}},j.prototype.reload=function(e){var i=this;i.config=x.extend({},i.config,e),i.render(!0)},j.prototype.render=function(e){var i=this,t=i.config,n=x(t.elem);return 1"].join("")),n=i.elem.next();(n.hasClass(u)||n.hasClass(f))&&n.remove(),b.ie&&b.ie<10&&i.elem.wrap('
      '),e.isFile()?(e.elemFile=i.elem,i.field=i.elem[0].name):i.elem.after(t),b.ie&&b.ie<10&&e.initIE()},j.prototype.initIE=function(){var t,e=this.config,i=x(''),n=x(['
      ',"
      "].join(""));x("#"+F)[0]||x("body").append(i),e.elem.next().hasClass(f)||(this.elemFile.wrap(n),e.elem.next("."+f).append((t=[],layui.each(e.data,function(e,i){i="function"==typeof i?i():i,t.push('')}),t.join(""))))},j.prototype.msg=function(e){return i.msg(e,{icon:2,shift:6})},j.prototype.isFile=function(){var e=this.config.elem[0];if(e)return"input"===e.tagName.toLocaleLowerCase()&&"file"===e.type},j.prototype.preview=function(n){window.FileReader&&layui.each(this.chooseFiles,function(e,i){var t=new FileReader;t.readAsDataURL(i),t.onload=function(){n&&n(e,i,this.result)}})},j.prototype.upload=function(e,i){var t,n,a,o,u=this,f=u.config,c=f.text||{},l=u.elemFile[0],s=function(){return e||u.files||u.chooseFiles||l.files},r=function(){var a=0,o=0,l=s(),r=function(){f.multiple&&a+o===u.fileLength&&"function"==typeof f.allDone&&f.allDone({total:u.fileLength,successful:a,failed:o})},t=function(t){var n=new FormData,i=function(e){t.unified?layui.each(l,function(e,i){delete i[L]}):delete e[L]};if(layui.each(f.data,function(e,i){i="function"==typeof i?i():i,n.append(e,i)}),t.unified)layui.each(l,function(e,i){i[L]||(i[L]=!0,n.append(f.field,i))});else{if(t.file[L])return;n.append(f.field,t.file),t.file[L]=!0}var e={url:f.url,type:"post",data:n,dataType:f.dataType||"json",contentType:!1,processData:!1,headers:f.headers||{},success:function(e){f.unified?a+=u.fileLength:a++,p(t.index,e),r(t.index),i(t.file)},error:function(e){f.unified?o+=u.fileLength:o++,u.msg(c.error||["Upload failed, please try again.","status: "+(e.status||"")+" - "+(e.statusText||"error")].join("
      ")),m(t.index),r(t.index),i(t.file)}};"function"==typeof f.progress&&(e.xhr=function(){var e=x.ajaxSettings.xhr();return e.upload.addEventListener("progress",function(e){var i;e.lengthComputable&&(i=Math.floor(e.loaded/e.total*100),f.progress(i,(f.item||f.elem)[0],e,t.index))}),e}),x.ajax(e)};f.unified?t({unified:!0,index:0}):layui.each(l,function(e,i){t({index:e,file:i})})},d=function(){var n=x("#"+F);u.elemFile.parent().submit(),clearInterval(j.timer),j.timer=setInterval(function(){var e,i=n.contents().find("body");try{e=i.text()}catch(t){u.msg(c["cross-domain"]),clearInterval(j.timer),m()}e&&(clearInterval(j.timer),i.html(""),p(0,e))},30)},p=function(e,i){if(u.elemFile.next("."+w).remove(),l.value="","json"===f.force&&"object"!=typeof i)try{i=JSON.parse(i)}catch(t){return i={},u.msg(c["data-format-error"])}"function"==typeof f.done&&f.done(i,e||0,function(e){u.upload(e)})},m=function(e){f.auto&&(l.value=""),"function"==typeof f.error&&f.error(e||0,function(e){u.upload(e)})},h=f.exts,g=(n=[],layui.each(e||u.chooseFiles,function(e,i){n.push(i.name)}),n),v={preview:function(e){u.preview(e)},upload:function(e,i){var t={};t[e]=i,u.upload(t)},pushFile:function(){return u.files=u.files||{},layui.each(u.chooseFiles,function(e,i){u.files[e]=i}),u.files},resetFile:function(e,i,t){i=new File([i],t);u.files=u.files||{},u.files[e]=i}},y={file:"\u6587\u4ef6",images:"\u56fe\u7247",video:"\u89c6\u9891",audio:"\u97f3\u9891"}[f.accept]||"\u6587\u4ef6",g=0===g.length?l.value.match(/[^\/\\]+\..+/g)||[]:g;if(0!==g.length){switch(f.accept){case"file":layui.each(g,function(e,i){if(h&&!RegExp(".\\.("+h+")$","i").test(escape(i)))return t=!0});break;case"video":layui.each(g,function(e,i){if(!RegExp(".\\.("+(h||"avi|mp4|wma|rmvb|rm|flash|3gp|flv")+")$","i").test(escape(i)))return t=!0});break;case"audio":layui.each(g,function(e,i){if(!RegExp(".\\.("+(h||"mp3|wav|mid")+")$","i").test(escape(i)))return t=!0});break;default:layui.each(g,function(e,i){if(!RegExp(".\\.("+(h||"jpg|png|gif|bmp|jpeg|svg")+")$","i").test(escape(i)))return t=!0})}if(t)return u.msg(c["check-error"]||"\u9009\u62e9\u7684"+y+"\u4e2d\u5305\u542b\u4e0d\u652f\u6301\u7684\u683c\u5f0f"),l.value="";if("choose"!==i&&!f.auto||(f.choose&&f.choose(v),"choose"!==i)){if(u.fileLength=(a=0,y=s(),layui.each(y,function(){a++}),a),f.number&&u.fileLength>f.number)return u.msg("function"==typeof c["limit-number"]?c["limit-number"](f,u.fileLength):"\u540c\u65f6\u6700\u591a\u53ea\u80fd\u4e0a\u4f20: "+f.number+" \u4e2a\u6587\u4ef6
      \u60a8\u5f53\u524d\u5df2\u7ecf\u9009\u62e9\u4e86: "+u.fileLength+" \u4e2a\u6587\u4ef6");if(01024*f.size&&(i=1<=(i=f.size/1024)?i.toFixed(2)+"MB":f.size+"KB",l.value="",o=i)}),o)return u.msg("function"==typeof c["limit-size"]?c["limit-size"](f,o):"\u6587\u4ef6\u5927\u5c0f\u4e0d\u80fd\u8d85\u8fc7 "+o);if(!f.before||!1!==f.before(v))b.ie?(9'+e+"")};a.elem.off("upload.start").on("upload.start",function(){var e=x(this);n.config.item=e,n.elemFile[0].click()}),b.ie&&b.ie<10||a.elem.off("upload.over").on("upload.over",function(){x(this).attr("lay-over","")}).off("upload.leave").on("upload.leave",function(){x(this).removeAttr("lay-over")}).off("upload.drop").on("upload.drop",function(e,i){var t=x(this),i=i.originalEvent.dataTransfer.files||[];t.removeAttr("lay-over"),o(i),a.auto?n.upload():l(i)}),n.elemFile.on("change",function(){var e=this.files||[];0!==e.length&&(o(e),a.auto?n.upload():l(e))}),a.bindAction.off("upload.action").on("upload.action",function(){n.upload()}),a.elem.data(r)||(a.elem.on("click",function(){n.isFile()||x(this).trigger("upload.start")}),a.drag&&a.elem.on("dragover",function(e){e.preventDefault(),x(this).trigger("upload.over")}).on("dragleave",function(e){x(this).trigger("upload.leave")}).on("drop",function(e){e.preventDefault(),x(this).trigger("upload.drop",e)}),a.bindAction.on("click",function(){x(this).trigger("upload.action")}),a.elem.data(r,a.id))},l.that={},l.getThis=function(e){var i=l.that[e];return i||hint.error(e?t+" instance with ID '"+e+"' not found":"ID argument required"),i},o.render=function(e){e=new j(e);return l.call(e)},e(t,o)});layui.define(["lay","layer","util"],function(e){"use strict";var C=layui.$,h=layui.layer,d=layui.util,l=layui.hint(),w=(layui.device(),"form"),o=".layui-form",N="layui-this",T="layui-hide",$="layui-disabled",t=function(){this.config={verify:{required:function(e){if(!/[\S]+/.test(e))return"\u5fc5\u586b\u9879\u4e0d\u80fd\u4e3a\u7a7a"},phone:function(e){if(e&&!/^1\d{10}$/.test(e))return"\u624b\u673a\u53f7\u683c\u5f0f\u4e0d\u6b63\u786e"},email:function(e){if(e&&!/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(e))return"\u90ae\u7bb1\u683c\u5f0f\u4e0d\u6b63\u786e"},url:function(e){if(e&&!/^(#|(http(s?)):\/\/|\/\/)[^\s]+\.[^\s]+$/.test(e))return"\u94fe\u63a5\u683c\u5f0f\u4e0d\u6b63\u786e"},number:function(e){if(e&&isNaN(e))return"\u53ea\u80fd\u586b\u5199\u6570\u5b57"},date:function(e){if(e&&!/^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/.test(e))return"\u65e5\u671f\u683c\u5f0f\u4e0d\u6b63\u786e"},identity:function(e){if(e&&!/(^\d{15}$)|(^\d{17}(x|X|\d)$)/.test(e))return"\u8eab\u4efd\u8bc1\u53f7\u683c\u5f0f\u4e0d\u6b63\u786e"}},autocomplete:null}},i=(t.prototype.set=function(e){return C.extend(!0,this.config,e),this},t.prototype.verify=function(e){return C.extend(!0,this.config.verify,e),this},t.prototype.getFormElem=function(e){return C(o+(e?'[lay-filter="'+e+'"]':""))},t.prototype.on=function(e,t){return layui.onevent.call(this,w,e,t)},t.prototype.val=function(e,i){return this.getFormElem(e).each(function(e,t){var a=C(this);layui.each(i,function(e,t){var i,e=a.find('[name="'+e+'"]');e[0]&&("checkbox"===(i=e[0].type)?e[0].checked=t:"radio"===i?e.each(function(){this.checked=this.value==t}):e.val(t))})}),r.render(null,e),this.getValue(e)},t.prototype.getValue=function(e,t){t=t||this.getFormElem(e);var a={},n={},e=t.find("input,select,textarea");return layui.each(e,function(e,t){var i;C(this);t.name=(t.name||"").replace(/^\s*|\s*&/,""),t.name&&(/^.*\[\]$/.test(t.name)&&(i=t.name.match(/^(.*)\[\]$/g)[0],a[i]=0|a[i],i=t.name.replace(/^(.*)\[\]$/,"$1["+a[i]+++"]")),/^(checkbox|radio)$/.test(t.type)&&!t.checked||(n[i||t.name]=t.value))}),n},t.prototype.render=function(e,t){var i=this.config,a=C(o+(t?'[lay-filter="'+t+'"]':"")),n={input:function(e){var e=e||a.find("input,textarea"),t=(i.autocomplete&&e.attr("autocomplete",i.autocomplete),function(e,t){var i=e.val(),a=Number(i),n=Number(e.attr("step"))||1,l=Number(e.attr("min")),r=Number(e.attr("max")),s=Number(e.attr("lay-precision")),o="click"!==t&&""===i,c="init"===t;isNaN(a)||("click"===t&&(a=!!C(this).index()?a-n:a+n),t=function(e){return((e.toString().match(/\.(\d+$)/)||[])[1]||"").length},s=0<=s?s:Math.max(t(n),t(i)),o||(c||r<=(a=a<=l?l:a)&&(a=r),s&&(a=a.toFixed(s)),e.val(a)),e[(a'),e=layui.isArray(i.value)?i.value:[i.value],e=C((a=[],layui.each(e,function(e,t){a.push('')}),a.join(""))),n=(t.append(e),i.split&&t.addClass("layui-input-split"),i.className&&t.addClass(i.className),r.next("."+u)),l=(n[0]&&n.remove(),r.parent().hasClass(o)||r.wrap('
      '),r.next("."+c));l[0]?((n=l.find("."+u))[0]&&n.remove(),l.prepend(t),r.css("padding-right",function(){return(r.closest(".layui-input-group")[0]?0:l.outerWidth())+t.outerWidth()})):(t.addClass(c),r.after(t)),"auto"===i.show&&d(t,r.val()),"function"==typeof i.init&&i.init.call(this,r,i),r.on("input propertychange",function(){var e=this.value;"auto"===i.show&&d(t,e)}),r.on("blur",function(){"function"==typeof i.blur&&i.blur.call(this,r,i)}),e.on("click",function(){var e=r.attr("lay-filter");C(this).hasClass($)||("function"==typeof i.click&&i.click.call(this,r,i),layui.event.call(this,w,"input-affix("+e+")",{elem:r[0],affix:s,options:i}))})},f={eye:{value:"eye-invisible",click:function(e,t){var i="LAY_FORM_INPUT_AFFIX_SHOW",a=e.data(i);e.attr("type",a?"password":"text").data(i,!a),n({value:a?"eye-invisible":"eye"})}},clear:{value:"clear",click:function(e){e.val("").focus(),d(C(this).parent(),null)},show:"auto",disabled:e},number:{value:["up","down"],split:!0,className:"layui-input-number",disabled:r.is("[disabled]"),init:function(e){t.call(this,e,"init")},click:function(e){t.call(this,e,"click")},blur:function(e){t.call(this,e,"blur")}}};n()})},select:function(e){var p,c="\u8bf7\u9009\u62e9",m="layui-form-select",g="layui-select-title",x="layui-select-none",b="",e=e||a.find("select"),k=function(e,t){C(e.target).parent().hasClass(g)&&!t||(C("."+m).removeClass(m+"ed "+m+"up"),p&&b&&p.val(b)),p=null},u=function(a,e,t){var s,r,i,n,o,l,c=C(this),u=a.find("."+g),d=u.find("input"),f=a.find("dl"),h=f.children("dd"),y=f.children("dt"),v=this.selectedIndex;e||(r=c.attr("lay-search"),i=function(){var e=a.offset().top+a.outerHeight()+5-F.scrollTop(),t=f.outerHeight();v=c[0].selectedIndex,a.addClass(m+"ed"),h.removeClass(T),y.removeClass(T),s=null,h.removeClass(N),0<=v&&h.eq(v).addClass(N),e+t>F.height()&&t<=e&&a.addClass(m+"up"),o()},n=function(e){a.removeClass(m+"ed "+m+"up"),d.blur(),s=null,e||l(d.val(),function(e){var t=c[0].selectedIndex;e&&(b=C(c[0].options[t]).html(),0===t&&b===d.attr("placeholder")&&(b=""),d.val(b||""))})},o=function(){var e,t,i=f.children("dd."+N);i[0]&&(e=i.position().top,t=f.height(),i=i.height(),t\u65e0\u5339\u914d\u9879

      '):f.find("."+x).remove()},"keyup"),""===t&&(c.val(""),f.find("."+N).removeClass(N),(c[0].options[0]||{}).value||f.children("dd:eq(0)").addClass(N),f.find("."+x).remove()),o()}).on("blur",function(e){var t=c[0].selectedIndex;p=d,b=C(c[0].options[t]).text(),0===t&&b===d.attr("placeholder")&&(b=""),setTimeout(function(){l(d.val(),function(e){b||d.val("")},"blur")},200)})),h.on("click",function(){var e=C(this),t=e.attr("lay-value"),i=c.attr("lay-filter");return e.hasClass($)||(e.hasClass("layui-select-tips")?d.val(""):(d.val(e.text()),e.addClass(N)),e.siblings().removeClass(N),c.val(t).removeClass("layui-form-danger"),layui.event.call(this,w,"select("+i+")",{elem:c[0],value:t,othis:a}),n(!0)),!1}),a.find("dl>dt").on("click",function(e){return!1}),C(document).off("click",k).on("click",k))};e.each(function(e,t){var i=C(this),a=i.next("."+m),n=this.disabled,l=t.value,r=C(t.options[t.selectedIndex]),t=t.options[0];if("string"==typeof i.attr("lay-ignore"))return i.show();var s,o="string"==typeof i.attr("lay-search"),t=t&&!t.value&&t.innerHTML||c,r=C(['
      ','
      ','','
      ','
      ',(t=i.find("*"),s=[],layui.each(t,function(e,t){var i=t.tagName.toLowerCase();0!==e||t.value||"optgroup"===i?s.push("optgroup"===i?"
      "+t.label+"
      ":'
      '+C.trim(t.innerHTML)+"
      "):s.push('
      '+C.trim(t.innerHTML||c)+"
      ")}),0===s.length&&s.push('
      \u6ca1\u6709\u9009\u9879
      '),s.join("")+"
      "),"
      "].join(""));a[0]&&a.remove(),i.after(r),u.call(this,r,n,o)})},checkbox:function(e){var o={checkbox:["layui-form-checkbox","layui-form-checked","checkbox"],"switch":["layui-form-switch","layui-form-onswitch","switch"],SUBTRA:"layui-icon-indeterminate"},e=e||a.find("input[type=checkbox]");e.each(function(e,t){var i=C(this),a=i.attr("lay-skin")||"primary",n=d.escape(C.trim(t.title||(t.title=i.attr("lay-text")||""))),l=this.disabled,r=o[a]||o.checkbox,s=i.next("."+r[0]);if(s[0]&&s.remove(),i.next("[lay-checkbox]")[0]&&(n=i.next().html()||""),n="switch"===a?n.split("|"):[n],"string"==typeof i.attr("lay-ignore"))return i.show();l=C(['
      ",(s={checkbox:[n[0]?"
      "+n[0]+"
      ":"primary"===a?"":"
      ",''].join(""),"switch":"
      "+((t.checked?n[0]:n[1])||"")+"
      "})[a]||s.checkbox,"
      "].join(""));i.after(l),function(a,n){var l=C(this);a.on("click",function(){var e=C(this),t=l.attr("lay-filter"),e=e.next("*[lay-checkbox]")[0]?e.next().html():l.attr("title")||"",i=l.attr("lay-skin")||"primary",e="switch"===i?e.split("|"):[e];l[0].disabled||(l[0].indeterminate&&(l[0].indeterminate=!1,a.find("."+o.SUBTRA).removeClass(o.SUBTRA).addClass("layui-icon-ok")),l[0].checked?(l[0].checked=!1,a.removeClass(n[1]),"switch"===i&&a.children("div").html(e[1])):(l[0].checked=!0,a.addClass(n[1]),"switch"===i&&a.children("div").html(e[0])),layui.event.call(l[0],w,n[2]+"("+t+")",{elem:l[0],value:l[0].value,othis:a}))})}.call(this,l,r)})},radio:function(e){var r="layui-form-radio",s=["layui-icon-radio","layui-icon-circle"],e=e||a.find("input[type=radio]");e.each(function(e,t){var i=C(this),a=i.next("."+r),n=this.disabled;if("string"==typeof i.attr("lay-ignore"))return i.show();a[0]&&a.remove();n=C(['
      ','',"
      "+(a=d.escape(t.title||""),a=i.next("[lay-radio]")[0]?i.next().html():a)+"
      ","
      "].join(""));i.after(n),function(a){var n=C(this),l="layui-anim-scaleSpring";a.on("click",function(){var e=n[0].name,t=n.parents(o),i=n.attr("lay-filter"),e=t.find("input[name="+e.replace(/(\.|#|\[|\])/g,"\\$1")+"]");n[0].disabled||(layui.each(e,function(){var e=C(this).next("."+r);this.checked=!1,e.removeClass(r+"ed"),e.children(".layui-icon").removeClass(l+" "+s[0]).addClass(s[1])}),n[0].checked=!0,a.addClass(r+"ed"),a.children(".layui-icon").addClass(l+" "+s[0]),layui.event.call(n[0],w,"radio("+i+")",{elem:n[0],value:n[0].value,othis:a}))})}.call(this,n)})}},t=function(){layui.each(n,function(e,t){t()})};return"object"===layui.type(e)?C(e).is(o)?(a=C(e),t()):e.each(function(e,t){var i=C(t);i.closest(o).length&&("SELECT"===t.tagName?n.select(i):"INPUT"===t.tagName&&("checkbox"===(t=t.type)||"radio"===t?n[t](i):n.input(i)))}):e?n[e]?n[e]():l.error('\u4e0d\u652f\u6301\u7684 "'+e+'" \u8868\u5355\u6e32\u67d3'):t(),this},t.prototype.validate=function(e){var u,d=this.config.verify,f="layui-form-danger";return!(e=C(e))[0]||(e.attr("lay-verify")!==undefined||!1!==this.validate(e.find("*[lay-verify]")))&&(layui.each(e,function(e,r){var s=C(this),t=(s.attr("lay-verify")||"").split("|"),o=s.attr("lay-vertype"),c=C.trim(s.val());if(s.removeClass(f),layui.each(t,function(e,t){var i="",a=d[t];if(a){var n="function"==typeof a?i=a(c,r):!a[0].test(c),l="select"===r.tagName.toLowerCase()||/^(checkbox|radio)$/.test(r.type),i=i||a[1];if("required"===t&&(i=s.attr("lay-reqtext")||i),n)return"tips"===o?h.tips(i,"string"!=typeof s.attr("lay-ignore")&&l?s.next():s,{tips:1}):"alert"===o?h.alert(i,{title:"\u63d0\u793a",shadeClose:!0}):/\b(string|number)\b/.test(typeof i)&&h.msg(i,{icon:5,shift:6}),setTimeout(function(){(l?s.next().find("input"):r).focus()},7),s.addClass(f),u=!0}}),u)return u}),!u)},t.prototype.submit=function(e,t){var i={},a=C(this),e="string"==typeof e?e:a.attr("lay-filter"),n=this.getFormElem?this.getFormElem(e):a.parents(o).eq(0),l=n.find("*[lay-verify]");return!!r.validate(l)&&(i=r.getValue(null,n),l={elem:this.getFormElem?window.event&&window.event.target:this,form:(this.getFormElem?n:a.parents("form"))[0],field:i},"function"==typeof t&&t(l),layui.event.call(this,w,"submit("+e+")",l))}),r=new t,t=C(document),F=C(window);C(function(){r.render()}),t.on("reset",o,function(){var e=C(this).attr("lay-filter");setTimeout(function(){r.render(null,e)},50)}),t.on("submit",o,i).on("click","*[lay-submit]",i),e(w,r)});layui.define(["lay","laytpl","laypage","form","util"],function(n){"use strict";var p=layui.$,r=layui.lay,m=layui.laytpl,O=layui.laypage,f=layui.layer,v=layui.form,g=layui.util,x=layui.hint(),b=layui.device(),k={config:{checkName:"LAY_CHECKED",indexName:"LAY_INDEX",numbersName:"LAY_NUM",disabledName:"LAY_DISABLED"},cache:{},index:layui.table?layui.table.index+1e4:0,set:function(e){return this.config=p.extend({},this.config,e),this},on:function(e,t){return layui.onevent.call(this,N,e,t)}},w=function(){var a=this,e=a.config,i=e.id||e.index;return{config:e,reload:function(e,t){a.reload.call(a,e,t)},reloadData:function(e,t){k.reloadData(i,e,t)},setColsWidth:function(){a.setColsWidth.call(a)},resize:function(){a.resize.call(a)}}},C=function(e){var t=w.that[e];return t||x.error(e?"The table instance with ID '"+e+"' not found":"ID argument required"),t||null},l=function(e){var t=w.config[e];return t||x.error(e?"The table instance with ID '"+e+"' not found":"ID argument required"),t||null},T=function(e){var t=this.config||{},a=(e=e||{}).item3,i=e.content;"numbers"===a.type&&(i=e.tplData[k.config.numbersName]);("escape"in a?a:t).escape&&(i=g.escape(i));t=e.text&&a.exportTemplet||a.templet||a.toolbar;return t&&(i="function"==typeof t?t.call(a,e.tplData,e.obj):m(function(e){try{return r(e).html()}catch(t){return e}}(t)||String(i)).render(p.extend({LAY_COL:a},e.tplData))),e.text?p("
      "+i+"
      ").text():i},N="table",t=".layui-table",R="layui-hide",y="layui-hide-v",h="layui-none",D="layui-table-view",o=".layui-table-header",L=".layui-table-body",u=".layui-table-fixed-r",I=".layui-table-pageview",A=".layui-table-sort",E="layui-table-checked",_="layui-table-edit",M="layui-table-hover",P="laytable-cell-group",W="layui-table-col-special",j="layui-table-tool-panel",H="layui-table-expanded",S="LAY_TABLE_MOVE_DICT",e=function(e){return['',"","{{# layui.each(d.data.cols, function(i1, item1){ }}","","{{# layui.each(item1, function(i2, item2){ }}",'{{# if(item2.fixed && item2.fixed !== "right"){ left = true; } }}','{{# if(item2.fixed === "right"){ right = true; } }}',(e=e||{}).fixed&&"right"!==e.fixed?'{{# if(item2.fixed && item2.fixed !== "right"){ }}':"right"===e.fixed?'{{# if(item2.fixed === "right"){ }}':"","{{# var isSort = !(item2.colGroup) && item2.sort; }}",'",e.fixed?"{{# }; }}":"","{{# }); }}","","{{# }); }}","","
      ','
      ','{{# if(item2.type === "checkbox"){ }}','',"{{# } else { }}",'{{-item2.title||""}}',"{{# if(isSort){ }}",'',"{{# } }}","{{# } }}","
      ","
      "].join("")},a=['',"","
      "].join(""),s=[,"{{# if(d.data.toolbar){ }}",'
      ','
      ','
      ',"
      ","{{# } }}",'
      ',"{{# if(d.data.loading){ }}",'
      ','',"
      ","{{# } }}","{{# var left, right; }}",'
      ',e(),"
      ",'
      ',a,"
      ","{{# if(left){ }}",'
      ','
      ',e({fixed:!0}),"
      ",'
      ',a,"
      ","
      ","{{# }; }}","{{# if(right){ }}",'
      ','
      ',e({fixed:"right"}),'
      ',"
      ",'
      ',a,"
      ","
      ","{{# }; }}","
      ","{{# if(d.data.totalRow){ }}",'
      ','','',"
      ","
      ","{{# } }}",'
      ','
      ',"
      "].join(""),d=p(window),F=p(document),i=function(e){this.index=++k.index,this.config=p.extend({},this.config,k.config,e),this.render()},c=(i.prototype.config={limit:10,loading:!0,escape:!0,cellMinWidth:60,cellMaxWidth:Number.MAX_VALUE,editTrigger:"click",defaultToolbar:["filter","exports","print"],defaultContextmenu:!0,autoSort:!0,text:{none:"\u65e0\u6570\u636e"},cols:[]},i.prototype.render=function(e){var t=this,a=t.config,i=(a.elem=p(a.elem),a.where=a.where||{},a.id="id"in a?a.id:a.elem.attr("id")||t.index);if(w.that[i]=t,(w.config[i]=a).request=p.extend({pageName:"page",limitName:"limit"},a.request),a.response=p.extend({statusName:"code",statusCode:0,msgName:"msg",dataName:"data",totalRowName:"totalRow",countName:"count"},a.response),null!==a.page&&"object"==typeof a.page&&(a.limit=a.page.limit||a.limit,a.limits=a.page.limits||a.limits,t.page=a.page.curr=a.page.curr||1,delete a.page.elem,delete a.page.jump),!a.elem[0])return t;if(a.elem.attr("lay-filter")||a.elem.attr("lay-filter",a.id),"reloadData"===e)return t.pullData(t.page,{type:"reloadData"});a.index=t.index,t.key=a.id||a.index,t.setInit(),a.height&&/^full-.+$/.test(a.height)?(t.fullHeightGap=a.height.split("-")[1],a.height=d.height()-(parseFloat(t.fullHeightGap)||0)):a.height&&/^#\w+\S*-.+$/.test(a.height)?(i=a.height.split("-"),t.parentHeightGap=i.pop(),t.parentDiv=i.join("-"),a.height=p(t.parentDiv).height()-(parseFloat(t.parentHeightGap)||0)):"function"==typeof a.height&&(t.customHeightFunc=a.height,a.height=t.customHeightFunc());var l,e=a.elem,i=e.next("."+D),n=t.elem=p("
      ");n.addClass((l=[D,D+"-"+t.index,"layui-form","layui-border-box"],a.className&&l.push(a.className),l.join(" "))).attr({"lay-filter":"LAY-TABLE-FORM-DF-"+t.index,"lay-id":a.id,style:(l=[],a.width&&l.push("width:"+a.width+"px;"),l.join(""))}).html(m(s,{open:"{{",close:"}}"}).render({data:a,index:t.index})),t.renderStyle(),i[0]&&i.remove(),e.after(n),t.layTool=n.find(".layui-table-tool"),t.layBox=n.find(".layui-table-box"),t.layHeader=n.find(o),t.layMain=n.find(".layui-table-main"),t.layBody=n.find(L),t.layFixed=n.find(".layui-table-fixed"),t.layFixLeft=n.find(".layui-table-fixed-l"),t.layFixRight=n.find(u),t.layTotal=n.find(".layui-table-total"),t.layPage=n.find(".layui-table-page"),t.renderToolbar(),t.renderPagebar(),t.fullSize(),t.pullData(t.page),t.events()},i.prototype.initOpts=function(e){this.config;e.checkbox&&(e.type="checkbox"),e.space&&(e.type="space"),e.type||(e.type="normal"),"normal"!==e.type&&(e.unresize=!0,e.width=e.width||{checkbox:50,radio:50,space:30,numbers:60}[e.type])},i.prototype.setInit=function(e){var l,a,d=this,r=d.config;if(r.clientWidth=r.width||(l=function(e){var t,a=(e=e||r.elem.parent()).width();try{t="none"===e.css("display")}catch(i){}return!e[0]||a&&!t?a:l(e.parent())})(),"width"===e)return r.clientWidth;r.height=r.maxHeight||r.height,r.css&&-1===r.css.indexOf(D)&&(a=r.css.split("}"),layui.each(a,function(e,t){t&&(a[e]="."+D+"-"+d.index+" "+t)}),r.css=a.join("}"));var c=function(a,e,i,l){var n,o;l?(l.key=[r.index,a,i].join("-"),l.colspan=l.colspan||0,l.rowspan=l.rowspan||0,d.initOpts(l),(n=a+(parseInt(l.rowspan)||1)) td:hover > .layui-table-cell{overflow: auto;}"].concat(b.ie?[".layui-table-edit{height: "+i+";}","td[data-edit]:hover:after{height: "+i+";}"]:[]),function(e,t){t&&o.push(a+" "+t)})),l.css&&o.push(l.css),r.style({target:this.elem[0],text:o.join(""),id:"DF-table-"+n})},i.prototype.renderToolbar=function(){var e=this.config,t=['
      ','
      ','
      '].join(""),a=this.layTool.find(".layui-table-tool-temp"),i=("default"===e.toolbar?a.html(t):"string"==typeof e.toolbar&&(t=p(e.toolbar).html()||"")&&a.html(m(t).render(e)),{filter:{title:"\u7b5b\u9009\u5217",layEvent:"LAYTABLE_COLS",icon:"layui-icon-cols"},exports:{title:"\u5bfc\u51fa",layEvent:"LAYTABLE_EXPORT",icon:"layui-icon-export"},print:{title:"\u6253\u5370",layEvent:"LAYTABLE_PRINT",icon:"layui-icon-print"}}),l=[];"object"==typeof e.defaultToolbar&&layui.each(e.defaultToolbar,function(e,t){t="string"==typeof t?i[t]:t;t&&l.push('
      ')}),this.layTool.find(".layui-table-tool-self").html(l.join(""))},i.prototype.renderPagebar=function(){var e,t=this.config,a=this.layPagebar=p('
      ');t.pagebar&&((e=p(t.pagebar).html()||"")&&a.append(m(e).render(t)),this.layPage.append(a))},i.prototype.setParentCol=function(e,t){var a=this.config,i=this.layHeader.find('th[data-key="'+t+'"]'),l=parseInt(i.attr("colspan"))||0;i[0]&&(t=t.split("-"),t=a.cols[t[1]][t[2]],e?l--:l++,i.attr("colspan",l),i[l?"removeClass":"addClass"](R),t.colspan2=l,t.hide=l<1,a=i.data("parentkey"))&&this.setParentCol(e,a)},i.prototype.setColsPatch=function(){var a=this,e=a.config;layui.each(e.cols,function(e,t){layui.each(t,function(e,t){t.hide&&a.setParentCol(t.hide,t.parentKey)})})},i.prototype.setGroupWidth=function(i){var e,l=this;l.config.cols.length<=1||((e=l.layHeader.find((i?"th[data-key="+i.data("parentkey")+"]>":"")+"."+P)).css("width",0),layui.each(e.get().reverse(),function(){var e=p(this),t=e.parent().data("key"),a=0;l.layHeader.eq(0).find("th[data-parentkey="+t+"]").width(function(e,t){p(this).hasClass(R)||0 tr:first-child > th:last-child")).data("field")&&e.prev()[0]?t(e.prev()):e})()).data("key"),n.cssRules(e,function(e){var t=e.style.width||a.outerWidth();e.style.width=parseFloat(t)+l+"px",0'+(e||"Error")+"
      ");a[0]&&(t.layNone.remove(),a.remove()),t.layFixed.addClass(R),t.layMain.find("tbody").html(""),t.layMain.append(t.layNone=e),t.layTotal.addClass(y),t.layPage.find(I).addClass(y),k.cache[t.key]=[],t.syncCheckAll(),t.renderForm(),t.setColsWidth()},i.prototype.page=1,i.prototype.pullData=function(a,t){var e,i,l=this,n=l.config,o=(n.HAS_SET_COLS_PATCH||l.setColsPatch(),n.HAS_SET_COLS_PATCH=!0,n.request),d=n.response,r=function(){"object"==typeof n.initSort&&l.sort({field:n.initSort.field,type:n.initSort.type,reloadType:t.type})},c=function(e,t){l.setColsWidth(),"function"==typeof n.done&&n.done(e,a,e[d.countName],t)};t=t||{},"function"==typeof n.before&&n.before(n),l.startTime=(new Date).getTime(),t.renderData?((e={})[d.dataName]=k.cache[l.key],e[d.countName]=n.url?"object"===layui.type(n.page)?n.page.count:e[d.dataName].length:n.data.length,"object"==typeof n.totalRow&&(e[d.totalRowName]=p.extend({},l.totalRow)),l.renderData({res:e,curr:a,count:e[d.countName],type:t.type,sort:!0}),c(e,"renderData")):n.url?(i={},n.page&&(i[o.pageName]=a,i[o.limitName]=n.limit),o=p.extend(i,n.where),n.contentType&&0==n.contentType.indexOf("application/json")&&(o=JSON.stringify(o)),l.loading(),p.ajax({type:n.method||"get",url:n.url,contentType:n.contentType,data:o,dataType:n.dataType||"json",jsonpCallback:n.jsonpCallback,headers:n.headers||{},complete:"function"==typeof n.complete?n.complete:undefined,success:function(e){(e="function"==typeof n.parseData?n.parseData(e)||e:e)[d.statusName]!=d.statusCode?l.errorView(e[d.msgName]||'\u8fd4\u56de\u7684\u6570\u636e\u4e0d\u7b26\u5408\u89c4\u8303\uff0c\u6b63\u786e\u7684\u6210\u529f\u72b6\u6001\u7801\u5e94\u4e3a\uff1a"'+d.statusName+'": '+d.statusCode):(l.totalRow=e[d.totalRowName],l.renderData({res:e,curr:a,count:e[d.countName],type:t.type}),r(),n.time=(new Date).getTime()-l.startTime+" ms"),c(e)},error:function(e,t){l.errorView("\u8bf7\u6c42\u5f02\u5e38\uff0c\u9519\u8bef\u63d0\u793a\uff1a"+t),"function"==typeof n.error&&n.error(e,t)}})):"array"===layui.type(n.data)&&(e={},i=a*n.limit-n.limit,o=n.data.concat(),e[d.dataName]=n.page?o.splice(i,n.limit):o,e[d.countName]=n.data.length,"object"==typeof n.totalRow&&(e[d.totalRowName]=p.extend({},n.totalRow)),l.totalRow=e[d.totalRowName],l.renderData({res:e,curr:a,count:e[d.countName],type:t.type}),r(),c(e))},i.prototype.eachCols=function(e){return k.eachCols(null,e,this.config.cols),this},i.prototype.col=function(e){try{return e=e.split("-"),this.config.cols[e[1]][e[2]]||{}}catch(t){return x.error(t),{}}},i.prototype.getTrHtml=function(a,l,n,e){var s=this,u=s.config,y=e&&e.trs||[],h=e&&e.trs_fixed||[],f=e&&e.trs_fixed_r||[];return n=n||1,layui.each(a,function(e,o){var i=[],d=[],r=[],c=e+u.limit*(n-1)+1;if("object"!=typeof o){a[e]=o={LAY_KEY:o};try{k.cache[s.key][e]=o}catch(t){}}"array"===layui.type(o)&&0===o.length||(o[k.config.numbersName]=c,l||(o[k.config.indexName]=e),s.eachCols(function(e,l){var t,e=l.field||e,a=l.key,n=o[e];n!==undefined&&null!==n||(n=""),l.colGroup||(e=['','
      "+function(){var e,t=p.extend(!0,{LAY_COL:l},o),a=k.config.checkName,i=k.config.disabledName;switch(l.type){case"checkbox":return'';case"radio":return'';case"numbers":return c}return l.toolbar?m(p(l.toolbar).html()||"").render(t):T.call(s,{item3:l,content:n,tplData:t})}(),"
      "].join(""),i.push(e),l.fixed&&"right"!==l.fixed&&d.push(e),"right"===l.fixed&&r.push(e))}),e=['data-index="'+e+'"'],o[k.config.checkName]&&e.push('class="'+E+'"'),e=e.join(" "),y.push(""+i.join("")+""),h.push(""+d.join("")+""),f.push(""+r.join("")+""))}),{trs:y,trs_fixed:h,trs_fixed_r:f}},k.getTrHtml=function(e,t){e=C(e);return e.getTrHtml(t,null,e.page)},i.prototype.renderData=function(e){var a=this,i=a.config,t=e.res,l=e.curr,n=a.count=e.count,o=e.sort,d=t[i.response.dataName]||[],t=t[i.response.totalRowName],r=[],c=[],s=[],u=function(){if(!o&&a.sortKey)return a.sort({field:a.sortKey.field,type:a.sortKey.sort,pull:!0,reloadType:e.type});a.getTrHtml(d,o,l,{trs:r,trs_fixed:c,trs_fixed_r:s}),"fixed"===i.scrollPos&&"reloadData"===e.type||a.layBody.scrollTop(0),"reset"===i.scrollPos&&a.layBody.scrollLeft(0),a.layMain.find("."+h).remove(),a.layMain.find("tbody").html(r.join("")),a.layFixLeft.find("tbody").html(c.join("")),a.layFixRight.find("tbody").html(s.join("")),a.syncCheckAll(),a.renderForm(),a.fullSize(),a.haveInit?a.scrollPatch():setTimeout(function(){a.scrollPatch()},50),a.haveInit=!0,f.close(a.tipsIndex)};return k.cache[a.key]=d,a.layTotal[0==d.length?"addClass":"removeClass"](y),a.layPage[i.page||i.pagebar?"removeClass":"addClass"](R),a.layPage.find(I)[!i.page||0==n||0===d.length&&1==l?"addClass":"removeClass"](y),0===d.length?a.errorView(i.text.none):(a.layFixLeft.removeClass(R),o?u():(u(),a.renderTotal(d,t),a.layTotal&&a.layTotal.removeClass(R),void(i.page&&(i.page=p.extend({elem:"layui-table-page"+i.index,count:n,limit:i.limit,limits:i.limits||[10,20,30,40,50,60,70,80,90],groups:3,layout:["prev","page","next","skip","count","limit"],prev:'',next:'',jump:function(e,t){t||(a.page=e.curr,i.limit=e.limit,a.pullData(e.curr))}},i.page),i.page.count=n,O.render(i.page)))))},k.renderData=function(e){e=C(e);e&&e.pullData(e.page,{renderData:!0,type:"reloadData"})},i.prototype.renderTotal=function(e,o){var d,r=this,c=r.config,s={};c.totalRow&&(layui.each(e,function(e,i){"array"===layui.type(i)&&0===i.length||r.eachCols(function(e,t){var e=t.field||e,a=i[e];t.totalRow&&(s[e]=(s[e]||0)+(parseFloat(a)||0))})}),r.dataTotal=[],d=[],r.eachCols(function(e,t){var a,e=t.field||e,i=o&&o[t.field],l="totalRowDecimals"in t?t.totalRowDecimals:2,l=s[e]?parseFloat(s[e]||0).toFixed(l):"",l=(a=t.totalRowText||"",(n={LAY_COL:t})[e]=l,n=t.totalRow&&T.call(r,{item3:t,content:l,tplData:n})||a,i||n),n=(t.field&&r.dataTotal.push({field:t.field,total:p("
      "+l+"
      ").text()}),['','
      "+("string"==typeof(a=t.totalRow||c.totalRow)?m(a).render(p.extend({TOTAL_NUMS:i||s[e],TOTAL_ROW:o||{},LAY_COL:t},t)):l),"
      "].join(""));d.push(n)}),e=r.layTotal.find(".layui-table-patch"),r.layTotal.find("tbody").html(""+d.join("")+(e.length?e.get(0).outerHTML:"")+""))},i.prototype.getColElem=function(e,t){return e.eq(0).find(".laytable-cell-"+t+":eq(0)")},i.prototype.renderForm=function(e){this.config;var t=this.elem.attr("lay-filter");v.render(e,t)},i.prototype.syncCheckAll=function(){var a,e=this,i=e.config,t=e.layHeader.find('input[name="layTableCheckbox"]'),l=k.checkStatus(e.key);t[0]&&(a=l.isAll,e.eachCols(function(e,t){"checkbox"===t.type&&(t[i.checkName]=a)}),t.prop({checked:l.isAll,indeterminate:!l.isAll&&l.data.length}),v.render(t))},i.prototype.setRowActive=function(e,t,a){this.config;e=this.layBody.find('tr[data-index="'+e+'"]');if(t=t||"layui-table-click",a)return e.removeClass(t);e.addClass(t),e.siblings("tr").removeClass(t)},i.prototype.setRowChecked=function(i){var e=this,l=e.config,n="all"===i.index,o="array"===layui.type(i.index),d=(t=e.layBody.find("tr"),n?t:t.filter(o?function(){var e=p(this).data("index");return-1!==i.index.indexOf(e)}:'[data-index="'+i.index+'"]')),t=(i=p.extend({type:"checkbox"},i),k.cache[e.key]),a="checked"in i,r=function(e){return"radio"===i.type||(a?i.checked:!e)},t=(layui.each(t,function(e,t){var a;"array"===layui.type(t)||t[l.disabledName]||(n||(o?-1!==i.index.indexOf(e):Number(i.index)===e)?(a=t[l.checkName]=r(t[l.checkName]),(e=d.filter('[data-index="'+e+'"]'))[a?"addClass":"removeClass"](E),"radio"===i.type&&e.siblings().removeClass(E)):"radio"===i.type&&delete t[l.checkName])}),d.find('input[lay-type="'+({radio:"layTableRadio",checkbox:"layTableCheckbox"}[i.type]||"checkbox")+'"]:not(:disabled)')),c=t.last(),s=c.closest(u);("radio"===i.type&&s.hasClass(R)?t.first():t).prop("checked",r(c.prop("checked"))),e.syncCheckAll(),e.renderForm(i.type)},i.prototype.sort=function(l){var e,t=this,a={},i=t.config,n=i.elem.attr("lay-filter"),o=k.cache[t.key];"string"==typeof(l=l||{}).field&&(d=l.field,t.layHeader.find("th").each(function(e,t){var a=p(this),i=a.data("field");if(i===l.field)return l.field=a,d=i,!1}));try{var d=d||l.field.data("field"),r=l.field.data("key");if(t.sortKey&&!l.pull&&d===t.sortKey.field&&l.type===t.sortKey.sort)return;var c=t.layHeader.find("th .laytable-cell-"+r).find(A);t.layHeader.find("th").find(A).removeAttr("lay-sort"),c.attr("lay-sort",l.type||null),t.layFixed.find("th")}catch(s){x.error("Table modules: sort field '"+d+"' not matched")}t.sortKey={field:d,sort:l.type},i.autoSort&&("asc"===l.type?e=layui.sort(o,d,null,!0):"desc"===l.type?e=layui.sort(o,d,!0,!0):(e=layui.sort(o,k.config.indexName,null,!0),delete t.sortKey,delete i.initSort)),a[i.response.dataName]=e||o,t.renderData({res:a,curr:t.page,count:t.count,sort:!0,type:l.reloadType}),l.fromEvent&&(i.initSort={field:d,type:l.type},layui.event.call(l.field,N,"sort("+n+")",p.extend({config:i},i.initSort)))},i.prototype.loading=function(e){var t=this;t.config.loading&&(e?(t.layInit&&t.layInit.remove(),delete t.layInit,t.layBox.find(".layui-table-init").remove()):(t.layInit=p(['
      ','',"
      "].join("")),t.layBox.append(t.layInit)))},i.prototype.cssRules=function(t,a){var e=this.elem.children("style")[0];r.getStyleRules(e,function(e){if(e.selectorText===".laytable-cell-"+t)return a(e),!0})},i.prototype.fullSize=function(){var e,a,i=this,t=i.config,l=t.height;i.fullHeightGap?(l=d.height()-i.fullHeightGap)<135&&(l=135):i.parentDiv&&i.parentHeightGap?(l=p(i.parentDiv).height()-i.parentHeightGap)<135&&(l=135):i.customHeightFunc&&(l=i.customHeightFunc())<135&&(l=135),1
      ')).find("div").css({width:a}),e.find("tr").append(t)):e.find(".layui-table-patch").remove()};n(e.layHeader),n(e.layTotal);n=e.layMain.height()-i;e.layFixed.find(L).css("height",t.height()>=n?n:"auto").scrollTop(e.layMain.scrollTop()),e.layFixRight[k.cache[e.key]&&k.cache[e.key].length&&0');a.html(t),u.height&&a.css("max-height",u.height-(s.layTool.outerHeight()||50)),i.find("."+j)[0]||i.append(a),s.renderForm(),a.on("click",function(e){layui.stope(e)}),e.done&&e.done(a,t)};switch(layui.stope(e),F.trigger("table.tool.panel.remove"),f.close(s.tipsIndex),t){case"LAYTABLE_COLS":n({list:(a=[],s.eachCols(function(e,t){t.field&&"normal"==t.type&&a.push('
    • "+(t.fieldTitle||t.title||t.field)+"
    • ").text())+'" lay-filter="LAY_TABLE_TOOL_COLS">')}),a.join("")),done:function(){v.on("checkbox(LAY_TABLE_TOOL_COLS)",function(e){var e=p(e.elem),t=this.checked,a=e.data("key"),i=s.col(a),l=i.hide,e=e.data("parentkey");i.key&&(i.hide=!t,s.elem.find('*[data-key="'+a+'"]')[t?"removeClass":"addClass"](R),l!=i.hide&&s.setParentCol(!t,e),s.resize(),layui.event.call(this,N,"colToggled("+c+")",{col:i,config:u}))})}});break;case"LAYTABLE_EXPORT":if(!l.length)return f.tips("\u5f53\u524d\u8868\u683c\u65e0\u6570\u636e",this,{tips:3});b.ie?f.tips("\u5bfc\u51fa\u529f\u80fd\u4e0d\u652f\u6301 IE\uff0c\u8bf7\u7528 Chrome \u7b49\u9ad8\u7ea7\u6d4f\u89c8\u5668\u5bfc\u51fa",this,{tips:3}):n({list:['
    • \u5bfc\u51fa csv \u683c\u5f0f\u6587\u4ef6
    • ','
    • \u5bfc\u51fa xls \u683c\u5f0f\u6587\u4ef6
    • '].join(""),done:function(e,t){t.on("click",function(){var e=p(this).data("type");k.exportFile.call(s,u.id,null,e)})}});break;case"LAYTABLE_PRINT":if(!l.length)return f.tips("\u5f53\u524d\u8868\u683c\u65e0\u6570\u636e",this,{tips:3});var o=window.open("about:blank","_blank"),d=[""].join(""),r=p(s.layHeader.html());r.append(s.layMain.find("table").html()),r.append(s.layTotal.find("table").html()),r.find("th.layui-table-patch").remove(),r.find("thead>tr>th."+W).filter(function(e,t){return!p(t).children("."+P).length}).remove(),r.find("tbody>tr>td."+W).remove(),o.document.write(d+r.prop("outerHTML")),o.document.close(),layui.device("edg").edg?(o.onafterprint=o.close,o.print()):(o.print(),o.close())}layui.event.call(this,N,"toolbar("+c+")",p.extend({event:t,config:u},{}))}),s.layHeader.on("click","*[lay-event]",function(e){var t=p(this),a=t.attr("lay-event"),t=t.closest("th").data("key"),t=s.col(t);layui.event.call(this,N,"colTool("+c+")",p.extend({event:a,config:u,col:t},{}))}),s.layPagebar.on("click","*[lay-event]",function(e){var t=p(this).attr("lay-event");layui.event.call(this,N,"pagebar("+c+")",p.extend({event:t,config:u},{}))}),e.on("mousemove",function(e){var t=p(this),a=t.offset().left,e=e.clientX-a;t.data("unresize")||w.eventMoveElem||(d.allowResize=t.width()-e<=10,o.css("cursor",d.allowResize?"col-resize":""))}).on("mouseleave",function(){p(this);w.eventMoveElem||o.css("cursor","")}).on("mousedown",function(e){var t,a=p(this);d.allowResize&&(t=a.data("key"),e.preventDefault(),d.offset=[e.clientX,e.clientY],s.cssRules(t,function(e){var t=e.style.width||a.outerWidth();d.rule=e,d.ruleWidth=parseFloat(t),d.minWidth=a.data("minwidth")||u.cellMinWidth,d.maxWidth=a.data("maxwidth")||u.cellMaxWidth}),a.data(S,d),w.eventMoveElem=a)}),w.docEvent||F.on("mousemove",function(e){var t,a;w.eventMoveElem&&(t=w.eventMoveElem.data(S)||{},w.eventMoveElem.data("resizing",1),e.preventDefault(),t.rule)&&(e=t.ruleWidth+e.clientX-t.offset[0],a=w.eventMoveElem.closest("."+D).attr("lay-id"),a=C(a))&&((e=et.maxWidth&&(e=t.maxWidth),t.rule.style.width=e+"px",a.setGroupWidth(w.eventMoveElem),f.close(s.tipsIndex))}).on("mouseup",function(e){var t,a,i,l,n;w.eventMoveElem&&(i=(t=w.eventMoveElem).closest("."+D).attr("lay-id"),a=C(i))&&(i=t.data("key"),l=a.col(i),n=a.config.elem.attr("lay-filter"),d={},o.css("cursor",""),a.scrollPatch(),t.removeData(S),delete w.eventMoveElem,a.cssRules(i,function(e){l.width=parseFloat(e.style.width),layui.event.call(t[0],N,"colResized("+n+")",{col:l,config:a.config})}))}),w.docEvent=!0,e.on("click",function(e){var t=p(this),a=t.find(A),i=a.attr("lay-sort");if(!a[0]||1===t.data("resizing"))return t.removeData("resizing");s.sort({field:t,type:"asc"===i?"desc":"desc"===i?null:"asc",fromEvent:!0})}).find(A+" .layui-edge ").on("click",function(e){var t=p(this),a=t.index(),t=t.parents("th").eq(0).data("field");layui.stope(e),0===a?s.sort({field:t,type:"asc",fromEvent:!0}):s.sort({field:t,type:"desc",fromEvent:!0})}),s.commonMember=function(e){var t=p(this).parents("tr").eq(0).data("index"),r=s.layBody.find('tr[data-index="'+t+'"]'),c=(c=k.cache[s.key]||[])[t]||{},a={tr:r,config:u,data:k.clearCacheKey(c),dataCache:c,index:t,del:function(){k.cache[s.key][t]=[],r.remove(),s.scrollPatch()},update:function(e,d){e=e||{},layui.each(e,function(i,l){var n=r.children('td[data-field="'+i+'"]'),o=n.children(y);c[i]=a.data[i]=l,s.eachCols(function(e,t){var a;t.field==i?(o.html(T.call(s,{item3:t,content:l,tplData:p.extend({LAY_COL:t},c)})),n.data("content",l)):d&&(t.templet||t.toolbar)&&(e=r.children('td[data-field="'+(t.field||e)+'"]'),a=c[t.field],e.children(y).html(T.call(s,{item3:t,content:a,tplData:p.extend({LAY_COL:t},c)})),e.data("content",a))})}),s.renderForm()},setRowChecked:function(e){s.setRowChecked(p.extend({index:t},e))}};return p.extend(a,e)}),a=(s.elem.on("click",'input[name="layTableCheckbox"]+',function(e){var t=p(this),a=t.closest("td"),t=t.prev(),i=(s.layBody.find('input[name="layTableCheckbox"]'),t.parents("tr").eq(0).data("index")),l=t[0].checked,n="layTableAllChoose"===t.attr("lay-filter");t[0].disabled||(n?s.setRowChecked({index:"all",checked:l}):(s.setRowChecked({index:i,checked:l}),layui.stope(e)),layui.event.call(t[0],N,"checkbox("+c+")",r.call(t[0],{checked:l,type:n?"all":"one",getCol:function(){return s.col(a.data("key"))}})))}),s.elem.on("click",'input[lay-type="layTableRadio"]+',function(e){var t=p(this),a=t.closest("td"),t=t.prev(),i=t[0].checked,l=t.parents("tr").eq(0).data("index");if(layui.stope(e),t[0].disabled)return!1;s.setRowChecked({type:"radio",index:l}),layui.event.call(t[0],N,"radio("+c+")",r.call(t[0],{checked:i,getCol:function(){return s.col(a.data("key"))}}))}),s.layBody.on("mouseenter","tr",function(){var e=p(this),t=e.index();e.data("off")||s.layBody.find("tr:eq("+t+")").addClass(M)}).on("mouseleave","tr",function(){var e=p(this),t=e.index();e.data("off")||s.layBody.find("tr:eq("+t+")").removeClass(M)}).on("click","tr",function(e){var t=[".layui-form-checkbox",".layui-form-switch",".layui-form-radio","[lay-unrow]"].join(",");p(e.target).is(t)||p(e.target).closest(t)[0]||a.call(this,"row")}).on("dblclick","tr",function(){a.call(this,"rowDouble")}).on("contextmenu","tr",function(e){u.defaultContextmenu||e.preventDefault(),a.call(this,"rowContextmenu")}),function(e){var t=p(this);t.data("off")||layui.event.call(this,N,e+"("+c+")",r.call(t.children("td")[0]))}),n=function(e,t){var a,i,l;(e=p(e)).data("off")||(l=e.data("field"),i=e.data("key"),i=s.col(i),a=e.closest("tr").data("index"),a=k.cache[s.key][a],e.children(y),(i="function"==typeof i.edit?i.edit(a):i.edit)&&((i=p("textarea"===i?'':''))[0].value=(l=e.data("content")||a[l])===undefined||null===l?"":l,e.find("."+_)[0]||e.append(i),i.focus(),t)&&layui.stope(t))},i=(s.layBody.on("change","."+_,function(){var e=p(this),t=e.parent(),a=this.value,i=e.parent().data("field"),e=e.closest("tr").data("index"),e=k.cache[s.key][e],l=r.call(t[0],{value:a,field:i,oldValue:e[i],td:t,reedit:function(){setTimeout(function(){n(l.td);var e={};e[i]=l.oldValue,l.update(e)})},getCol:function(){return s.col(t.data("key"))}}),e={};e[i]=a,l.update(e),layui.event.call(t[0],N,"edit("+c+")",l)}).on("blur","."+_,function(){p(this).remove()}),s.layBody.on(u.editTrigger,"td",function(e){n(this,e)}).on("mouseenter","td",function(){t.call(this)}).on("mouseleave","td",function(){t.call(this,"hide")}),s.layTotal.on("mouseenter","td",function(){t.call(this)}).on("mouseleave","td",function(){t.call(this,"hide")}),"layui-table-grid-down"),t=function(e){var t=p(this),a=t.children(y);t.data("off")||t.parent().hasClass(H)||(e?t.find(".layui-table-grid-down").remove():!(a.prop("scrollWidth")>a.outerWidth()||0'))},l=function(e,t){var a=p(this),i=a.parent(),l=i.data("key"),n=s.col(l),o=i.parent().data("index"),i=i.children(y),d="layui-table-cell-c",r=p('');"tips"===(t=t||n.expandedMode||u.cellExpandedMode)?s.tipsIndex=f.tips(['
      ',i.html(),"
      ",''].join(""),i[0],{tips:[3,""],time:-1,anim:-1,maxWidth:b.ios||b.android?300:s.elem.width()/2,isOutAnim:!1,skin:"layui-table-tips",success:function(e,t){e.find(".layui-table-tips-c").on("click",function(){f.close(t)})}}):(s.elem.find("."+d).trigger("click"),s.cssRules(l,function(e){var t=e.style.width,a=n.expandedWidth||u.cellExpandedWidth;atr").each(function(i){n.cols[i]=[],p(this).children().each(function(e){var t=p(this),a=t.attr("lay-data"),a=r.options(this,{attr:a?"lay-data":null,errorText:d+(a||t.attr("lay-options"))}),t=p.extend({title:t.text(),colspan:parseInt(t.attr("colspan"))||1,rowspan:parseInt(t.attr("rowspan"))||1},a);n.cols[i].push(t)})}),e.find("tbody>tr")),t=k.render(n);!a.length||o.data||t.config.url||(l=0,k.eachCols(t.config.id,function(e,i){a.each(function(e){n.data[e]=n.data[e]||{};var t=p(this),a=i.field;n.data[e][a]=t.children("td").eq(l).html()}),l++}),t.reloadData({data:n.data}))}),this},w.that={},w.config={},function(a,i,e,l){var n,o;l.colGroup&&(n=0,a++,l.CHILD_COLS=[],o=e+(parseInt(l.rowspan)||1),layui.each(i[o],function(e,t){t.parentKey?t.parentKey===l.key&&(t.PARENT_COL_INDEX=a,l.CHILD_COLS.push(t),c(a,i,o,t)):t.PARENT_COL_INDEX||1<=n&&n==(l.colspan||1)||(t.PARENT_COL_INDEX=a,l.CHILD_COLS.push(t),n+=parseInt(1td').filter('[data-field="'+e+'"]')}}})).replace(/"/g,'""'),n.push(a='"'+a+'"')))}),d.push(n.join(","))}),c&&layui.each(c.dataTotal,function(e,t){r[t.field]||i.push('"'+(t.total||"")+'"')}),o.join(",")+"\r\n"+d.join("\r\n")+"\r\n"+i.join(","))),u.download=(a.title||n.title||"table_"+(n.index||""))+"."+l,document.body.appendChild(u),u.click(),document.body.removeChild(u)},k.getOptions=l,k.hideCol=function(e,l){var n=C(e);n&&("boolean"===layui.type(l)?n.eachCols(function(e,t){var a=t.key,i=n.col(a),t=t.parentKey;i.hide!=l&&(i=i.hide=l,n.elem.find('*[data-key="'+a+'"]')[i?"addClass":"removeClass"](R),n.setParentCol(i,t))}):(l=layui.isArray(l)?l:[l],layui.each(l,function(e,l){n.eachCols(function(e,t){var a,i;l.field===t.field&&(a=t.key,i=n.col(a),t=t.parentKey,"hide"in l)&&i.hide!=l.hide&&(i=i.hide=!!l.hide,n.elem.find('*[data-key="'+a+'"]')[i?"addClass":"removeClass"](R),n.setParentCol(i,t))})})),p("."+j).remove(),n.resize())},k.reload=function(e,t,a,i){if(l(e))return(e=C(e)).reload(t,a,i),w.call(e)},k.reloadData=function(){var a=p.extend([],arguments),i=(a[3]="reloadData",new RegExp("^("+["elem","id","cols","width","height","maxHeight","toolbar","defaultToolbar","className","css","pagebar"].join("|")+")$"));return layui.each(a[1],function(e,t){i.test(e)&&delete a[1][e]}),k.reload.apply(null,a)},k.render=function(e){e=new i(e);return w.call(e)},k.clearCacheKey=function(e){return delete(e=p.extend({},e))[k.config.checkName],delete e[k.config.indexName],delete e[k.config.numbersName],delete e[k.config.disabledName],e},p(function(){k.init()}),n(N,k)});layui.define(["table"],function(e){"use strict";var E=layui.$,x=layui.form,B=layui.table,y=layui.hint(),j={config:{},on:B.on,eachCols:B.eachCols,index:B.index,set:function(e){var t=this;return t.config=E.extend({},t.config,e),t},resize:B.resize,getOptions:B.getOptions,hideCol:B.hideCol,renderData:B.renderData},i=function(){var a=this,e=a.config,n=e.id||e.index;return{config:e,reload:function(e,t){a.reload.call(a,e,t)},reloadData:function(e,t){j.reloadData(n,e,t)}}},P=function(e){var t=i.that[e];return t||y.error(e?"The treeTable instance with ID '"+e+"' not found":"ID argument required"),t||null},F="layui-hide",L=".layui-table-main",q=".layui-table-fixed-l",R=".layui-table-fixed-r",l="layui-table-checked",h="layui-table-tree",Y="LAY_DATA_INDEX",m="LAY_DATA_INDEX_HISTORY",s="LAY_PARENT_INDEX",b="LAY_CHECKBOX_HALF",H="LAY_EXPAND",z="LAY_HAS_EXPANDED",X="LAY_ASYNC_STATUS",n=["all","parent","children","none"],t=function(e){var t=this;t.index=++j.index,t.config=E.extend(!0,{},t.config,j.config,e),t.init(),t.render()},f=function(n,i,e){var l=B.cache[n];layui.each(e||l,function(e,t){var a=t[Y]||"";-1!==a.indexOf("-")&&(l[a]=t),t[i]&&f(n,i,t[i])})},d=function(l,a,e){var d=P(l),r=("reloadData"!==e&&(d.status={expand:{}}),E.extend(!0,{},d.getOptions(),a)),n=r.tree,o=n.customName.children,i=n.customName.id,c=(delete a.hasNumberCol,delete a.hasChecboxCol,delete a.hasRadioCol,B.eachCols(null,function(e,t){"numbers"===t.type?a.hasNumberCol=!0:"checkbox"===t.type?a.hasChecboxCol=!0:"radio"===t.type&&(a.hasRadioCol=!0)},r.cols),a.parseData),u=a.done;r.url?e&&(!c||c.mod)||(a.parseData=function(){var e=this,t=arguments,a=t[0],t=("function"===layui.type(c)&&(a=c.apply(e,t)||t[0]),e.response.dataName);return n.data.isSimpleData&&!n["async"].enable&&(a[t]=d.flatToTree(a[t])),p(a[t],function(e){e[H]=H in e?e[H]:e[i]!==undefined&&d.status.expand[e[i]]},o),e.autoSort&&e.initSort&&e.initSort.type&&layui.sort(a[t],e.initSort.field,"desc"===e.initSort.type,!0),d.initData(a[t]),a},a.parseData.mod=!0):(a.data=a.data||[],n.data.isSimpleData&&(a.data=d.flatToTree(a.data)),d.initData(a.data)),e&&(!u||u.mod)||(a.done=function(){var e,t=arguments,a=t[3],n=(a||delete d.isExpandAll,this.elem.next()),i=(d.updateStatus(null,{LAY_HAS_EXPANDED:!1}),f(l,o),n.find('[name="layTableCheckbox"][lay-filter="layTableAllChoose"]'));if(i.length&&(e=j.checkStatus(l),i.prop({checked:e.isAll&&e.data.length,indeterminate:!e.isAll&&e.data.length})),!a&&r.autoSort&&r.initSort&&r.initSort.type&&j.sort(l),d.renderTreeTable(n),"function"===layui.type(u))return u.apply(this,t)},a.done.mod=!0)};t.prototype.init=function(){var e=this.config,t=e.tree.data.cascade,t=(-1===n.indexOf(t)&&(e.tree.data.cascade="all"),B.render(E.extend({},e,{data:[],url:"",done:null}))),a=t.config.id;(i.that[a]=this).tableIns=t,d(a,e)},t.prototype.config={tree:{customName:{children:"children",isParent:"isParent",name:"name",id:"id",pid:"parentId",icon:"icon"},view:{indent:14,flexIconClose:'',flexIconOpen:'',showIcon:!0,icon:"",iconClose:'',iconOpen:'',iconLeaf:'',showFlexIconIfNotParent:!1,dblClickExpand:!0,expandAllDefault:!1},data:{isSimpleData:!1,rootPid:null,cascade:"all"},"async":{enable:!1,url:"",type:null,contentType:null,headers:null,where:null,autoParam:[]},callback:{beforeExpand:null,onExpand:null}}},t.prototype.getOptions=function(){return this.tableIns?B.getOptions(this.tableIns.config.id):this.config},t.prototype.flatToTree=function(e){var a,n,i,t,l,d,r,o=this.getOptions(),c=o.tree,u=c.customName,o=o.id;return e=e||B.cache[o],o=e,a=u.id,n=u.pid,i=u.children,t=c.data.rootPid,a=a||"id",n=n||"parentId",i=i||"children",r={},layui.each(o,function(e,t){l=a+t[a],r[l]=E.extend({},t),r[l][i]=[]}),layui.each(r,function(e,t){(d=a+t[n])&&r[d]&&r[d][i].push(t)}),Object.keys(r).map(function(e){return r[e]}).filter(function(e){return t?e[n]===t:!e[n]})},t.prototype.treeToFlat=function(e,n,i){var l=this,d=l.getOptions().tree.customName,r=d.children,o=d.pid,c=[];return layui.each(e,function(e,t){var e=(i?i+"-":"")+e,a=E.extend({},t);a[o]=t[o]||n,c.push(a),c=c.concat(l.treeToFlat(t[r],t[d.id],e))}),c},t.prototype.getTreeNode=function(e){var t,a,n=this;return e?(a=(t=n.getOptions()).tree,t.id,a.customName,{data:e,dataIndex:e[Y],getParentNode:function(){return n.getNodeByIndex(e[s])}}):y.error("\u627e\u4e0d\u5230\u8282\u70b9\u6570\u636e")},t.prototype.getNodeByIndex=function(t){var a,e,n=this,i=n.getNodeDataByIndex(t);return i?((e=n.getOptions()).tree.customName.parent,a=e.id,(e={data:i,dataIndex:i[Y],getParentNode:function(){return n.getNodeByIndex(i[s])},update:function(e){return j.updateNode(a,t,e)},remove:function(){return j.removeNode(a,t)},expand:function(e){return j.expandNode(a,E.extend({},e,{index:t}))},setChecked:function(e){return j.setRowChecked(a,E.extend({},e,{index:t}))}}).dataIndex=t,e):y.error("\u627e\u4e0d\u5230\u8282\u70b9\u6570\u636e")},t.prototype.getNodeById=function(a){var e=this.getOptions(),n=e.tree.customName.id,i="",e=j.getData(e.id,!0);if(layui.each(e,function(e,t){if(t[n]===a)return i=t[Y],!0}),i)return this.getNodeByIndex(i)},t.prototype.getNodeDataByIndex=function(e,t,a){var n=this.getOptions(),i=n.tree,n=n.id,n=B.cache[n],l=n[e];if("delete"!==a&&l)return E.extend(l,a),t?E.extend({},l):l;for(var d=n,r=String(e).split("-"),o=0,c=i.customName.children;o
      '),N=function(e){y[X]="success",y[s.children]=e,c.initData(y[s.children],y[Y]),U(t,!0,!p&&n,i,l)},C=m.format,"function"===layui.type(C)?C(y,o,N):(I=E.extend({},m.where||o.where),C=m.autoParam,layui.each(C,function(e,t){t=t.split("=");I[t[0].trim()]=y[(t[1]||t[0]).trim()]}),(C=m.contentType||o.contentType)&&0==C.indexOf("application/json")&&(I=JSON.stringify(I)),w=m.method||o.method,D=m.dataType||o.dataType,T=m.jsonpCallback||o.jsonpCallback,k=m.headers||o.headers,_=m.parseData||o.parseData,O=m.response||o.response,E.ajax({type:w||"get",url:b,contentType:C,data:I,dataType:D||"json",jsonpCallback:T,headers:k||{},success:function(e){(e="function"==typeof _?_.call(o,e)||e:e)[O.statusName]!=O.statusCode?(y[X]="error",g.html('')):N(e[O.dataName])},error:function(e,t){y[X]="error","function"==typeof o.error&&o.error(e,t)}})),h;y[z]=!0,v.length&&(!o.initSort||o.url&&!o.autoSort||((m=o.initSort).type?layui.sort(v,m.field,"desc"===m.type,!0):layui.sort(v,B.config.indexName,null,!0)),c.initData(y[s.children],y[Y]),w=B.getTrHtml(r,v,null,null,e),S={trs:E(w.trs.join("")),trs_fixed:E(w.trs_fixed.join("")),trs_fixed_r:E(w.trs_fixed_r.join(""))},A=(e.split("-").length-1||0)+1,layui.each(v,function(e,t){S.trs.eq(e).attr({"data-index":t[Y],"lay-data-index":t[Y],"data-level":A}),S.trs_fixed.eq(e).attr({"data-index":t[Y],"lay-data-index":t[Y],"data-level":A}),S.trs_fixed_r.eq(e).attr({"data-index":t[Y],"lay-data-index":t[Y],"data-level":A})}),d.find(L).find('tbody tr[lay-data-index="'+e+'"]').after(S.trs),d.find(q).find('tbody tr[lay-data-index="'+e+'"]').after(S.trs_fixed),d.find(R).find('tbody tr[lay-data-index="'+e+'"]').after(S.trs_fixed_r),c.renderTreeTable(S.trs,A),n)&&!p&&layui.each(v,function(e,t){U({dataIndex:t[Y],trElem:d.find('tr[lay-data-index="'+t[Y]+'"]').first(),tableViewElem:d,tableId:r,options:o},a,n,i,l)})}else c.isExpandAll=!1,(n&&!p?(layui.each(v,function(e,t){U({dataIndex:t[Y],trElem:d.find('tr[lay-data-index="'+t[Y]+'"]').first(),tableViewElem:d,tableId:r,options:o},a,n,i,l)}),d.find(v.map(function(e,t,a){return'tr[lay-data-index="'+e[Y]+'"]'}).join(","))):(b=c.treeToFlat(v,y[s.id],e),d.find(b.map(function(e,t,a){return'tr[lay-data-index="'+e[Y]+'"]'}).join(",")))).addClass(F);V("resize-"+r,function(){j.resize(r)},0)(),l&&"loading"!==y[X]&&(C=u.callback.onExpand,"function"===layui.type(C))&&C(r,y,x)}return h},g=(j.expandNode=function(e,t){var a,n,i,e=P(e);if(e)return a=(t=t||{}).index,n=t.expandFlag,i=t.inherit,t=t.callbackFlag,e=e.getOptions().elem.next(),U({trElem:e.find('tr[lay-data-index="'+a+'"]').first()},n,i,null,t)},j.expandAll=function(a,e){if("boolean"!==layui.type(e))return y.error("expandAll \u7684\u5c55\u5f00\u72b6\u6001\u53c2\u6570\u53ea\u63a5\u6536true/false");var t=P(a);if(t){t.isExpandAll=e;var n=t.getOptions(),i=n.tree,l=n.elem.next(),d=i.customName.isParent,r=i.customName.id,o=i.view.showFlexIconIfNotParent;if(e){e=j.getData(a,!0);if(i["async"].enable){var c=!0;if(layui.each(e,function(e,t){if(t[d]&&!t[X])return!(c=!1)}),!c)return void layui.each(j.getData(a),function(e,t){j.expandNode(a,{index:t[Y],expandFlag:!0,inherit:!0})})}var u=!0;if(layui.each(e,function(e,t){if(t[d]&&!t[z])return!(u=!1)}),u)t.updateStatus(null,function(e){(e[d]||o)&&(e[H]=!0,e[r]!==undefined)&&(t.status.expand[e[r]]=!0)}),l.find('tbody tr[data-level!="0"]').removeClass(F),l.find(".layui-table-tree-flexIcon").html(i.view.flexIconOpen),i.view.showIcon&&l.find(".layui-table-tree-nodeIcon:not(.layui-table-tree-iconCustom,.layui-table-tree-iconLeaf)").html(i.view.iconOpen);else{if(t.updateStatus(null,function(e){(e[d]||o)&&(e[H]=!0,e[z]=!0,e[r]!==undefined)&&(t.status.expand[e[r]]=!0)}),n.initSort&&n.initSort.type&&n.autoSort)return j.sort(a);var s,n=B.getTrHtml(a,e),f={trs:E(n.trs.join("")),trs_fixed:E(n.trs_fixed.join("")),trs_fixed_r:E(n.trs_fixed_r.join(""))};layui.each(e,function(e,t){var a=t[Y].split("-").length-1;s={"data-index":t[Y],"lay-data-index":t[Y],"data-level":a},f.trs.eq(e).attr(s),f.trs_fixed.eq(e).attr(s),f.trs_fixed_r.eq(e).attr(s)}),layui.each(["main","fixed-l","fixed-r"],function(e,t){l.find(".layui-table-"+t+" tbody").html(f[["trs","trs_fixed","trs_fixed_r"][e]])}),t.renderTreeTable(l,0,!1)}}else t.updateStatus(null,function(e){(e[d]||o)&&(e[H]=!1,e[r]!==undefined)&&(t.status.expand[e[r]]=!1)}),l.find('.layui-table-box tbody tr[data-level!="0"]').addClass(F),l.find(".layui-table-tree-flexIcon").html(i.view.flexIconClose),i.view.showIcon&&l.find(".layui-table-tree-nodeIcon:not(.layui-table-tree-iconCustom,.layui-table-tree-iconLeaf)").html(i.view.iconClose);j.resize(a)}},t.prototype.renderTreeTable=function(e,t,a){var n=this,i=n.getOptions(),l=i.elem.next(),d=(l.hasClass(h)||l.addClass(h),i.id),r=i.tree||{},o=(r.data,r.view||{}),c=r.customName||{},u=c.isParent,s=(l.attr("lay-filter"),n),f=((t=t||0)||(l.find(".layui-table-body tr:not([data-level])").attr("data-level",t),layui.each(B.cache[d],function(e,t){l.find('.layui-table-main tbody tr[data-level="0"]:eq('+e+")").attr("lay-data-index",t[Y]),l.find('.layui-table-fixed-l tbody tr[data-level="0"]:eq('+e+")").attr("lay-data-index",t[Y]),l.find('.layui-table-fixed-r tbody tr[data-level="0"]:eq('+e+")").attr("lay-data-index",t[Y])})),null),y=c.name,p=o.indent||14;if(layui.each(e.find('td[data-field="'+y+'"]'),function(e,t){var a,n,i=(t=E(t)).closest("tr"),t=t.children(".layui-table-cell");t.hasClass("layui-table-tree-item")||(n=i.attr("lay-data-index"))&&(i=l.find('tr[lay-data-index="'+n+'"]'),(a=s.getNodeDataByIndex(n))[H]&&a[u]&&((f=f||{})[n]=!0),a[b]&&i.find('input[type="checkbox"][name="layTableCheckbox"]').prop("indeterminate",!0),n=t.html(),(t=i.find('td[data-field="'+y+'"]>div.layui-table-cell')).addClass("layui-table-tree-item"),t.html(['
      ',a[H]?o.flexIconOpen:o.flexIconClose,"
      ",o.showIcon?'
      '+(a[c.icon]||o.icon||(a[u]?a[H]?o.iconOpen:o.iconClose:o.iconLeaf)||"")+"
      ":"",n].join("")).find(".layui-table-tree-flexIcon").on("click",function(e){layui.stope(e),U({trElem:i},null,null,null,!0)}))}),!t&&r.view.expandAllDefault&&n.isExpandAll===undefined)return j.expandAll(d,!0);!1!==a&&f?layui.each(f,function(e,t){e=l.find('tr[lay-data-index="'+e+'"]');e.find(".layui-table-tree-flexIcon").html(o.flexIconOpen),U({trElem:e.first()},!0)}):V("renderTreeTable-"+d,function(){i.hasNumberCol&&g(n),x.render(E('.layui-table-tree[lay-id="'+d+'"]'))},0)()},function(a){var e=a.getOptions(),t=e.elem.next(),n=0,i=t.find(".layui-table-main tbody tr"),l=t.find(".layui-table-fixed-l tbody tr"),d=t.find(".layui-table-fixed-r tbody tr");layui.each(a.treeToFlat(B.cache[e.id]),function(e,t){t.LAY_HIDE||(a.getNodeDataByIndex(t[Y]).LAY_NUM=++n,i.eq(e).find(".laytable-cell-numbers").html(n),l.eq(e).find(".laytable-cell-numbers").html(n),d.eq(e).find(".laytable-cell-numbers").html(n))})}),p=(t.prototype.render=function(e){var t=this;t.tableIns=B["reloadData"===e?"reloadData":"reload"](t.tableIns.config.id,E.extend(!0,{},t.config)),t.config=t.tableIns.config},t.prototype.reload=function(e,t,a){var n=this;e=e||{},delete n.haveInit,layui.each(e,function(e,t){"array"===layui.type(t)&&delete n.config[e]}),d(n.getOptions().id,e,a||!0),n.config=E.extend(t,{},n.config,e),n.render(a)},j.reloadData=function(){var e=E.extend(!0,[],arguments);return e[3]="reloadData",j.reload.apply(null,e)},function(e,a,n,i){var l=[];return layui.each(e,function(e,t){"function"===layui.type(a)?a(t):E.extend(t,a),l.push(E.extend({},t)),i||(l=l.concat(p(t[n],a,n,i)))}),l}),o=(t.prototype.updateStatus=function(e,t,a){var n=this.getOptions(),i=n.tree;return e=e||B.cache[n.id],p(e,t,i.customName.children,a)},t.prototype.getTableData=function(){var e=this.getOptions();return B.cache[e.id]},j.updateStatus=function(e,t,a){var e=P(e),n=e.getOptions();return a=a||(n.url?B.cache[n.id]:n.data),e.updateStatus(a,t)},j.sort=function(e){var t=P(e);t&&t.getOptions().autoSort&&(t.initData(),j.renderData(e))},function(n){var t=n.config.id,i=P(t),a=n.data=j.getNodeDataByIndex(t,n.index),l=a[Y],d=(n.dataIndex=l,n.update);n.update=function(){var e=arguments,t=(E.extend(i.getNodeDataByIndex(l),e[0]),d.apply(this,e)),a=n.config.tree.customName.name;return a in e[0]&&n.tr.find('td[data-field="'+a+'"]').children("div.layui-table-cell").removeClass("layui-table-tree-item"),i.renderTreeTable(n.tr,n.tr.attr("data-level"),!1),t},n.del=function(){j.removeNode(t,a)},n.setRowChecked=function(e){j.setRowChecked(t,{index:a,checked:e})}}),u=(j.updateNode=function(e,a,t){var n,i,l,d,r,o=P(e);o&&((d=o.getOptions()).tree,d=(n=d.elem.next()).find('tr[lay-data-index="'+a+'"]'),i=d.attr("data-index"),l=d.attr("data-level"),t)&&(d=o.getNodeDataByIndex(a,!1,t),r=B.getTrHtml(e,[d]),layui.each(["main","fixed-l","fixed-r"],function(e,t){n.find(".layui-table-"+t+' tbody tr[lay-data-index="'+a+'"]').replaceWith(E(r[["trs","trs_fixed","trs_fixed_r"][e]].join("")).attr({"data-index":i,"lay-data-index":a,"data-level":l}))}),o.renderTreeTable(n.find('tr[lay-data-index="'+a+'"]'),l))},j.removeNode=function(e,t){var a,n,i,l,d,r=P(e);r&&(d=(a=r.getOptions()).tree,n=a.elem.next(),i=[],t=r.getNodeDataByIndex("string"===layui.type(t)?t:t[Y],!1,"delete"),l=r.getNodeDataByIndex(t[s]),r.updateCheckStatus(l),l=r.treeToFlat([t],t[d.customName.pid],t[s]),layui.each(l,function(e,t){i.push('tr[lay-data-index="'+t[Y]+'"]')}),n.find(i.join(",")).remove(),d=r.initData(),layui.each(r.treeToFlat(d),function(e,t){t[m]&&t[m]!==t[Y]&&n.find('tr[lay-data-index="'+t[m]+'"]').attr({"data-index":t[Y],"lay-data-index":t[Y]})}),layui.each(B.cache[e],function(e,t){n.find('tr[data-level="0"][lay-data-index="'+t[Y]+'"]').attr("data-index",e)}),a.hasNumberCol&&g(r),j.resize(e))},j.addNodes=function(e,t){var a=P(e);if(a){var n=a.getOptions(),i=n.tree,l=n.elem.next(),d=B.config.checkName,r=(t=t||{}).parentIndex,o=t.index,c=t.data,t=t.focus,u=(r="number"===layui.type(r)?r.toString():r)?a.getNodeDataByIndex(r):null,o="number"===layui.type(o)?o:-1,c=E.extend(!0,[],layui.isArray(c)?c:[c]);layui.each(c,function(e,t){d in t||!u||(t[d]=u[d])}),a.getTableData();if(u){var s=i.customName.isParent,f=i.customName.children;u[s]=!0;var y=(y=u[f])?(p=y.splice(-1===o?y.length:o),u[f]=y.concat(c,p)):u[f]=c,f=(a.updateStatus(y,function(e){(e[s]||i.view.showFlexIconIfNotParent)&&(e[z]=!1)}),a.treeToFlat(y));l.find(f.map(function(e){return'tr[lay-data-index="'+e[Y]+'"]'}).join(",")).remove(),a.initData(),u[z]=!1,u[X]="local",U({trElem:l.find('tr[lay-data-index="'+r+'"]')},!0)}else{var p=B.cache[e].splice(-1===o?B.cache[e].length:o);if(B.cache[e]=B.cache[e].concat(c,p),n.url||(n.page?(y=n.page,n.data.splice.apply(n.data,[y.limit*(y.curr-1),y.limit].concat(B.cache[e]))):n.data=B.cache[e]),a.initData(),l.find(".layui-none").length)return B.renderData(e),c;var x,f=B.getTrHtml(e,c),h={trs:E(f.trs.join("")),trs_fixed:E(f.trs_fixed.join("")),trs_fixed_r:E(f.trs_fixed_r.join(""))},r=(layui.each(c,function(e,t){x={"data-index":t[Y],"lay-data-index":t[Y],"data-level":"0"},h.trs.eq(e).attr(x),h.trs_fixed.eq(e).attr(x),h.trs_fixed_r.eq(e).attr(x)}),parseInt(c[0][Y])-1),y=l.find(L),n=l.find(q),f=l.find(R);-1==r?(y.find('tr[data-level="0"][data-index="0"]').before(h.trs),n.find('tr[data-level="0"][data-index="0"]').before(h.trs_fixed),f.find('tr[data-level="0"][data-index="0"]').before(h.trs_fixed_r)):-1===o?(y.find("tbody").append(h.trs),n.find("tbody").append(h.trs_fixed),f.find("tbody").append(h.trs_fixed_r)):(r=p[0][m],y.find('tr[data-level="0"][data-index="'+r+'"]').before(h.trs),n.find('tr[data-level="0"][data-index="'+r+'"]').before(h.trs_fixed),f.find('tr[data-level="0"][data-index="'+r+'"]').before(h.trs_fixed_r)),layui.each(B.cache[e],function(e,t){l.find('tr[data-level="0"][lay-data-index="'+t[Y]+'"]').attr("data-index",e)}),a.renderTreeTable(l.find(c.map(function(e,t,a){return'tr[lay-data-index="'+e[Y]+'"]'}).join(",")))}return a.updateCheckStatus(u),j.resize(e),t&&l.find(L).find('tr[lay-data-index="'+c[0][Y]+'"]').get(0).scrollIntoViewIfNeeded(),c}},j.checkStatus=function(e,n){var i,t,a,l=P(e);if(l)return l=l.getOptions().tree,i=B.config.checkName,t=j.getData(e,!0).filter(function(e,t,a){return e[i]||n&&e[b]}),a=!0,layui.each("all"===l.data.cascade?B.cache[e]:j.getData(e,!0),function(e,t){if(!t[i])return!(a=!1)}),{data:t,isAll:a}},j.on("sort",function(e){var e=e.config,t=e.elem.next(),e=e.id;t.hasClass(h)&&j.sort(e)}),j.on("row",function(e){e.config.elem.next().hasClass(h)&&o(e)}),j.on("rowDouble",function(e){var t=e.config,a=t.elem.next();t.id;a.hasClass(h)&&(o(e),(t.tree||{}).view.dblClickExpand)&&U({trElem:e.tr.first()},null,null,null,!0)}),j.on("rowContextmenu",function(e){var t=e.config,a=t.elem.next();t.id;a.hasClass(h)&&o(e)}),j.on("tool",function(e){var t=e.config,a=t.elem.next();t.id;a.hasClass(h)&&o(e)}),j.on("edit",function(e){var t=e.config,a=t.elem.next();t.id;a.hasClass(h)&&(o(e),e.field===t.tree.customName.name)&&((a={})[e.field]=e.value,e.update(a))}),j.on("radio",function(e){var t=e.config,a=t.elem.next(),t=t.id;a.hasClass(h)&&(a=P(t),o(e),u.call(a,e.tr,e.checked))}),t.prototype.setRowCheckedClass=function(e,t){var a=this.getOptions(),n=(e.data("index"),a.elem.next());e[t?"addClass":"removeClass"](l),e.each(function(){var e=E(this).data("index");n.find('.layui-table-fixed-r tbody tr[data-index="'+e+'"]')[t?"addClass":"removeClass"](l)})},t.prototype.updateCheckStatus=function(e,t){var a,n,i,l,d,r,o,c=this,u=c.getOptions();return!!u.hasChecboxCol&&(a=u.tree,n=u.id,i=u.elem.next(),l=B.config.checkName,"all"!==(d=a.data.cascade)&&"parent"!==d||!e||(d=c.updateParentCheckStatus(e,"boolean"===layui.type(t)?t:null),layui.each(d,function(e,t){var a=i.find('tr[lay-data-index="'+t[Y]+'"] input[name="layTableCheckbox"]:not(:disabled)'),n=t[l];c.setRowCheckedClass(a.closest("tr"),n),x.render(a.prop({checked:n,indeterminate:t[b]}))})),o=!(r=!0),e=(e="all"===a.data.cascade?B.cache[n]:j.getData(n,!0)).filter(function(e){return!e[u.disabledName]}),layui.each(e,function(e,t){if((t[l]||t[b])&&(o=!0),t[l]||(r=!1),o&&!r)return!0}),o=o&&!r,x.render(i.find('input[name="layTableCheckbox"][lay-filter="layTableAllChoose"]').prop({checked:r,indeterminate:o})),r)},t.prototype.updateParentCheckStatus=function(a,n){var i,e=this.getOptions(),t=e.tree,e=e.id,l=B.config.checkName,t=t.customName.children,d=[];return!(a[b]=!1)===n?a[t].length?layui.each(a[t],function(e,t){if(!t[l])return n=!1,a[b]=!0}):n=!1:!1===n?layui.each(a[t],function(e,t){if(t[l]||t[b])return a[b]=!0}):(n=!1,i=0,layui.each(a[t],function(e,t){t[l]&&i++}),n=a[t].length?a[t].length===i:a[l],a[b]=!n&&0')),n=(e.tree(a),i.elem=p(i.elem));if(n[0]){if(e.key=i.id||e.index,e.elem=a,e.elemNone=p('
      '+i.text.none+"
      "),n.html(e.elem),0==e.elem.find(".layui-tree-set").length)return e.elem.append(e.elemNone);i.showCheckbox&&e.renderForm("checkbox"),e.elem.find(".layui-tree-set").each(function(){var e=p(this);e.parent(".layui-tree-pack")[0]||e.addClass("layui-tree-setHide"),!e.next()[0]&&e.parents(".layui-tree-pack").eq(1).hasClass("layui-tree-lineExtend")&&e.addClass(T),e.next()[0]||e.parents(".layui-tree-set").eq(0).next()[0]||e.addClass(T)}),e.events()}},l.prototype.renderForm=function(e){i.render(e,"LAY-tree-"+this.index)},l.prototype.tree=function(r,e){var d=this,s=d.config,o=s.customName,e=e||s.data;layui.each(e,function(e,i){var a,n,t=i[o.children]&&0"),c=p(['
      ','
      ','
      ',s.showLine?t?'':'':'',s.showCheckbox?'':"",s.isJump&&i.href?''+(i[o.title]||i.label||s.text.defaultNodeName)+"":''+(i[o.title]||i.label||s.text.defaultNodeName)+"","
      ",s.edit?(a={add:'',update:'',del:''},n=['
      '],!0===s.edit&&(s.edit=["update","del"]),"object"==typeof s.edit?(layui.each(s.edit,function(e,i){n.push(a[i]||"")}),n.join("")+"
      "):void 0):"","
      "].join(""));t&&(c.append(l),d.tree(l,i[o.children])),r.append(c),c.prev("."+k)[0]&&c.prev().children(".layui-tree-pack").addClass("layui-tree-showLine"),t||c.parent(".layui-tree-pack").addClass("layui-tree-lineExtend"),d.spread(c,i),s.showCheckbox&&(i.checked&&d.checkids.push(i[o.id]),d.checkClick(c,i)),s.edit&&d.operate(c,i)})},l.prototype.spread=function(n,t){var l=this,c=l.config,e=n.children("."+b),i=e.children("."+g),a=i.find('input[same="layuiTreeCheck"]'),r=e.find("."+C),e=e.find("."+w),d=c.onlyIconControl?r:i,s="";d.on("click",function(e){var i=n.children("."+N),a=(d.children(".layui-icon")[0]?d:d.find(".layui-tree-icon")).children(".layui-icon");i[0]?n.hasClass(F)?(n.removeClass(F),i.slideUp(200),a.removeClass(x).addClass(v),l.updateFieldValue(t,"spread",!1)):(n.addClass(F),i.slideDown(200),a.addClass(x).removeClass(v),l.updateFieldValue(t,"spread",!0),c.accordion&&((i=n.siblings("."+k)).removeClass(F),i.children("."+N).slideUp(200),i.find(".layui-tree-icon").children(".layui-icon").removeClass(x).addClass(v))):s="normal"}),e.on("click",function(){p(this).hasClass(u)||(s=n.hasClass(F)?c.onlyIconControl?"open":"close":c.onlyIconControl?"close":"open",a[0]&&l.updateFieldValue(t,"checked",a.prop("checked")),c.click&&c.click({elem:n,state:s,data:t}))})},l.prototype.updateFieldValue=function(e,i,a){i in e&&(e[i]=a)},l.prototype.setCheckbox=function(e,i,a){var t,n=this,l=n.config.customName,c=a.prop("checked");a.prop("disabled")||("object"!=typeof i[l.children]&&!e.find("."+N)[0]||e.find("."+N).find('input[same="layuiTreeCheck"]').each(function(e){this.disabled||((e=i[l.children][e])&&n.updateFieldValue(e,"checked",c),n.updateFieldValue(this,"checked",c))}),(t=function(e){var i,a,n;e.parents("."+k)[0]&&(a=(e=e.parent("."+N)).parent(),n=e.prev().find('input[same="layuiTreeCheck"]'),c?n.prop("checked",c):(e.find('input[same="layuiTreeCheck"]').each(function(){this.checked&&(i=!0)}),i||n.prop("checked",!1)),t(a))})(e),n.renderForm("checkbox"))},l.prototype.checkClick=function(a,n){var t=this,l=t.config;a.children("."+b).children("."+g).on("click",'input[same="layuiTreeCheck"]+',function(e){layui.stope(e);var e=p(this).prev(),i=e.prop("checked");e.prop("disabled")||(t.setCheckbox(a,n,e),t.updateFieldValue(n,"checked",i),l.oncheck&&l.oncheck({elem:a,checked:i,data:n}))})},l.prototype.operate=function(r,d){var s=this,o=s.config,u=o.customName,e=r.children("."+b),h=e.children("."+g);e.children(".layui-tree-btnGroup").on("click",".layui-icon",function(e){layui.stope(e);var i,e=p(this).data("type"),n=r.children("."+N),t={data:d,type:e,elem:r};if("add"==e){n[0]||(o.showLine?(h.find("."+C).addClass("layui-tree-icon"),h.find("."+C).children(".layui-icon").addClass(v).removeClass("layui-icon-file")):h.find(".layui-tree-iconArrow").removeClass(m),r.append('
      '));var a,l=o.operate&&o.operate(t),c={};if(c[u.title]=o.text.defaultNodeName,c[u.id]=l,s.tree(r.children("."+N),[c]),o.showLine&&(n[0]?(n.hasClass(S)||n.addClass(S),r.find("."+N).each(function(){p(this).children("."+k).last().addClass(T)}),(n.children("."+k).last().prev().hasClass(T)?n.children("."+k).last().prev():n.children("."+k).last()).removeClass(T),!r.parent("."+N)[0]&&r.next()[0]&&n.children("."+k).last().removeClass(T)):(l=r.siblings("."+k),a=1,c=r.parent("."+N),layui.each(l,function(e,i){p(i).children("."+N)[0]||(a=0)}),(1==a?(l.children("."+N).addClass(L),l.children("."+N).children("."+k).removeClass(T),r.children("."+N).addClass(L),c.removeClass(S),c.children("."+k).last().children("."+N).children("."+k).last()):r.children("."+N).children("."+k)).addClass(T))),!o.showCheckbox)return;h.find('input[same="layuiTreeCheck"]')[0].checked&&(r.children("."+N).children("."+k).last().find('input[same="layuiTreeCheck"]')[0].checked=!0),s.renderForm("checkbox")}else"update"==e?(l=h.children("."+w).html(),h.children("."+w).html(""),h.append(''),h.children(".layui-tree-editInput").val(f.unescape(l)).focus(),i=function(e){var i=e.val().trim()||o.text.defaultNodeName;e.remove(),h.children("."+w).html(i),t.data[u.title]=i,o.operate&&o.operate(t)},h.children(".layui-tree-editInput").blur(function(){i(p(this))}),h.children(".layui-tree-editInput").on("keydown",function(e){13===e.keyCode&&(e.preventDefault(),i(p(this)))})):y.confirm('\u786e\u8ba4\u5220\u9664\u8be5\u8282\u70b9 "'+(d[u.title]||"")+'" \u5417\uff1f',function(e){var l,a,i;o.operate&&o.operate(t),t.status="remove",y.close(e),r.prev("."+k)[0]||r.next("."+k)[0]||r.parent("."+N)[0]?(r.siblings("."+k).children("."+b)[0]?(o.showCheckbox&&(l=function(e){var i,a,n,t;e.parents("."+k)[0]&&(i=e.siblings("."+k).children("."+b),a=(e=e.parent("."+N).prev()).find('input[same="layuiTreeCheck"]')[0],n=1,(t=0)==a.checked)&&(i.each(function(e,i){i=p(i).find('input[same="layuiTreeCheck"]')[0];0!=i.checked||i.disabled||(n=0),i.disabled||(t=1)}),1==n)&&1==t&&(a.checked=!0,s.renderForm("checkbox"),l(e.parent("."+k)))})(r),o.showLine&&(e=r.siblings("."+k),a=1,i=r.parent("."+N),layui.each(e,function(e,i){p(i).children("."+N)[0]||(a=0)}),1==a?(n[0]||(i.removeClass(S),e.children("."+N).addClass(L),e.children("."+N).children("."+k).removeClass(T)),(r.next()[0]?i.children("."+k).last():r.prev()).children("."+N).children("."+k).last().addClass(T),r.next()[0]||r.parents("."+k)[1]||r.parents("."+k).eq(0).next()[0]||r.prev("."+k).addClass(T)):!r.next()[0]&&r.hasClass(T)&&r.prev().addClass(T))):(e=r.parent("."+N).prev(),o.showLine?(e.find("."+C).removeClass("layui-tree-icon"),e.find("."+C).children(".layui-icon").removeClass(x).addClass("layui-icon-file"),(i=e.parents("."+N).eq(0)).addClass(S),i.children("."+k).each(function(){p(this).children("."+N).children("."+k).last().addClass(T)})):e.find(".layui-tree-iconArrow").addClass(m),r.parents("."+k).eq(0).removeClass(F),r.parent("."+N).remove()),r.remove()):(r.remove(),s.elem.append(s.elemNone))})})},l.prototype.events=function(){var i=this,t=i.config;i.elem.find(".layui-tree-checkedFirst");i.setChecked(i.checkids),i.elem.find(".layui-tree-search").on("keyup",function(){var e=p(this),a=e.val(),e=e.nextAll(),n=[];e.find("."+w).each(function(){var i,e=p(this).parents("."+b);-1!=p(this).html().indexOf(a)&&(n.push(p(this).parent()),(i=function(e){e.addClass("layui-tree-searchShow"),e.parent("."+N)[0]&&i(e.parent("."+N).parent("."+k))})(e.parent("."+k)))}),e.find("."+b).each(function(){var e=p(this).parent("."+k);e.hasClass("layui-tree-searchShow")||e.addClass(m)}),0==e.find(".layui-tree-searchShow").length&&i.elem.append(i.elemNone),t.onsearch&&t.onsearch({elem:n})}),i.elem.find(".layui-tree-search").on("keydown",function(){p(this).nextAll().find("."+b).each(function(){p(this).parent("."+k).removeClass("layui-tree-searchShow "+m)}),p(".layui-tree-emptyText")[0]&&p(".layui-tree-emptyText").remove()})},l.prototype.getChecked=function(){var t=this,e=t.config,l=e.customName,i=[],a=[],c=(t.elem.find(".layui-form-checked").each(function(){i.push(p(this).prev()[0].value)}),function(e,n){layui.each(e,function(e,a){layui.each(i,function(e,i){if(a[l.id]==i)return t.updateFieldValue(a,"checked",!0),delete(i=p.extend({},a))[l.children],n.push(i),a[l.children]&&(i[l.children]=[],c(a[l.children],i[l.children])),!0})})});return c(p.extend({},e.data),a),a},l.prototype.setChecked=function(l){this.config;this.elem.find("."+k).each(function(e,i){var a=p(this).data("id"),n=p(i).children("."+b).find('input[same="layuiTreeCheck"]'),t=n.next();if("number"==typeof l){if(a.toString()==l.toString())return n[0].checked||t.click(),!1}else"object"==typeof l&&layui.each(l,function(e,i){if(i.toString()==a.toString()&&!n[0].checked)return t.click(),!0})})},n.that={},n.config={},t.reload=function(e,i){e=n.that[e];return e.reload(i),n.call(e)},t.getChecked=function(e){return n.that[e].getChecked()},t.setChecked=function(e,i){return n.that[e].setChecked(i)},t.render=function(e){e=new l(e);return n.call(e)},e(a,t)});layui.define(["laytpl","form"],function(e){"use strict";var s=layui.$,n=layui.laytpl,t=layui.form,a="transfer",i={config:{},index:layui[a]?layui[a].index+1e4:0,set:function(e){var t=this;return t.config=s.extend({},t.config,e),t},on:function(e,t){return layui.onevent.call(this,a,e,t)}},l=function(){var t=this,e=t.config,a=e.id||t.index;return l.that[a]=t,{config:l.config[a]=e,reload:function(e){t.reload.call(t,e)},getData:function(){return t.getData.call(t)}}},d="layui-hide",h="layui-btn-disabled",r="layui-none",c="layui-transfer-box",u="layui-transfer-header",o="layui-transfer-search",f="layui-transfer-data",y=function(e){return['
      ','
      ','","
      ","{{# if(d.data.showSearch){ }}",'","{{# } }}",'
        ',"
        "].join("")},p=['
        ',y({index:0,checkAllName:"layTransferLeftCheckAll"}),'
        ','",'","
        ",y({index:1,checkAllName:"layTransferRightCheckAll"}),"
        "].join(""),v=function(e){var t=this;t.index=++i.index,t.config=s.extend({},t.config,i.config,e),t.render()};v.prototype.config={title:["\u5217\u8868\u4e00","\u5217\u8868\u4e8c"],width:200,height:360,data:[],value:[],showSearch:!1,id:"",text:{none:"\u65e0\u6570\u636e",searchNone:"\u65e0\u5339\u914d\u6570\u636e"}},v.prototype.reload=function(e){var t=this;t.config=s.extend({},t.config,e),t.render()},v.prototype.render=function(){var e=this,t=e.config,a=e.elem=s(n(p,{open:"{{",close:"}}"}).render({data:t,index:e.index})),i=t.elem=s(t.elem);i[0]&&(t.data=t.data||[],t.value=t.value||[],t.id="id"in t?t.id:elem.attr("id")||e.index,e.key=t.id,i.html(e.elem),e.layBox=e.elem.find("."+c),e.layHeader=e.elem.find("."+u),e.laySearch=e.elem.find("."+o),e.layData=a.find("."+f),e.layBtn=a.find(".layui-transfer-active .layui-btn"),e.layBox.css({width:t.width,height:t.height}),e.layData.css({height:(i=t.height-e.layHeader.outerHeight(),t.showSearch&&(i-=e.laySearch.outerHeight()),i-2)}),e.renderData(),e.events())},v.prototype.renderData=function(){var e=this,t=e.config,l=[{checkName:"layTransferLeftCheck",views:[]},{checkName:"layTransferRightCheck",views:[]}];e.parseData(function(a){var i=a.selected?1:0,n=["
      • ",'',"
      • "].join("");i?layui.each(t.value,function(e,t){t==a.value&&a.selected&&(l[i].views[e]=n)}):l[i].views.push(n),delete a.selected}),e.layData.eq(0).html(l[0].views.join("")),e.layData.eq(1).html(l[1].views.join("")),e.renderCheckBtn()},v.prototype.renderForm=function(e){t.render(e,"LAY-transfer-"+this.index)},v.prototype.renderCheckBtn=function(r){var c=this,o=c.config;r=r||{},c.layBox.each(function(e){var t=s(this),a=t.find("."+f),t=t.find("."+u).find('input[type="checkbox"]'),i=a.find('input[type="checkbox"]'),n=0,l=!1;i.each(function(){var e=s(this).data("hide");(this.checked||this.disabled||e)&&n++,this.checked&&!e&&(l=!0)}),t.prop("checked",l&&n===i.length),c.layBtn.eq(e)[l?"removeClass":"addClass"](h),r.stopNone||(i=a.children("li:not(."+d+")").length,c.noneView(a,i?"":o.text.none))}),c.renderForm("checkbox")},v.prototype.noneView=function(e,t){var a=s('

        '+(t||"")+"

        ");e.find("."+r)[0]&&e.find("."+r).remove(),t.replace(/\s/g,"")&&e.append(a)},v.prototype.setValue=function(){var e=this.config,t=[];return this.layBox.eq(1).find("."+f+' input[type="checkbox"]').each(function(){s(this).data("hide")||t.push(this.value)}),e.value=t,this},v.prototype.parseData=function(t){var i=this.config,n=[];return layui.each(i.data,function(e,a){a=("function"==typeof i.parseData?i.parseData(a):a)||a,n.push(a=s.extend({},a)),layui.each(i.value,function(e,t){t==a.value&&(a.selected=!0)}),t&&t(a)}),i.data=n,this},v.prototype.getData=function(e){var t=this.config,i=[];return this.setValue(),layui.each(e||t.value,function(e,a){layui.each(t.data,function(e,t){delete t.selected,a==t.value&&i.push(t)})}),i},v.prototype.transfer=function(e,t){var a,i=this,n=i.config,l=i.layBox.eq(e),r=[],t=(t?((a=(t=t).find('input[type="checkbox"]'))[0].checked=!1,l.siblings("."+c).find("."+f).append(t.clone()),t.remove(),r.push(a[0].value),i.setValue()):l.each(function(e){s(this).find("."+f).children("li").each(function(){var e=s(this),t=e.find('input[type="checkbox"]'),a=t.data("hide");t[0].checked&&!a&&(t[0].checked=!1,l.siblings("."+c).find("."+f).append(e.clone()),e.remove(),r.push(t[0].value)),i.setValue()})}),i.renderCheckBtn(),l.siblings("."+c).find("."+o+" input"));""!==t.val()&&t.trigger("keyup"),n.onchange&&n.onchange(i.getData(r),e)},v.prototype.events=function(){var n=this,l=n.config;n.elem.on("click",'input[lay-filter="layTransferCheckbox"]+',function(){var e=s(this).prev(),t=e[0].checked,a=e.parents("."+c).eq(0).find("."+f);e[0].disabled||("all"===e.attr("lay-type")&&a.find('input[type="checkbox"]').each(function(){this.disabled||(this.checked=t)}),setTimeout(function(){n.renderCheckBtn({stopNone:!0})},0))}),n.elem.on("dblclick","."+f+">li",function(e){var t=s(this),a=t.children('input[type="checkbox"]'),i=t.parent().parent();a[0].disabled||n.transfer(i.data("index"),t)}),n.layBtn.on("click",function(){var e=s(this),t=e.data("index");e.hasClass(h)||n.transfer(t)}),n.laySearch.find("input").on("keyup",function(){var i=this.value,e=s(this).parents("."+o).eq(0).siblings("."+f),t=e.children("li"),t=(t.each(function(){var e=s(this),t=e.find('input[type="checkbox"]'),a=t[0].title,a=("cs"!==l.showSearch&&(a=a.toLowerCase(),i=i.toLowerCase()),-1!==a.indexOf(i));e[a?"removeClass":"addClass"](d),t.data("hide",!a)}),n.renderCheckBtn(),t.length===e.children("li."+d).length);n.noneView(e,t?l.text.searchNone:"")})},l.that={},l.config={},i.reload=function(e,t){e=l.that[e];return e.reload(t),l.call(e)},i.getData=function(e){return l.that[e].getData()},i.render=function(e){e=new v(e);return l.call(e)},e(a,i)});layui.define(["jquery","lay"],function(e){"use strict";var a=layui.$,l=layui.lay,t=(layui.hint(),layui.device(),{config:{},set:function(e){var i=this;return i.config=a.extend({},i.config,e),i},on:function(e,i){return layui.onevent.call(this,d,e,i)}}),d="carousel",r="layui-this",s="layui-carousel-left",u="layui-carousel-right",c="layui-carousel-prev",h="layui-carousel-next",o="layui-carousel-arrow",m="layui-carousel-ind",i=function(e){var i=this;i.config=a.extend({},i.config,t.config,e),i.render()};i.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},i.prototype.render=function(){var e=this,i=e.config,n=a(i.elem);if(1*[carousel-item]>*"),i.index<0&&(i.index=0),i.index>=e.elemItem.length&&(i.index=e.elemItem.length-1),i.interval<800&&(i.interval=800),i.full?i.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):i.elem.css({width:i.width,height:i.height}),i.elem.attr("lay-anim",i.anim),e.elemItem.eq(i.index).addClass(r),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},i.prototype.reload=function(e){var i=this;clearInterval(i.timer),i.config=a.extend({},i.config,e),i.render()},i.prototype.prevIndex=function(){var e=this.config.index-1;return e=e<0?this.elemItem.length-1:e},i.prototype.nextIndex=function(){var e=this.config.index+1;return e=e>=this.elemItem.length?0:e},i.prototype.addIndex=function(e){var i=this.config;i.index=i.index+(e=e||1),i.index>=this.elemItem.length&&(i.index=0)},i.prototype.subIndex=function(e){var i=this.config;i.index=i.index-(e=e||1),i.index<0&&(i.index=this.elemItem.length-1)},i.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(clearInterval(e.timer),e.timer=setInterval(function(){e.slide()},i.interval))},i.prototype.arrow=function(){var i=this,e=i.config,n=a(['",'"].join(""));e.elem.attr("lay-arrow",e.arrow),e.elem.find("."+o)[0]&&e.elem.find("."+o).remove(),e.elem.append(n),n.on("click",function(){var e=a(this).attr("lay-type");i.slide(e)})},i.prototype["goto"]=function(e){var i=this,n=i.config;e>n.index?i.slide("add",e-n.index):e
          ',(i=[],layui.each(e.elemItem,function(e){i.push("")}),i.join("")),"
        "].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+m)[0]&&n.elem.find("."+m).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-t.height()/2),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){e["goto"](a(this).index())})},i.prototype.slide=function(e,i){var n=this,t=n.elemItem,a=n.config,o=a.index,l=a.elem.attr("lay-filter");n.haveSlide||("sub"===e?(n.subIndex(i),t.eq(a.index).addClass(c),setTimeout(function(){t.eq(o).addClass(u),t.eq(a.index).addClass(u)},50)):(n.addIndex(i),t.eq(a.index).addClass(h),setTimeout(function(){t.eq(o).addClass(s),t.eq(a.index).addClass(s)},50)),setTimeout(function(){t.removeClass(r+" "+c+" "+h+" "+s+" "+u),t.eq(a.index).addClass(r),n.haveSlide=!1},350),n.elemInd.find("li").eq(a.index).addClass(r).siblings().removeClass(r),n.haveSlide=!0,e={index:a.index,prevIndex:o,item:t.eq(a.index)},"function"==typeof a.change&&a.change(e),layui.event.call(this,d,"change("+l+")",e))},i.prototype.events=function(){var t,a,o=this,e=o.config;e.elem.data("haveEvents")||(e.elem.on("mouseenter touchstart",function(){"always"!==o.config.autoplay&&clearInterval(o.timer)}).on("mouseleave touchend",function(){"always"!==o.config.autoplay&&o.autoplay()}),t=e.elem,a="updown"===e.anim,l.touchSwipe(t,{onTouchEnd:function(e,i){var n=Date.now()-i.timeStart,i=a?i.distanceY:i.distanceX;(.25t[a?"height":"width"]()/3)&&o.slide(0a.length&&(a.value=a.length),parseInt(a.value)===a.value||a.half||(a.value=Math.ceil(a.value)-a.value<.5?Math.ceil(a.value):Math.floor(a.value)),'
          "),n=1;n<=a.length;n++){var o='
        • ";a.half&&parseInt(a.value)!==a.value&&n==Math.ceil(a.value)?i=i+'
        • ":i+=o}i+="
        "+(a.text?''+a.value+"\u661f":"")+"";var l=a.elem,s=l.next(".layui-rate");s[0]&&s.remove(),e.elemTemp=u(i),a.span=e.elemTemp.next("span"),a.setText&&a.setText(a.value),l.html(e.elemTemp),l.addClass("layui-inline"),a.readonly||e.action()},a.prototype.setvalue=function(e){this.config.value=e,this.render()},a.prototype.action=function(){var n=this.config,t=this.elemTemp,i=t.find("i").width(),l=t.children("li");l.each(function(e){var a=e+1,l=u(this);l.on("click",function(e){n.value=a,n.half&&e.pageX-u(this).offset().left<=i/2&&(n.value=n.value-.5),n.text&&t.next("span").text(n.value+"\u661f"),n.choose&&n.choose(n.value),n.setText&&n.setText(n.value)}),l.on("mousemove",function(e){t.find("i").each(function(){u(this).addClass(h).removeClass(s)}),t.find("i:lt("+a+")").each(function(){u(this).addClass(f).removeClass(v)}),n.half&&e.pageX-u(this).offset().left<=i/2&&l.children("i").addClass(o).removeClass(f)}),l.on("mouseleave",function(){t.find("i").each(function(){u(this).addClass(h).removeClass(s)}),t.find("i:lt("+Math.floor(n.value)+")").each(function(){u(this).addClass(f).removeClass(v)}),n.half&&parseInt(n.value)!==n.value&&t.children("li:eq("+Math.floor(n.value)+")").children("i").addClass(o).removeClass("layui-icon-rate-solid layui-icon-rate")})}),r.touchSwipe(t,{onTouchMove:function(e,a){var i;Date.now()-a.timeStart<=200||(a=e.touches[0].pageX,e=t.width()/n.length,a=(a-t.offset().left)/e,(i=(i=(e=a%1)<=.5&&n.half?.5+(a-e):Math.ceil(a))>n.length?n.length:i)<0&&(i=0),l.each(function(e){var a=u(this).children("i"),l=Math.ceil(i)-e==1,t=Math.ceil(i)>e,e=i-e==.5;t?(a.addClass(f).removeClass(v),n.half&&e&&a.addClass(o).removeClass(f)):a.addClass(h).removeClass(s),a.toggleClass("layui-rate-hover",l)}),n.value=i,n.setText&&n.setText(n.value))},onTouchEnd:function(e,a){Date.now()-a.timeStart<=200||(t.find("i").removeClass("layui-rate-hover"),n.choose&&n.choose(n.value),n.setText&&n.setText(n.value))}})},a.prototype.events=function(){},c.render=function(e){e=new a(e);return function(){var a=this;return{setvalue:function(e){a.setvalue.call(a,e)},config:a.config}}.call(e)},e(l,c)});layui.define("jquery",function(l){"use strict";var g=layui.$,e=function(l){};e.prototype.load=function(l){var t,i,o,n,e,r,a,c,m,s,u,f,y,d=this,p=0,h=g((l=l||{}).elem);if(h[0])return e=g(l.scrollElem||document),r=l.mb||50,a=!("isAuto"in l)||l.isAuto,c=l.end||"\u6ca1\u6709\u66f4\u591a\u4e86",m=l.scrollElem&&l.scrollElem!==document,u=g('"),h.find(".layui-flow-more")[0]||h.append(u),f=function(l,e){l=g(l),u.before(l),(e=0==e||null)?u.html(c):u.find("a").html(s),i=e,t=null,o&&o()},(y=function(){t=!0,u.find("a").html(''),"function"==typeof l.done&&l.done(++p,f)})(),u.find("a").on("click",function(){g(this);i||t||y()}),l.isLazyimg&&(o=d.lazyimg({elem:l.elem+" img",scrollElem:l.scrollElem})),a&&e.on("scroll",function(){var e=g(this),o=e.scrollTop();n&&clearTimeout(n),!i&&h.width()&&(n=setTimeout(function(){var l=(m?e:g(window)).height();(m?e.prop("scrollHeight"):document.documentElement.scrollHeight)-o-l<=r&&(t||y())},100))}),d},e.prototype.lazyimg=function(l){var e,c=this,m=0,s=g((l=l||{}).scrollElem||document),u=l.elem||"img",f=l.scrollElem&&l.scrollElem!==document,y=function(e,l){var o,t=s.scrollTop(),l=t+l,i=f?e.offset().top-s.offset().top+t:e.offset().top;t<=i&&i<=l&&e.attr("lay-src")&&(o=e.attr("lay-src"),layui.img(o,function(){var l=c.lazyimg.elem.eq(m);e.attr("src",o).removeAttr("lay-src"),l[0]&&n(l),m++},function(){c.lazyimg.elem.eq(m);e.removeAttr("lay-src")}))},n=function(l,e){var o=(f?e||s:g(window)).height(),t=s.scrollTop(),i=t+o;if(c.lazyimg.elem=g(u),l)y(l,o);else for(var n=0;n"),preview:"Preview"},wordWrap:!0,lang:"text",highlighter:!1,langMarker:!1},W=layui.code?layui.code.index+1e4:0,R=function(e){return String(e).replace(/\s+$/,"").replace(/^\n|\n$/,"")};e("code",function(l,e){var o,i,t,a,n,d,c,s,r,u,y,p,E,f,h,v,m,L,_,M,C,g={config:l=x.extend(!0,{},T,l),reload:function(e){layui.code(this.updateOptions(e))},updateOptions:function(e){return delete(e=e||{}).elem,x.extend(!0,l,e)},reloadCode:function(e){layui.code(this.updateOptions(e),"reloadCode")}},w=x(l.elem);return 1',l.ln?['
        ',D.digit(t+1)+".","
        "].join(""):"",'
        ',e||" ","
        ",""].join("")})}},a=l.code,n=function(e){return"function"==typeof l.codeParse?l.codeParse(e,l):e},"reloadCode"===e?o.children(".layui-code-wrap").html(w(n(a)).html):(d=layui.code.index=++W,o.attr("lay-code-index",d),(M=A.CDDE_DATA_CLASS in o.data())&&o.attr("class",o.data(A.CDDE_DATA_CLASS)||""),M||o.data(A.CDDE_DATA_CLASS,o.attr("class")),c={copy:{className:"file-b",title:["\u590d\u5236\u4ee3\u7801"],event:function(e){var t=D.unescape(n(l.code));lay.clipboard.writeText({text:t,done:function(){N.msg("\u5df2\u590d\u5236",{icon:1})},error:function(){N.msg("\u590d\u5236\u5931\u8d25",{icon:2})}}),"function"==typeof l.onCopy&&l.onCopy(t)}}},function b(){var e=o.parent("."+A.ELEM_PREVIEW),t=e.children("."+A.ELEM_TAB),a=e.children("."+A.ELEM_ITEM+"-preview");return t.remove(),a.remove(),e[0]&&o.unwrap(),b}(),l.preview&&(M="LAY-CODE-DF-"+d,f=l.layout||["code","preview"],s="iframe"===l.preview,E=x('
        '),C=x('
        '),r=x('
        '),_=x('
        '),u=x('
        '),l.id&&E.attr("id",l.id),E.addClass(l.className),C.attr("lay-filter",M),layui.each(f,function(e,t){var a=x('
      • ');0===e&&a.addClass("layui-this"),a.html(l.text[t]),r.append(a)}),x.extend(c,{full:{className:"screen-full",title:["\u6700\u5927\u5316\u663e\u793a","\u8fd8\u539f\u663e\u793a"],event:function(e){var e=e.elem,t=e.closest("."+A.ELEM_PREVIEW),a="layui-icon-"+this.className,i="layui-icon-screen-restore",l=this.title,o=x("html,body"),n="layui-scrollbar-hide";e.hasClass(a)?(t.addClass(A.ELEM_FULL),e.removeClass(a).addClass(i),e.attr("title",l[1]),o.addClass(n)):(t.removeClass(A.ELEM_FULL),e.removeClass(i).addClass(a),e.attr("title",l[0]),o.removeClass(n))}},window:{className:"release",title:["\u5728\u65b0\u7a97\u53e3\u9884\u89c8"],event:function(e){D.openWin({content:n(l.code)})}}}),l.copy&&("array"===layui.type(l.tools)?-1===l.tools.indexOf("copy")&&l.tools.unshift("copy"):l.tools=["copy"]),u.on("click",">i",function(){var e=x(this),t=e.data("type"),e={elem:e,type:t,options:l,rawCode:l.code,finalCode:D.unescape(n(l.code))};c[t]&&"function"==typeof c[t].event&&c[t].event(e),"function"==typeof l.toolsEvent&&l.toolsEvent(e)}),l.addTools&&l.tools&&(l.tools=[].concat(l.tools,l.addTools)),layui.each(l.tools,function(e,t){var a="object"==typeof t,i=a?t:c[t]||{className:t,title:[t]},l=i.className||i.type,o=i.title||[""],a=a?i.type||l:t;a&&(c[a]||((t={})[a]=i,x.extend(c,t)),u.append(''))}),o.addClass(A.ELEM_ITEM).wrap(E),C.append(r),l.tools&&C.append(u),o.before(C),s&&_.html(''),y=function(e){var t=e.children("iframe")[0];s&&t?t.srcdoc=n(l.code):e.html(l.code),setTimeout(function(){"function"==typeof l.done&&l.done({container:e,options:l,render:function(){I.render(e.find(".layui-form")),S.render()}})},3)},"preview"===f[0]?(_.addClass(A.ELEM_SHOW),o.before(_),y(_)):o.addClass(A.ELEM_SHOW).after(_),l.previewStyle=[l.style,l.previewStyle].join(""),_.attr("style",l.previewStyle),S.on("tab("+M+")",function(e){var t=x(this),a=x(e.elem).closest("."+A.ELEM_PREVIEW).find("."+A.ELEM_ITEM),e=a.eq(e.index);a.removeClass(A.ELEM_SHOW),e.addClass(A.ELEM_SHOW),"preview"===t.attr("lay-id")&&y(e),L()})),p=x(''),o.addClass((E=["layui-code-view layui-border-box"],l.wordWrap||E.push("layui-code-nowrap"),E.join(" "))),(C=l.theme||l.skin)&&(o.removeClass("layui-code-theme-dark layui-code-theme-light"),o.addClass("layui-code-theme-"+C)),l.highlighter&&o.addClass([l.highlighter,"language-"+l.lang,"layui-code-hl"].join(" ")),f=w(l.encode?D.escape(n(a)):a),h=f.lines,o.html(p.html(f.html)),l.ln&&o.append('
        '),l.height&&p.css("max-height",l.height),l.codeStyle=[l.style,l.codeStyle].join(""),l.codeStyle&&p.attr("style",function(e,t){return(t||"")+l.codeStyle}),v=[{selector:">.layui-code-wrap>.layui-code-line{}",setValue:function(e,t){e.style["padding-left"]=t+"px"}},{selector:">.layui-code-wrap>.layui-code-line>.layui-code-line-number{}",setValue:function(e,t){e.style.width=t+"px"}},{selector:">.layui-code-ln-side{}",setValue:function(e,t){e.style.width=t+"px"}}],m=lay.style({target:o[0],id:"DF-code-"+d,text:x.map(x.map(v,function(e){return e.selector}),function(e,t){return['.layui-code-view[lay-code-index="'+d+'"]',e].join(" ")}).join("")}),L=function b(){var e,i;return l.ln&&(e=Math.floor(h.length/100),i=p.children("."+A.ELEM_LINE).last().children("."+A.ELEM_LINE_NUM).outerWidth(),o.addClass(A.ELEM_LN_MODE),e)&&A.LINE_RAW_WIDTH
      • ')).html(l.title||l.text.code),o.prepend(_)),M=x('
        '),l.copy&&!l.preview&&((C=x(['','',""].join(""))).on("click",function(){c.copy.event()}),M.append(C)),l.langMarker&&M.append(''+l.lang+""),l.about&&M.append(l.about),o.append(M),l.preview||setTimeout(function(){"function"==typeof l.done&&l.done({})},3),l.elem.length===1+d&&"function"==typeof l.allDone&&l.allDone())),g})}),layui["layui.all"]||layui.addcss("modules/code.css?v=6","skincodecss"); +//# sourceMappingURL=layui.js.map \ No newline at end of file diff --git a/dist/layui.min.css b/dist/layui.min.css new file mode 100755 index 0000000..5ff973b --- /dev/null +++ b/dist/layui.min.css @@ -0,0 +1,8 @@ +/** + * Skipped minification because the original files appears to be already minified. + * Original file: /npm/layui@2.9.2/dist/css/layui.css + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +blockquote,body,button,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,input,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}a:active,a:hover{outline:0}img{display:inline-block;border:none;vertical-align:middle}li{list-style:none}table{border-collapse:collapse;border-spacing:0}h1,h2,h3,h4{font-weight:700}h5,h6{font-weight:500;font-size:100%}button,input,select,textarea{font-size:100%}button,input,optgroup,option,select,textarea{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;outline:0}pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}body{line-height:1.6;color:#333;color:rgba(0,0,0,.85);font:14px Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif}hr{height:0;line-height:0;margin:10px 0;padding:0;border:none;border-bottom:1px solid #eee;clear:both;overflow:hidden;background:0 0}a{color:#333;text-decoration:none}a:hover{color:#777}a cite{font-style:normal;*cursor:pointer}.layui-border-box,.layui-border-box *{box-sizing:border-box}.layui-box,.layui-box *{box-sizing:content-box}.layui-clear{clear:both;*zoom:1}.layui-clear:after{content:'\20';clear:both;*zoom:1;display:block;height:0}.layui-clear-space{word-spacing:-5px}.layui-inline{position:relative;display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.layui-edge{position:relative;display:inline-block;vertical-align:middle;width:0;height:0;border-width:6px;border-style:dashed;border-color:transparent;overflow:hidden}.layui-edge-top{top:-4px;border-bottom-color:#999;border-bottom-style:solid}.layui-edge-right{border-left-color:#999;border-left-style:solid}.layui-edge-bottom{top:2px;border-top-color:#999;border-top-style:solid}.layui-edge-left{border-right-color:#999;border-right-style:solid}.layui-elip{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-disabled,.layui-icon,.layui-unselect{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-disabled,.layui-disabled:hover{color:#d2d2d2!important;cursor:not-allowed!important}.layui-circle{border-radius:100%}.layui-show{display:block!important}.layui-hide{display:none!important}.layui-show-v{visibility:visible!important}.layui-hide-v{visibility:hidden!important}@font-face{font-family:layui-icon;src:url(../font/iconfont.eot?v=282);src:url(../font/iconfont.eot?v=282#iefix) format('embedded-opentype'),url(../font/iconfont.woff2?v=282) format('woff2'),url(../font/iconfont.woff?v=282) format('woff'),url(../font/iconfont.ttf?v=282) format('truetype'),url(../font/iconfont.svg?v=282#layui-icon) format('svg')}.layui-icon{font-family:layui-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-icon-leaf:before{content:"\e701"}.layui-icon-folder:before{content:"\eabe"}.layui-icon-folder-open:before{content:"\eac1"}.layui-icon-gitee:before{content:"\e69b"}.layui-icon-github:before{content:"\e6a7"}.layui-icon-disabled:before{content:"\e6cc"}.layui-icon-moon:before{content:"\e6c2"}.layui-icon-error:before{content:"\e693"}.layui-icon-success:before{content:"\e697"}.layui-icon-question:before{content:"\e699"}.layui-icon-lock:before{content:"\e69a"}.layui-icon-eye:before{content:"\e695"}.layui-icon-eye-invisible:before{content:"\e696"}.layui-icon-backspace:before{content:"\e694"}.layui-icon-tips-fill:before{content:"\eb2e"}.layui-icon-test:before{content:"\e692"}.layui-icon-clear:before{content:"\e788"}.layui-icon-heart-fill:before{content:"\e68f"}.layui-icon-light:before{content:"\e748"}.layui-icon-music:before{content:"\e690"}.layui-icon-time:before{content:"\e68d"}.layui-icon-ie:before{content:"\e7bb"}.layui-icon-firefox:before{content:"\e686"}.layui-icon-at:before{content:"\e687"}.layui-icon-bluetooth:before{content:"\e689"}.layui-icon-chrome:before{content:"\e68a"}.layui-icon-edge:before{content:"\e68b"}.layui-icon-heart:before{content:"\e68c"}.layui-icon-key:before{content:"\e683"}.layui-icon-android:before{content:"\e684"}.layui-icon-mike:before{content:"\e6dc"}.layui-icon-mute:before{content:"\e685"}.layui-icon-gift:before{content:"\e627"}.layui-icon-windows:before{content:"\e67f"}.layui-icon-ios:before{content:"\e680"}.layui-icon-logout:before{content:"\e682"}.layui-icon-wifi:before{content:"\e7e0"}.layui-icon-rss:before{content:"\e808"}.layui-icon-email:before{content:"\e618"}.layui-icon-reduce-circle:before{content:"\e616"}.layui-icon-transfer:before{content:"\e691"}.layui-icon-service:before{content:"\e626"}.layui-icon-addition:before{content:"\e624"}.layui-icon-subtraction:before{content:"\e67e"}.layui-icon-slider:before{content:"\e714"}.layui-icon-print:before{content:"\e66d"}.layui-icon-export:before{content:"\e67d"}.layui-icon-cols:before{content:"\e610"}.layui-icon-screen-full:before{content:"\e622"}.layui-icon-screen-restore:before{content:"\e758"}.layui-icon-rate-half:before{content:"\e6c9"}.layui-icon-rate-solid:before{content:"\e67a"}.layui-icon-rate:before{content:"\e67b"}.layui-icon-cellphone:before{content:"\e678"}.layui-icon-vercode:before{content:"\e679"}.layui-icon-login-weibo:before{content:"\e675"}.layui-icon-login-qq:before{content:"\e676"}.layui-icon-login-wechat:before{content:"\e677"}.layui-icon-username:before{content:"\e66f"}.layui-icon-password:before{content:"\e673"}.layui-icon-refresh-3:before{content:"\e9aa"}.layui-icon-auz:before{content:"\e672"}.layui-icon-shrink-right:before{content:"\e668"}.layui-icon-spread-left:before{content:"\e66b"}.layui-icon-snowflake:before{content:"\e6b1"}.layui-icon-tips:before{content:"\e702"}.layui-icon-note:before{content:"\e66e"}.layui-icon-senior:before{content:"\e674"}.layui-icon-refresh-1:before{content:"\e666"}.layui-icon-refresh:before{content:"\e669"}.layui-icon-flag:before{content:"\e66c"}.layui-icon-theme:before{content:"\e66a"}.layui-icon-notice:before{content:"\e667"}.layui-icon-console:before{content:"\e665"}.layui-icon-website:before{content:"\e7ae"}.layui-icon-face-surprised:before{content:"\e664"}.layui-icon-set:before{content:"\e716"}.layui-icon-template:before{content:"\e663"}.layui-icon-app:before{content:"\e653"}.layui-icon-template-1:before{content:"\e656"}.layui-icon-home:before{content:"\e68e"}.layui-icon-female:before{content:"\e661"}.layui-icon-male:before{content:"\e662"}.layui-icon-tread:before{content:"\e6c5"}.layui-icon-praise:before{content:"\e6c6"}.layui-icon-rmb:before{content:"\e65e"}.layui-icon-more:before{content:"\e65f"}.layui-icon-camera:before{content:"\e660"}.layui-icon-cart-simple:before{content:"\e698"}.layui-icon-face-cry:before{content:"\e69c"}.layui-icon-face-smile:before{content:"\e6af"}.layui-icon-survey:before{content:"\e6b2"}.layui-icon-read:before{content:"\e705"}.layui-icon-location:before{content:"\e715"}.layui-icon-dollar:before{content:"\e659"}.layui-icon-diamond:before{content:"\e735"}.layui-icon-return:before{content:"\e65c"}.layui-icon-camera-fill:before{content:"\e65d"}.layui-icon-fire:before{content:"\e756"}.layui-icon-more-vertical:before{content:"\e671"}.layui-icon-cart:before{content:"\e657"}.layui-icon-star-fill:before{content:"\e658"}.layui-icon-prev:before{content:"\e65a"}.layui-icon-next:before{content:"\e65b"}.layui-icon-upload:before{content:"\e67c"}.layui-icon-upload-drag:before{content:"\e681"}.layui-icon-user:before{content:"\e770"}.layui-icon-file-b:before{content:"\e655"}.layui-icon-component:before{content:"\e857"}.layui-icon-find-fill:before{content:"\e670"}.layui-icon-loading:before{content:"\e63d"}.layui-icon-loading-1:before{content:"\e63e"}.layui-icon-add-1:before{content:"\e654"}.layui-icon-pause:before{content:"\e651"}.layui-icon-play:before{content:"\e652"}.layui-icon-video:before{content:"\e6ed"}.layui-icon-headset:before{content:"\e6fc"}.layui-icon-voice:before{content:"\e688"}.layui-icon-speaker:before{content:"\e645"}.layui-icon-fonts-del:before{content:"\e64f"}.layui-icon-fonts-html:before{content:"\e64b"}.layui-icon-fonts-code:before{content:"\e64e"}.layui-icon-fonts-strong:before{content:"\e62b"}.layui-icon-unlink:before{content:"\e64d"}.layui-icon-picture:before{content:"\e64a"}.layui-icon-link:before{content:"\e64c"}.layui-icon-face-smile-b:before{content:"\e650"}.layui-icon-align-center:before{content:"\e647"}.layui-icon-align-right:before{content:"\e648"}.layui-icon-align-left:before{content:"\e649"}.layui-icon-fonts-u:before{content:"\e646"}.layui-icon-fonts-i:before{content:"\e644"}.layui-icon-tabs:before{content:"\e62a"}.layui-icon-circle:before{content:"\e63f"}.layui-icon-radio:before{content:"\e643"}.layui-icon-share:before{content:"\e641"}.layui-icon-edit:before{content:"\e642"}.layui-icon-delete:before{content:"\e640"}.layui-icon-engine:before{content:"\e628"}.layui-icon-chart-screen:before{content:"\e629"}.layui-icon-chart:before{content:"\e62c"}.layui-icon-table:before{content:"\e62d"}.layui-icon-tree:before{content:"\e62e"}.layui-icon-upload-circle:before{content:"\e62f"}.layui-icon-templeate-1:before{content:"\e630"}.layui-icon-util:before{content:"\e631"}.layui-icon-layouts:before{content:"\e632"}.layui-icon-prev-circle:before{content:"\e633"}.layui-icon-carousel:before{content:"\e634"}.layui-icon-code-circle:before{content:"\e635"}.layui-icon-water:before{content:"\e636"}.layui-icon-date:before{content:"\e637"}.layui-icon-layer:before{content:"\e638"}.layui-icon-fonts-clear:before{content:"\e639"}.layui-icon-dialogue:before{content:"\e63a"}.layui-icon-cellphone-fine:before{content:"\e63b"}.layui-icon-form:before{content:"\e63c"}.layui-icon-file:before{content:"\e621"}.layui-icon-triangle-r:before{content:"\e623"}.layui-icon-triangle-d:before{content:"\e625"}.layui-icon-set-sm:before{content:"\e620"}.layui-icon-add-circle:before{content:"\e61f"}.layui-icon-layim-download:before{content:"\e61e"}.layui-icon-layim-uploadfile:before{content:"\e61d"}.layui-icon-404:before{content:"\e61c"}.layui-icon-about:before{content:"\e60b"}.layui-icon-layim-theme:before{content:"\e61b"}.layui-icon-down:before{content:"\e61a"}.layui-icon-up:before{content:"\e619"}.layui-icon-circle-dot:before{content:"\e617"}.layui-icon-set-fill:before{content:"\e614"}.layui-icon-search:before{content:"\e615"}.layui-icon-friends:before{content:"\e612"}.layui-icon-group:before{content:"\e613"}.layui-icon-reply-fill:before{content:"\e611"}.layui-icon-menu-fill:before{content:"\e60f"}.layui-icon-face-smile-fine:before{content:"\e60c"}.layui-icon-picture-fine:before{content:"\e60d"}.layui-icon-log:before{content:"\e60e"}.layui-icon-list:before{content:"\e60a"}.layui-icon-release:before{content:"\e609"}.layui-icon-add-circle-fine:before{content:"\e608"}.layui-icon-ok:before{content:"\e605"}.layui-icon-help:before{content:"\e607"}.layui-icon-chat:before{content:"\e606"}.layui-icon-top:before{content:"\e604"}.layui-icon-right:before{content:"\e602"}.layui-icon-left:before{content:"\e603"}.layui-icon-star:before{content:"\e600"}.layui-icon-download-circle:before{content:"\e601"}.layui-icon-close:before{content:"\1006"}.layui-icon-close-fill:before{content:"\1007"}.layui-icon-ok-circle:before{content:"\1005"}.layui-main{position:relative;width:1160px;margin:0 auto}.layui-header{position:relative;z-index:1000;height:60px}.layui-header a:hover{transition:all .5s;-webkit-transition:all .5s}.layui-side{position:fixed;left:0;top:0;bottom:0;z-index:999;width:200px;overflow-x:hidden}.layui-side-scroll{position:relative;width:220px;height:100%;overflow-x:hidden}.layui-body{position:relative;left:200px;right:0;top:0;bottom:0;z-index:900;width:auto;box-sizing:border-box}.layui-layout-body{overflow-x:hidden}.layui-layout-admin .layui-header{position:fixed;top:0;left:0;right:0;background-color:#23292e}.layui-layout-admin .layui-side{top:60px;width:200px;overflow-x:hidden}.layui-layout-admin .layui-body{position:absolute;top:60px;padding-bottom:44px}.layui-layout-admin .layui-main{width:auto;margin:0 15px}.layui-layout-admin .layui-footer{position:fixed;left:200px;right:0;bottom:0;z-index:990;height:44px;line-height:44px;padding:0 15px;box-shadow:-1px 0 4px rgb(0 0 0 / 12%);background-color:#fafafa}.layui-layout-admin .layui-logo{position:absolute;left:0;top:0;width:200px;height:100%;line-height:60px;text-align:center;color:#16baaa;font-size:16px;box-shadow:0 1px 2px 0 rgb(0 0 0 / 15%)}.layui-layout-admin .layui-header .layui-nav{background:0 0}.layui-layout-left{position:absolute!important;left:200px;top:0}.layui-layout-right{position:absolute!important;right:0;top:0}.layui-container{position:relative;margin:0 auto;box-sizing:border-box}.layui-fluid{position:relative;margin:0 auto;padding:0 15px}.layui-row:after,.layui-row:before{content:"";display:block;clear:both}.layui-col-lg1,.layui-col-lg10,.layui-col-lg11,.layui-col-lg12,.layui-col-lg2,.layui-col-lg3,.layui-col-lg4,.layui-col-lg5,.layui-col-lg6,.layui-col-lg7,.layui-col-lg8,.layui-col-lg9,.layui-col-md1,.layui-col-md10,.layui-col-md11,.layui-col-md12,.layui-col-md2,.layui-col-md3,.layui-col-md4,.layui-col-md5,.layui-col-md6,.layui-col-md7,.layui-col-md8,.layui-col-md9,.layui-col-sm1,.layui-col-sm10,.layui-col-sm11,.layui-col-sm12,.layui-col-sm2,.layui-col-sm3,.layui-col-sm4,.layui-col-sm5,.layui-col-sm6,.layui-col-sm7,.layui-col-sm8,.layui-col-sm9,.layui-col-xl1,.layui-col-xl10,.layui-col-xl11,.layui-col-xl12,.layui-col-xl2,.layui-col-xl3,.layui-col-xl4,.layui-col-xl5,.layui-col-xl6,.layui-col-xl7,.layui-col-xl8,.layui-col-xl9,.layui-col-xs1,.layui-col-xs10,.layui-col-xs11,.layui-col-xs12,.layui-col-xs2,.layui-col-xs3,.layui-col-xs4,.layui-col-xs5,.layui-col-xs6,.layui-col-xs7,.layui-col-xs8,.layui-col-xs9{position:relative;display:block;box-sizing:border-box}.layui-col-xs1,.layui-col-xs10,.layui-col-xs11,.layui-col-xs12,.layui-col-xs2,.layui-col-xs3,.layui-col-xs4,.layui-col-xs5,.layui-col-xs6,.layui-col-xs7,.layui-col-xs8,.layui-col-xs9{float:left}.layui-col-xs1{width:8.33333333%}.layui-col-xs2{width:16.66666667%}.layui-col-xs3{width:25%}.layui-col-xs4{width:33.33333333%}.layui-col-xs5{width:41.66666667%}.layui-col-xs6{width:50%}.layui-col-xs7{width:58.33333333%}.layui-col-xs8{width:66.66666667%}.layui-col-xs9{width:75%}.layui-col-xs10{width:83.33333333%}.layui-col-xs11{width:91.66666667%}.layui-col-xs12{width:100%}.layui-col-xs-offset1{margin-left:8.33333333%}.layui-col-xs-offset2{margin-left:16.66666667%}.layui-col-xs-offset3{margin-left:25%}.layui-col-xs-offset4{margin-left:33.33333333%}.layui-col-xs-offset5{margin-left:41.66666667%}.layui-col-xs-offset6{margin-left:50%}.layui-col-xs-offset7{margin-left:58.33333333%}.layui-col-xs-offset8{margin-left:66.66666667%}.layui-col-xs-offset9{margin-left:75%}.layui-col-xs-offset10{margin-left:83.33333333%}.layui-col-xs-offset11{margin-left:91.66666667%}.layui-col-xs-offset12{margin-left:100%}@media screen and (max-width:767.98px){.layui-container{padding:0 15px}.layui-hide-xs{display:none!important}.layui-show-xs-block{display:block!important}.layui-show-xs-inline{display:inline!important}.layui-show-xs-inline-block{display:inline-block!important}}@media screen and (min-width:768px){.layui-container{width:720px}.layui-hide-sm{display:none!important}.layui-show-sm-block{display:block!important}.layui-show-sm-inline{display:inline!important}.layui-show-sm-inline-block{display:inline-block!important}.layui-col-sm1,.layui-col-sm10,.layui-col-sm11,.layui-col-sm12,.layui-col-sm2,.layui-col-sm3,.layui-col-sm4,.layui-col-sm5,.layui-col-sm6,.layui-col-sm7,.layui-col-sm8,.layui-col-sm9{float:left}.layui-col-sm1{width:8.33333333%}.layui-col-sm2{width:16.66666667%}.layui-col-sm3{width:25%}.layui-col-sm4{width:33.33333333%}.layui-col-sm5{width:41.66666667%}.layui-col-sm6{width:50%}.layui-col-sm7{width:58.33333333%}.layui-col-sm8{width:66.66666667%}.layui-col-sm9{width:75%}.layui-col-sm10{width:83.33333333%}.layui-col-sm11{width:91.66666667%}.layui-col-sm12{width:100%}.layui-col-sm-offset1{margin-left:8.33333333%}.layui-col-sm-offset2{margin-left:16.66666667%}.layui-col-sm-offset3{margin-left:25%}.layui-col-sm-offset4{margin-left:33.33333333%}.layui-col-sm-offset5{margin-left:41.66666667%}.layui-col-sm-offset6{margin-left:50%}.layui-col-sm-offset7{margin-left:58.33333333%}.layui-col-sm-offset8{margin-left:66.66666667%}.layui-col-sm-offset9{margin-left:75%}.layui-col-sm-offset10{margin-left:83.33333333%}.layui-col-sm-offset11{margin-left:91.66666667%}.layui-col-sm-offset12{margin-left:100%}}@media screen and (min-width:992px){.layui-container{width:960px}.layui-hide-md{display:none!important}.layui-show-md-block{display:block!important}.layui-show-md-inline{display:inline!important}.layui-show-md-inline-block{display:inline-block!important}.layui-col-md1,.layui-col-md10,.layui-col-md11,.layui-col-md12,.layui-col-md2,.layui-col-md3,.layui-col-md4,.layui-col-md5,.layui-col-md6,.layui-col-md7,.layui-col-md8,.layui-col-md9{float:left}.layui-col-md1{width:8.33333333%}.layui-col-md2{width:16.66666667%}.layui-col-md3{width:25%}.layui-col-md4{width:33.33333333%}.layui-col-md5{width:41.66666667%}.layui-col-md6{width:50%}.layui-col-md7{width:58.33333333%}.layui-col-md8{width:66.66666667%}.layui-col-md9{width:75%}.layui-col-md10{width:83.33333333%}.layui-col-md11{width:91.66666667%}.layui-col-md12{width:100%}.layui-col-md-offset1{margin-left:8.33333333%}.layui-col-md-offset2{margin-left:16.66666667%}.layui-col-md-offset3{margin-left:25%}.layui-col-md-offset4{margin-left:33.33333333%}.layui-col-md-offset5{margin-left:41.66666667%}.layui-col-md-offset6{margin-left:50%}.layui-col-md-offset7{margin-left:58.33333333%}.layui-col-md-offset8{margin-left:66.66666667%}.layui-col-md-offset9{margin-left:75%}.layui-col-md-offset10{margin-left:83.33333333%}.layui-col-md-offset11{margin-left:91.66666667%}.layui-col-md-offset12{margin-left:100%}}@media screen and (min-width:1200px){.layui-container{width:1150px}.layui-hide-lg{display:none!important}.layui-show-lg-block{display:block!important}.layui-show-lg-inline{display:inline!important}.layui-show-lg-inline-block{display:inline-block!important}.layui-col-lg1,.layui-col-lg10,.layui-col-lg11,.layui-col-lg12,.layui-col-lg2,.layui-col-lg3,.layui-col-lg4,.layui-col-lg5,.layui-col-lg6,.layui-col-lg7,.layui-col-lg8,.layui-col-lg9{float:left}.layui-col-lg1{width:8.33333333%}.layui-col-lg2{width:16.66666667%}.layui-col-lg3{width:25%}.layui-col-lg4{width:33.33333333%}.layui-col-lg5{width:41.66666667%}.layui-col-lg6{width:50%}.layui-col-lg7{width:58.33333333%}.layui-col-lg8{width:66.66666667%}.layui-col-lg9{width:75%}.layui-col-lg10{width:83.33333333%}.layui-col-lg11{width:91.66666667%}.layui-col-lg12{width:100%}.layui-col-lg-offset1{margin-left:8.33333333%}.layui-col-lg-offset2{margin-left:16.66666667%}.layui-col-lg-offset3{margin-left:25%}.layui-col-lg-offset4{margin-left:33.33333333%}.layui-col-lg-offset5{margin-left:41.66666667%}.layui-col-lg-offset6{margin-left:50%}.layui-col-lg-offset7{margin-left:58.33333333%}.layui-col-lg-offset8{margin-left:66.66666667%}.layui-col-lg-offset9{margin-left:75%}.layui-col-lg-offset10{margin-left:83.33333333%}.layui-col-lg-offset11{margin-left:91.66666667%}.layui-col-lg-offset12{margin-left:100%}}@media screen and (min-width:1400px){.layui-container{width:1330px}.layui-hide-xl{display:none!important}.layui-show-xl-block{display:block!important}.layui-show-xl-inline{display:inline!important}.layui-show-xl-inline-block{display:inline-block!important}.layui-col-xl1,.layui-col-xl10,.layui-col-xl11,.layui-col-xl12,.layui-col-xl2,.layui-col-xl3,.layui-col-xl4,.layui-col-xl5,.layui-col-xl6,.layui-col-xl7,.layui-col-xl8,.layui-col-xl9{float:left}.layui-col-xl1{width:8.33333333%}.layui-col-xl2{width:16.66666667%}.layui-col-xl3{width:25%}.layui-col-xl4{width:33.33333333%}.layui-col-xl5{width:41.66666667%}.layui-col-xl6{width:50%}.layui-col-xl7{width:58.33333333%}.layui-col-xl8{width:66.66666667%}.layui-col-xl9{width:75%}.layui-col-xl10{width:83.33333333%}.layui-col-xl11{width:91.66666667%}.layui-col-xl12{width:100%}.layui-col-xl-offset1{margin-left:8.33333333%}.layui-col-xl-offset2{margin-left:16.66666667%}.layui-col-xl-offset3{margin-left:25%}.layui-col-xl-offset4{margin-left:33.33333333%}.layui-col-xl-offset5{margin-left:41.66666667%}.layui-col-xl-offset6{margin-left:50%}.layui-col-xl-offset7{margin-left:58.33333333%}.layui-col-xl-offset8{margin-left:66.66666667%}.layui-col-xl-offset9{margin-left:75%}.layui-col-xl-offset10{margin-left:83.33333333%}.layui-col-xl-offset11{margin-left:91.66666667%}.layui-col-xl-offset12{margin-left:100%}}.layui-col-space1{margin:-.5px}.layui-col-space1>*{padding:.5px}.layui-col-space2{margin:-1px}.layui-col-space2>*{padding:1px}.layui-col-space4{margin:-2px}.layui-col-space4>*{padding:2px}.layui-col-space5{margin:-2.5px}.layui-col-space5>*{padding:2.5px}.layui-col-space6{margin:-3px}.layui-col-space6>*{padding:3px}.layui-col-space8{margin:-4px}.layui-col-space8>*{padding:4px}.layui-col-space10{margin:-5px}.layui-col-space10>*{padding:5px}.layui-col-space12{margin:-6px}.layui-col-space12>*{padding:6px}.layui-col-space14{margin:-7px}.layui-col-space14>*{padding:7px}.layui-col-space15{margin:-7.5px}.layui-col-space15>*{padding:7.5px}.layui-col-space16{margin:-8px}.layui-col-space16>*{padding:8px}.layui-col-space18{margin:-9px}.layui-col-space18>*{padding:9px}.layui-col-space20{margin:-10px}.layui-col-space20>*{padding:10px}.layui-col-space22{margin:-11px}.layui-col-space22>*{padding:11px}.layui-col-space24{margin:-12px}.layui-col-space24>*{padding:12px}.layui-col-space25{margin:-12.5px}.layui-col-space25>*{padding:12.5px}.layui-col-space26{margin:-13px}.layui-col-space26>*{padding:13px}.layui-col-space28{margin:-14px}.layui-col-space28>*{padding:14px}.layui-col-space30{margin:-15px}.layui-col-space30>*{padding:15px}.layui-col-space32{margin:-16px}.layui-col-space32>*{padding:16px}.layui-padding-1{padding:4px!important}.layui-padding-2{padding:8px!important}.layui-padding-3{padding:16px!important}.layui-padding-4{padding:32px!important}.layui-padding-5{padding:48px!important}.layui-margin-1{margin:4px!important}.layui-margin-2{margin:8px!important}.layui-margin-3{margin:16px!important}.layui-margin-4{margin:32px!important}.layui-margin-5{margin:48px!important}.layui-btn,.layui-input,.layui-select,.layui-textarea,.layui-upload-button{outline:0;-webkit-appearance:none;transition:all .3s;-webkit-transition:all .3s;box-sizing:border-box}.layui-elem-quote{margin-bottom:10px;padding:15px;line-height:1.8;border-left:5px solid #16b777;border-radius:0 2px 2px 0;background-color:#fafafa}.layui-quote-nm{border-style:solid;border-width:1px;border-left-width:5px;background:0 0}.layui-elem-field{margin-bottom:10px;padding:0;border-width:1px;border-style:solid}.layui-elem-field legend{margin-left:20px;padding:0 10px;font-size:20px}.layui-field-title{margin:16px 0;border-width:0;border-top-width:1px}.layui-field-box{padding:15px}.layui-field-title .layui-field-box{padding:10px 0}.layui-progress{position:relative;height:6px;border-radius:20px;background-color:#eee}.layui-progress-bar{position:absolute;left:0;top:0;width:0;max-width:100%;height:6px;border-radius:20px;text-align:right;background-color:#16b777;transition:all .3s;-webkit-transition:all .3s}.layui-progress-big,.layui-progress-big .layui-progress-bar{height:18px;line-height:18px}.layui-progress-text{position:relative;top:-20px;line-height:18px;font-size:12px;color:#5f5f5f}.layui-progress-big .layui-progress-text{position:static;padding:0 10px;color:#fff}.layui-collapse{border-width:1px;border-style:solid;border-radius:2px}.layui-colla-content,.layui-colla-item{border-top-width:1px;border-top-style:solid}.layui-colla-item:first-child{border-top:none}.layui-colla-title{position:relative;height:42px;line-height:42px;padding:0 15px 0 35px;color:#333;background-color:#fafafa;cursor:pointer;font-size:14px;overflow:hidden}.layui-colla-content{display:none;padding:10px 15px;line-height:1.6;color:#5f5f5f}.layui-colla-icon{position:absolute;left:15px;top:0;font-size:14px}.layui-card{margin-bottom:15px;border-radius:2px;background-color:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.layui-card:last-child{margin-bottom:0}.layui-card-header{position:relative;height:42px;line-height:42px;padding:0 15px;border-bottom:1px solid #f8f8f8;color:#333;border-radius:2px 2px 0 0;font-size:14px}.layui-card-body{position:relative;padding:10px 15px;line-height:24px}.layui-card-body[pad15]{padding:15px}.layui-card-body[pad20]{padding:20px}.layui-card-body .layui-table{margin:5px 0}.layui-card .layui-tab{margin:0}.layui-panel{position:relative;border-width:1px;border-style:solid;border-radius:2px;box-shadow:1px 1px 4px rgb(0 0 0 / 8%);background-color:#fff;color:#5f5f5f}.layui-panel-window{position:relative;padding:15px;border-radius:0;border-top:5px solid #eee;background-color:#fff}.layui-auxiliar-moving{position:fixed;left:0;right:0;top:0;bottom:0;width:100%;height:100%;background:0 0;z-index:9999999999}.layui-scrollbar-hide{overflow:hidden!important}.layui-bg-red{background-color:#ff5722!important;color:#fff!important}.layui-bg-orange{background-color:#ffb800!important;color:#fff!important}.layui-bg-green{background-color:#16baaa!important;color:#fff!important}.layui-bg-cyan{background-color:#2f4056!important;color:#fff!important}.layui-bg-blue{background-color:#1e9fff!important;color:#fff!important}.layui-bg-purple{background-color:#a233c6!important;color:#fff!important}.layui-bg-black{background-color:#2f363c!important;color:#fff!important}.layui-bg-gray{background-color:#fafafa!important;color:#5f5f5f!important}.layui-badge-rim,.layui-border,.layui-colla-content,.layui-colla-item,.layui-collapse,.layui-elem-field,.layui-form-pane .layui-form-item[pane],.layui-form-pane .layui-form-label,.layui-input,.layui-input-split,.layui-panel,.layui-quote-nm,.layui-select,.layui-tab-bar,.layui-tab-card,.layui-tab-title,.layui-tab-title .layui-this:after,.layui-textarea{border-color:#eee}.layui-border{border-width:1px;border-style:solid;color:#5f5f5f!important}.layui-border-red{border-width:1px;border-style:solid;border-color:#ff5722!important;color:#ff5722!important}.layui-border-orange{border-width:1px;border-style:solid;border-color:#ffb800!important;color:#ffb800!important}.layui-border-green{border-width:1px;border-style:solid;border-color:#16baaa!important;color:#16baaa!important}.layui-border-cyan{border-width:1px;border-style:solid;border-color:#2f4056!important;color:#2f4056!important}.layui-border-blue{border-width:1px;border-style:solid;border-color:#1e9fff!important;color:#1e9fff!important}.layui-border-purple{border-width:1px;border-style:solid;border-color:#a233c6!important;color:#a233c6!important}.layui-border-black{border-width:1px;border-style:solid;border-color:#2f363c!important;color:#2f363c!important}hr.layui-border-black,hr.layui-border-blue,hr.layui-border-cyan,hr.layui-border-green,hr.layui-border-orange,hr.layui-border-purple,hr.layui-border-red{border-width:0 0 1px}.layui-timeline-item:before{background-color:#eee}.layui-text{line-height:1.8;font-size:14px}.layui-text h1,.layui-text h2,.layui-text h3,.layui-text h4,.layui-text h5,.layui-text h6{color:#3a3a3a}.layui-text h1{font-size:32px}.layui-text h2{font-size:24px}.layui-text h3{font-size:18px}.layui-text h4{font-size:16px}.layui-text h5{font-size:14px}.layui-text h6{font-size:13px}.layui-text ol,.layui-text ul{padding-left:15px}.layui-text ul li{margin-top:5px;list-style-type:disc}.layui-text ol li{margin-top:5px;list-style-type:decimal}.layui-text-em,.layui-word-aux{color:#999!important;padding-left:5px!important;padding-right:5px!important}.layui-text p{margin:15px 0}.layui-text p:first-child{margin-top:0}.layui-text p:last-child{margin-bottom:0}.layui-text a:not(.layui-btn){color:#01aaed}.layui-text a:not(.layui-btn):hover{text-decoration:underline}.layui-text blockquote:not(.layui-elem-quote){padding:5px 15px;border-left:5px solid #eee}.layui-text pre>code:not(.layui-code){padding:15px;font-family:"Courier New",Consolas,"Lucida Console"}.layui-font-12{font-size:12px!important}.layui-font-13{font-size:13px!important}.layui-font-14{font-size:14px!important}.layui-font-16{font-size:16px!important}.layui-font-18{font-size:18px!important}.layui-font-20{font-size:20px!important}.layui-font-22{font-size:22px!important}.layui-font-24{font-size:24px!important}.layui-font-26{font-size:26px!important}.layui-font-28{font-size:28px!important}.layui-font-30{font-size:30px!important}.layui-font-32{font-size:32px!important}.layui-font-red{color:#ff5722!important}.layui-font-orange{color:#ffb800!important}.layui-font-green{color:#16baaa!important}.layui-font-cyan{color:#2f4056!important}.layui-font-blue{color:#01aaed!important}.layui-font-purple{color:#a233c6!important}.layui-font-black{color:#000!important}.layui-font-gray{color:#c2c2c2!important}.layui-btn{display:inline-block;vertical-align:middle;height:38px;line-height:38px;border:1px solid transparent;padding:0 18px;background-color:#16baaa;color:#fff;white-space:nowrap;text-align:center;font-size:14px;border-radius:2px;cursor:pointer;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-btn:hover{opacity:.8;filter:alpha(opacity=80);color:#fff}.layui-btn:active{opacity:1;filter:alpha(opacity=100)}.layui-btn+.layui-btn{margin-left:10px}.layui-btn-container{word-spacing:-5px}.layui-btn-container .layui-btn{margin-right:10px;margin-bottom:10px;word-spacing:normal}.layui-btn-container .layui-btn+.layui-btn{margin-left:0}.layui-table .layui-btn-container .layui-btn{margin-bottom:9px}.layui-btn-radius{border-radius:100px}.layui-btn .layui-icon{padding:0 2px;vertical-align:middle\0;vertical-align:bottom}.layui-btn-primary{border-color:#d2d2d2;background:0 0;color:#5f5f5f}.layui-btn-primary:hover{border-color:#16baaa;color:#333}.layui-btn-normal{background-color:#1e9fff}.layui-btn-warm{background-color:#ffb800}.layui-btn-danger{background-color:#ff5722}.layui-btn-checked{background-color:#16b777}.layui-btn-disabled,.layui-btn-disabled:active,.layui-btn-disabled:hover{border-color:#eee!important;background-color:#fbfbfb!important;color:#d2d2d2!important;cursor:not-allowed!important;opacity:1}.layui-btn-lg{height:44px;line-height:44px;padding:0 25px;font-size:16px}.layui-btn-sm{height:30px;line-height:30px;padding:0 10px;font-size:12px}.layui-btn-xs{height:22px;line-height:22px;padding:0 5px;font-size:12px}.layui-btn-xs i{font-size:12px!important}.layui-btn-group{display:inline-block;vertical-align:middle;font-size:0}.layui-btn-group .layui-btn{margin-left:0!important;margin-right:0!important;border-left:1px solid rgba(255,255,255,.5);border-radius:0}.layui-btn-group .layui-btn-primary{border-left:none}.layui-btn-group .layui-btn-primary:hover{border-color:#d2d2d2;color:#16baaa}.layui-btn-group .layui-btn:first-child{border-left:none;border-radius:2px 0 0 2px}.layui-btn-group .layui-btn-primary:first-child{border-left:1px solid #d2d2d2}.layui-btn-group .layui-btn:last-child{border-radius:0 2px 2px 0}.layui-btn-group .layui-btn+.layui-btn{margin-left:0}.layui-btn-group+.layui-btn-group{margin-left:10px}.layui-btn-fluid{width:100%}.layui-input,.layui-select,.layui-textarea{height:38px;line-height:1.3;line-height:38px\9;border-width:1px;border-style:solid;background-color:#fff;color:rgba(0,0,0,.85);border-radius:2px}.layui-input::-webkit-input-placeholder,.layui-select::-webkit-input-placeholder,.layui-textarea::-webkit-input-placeholder{line-height:1.3}.layui-input,.layui-textarea{display:block;width:100%;padding-left:10px}.layui-input:hover,.layui-textarea:hover{border-color:#d2d2d2!important}.layui-input:focus,.layui-textarea:focus{border-color:#16b777!important;box-shadow:0 0 0 3px rgba(22,183,119,.08)}.layui-textarea{position:relative;min-height:100px;height:auto;line-height:20px;padding:6px 10px;resize:vertical}.layui-input[disabled],.layui-textarea[disabled]{background-color:#fafafa}.layui-select{padding:0 10px}.layui-form input[type=checkbox],.layui-form input[type=radio],.layui-form select{display:none}.layui-form [lay-ignore]{display:initial}.layui-form-item{position:relative;margin-bottom:15px;clear:both;*zoom:1}.layui-form-item:after{content:'\20';clear:both;*zoom:1;display:block;height:0}.layui-form-label{position:relative;float:left;display:block;padding:9px 15px;width:80px;font-weight:400;line-height:20px;text-align:right}.layui-form-label-col{display:block;float:none;padding:9px 0;line-height:20px;text-align:left}.layui-form-item .layui-inline{margin-bottom:5px;margin-right:10px}.layui-input-block,.layui-input-inline{position:relative}.layui-input-block{margin-left:110px;min-height:36px}.layui-input-inline{display:inline-block;vertical-align:middle}.layui-form-item .layui-input-inline{float:left;width:190px;margin-right:10px}.layui-form-text .layui-input-inline{width:auto}.layui-form-mid{position:relative;float:left;display:block;padding:9px 0!important;line-height:20px;margin-right:10px}.layui-form-danger+.layui-form-select .layui-input,.layui-form-danger:focus{border-color:#ff5722!important;box-shadow:0 0 0 3px rgba(255,87,34,.08)}.layui-input-prefix,.layui-input-split,.layui-input-suffix,.layui-input-suffix .layui-input-affix{position:absolute;right:0;top:0;padding:0 10px;width:35px;height:100%;text-align:center;transition:all .3s;box-sizing:border-box}.layui-input-prefix{left:0;border-radius:2px 0 0 2px}.layui-input-suffix{right:0;border-radius:0 2px 2px 0}.layui-input-split{border-width:1px;border-style:solid}.layui-input-prefix .layui-icon,.layui-input-split .layui-icon,.layui-input-suffix .layui-icon{position:relative;font-size:16px;color:#5f5f5f;transition:all .3s}.layui-input-group{position:relative;display:table;box-sizing:border-box}.layui-input-group>*{display:table-cell;vertical-align:middle;position:relative}.layui-input-group .layui-input{padding-right:15px}.layui-input-group>.layui-input-prefix{width:auto;border-right:0}.layui-input-group>.layui-input-suffix{width:auto;border-left:0}.layui-input-group .layui-input-split{white-space:nowrap}.layui-input-wrap{position:relative;line-height:38px}.layui-input-wrap .layui-input{padding-right:35px}.layui-input-wrap .layui-input::-ms-clear,.layui-input-wrap .layui-input::-ms-reveal{display:none}.layui-input-wrap .layui-input-prefix+.layui-input,.layui-input-wrap .layui-input-prefix~* .layui-input{padding-left:35px}.layui-input-wrap .layui-input-split+.layui-input,.layui-input-wrap .layui-input-split~* .layui-input{padding-left:45px}.layui-input-wrap .layui-input-prefix~.layui-form-select{position:static}.layui-input-wrap .layui-input-prefix,.layui-input-wrap .layui-input-split,.layui-input-wrap .layui-input-suffix{pointer-events:none}.layui-input-wrap .layui-input:hover+.layui-input-split{border-color:#d2d2d2}.layui-input-wrap .layui-input:focus+.layui-input-split{border-color:#16b777}.layui-input-wrap .layui-input.layui-form-danger:focus+.layui-input-split{border-color:#ff5722}.layui-input-wrap .layui-input-prefix.layui-input-split{border-width:0;border-right-width:1px}.layui-input-affix{line-height:38px}.layui-input-suffix .layui-input-affix{right:auto;left:-35px}.layui-input-affix .layui-icon{color:rgba(0,0,0,.8);pointer-events:auto!important;cursor:pointer}.layui-input-affix .layui-icon-clear{color:rgba(0,0,0,.3)}.layui-input-affix .layui-icon:hover{color:rgba(0,0,0,.6)}.layui-input-wrap .layui-input-number{width:24px;padding:0}.layui-input-wrap .layui-input-number .layui-icon{position:absolute;right:0;width:100%;height:50%;line-height:normal;font-size:12px}.layui-input-wrap .layui-input-number .layui-icon:before{position:absolute;left:50%;top:50%;margin-top:-6px;margin-left:-6px}.layui-input-wrap .layui-input-number .layui-icon-up{top:0;border-bottom:1px solid #eee}.layui-input-wrap .layui-input-number .layui-icon-down{bottom:0}.layui-input-wrap .layui-input-number .layui-icon:hover{font-weight:700}.layui-input-wrap .layui-input[type=number]::-webkit-inner-spin-button,.layui-input-wrap .layui-input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none!important}.layui-input-wrap .layui-input[type=number]{-moz-appearance:textfield}.layui-input-wrap .layui-input[type=number].layui-input-number-out-of-range{color:#ff5722}.layui-form-select{position:relative;color:#5f5f5f}.layui-form-select .layui-input{padding-right:30px;cursor:pointer}.layui-form-select .layui-edge{position:absolute;right:10px;top:50%;margin-top:-3px;cursor:pointer;border-width:6px;border-top-color:#c2c2c2;border-top-style:solid;transition:all .3s;-webkit-transition:all .3s}.layui-form-select dl{display:none;position:absolute;left:0;top:42px;padding:5px 0;z-index:899;min-width:100%;border:1px solid #eee;max-height:300px;overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:1px 1px 4px rgb(0 0 0 / 8%);box-sizing:border-box}.layui-form-select dl dd,.layui-form-select dl dt{padding:0 10px;line-height:36px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.layui-form-select dl dt{font-size:12px;color:#999}.layui-form-select dl dd{cursor:pointer}.layui-form-select dl dd:hover{background-color:#f8f8f8;-webkit-transition:.5s all;transition:.5s all}.layui-form-select .layui-select-group dd{padding-left:20px}.layui-form-select dl dd.layui-select-tips{padding-left:10px!important;color:#999}.layui-form-select dl dd.layui-this{background-color:#f8f8f8;color:#16b777;font-weight:700}.layui-form-select dl dd.layui-disabled{background-color:#fff}.layui-form-selected dl{display:block}.layui-form-selected .layui-edge{margin-top:-9px;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.layui-form-selected .layui-edge{margin-top:-3px\0}:root .layui-form-selected .layui-edge{margin-top:-9px\0/IE9}.layui-form-selectup dl{top:auto;bottom:42px}.layui-select-none{margin:5px 0;text-align:center;color:#999}.layui-select-disabled .layui-disabled{border-color:#eee!important}.layui-select-disabled .layui-edge{border-top-color:#d2d2d2}.layui-form-checkbox{position:relative;display:inline-block;vertical-align:middle;height:30px;line-height:30px;margin-right:10px;padding-right:30px;background-color:#fff;cursor:pointer;font-size:0;-webkit-transition:.1s linear;transition:.1s linear;box-sizing:border-box}.layui-form-checkbox>*{display:inline-block;vertical-align:middle}.layui-form-checkbox>div{padding:0 11px;font-size:14px;border-radius:2px 0 0 2px;background-color:#d2d2d2;color:#fff;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.layui-form-checkbox>div>.layui-icon{line-height:normal}.layui-form-checkbox:hover>div{background-color:#c2c2c2}.layui-form-checkbox>i{position:absolute;right:0;top:0;width:30px;height:100%;border:1px solid #d2d2d2;border-left:none;border-radius:0 2px 2px 0;color:#fff;color:rgba(255,255,255,0);font-size:20px;text-align:center;box-sizing:border-box}.layui-form-checkbox:hover>i{border-color:#c2c2c2;color:#c2c2c2}.layui-form-checked,.layui-form-checked:hover{border-color:#16b777}.layui-form-checked:hover>div,.layui-form-checked>div{background-color:#16b777}.layui-form-checked:hover>i,.layui-form-checked>i{color:#16b777}.layui-form-item .layui-form-checkbox{margin-top:4px}.layui-form-checkbox.layui-checkbox-disabled>div{background-color:#eee!important}.layui-form [lay-checkbox]{display:none}.layui-form-checkbox[lay-skin=primary]{height:auto!important;line-height:normal!important;min-width:18px;min-height:18px;border:none!important;margin-right:0;padding-left:24px;padding-right:0;background:0 0}.layui-form-checkbox[lay-skin=primary]>div{margin-top:-1px;padding-left:0;padding-right:15px;line-height:18px;background:0 0;color:#5f5f5f}.layui-form-checkbox[lay-skin=primary]>i{right:auto;left:0;width:16px;height:16px;line-height:14px;border:1px solid #d2d2d2;font-size:12px;border-radius:2px;background-color:#fff;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-checkbox[lay-skin=primary]:hover>i{border-color:#16b777;color:#fff}.layui-form-checked[lay-skin=primary]>i{border-color:#16b777!important;background-color:#16b777;color:#fff}.layui-checkbox-disabled[lay-skin=primary]>div{background:0 0!important}.layui-form-checked.layui-checkbox-disabled[lay-skin=primary]>i{background:#eee!important;border-color:#eee!important}.layui-checkbox-disabled[lay-skin=primary]:hover>i{border-color:#d2d2d2}.layui-form-item .layui-form-checkbox[lay-skin=primary]{margin-top:10px}.layui-form-checkbox[lay-skin=primary]>.layui-icon-indeterminate{border-color:#16b777}.layui-form-checkbox[lay-skin=primary]>.layui-icon-indeterminate:before{content:'';display:inline-block;vertical-align:middle;position:relative;width:50%;height:1px;margin:-1px auto 0;background-color:#16b777}.layui-form-switch{position:relative;display:inline-block;vertical-align:middle;height:24px;line-height:22px;min-width:44px;padding:0 5px;margin-top:8px;border:1px solid #d2d2d2;border-radius:20px;cursor:pointer;box-sizing:border-box;background-color:#fff;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-switch>i{position:absolute;left:5px;top:3px;width:16px;height:16px;border-radius:20px;background-color:#d2d2d2;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-switch>div{position:relative;top:0;margin-left:21px;padding:0!important;text-align:center!important;color:#999!important;font-style:normal!important;font-size:12px}.layui-form-onswitch{border-color:#16b777;background-color:#16b777}.layui-form-onswitch>i{left:100%;margin-left:-21px;background-color:#fff}.layui-form-onswitch>div{margin-left:0;margin-right:21px;color:#fff!important}.layui-checkbox-disabled{border-color:#eee!important}.layui-checkbox-disabled>div{color:#c2c2c2!important}.layui-checkbox-disabled>i{border-color:#eee!important}.layui-checkbox-disabled:hover>i{color:#fff!important}.layui-form-radio{display:inline-block;vertical-align:middle;line-height:28px;margin:6px 10px 0 0;padding-right:10px;cursor:pointer;font-size:0}.layui-form-radio>*{display:inline-block;vertical-align:middle;font-size:14px}.layui-form-radio>i{margin-right:8px;font-size:22px;color:#c2c2c2}.layui-form-radio:hover>*,.layui-form-radioed,.layui-form-radioed>i{color:#16b777}.layui-radio-disabled>i{color:#eee!important}.layui-radio-disabled>*{color:#c2c2c2!important}.layui-form [lay-radio]{display:none}.layui-form-pane .layui-form-label{width:110px;padding:8px 15px;height:38px;line-height:20px;border-width:1px;border-style:solid;border-radius:2px 0 0 2px;text-align:center;background-color:#fafafa;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;box-sizing:border-box}.layui-form-pane .layui-input-inline{margin-left:-1px}.layui-form-pane .layui-input-block{margin-left:110px;left:-1px}.layui-form-pane .layui-input{border-radius:0 2px 2px 0}.layui-form-pane .layui-form-text .layui-form-label{float:none;width:100%;border-radius:2px;box-sizing:border-box;text-align:left}.layui-form-pane .layui-form-text .layui-input-inline{display:block;margin:0;top:-1px;clear:both}.layui-form-pane .layui-form-text .layui-input-block{margin:0;left:0;top:-1px}.layui-form-pane .layui-form-text .layui-textarea{min-height:100px;border-radius:0 0 2px 2px}.layui-form-pane .layui-form-checkbox{margin:4px 0 4px 10px}.layui-form-pane .layui-form-radio,.layui-form-pane .layui-form-switch{margin-top:6px;margin-left:10px}.layui-form-pane .layui-form-item[pane]{position:relative;border-width:1px;border-style:solid}.layui-form-pane .layui-form-item[pane] .layui-form-label{position:absolute;left:0;top:0;height:100%;border-width:0;border-right-width:1px}.layui-form-pane .layui-form-item[pane] .layui-input-inline{margin-left:110px}@media screen and (max-width:450px){.layui-form-item .layui-form-label{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-form-item .layui-inline{display:block;margin-right:0;margin-bottom:20px;clear:both}.layui-form-item .layui-inline:after{content:'\20';clear:both;display:block;height:0}.layui-form-item .layui-input-inline{display:block;float:none;left:-3px;width:auto!important;margin:0 0 10px 112px}.layui-form-item .layui-input-inline+.layui-form-mid{margin-left:110px;top:-5px;padding:0}.layui-form-item .layui-form-checkbox{margin-right:5px;margin-bottom:5px}}.layui-laypage{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;margin:10px 0;font-size:0}.layui-laypage>a:first-child,.layui-laypage>a:first-child em{border-radius:2px 0 0 2px}.layui-laypage>a:last-child,.layui-laypage>a:last-child em{border-radius:0 2px 2px 0}.layui-laypage>:first-child{margin-left:0!important}.layui-laypage>:last-child{margin-right:0!important}.layui-laypage a,.layui-laypage button,.layui-laypage input,.layui-laypage select,.layui-laypage span{border:1px solid #eee}.layui-laypage a,.layui-laypage span{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding:0 15px;height:28px;line-height:28px;margin:0 -1px 5px 0;background-color:#fff;color:#333;font-size:12px}.layui-laypage a[data-page]{color:#333}.layui-laypage a{text-decoration:none!important;cursor:pointer}.layui-laypage a:hover{color:#16baaa}.layui-laypage em{font-style:normal}.layui-laypage .layui-laypage-spr{color:#999;font-weight:700}.layui-laypage .layui-laypage-curr{position:relative}.layui-laypage .layui-laypage-curr em{position:relative;color:#fff}.layui-laypage .layui-laypage-curr .layui-laypage-em{position:absolute;left:-1px;top:-1px;padding:1px;width:100%;height:100%;background-color:#16baaa}.layui-laypage-em{border-radius:2px}.layui-laypage-next em,.layui-laypage-prev em{font-family:Sim sun;font-size:16px}.layui-laypage .layui-laypage-count,.layui-laypage .layui-laypage-limits,.layui-laypage .layui-laypage-refresh,.layui-laypage .layui-laypage-skip{margin-left:10px;margin-right:10px;padding:0;border:none}.layui-laypage .layui-laypage-limits,.layui-laypage .layui-laypage-refresh{vertical-align:top}.layui-laypage .layui-laypage-refresh i{font-size:18px;cursor:pointer}.layui-laypage select{height:22px;padding:3px;border-radius:2px;cursor:pointer}.layui-laypage .layui-laypage-skip{height:30px;line-height:30px;color:#999}.layui-laypage button,.layui-laypage input{height:30px;line-height:30px;border-radius:2px;vertical-align:top;background-color:#fff;box-sizing:border-box}.layui-laypage input{display:inline-block;width:40px;margin:0 10px;padding:0 3px;text-align:center}.layui-laypage input:focus,.layui-laypage select:focus{border-color:#16baaa!important}.layui-laypage button{margin-left:10px;padding:0 10px;cursor:pointer}.layui-flow-more{margin:10px 0;text-align:center;color:#999;font-size:14px;clear:both}.layui-flow-more a{height:32px;line-height:32px}.layui-flow-more a *{display:inline-block;vertical-align:top}.layui-flow-more a cite{padding:0 20px;border-radius:3px;background-color:#eee;color:#333;font-style:normal}.layui-flow-more a cite:hover{opacity:.8}.layui-flow-more a i{font-size:30px;color:#737383}.layui-table{width:100%;margin:10px 0;background-color:#fff;color:#5f5f5f}.layui-table tr{transition:all .3s;-webkit-transition:all .3s}.layui-table th{text-align:left;font-weight:600}.layui-table-mend{background-color:#fff}.layui-table-click,.layui-table-hover,.layui-table[lay-even] tbody tr:nth-child(even){background-color:#f8f8f8}.layui-table-checked{background-color:#dbfbf0}.layui-table-checked.layui-table-click,.layui-table-checked.layui-table-hover{background-color:#abf8dd}.layui-table td,.layui-table th,.layui-table-col-set,.layui-table-fixed-r,.layui-table-grid-down,.layui-table-header,.layui-table-mend,.layui-table-page,.layui-table-tips-main,.layui-table-tool,.layui-table-total,.layui-table-view,.layui-table[lay-skin=line],.layui-table[lay-skin=row]{border-width:1px;border-style:solid;border-color:#eee}.layui-table td,.layui-table th{position:relative;padding:9px 15px;min-height:20px;line-height:20px;font-size:14px}.layui-table[lay-skin=line] td,.layui-table[lay-skin=line] th{border-width:0;border-bottom-width:1px}.layui-table[lay-skin=row] td,.layui-table[lay-skin=row] th{border-width:0;border-right-width:1px}.layui-table[lay-skin=nob] td,.layui-table[lay-skin=nob] th{border:none}.layui-table img{max-width:100px}.layui-table[lay-size=lg] td,.layui-table[lay-size=lg] th{padding-top:15px;padding-right:30px;padding-bottom:15px;padding-left:30px}.layui-table-view .layui-table[lay-size=lg] .layui-table-cell{height:50px;line-height:40px}.layui-table[lay-size=sm] td,.layui-table[lay-size=sm] th{padding-top:5px;padding-right:10px;padding-bottom:5px;padding-left:10px;font-size:12px}.layui-table-view .layui-table[lay-size=sm] .layui-table-cell{height:30px;line-height:20px;padding-top:5px;padding-left:11px;padding-right:11px}.layui-table[lay-data],.layui-table[lay-options]{display:none}.layui-table-box{position:relative;overflow:hidden}.layui-table-view{clear:both}.layui-table-view .layui-table{position:relative;width:auto;margin:0;border:0;border-collapse:separate}.layui-table-view .layui-table[lay-skin=line]{border-width:0;border-right-width:1px}.layui-table-view .layui-table[lay-skin=row]{border-width:0;border-bottom-width:1px}.layui-table-view .layui-table td,.layui-table-view .layui-table th{padding:0;border-top:none;border-left:none}.layui-table-view .layui-table th [lay-event],.layui-table-view .layui-table th.layui-unselect .layui-table-cell span{cursor:pointer}.layui-table-view .layui-table td,.layui-table-view .layui-table th span{cursor:default}.layui-table-view .layui-table td[data-edit]{cursor:text}.layui-table-view .layui-table td[data-edit]:hover:after{position:absolute;left:0;top:0;width:100%;height:100%;box-sizing:border-box;border:1px solid #16b777;pointer-events:none;content:""}.layui-table-view .layui-form-checkbox[lay-skin=primary] i{width:18px;height:18px;line-height:16px}.layui-table-view .layui-form-radio{line-height:0;padding:0}.layui-table-view .layui-form-radio>i{margin:0;font-size:20px}.layui-table-init{position:absolute;left:0;top:0;width:100%;height:100%;text-align:center;z-index:199}.layui-table-init .layui-icon{position:absolute;left:50%;top:50%;margin:-15px 0 0 -15px;font-size:30px;color:#c2c2c2}.layui-table-header{border-width:0;border-bottom-width:1px;overflow:hidden}.layui-table-header .layui-table{margin-bottom:-1px}.layui-table-column{position:relative;width:100%;min-height:41px;padding:8px 16px;border-width:0;border-bottom-width:1px}.layui-table-column .layui-btn-container{margin-bottom:-8px}.layui-table-column .layui-btn-container .layui-btn{margin-right:8px;margin-bottom:8px}.layui-table-tool .layui-inline[lay-event]{position:relative;width:26px;height:26px;padding:5px;line-height:16px;margin-right:10px;text-align:center;color:#333;border:1px solid #ccc;cursor:pointer;-webkit-transition:.5s all;transition:.5s all}.layui-table-tool .layui-inline[lay-event]:hover{border:1px solid #999}.layui-table-tool-temp{padding-right:120px}.layui-table-tool-self{position:absolute;right:17px;top:10px}.layui-table-tool .layui-table-tool-self .layui-inline[lay-event]{margin:0 0 0 10px}.layui-table-tool-panel{position:absolute;top:29px;left:-1px;z-index:399;padding:5px 0!important;min-width:150px;min-height:40px;border:1px solid #d2d2d2;text-align:left;overflow-y:auto;background-color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.12)}.layui-table-tool-panel li{padding:0 10px;margin:0!important;line-height:30px;list-style-type:none!important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-transition:.5s all;transition:.5s all}.layui-table-tool-panel li .layui-form-checkbox[lay-skin=primary]{width:100%}.layui-table-tool-panel li:hover{background-color:#f8f8f8}.layui-table-tool-panel li .layui-form-checkbox[lay-skin=primary]{padding-left:28px}.layui-table-tool-panel li .layui-form-checkbox[lay-skin=primary] i{position:absolute;left:0;top:0}.layui-table-tool-panel li .layui-form-checkbox[lay-skin=primary] span{padding:0}.layui-table-tool .layui-table-tool-self .layui-table-tool-panel{left:auto;right:-1px}.layui-table-col-set{position:absolute;right:0;top:0;width:20px;height:100%;border-width:0;border-left-width:1px;background-color:#fff}.layui-table-sort{width:10px;height:20px;margin-left:5px;cursor:pointer!important}.layui-table-sort .layui-edge{position:absolute;left:5px;border-width:5px}.layui-table-sort .layui-table-sort-asc{top:3px;border-top:none;border-bottom-style:solid;border-bottom-color:#b2b2b2}.layui-table-sort .layui-table-sort-asc:hover{border-bottom-color:#5f5f5f}.layui-table-sort .layui-table-sort-desc{bottom:5px;border-bottom:none;border-top-style:solid;border-top-color:#b2b2b2}.layui-table-sort .layui-table-sort-desc:hover{border-top-color:#5f5f5f}.layui-table-sort[lay-sort=asc] .layui-table-sort-asc{border-bottom-color:#000}.layui-table-sort[lay-sort=desc] .layui-table-sort-desc{border-top-color:#000}.layui-table-cell{height:38px;line-height:28px;padding:6px 15px;position:relative;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;box-sizing:border-box}.layui-table-cell .layui-form-checkbox[lay-skin=primary]{top:-1px;padding:0}.layui-table-cell .layui-form-checkbox[lay-skin=primary]>div{padding-left:24px}.layui-table-cell .layui-table-link{color:#01aaed}.layui-table-cell .layui-btn{vertical-align:inherit}.layui-table-cell[align=center]{-webkit-box-pack:center}.layui-table-cell[align=right]{-webkit-box-pack:end}.laytable-cell-checkbox,.laytable-cell-numbers,.laytable-cell-radio,.laytable-cell-space{text-align:center;-webkit-box-pack:center}.layui-table-body{position:relative;overflow:auto;margin-right:-1px;margin-bottom:-1px}.layui-table-body .layui-none{line-height:26px;padding:30px 15px;text-align:center;color:#999}.layui-table-fixed{position:absolute;left:0;top:0;z-index:101}.layui-table-fixed .layui-table-body{overflow:hidden}.layui-table-fixed-l{box-shadow:1px 0 8px rgba(0,0,0,.08)}.layui-table-fixed-r{left:auto;right:-1px;border-width:0;border-left-width:1px;box-shadow:-1px 0 8px rgba(0,0,0,.08)}.layui-table-fixed-r .layui-table-header{position:relative;overflow:visible}.layui-table-mend{position:absolute;right:-49px;top:0;height:100%;width:50px;border-width:0;border-left-width:1px}.layui-table-tool{position:relative;width:100%;min-height:50px;line-height:30px;padding:10px 15px;border-width:0;border-bottom-width:1px}.layui-table-tool .layui-btn-container{margin-bottom:-10px}.layui-table-total{margin-bottom:-1px;border-width:0;border-top-width:1px;overflow:hidden}.layui-table-page{border-width:0;border-top-width:1px;margin-bottom:-1px;white-space:nowrap;overflow:hidden}.layui-table-page>div{height:26px}.layui-table-page .layui-laypage{margin:0}.layui-table-page .layui-laypage a,.layui-table-page .layui-laypage span{height:26px;line-height:26px;margin-bottom:10px;border:none;background:0 0}.layui-table-page .layui-laypage a,.layui-table-page .layui-laypage span.layui-laypage-curr{padding:0 12px}.layui-table-page .layui-laypage span{margin-left:0;padding:0}.layui-table-page .layui-laypage .layui-laypage-prev{margin-left:-11px!important}.layui-table-page .layui-laypage .layui-laypage-curr .layui-laypage-em{left:0;top:0;padding:0}.layui-table-page .layui-laypage button,.layui-table-page .layui-laypage input{height:26px;line-height:26px}.layui-table-page .layui-laypage input{width:40px}.layui-table-page .layui-laypage button{padding:0 10px}.layui-table-page select{height:18px}.layui-table-pagebar{float:right;line-height:23px}.layui-table-pagebar .layui-btn-sm{margin-top:-1px}.layui-table-pagebar .layui-btn-xs{margin-top:2px}.layui-table-view select[lay-ignore]{display:inline-block}.layui-table-patch .layui-table-cell{padding:0;width:30px}.layui-table-edit{position:absolute;left:0;top:0;z-index:189;min-width:100%;min-height:100%;padding:5px 14px;border-radius:0;box-shadow:1px 1px 20px rgba(0,0,0,.15);background-color:#fff}.layui-table-edit:focus{border-color:#16b777!important}input.layui-input.layui-table-edit{height:100%}select.layui-table-edit{padding:0 0 0 10px;border-color:#d2d2d2}.layui-table-view .layui-form-checkbox,.layui-table-view .layui-form-radio,.layui-table-view .layui-form-switch{top:0;margin:0}.layui-table-view .layui-form-checkbox{top:-1px;height:26px;line-height:26px}.layui-table-view .layui-form-checkbox i{height:26px}.layui-table-grid .layui-table-cell{overflow:visible}.layui-table-grid-down{position:absolute;top:0;right:0;width:24px;height:100%;padding:5px 0;border-width:0;border-left-width:1px;text-align:center;background-color:#fff;color:#999;cursor:pointer}.layui-table-grid-down .layui-icon{position:absolute;top:50%;left:50%;margin:-8px 0 0 -8px;font-size:14px}.layui-table-grid-down:hover{background-color:#fbfbfb}.layui-table-expanded{height:95px}.layui-table-expanded .layui-table-cell,.layui-table-view .layui-table[lay-size=lg] .layui-table-expanded .layui-table-cell,.layui-table-view .layui-table[lay-size=sm] .layui-table-expanded .layui-table-cell{height:auto;max-height:94px;white-space:normal;text-overflow:clip}.layui-table-cell-c{position:absolute;bottom:-10px;right:50%;margin-right:-9px;width:20px;height:20px;line-height:18px;cursor:pointer;text-align:center;background-color:#fff;border:1px solid #eee;border-radius:50%;z-index:1000;transition:.3s all;font-size:14px}.layui-table-cell-c:hover{border-color:#16b777}.layui-table-expanded td:hover .layui-table-cell{overflow:auto}.layui-table-main>.layui-table>tbody>tr:last-child>td>.layui-table-cell-c{bottom:0}body .layui-table-tips .layui-layer-content{background:0 0;padding:0;box-shadow:0 1px 6px rgba(0,0,0,.12)}.layui-table-tips-main{margin:-49px 0 0 -1px;max-height:150px;padding:8px 15px;font-size:14px;overflow-y:scroll;background-color:#fff;color:#5f5f5f}.layui-table-tips-c{position:absolute;right:-3px;top:-13px;width:20px;height:20px;padding:3px;cursor:pointer;background-color:#5f5f5f;border-radius:50%;color:#fff}.layui-table-tips-c:hover{background-color:#777}.layui-table-tips-c:before{position:relative;right:-2px}.layui-table-tree-nodeIcon{max-width:20px}.layui-table-tree-nodeIcon>*{width:100%}.layui-table-tree-flexIcon,.layui-table-tree-nodeIcon{margin-right:2px}.layui-table-tree-flexIcon{cursor:pointer}.layui-upload-file{display:none!important;opacity:.01;filter:Alpha(opacity=1)}.layui-upload-list{margin:11px 0}.layui-upload-choose{max-width:200px;padding:0 10px;color:#999;font-size:14px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-upload-drag{position:relative;display:inline-block;padding:30px;border:1px dashed #e2e2e2;background-color:#fff;text-align:center;cursor:pointer;color:#999}.layui-upload-drag .layui-icon{font-size:50px;color:#16baaa}.layui-upload-drag[lay-over]{border-color:#16baaa}.layui-upload-form{display:inline-block}.layui-upload-iframe{position:absolute;width:0;height:0;border:0;visibility:hidden}.layui-upload-wrap{position:relative;display:inline-block;vertical-align:middle}.layui-upload-wrap .layui-upload-file{display:block!important;position:absolute;left:0;top:0;z-index:10;font-size:100px;width:100%;height:100%;opacity:.01;filter:Alpha(opacity=1);cursor:pointer}.layui-btn-container .layui-upload-choose{padding-left:0}.layui-menu{position:relative;margin:5px 0;background-color:#fff;box-sizing:border-box}.layui-menu *{box-sizing:border-box}.layui-menu li,.layui-menu-body-title,.layui-menu-body-title a{padding:5px 15px;color:initial}.layui-menu li{position:relative;margin:0 0 1px;line-height:26px;color:rgba(0,0,0,.8);font-size:14px;white-space:nowrap;cursor:pointer;transition:all .3s}.layui-menu li:hover{background-color:#f8f8f8}.layui-menu li.layui-disabled,.layui-menu li.layui-disabled *{background:0 0!important;color:#d2d2d2!important;cursor:not-allowed!important}.layui-menu-item-parent:hover>.layui-menu-body-panel{display:block;animation-name:layui-fadein;animation-duration:.3s;animation-fill-mode:both;animation-delay:.2s}.layui-menu-item-group>.layui-menu-body-title,.layui-menu-item-parent>.layui-menu-body-title{padding-right:38px}.layui-menu .layui-menu-item-divider:hover,.layui-menu .layui-menu-item-group:hover,.layui-menu .layui-menu-item-none:hover{background:0 0;cursor:default}.layui-menu .layui-menu-item-group>ul{margin:5px 0 -5px}.layui-menu .layui-menu-item-group>.layui-menu-body-title{color:rgba(0,0,0,.35);user-select:none}.layui-menu .layui-menu-item-none{color:rgba(0,0,0,.35);cursor:default}.layui-menu .layui-menu-item-none{text-align:center}.layui-menu .layui-menu-item-divider{margin:5px 0;padding:0;height:0;line-height:0;border-bottom:1px solid #eee;overflow:hidden}.layui-menu .layui-menu-item-down:hover,.layui-menu .layui-menu-item-up:hover{cursor:pointer}.layui-menu .layui-menu-item-up>.layui-menu-body-title{color:rgba(0,0,0,.8)}.layui-menu .layui-menu-item-up>ul{visibility:hidden;height:0;overflow:hidden}.layui-menu .layui-menu-item-down>.layui-menu-body-title>.layui-icon-down{transform:rotate(180deg)}.layui-menu .layui-menu-item-up>.layui-menu-body-title>.layui-icon-up{transform:rotate(-180deg)}.layui-menu .layui-menu-item-down:hover>.layui-menu-body-title>.layui-icon,.layui-menu .layui-menu-item-up>.layui-menu-body-title:hover>.layui-icon{color:#000}.layui-menu .layui-menu-item-down>ul{visibility:visible;height:auto}.layui-menu .layui-menu-item-checked,.layui-menu .layui-menu-item-checked2{background-color:#f8f8f8!important;color:#16b777}.layui-menu .layui-menu-item-checked a,.layui-menu .layui-menu-item-checked2 a{color:#16b777}.layui-menu .layui-menu-item-checked:after{position:absolute;right:-1px;top:0;bottom:0;border-right:3px solid #16b777;content:""}.layui-menu-body-title{position:relative;margin:-5px -15px;overflow:hidden;text-overflow:ellipsis}.layui-menu-body-title a{display:block;margin:-5px -15px;color:rgba(0,0,0,.8)}.layui-menu-body-title a:hover{transition:all .3s}.layui-menu-body-title>.layui-icon{position:absolute;right:15px;top:50%;margin-top:-6px;line-height:normal;font-size:14px;transition:all .2s;-webkit-transition:all .2s}.layui-menu-body-title>.layui-icon:hover{transition:all .3s}.layui-menu-body-title>.layui-icon-right{right:14px}.layui-menu-body-panel{display:none;position:absolute;top:-7px;left:100%;z-index:1000;margin-left:13px;padding:5px 0}.layui-menu-body-panel:before{content:"";position:absolute;width:20px;left:-16px;top:0;bottom:0}.layui-menu-body-panel-left{left:auto;right:100%;margin:0 13px 0}.layui-menu-body-panel-left:before{left:auto;right:-16px}.layui-menu-lg li{line-height:32px}.layui-menu-lg .layui-menu-body-title a:hover,.layui-menu-lg li:hover{background:0 0;color:#16b777}.layui-menu-lg li .layui-menu-body-panel{margin-left:14px}.layui-menu-lg li .layui-menu-body-panel-left{margin:0 15px 0}.layui-dropdown{position:absolute;left:-999999px;top:-999999px;z-index:77777777;margin:5px 0;min-width:100px}.layui-dropdown:before{content:"";position:absolute;width:100%;height:6px;left:0;top:-6px}.layui-dropdown-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px");position:fixed;_position:absolute;pointer-events:auto}.layui-nav{position:relative;padding:0 15px;background-color:#2f363c;color:#fff;border-radius:2px;font-size:0;box-sizing:border-box}.layui-nav *{font-size:14px}.layui-nav .layui-nav-item{position:relative;display:inline-block;*display:inline;*zoom:1;margin-top:0;list-style:none;vertical-align:middle;line-height:60px}.layui-nav .layui-nav-item a{display:block;padding:0 20px;color:#fff;color:rgba(255,255,255,.7);transition:all .3s;-webkit-transition:all .3s}.layui-nav .layui-this:after,.layui-nav-bar{content:"";position:absolute;left:0;top:0;width:0;height:3px;background-color:#16b777;transition:all .2s;-webkit-transition:all .2s;pointer-events:none}.layui-nav-bar{z-index:1000}.layui-nav[lay-bar=disabled] .layui-nav-bar{display:none}.layui-nav .layui-nav-item a:hover,.layui-nav .layui-this a{color:#fff;text-decoration:none}.layui-nav .layui-this:after{top:auto;bottom:0;width:100%}.layui-nav-img{width:30px;height:30px;margin-right:10px;border-radius:50%}.layui-nav .layui-nav-more{position:absolute;top:0;right:3px;left:auto!important;margin-top:0;font-size:12px;cursor:pointer;transition:all .2s;-webkit-transition:all .2s}.layui-nav .layui-nav-mored,.layui-nav-itemed>a .layui-nav-more{transform:rotate(180deg)}.layui-nav-child{display:none;position:absolute;left:0;top:65px;min-width:100%;line-height:36px;padding:5px 0;box-shadow:0 2px 4px rgba(0,0,0,.12);border:1px solid #eee;background-color:#fff;z-index:100;border-radius:2px;white-space:nowrap;box-sizing:border-box}.layui-nav .layui-nav-child a{color:#5f5f5f;color:rgba(0,0,0,.8)}.layui-nav .layui-nav-child a:hover{background-color:#f8f8f8;color:rgba(0,0,0,.8)}.layui-nav-child dd{margin:1px 0;position:relative}.layui-nav-child dd.layui-this{background-color:#f8f8f8;color:#000}.layui-nav-child dd.layui-this:after{display:none}.layui-nav-child-r{left:auto;right:0}.layui-nav-child-c{text-align:center}.layui-nav.layui-nav-tree{width:200px;padding:0}.layui-nav-tree .layui-nav-item{display:block;width:100%;line-height:40px}.layui-nav-tree .layui-nav-item a{position:relative;height:40px;line-height:40px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-nav-tree .layui-nav-item>a{padding-top:5px;padding-bottom:5px}.layui-nav-tree .layui-nav-more{right:15px}.layui-nav-tree .layui-nav-item>a .layui-nav-more{padding:5px 0}.layui-nav-tree .layui-nav-bar{width:5px;height:0}.layui-side .layui-nav-tree .layui-nav-bar{width:2px}.layui-nav-tree .layui-nav-child dd.layui-this,.layui-nav-tree .layui-nav-child dd.layui-this a,.layui-nav-tree .layui-this,.layui-nav-tree .layui-this>a,.layui-nav-tree .layui-this>a:hover{background-color:#16baaa;color:#fff}.layui-nav-tree .layui-this:after{display:none}.layui-nav-itemed>a,.layui-nav-tree .layui-nav-title a,.layui-nav-tree .layui-nav-title a:hover{color:#fff!important}.layui-nav-tree .layui-nav-bar{background-color:#16baaa}.layui-nav-tree .layui-nav-child{position:relative;z-index:0;top:0;border:none;background:0 0;background-color:rgba(0,0,0,.3);box-shadow:none}.layui-nav-tree .layui-nav-child dd{margin:0}.layui-nav-tree .layui-nav-child a{color:#fff;color:rgba(255,255,255,.7)}.layui-nav-tree .layui-nav-child a:hover{background:0 0;color:#fff}.layui-nav-itemed>.layui-nav-child,.layui-nav-itemed>.layui-nav-child>.layui-this>.layui-nav-child{display:block}.layui-nav-side{position:fixed;top:0;bottom:0;left:0;overflow-x:hidden;z-index:999}.layui-nav-tree.layui-bg-gray a,.layui-nav.layui-bg-gray .layui-nav-item a{color:#373737;color:rgba(0,0,0,.8)}.layui-nav-tree.layui-bg-gray .layui-nav-itemed>a{color:#000!important}.layui-nav.layui-bg-gray .layui-this a{color:#16b777}.layui-nav-tree.layui-bg-gray .layui-nav-child{padding-left:11px;background:0 0}.layui-nav-tree.layui-bg-gray .layui-nav-child dd.layui-this,.layui-nav-tree.layui-bg-gray .layui-nav-child dd.layui-this a,.layui-nav-tree.layui-bg-gray .layui-this,.layui-nav-tree.layui-bg-gray .layui-this>a{background:0 0!important;color:#16b777!important;font-weight:700}.layui-nav-tree.layui-bg-gray .layui-nav-bar{background-color:#16b777}.layui-breadcrumb{visibility:hidden;font-size:0}.layui-breadcrumb>*{font-size:14px}.layui-breadcrumb a{color:#999!important}.layui-breadcrumb a:hover{color:#16b777!important}.layui-breadcrumb a cite{color:#5f5f5f;font-style:normal}.layui-breadcrumb span[lay-separator]{margin:0 10px;color:#999}.layui-tab{margin:10px 0;text-align:left!important}.layui-tab[overflow]>.layui-tab-title{overflow:hidden}.layui-tab .layui-tab-title{position:relative;left:0;height:40px;white-space:nowrap;font-size:0;border-bottom-width:1px;border-bottom-style:solid;transition:all .2s;-webkit-transition:all .2s}.layui-tab .layui-tab-title li{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;font-size:14px;transition:all .2s;-webkit-transition:all .2s}.layui-tab .layui-tab-title li{position:relative;line-height:40px;min-width:65px;margin:0;padding:0 15px;text-align:center;cursor:pointer}.layui-tab .layui-tab-title li a{display:block;padding:0 15px;margin:0 -15px}.layui-tab-title .layui-this{color:#000}.layui-tab-title .layui-this:after{position:absolute;left:0;top:0;content:"";width:100%;height:41px;border-width:1px;border-style:solid;border-bottom-color:#fff;border-radius:2px 2px 0 0;box-sizing:border-box;pointer-events:none}.layui-tab-bar{position:absolute;right:0;top:0;z-index:10;width:30px;height:39px;line-height:39px;border-width:1px;border-style:solid;border-radius:2px;text-align:center;background-color:#fff;cursor:pointer}.layui-tab-bar .layui-icon{position:relative;display:inline-block;top:3px;transition:all .3s;-webkit-transition:all .3s}.layui-tab-item{display:none}.layui-tab-more{padding-right:30px;height:auto!important;white-space:normal!important}.layui-tab-more li.layui-this:after{border-bottom-color:#eee;border-radius:2px}.layui-tab-more .layui-tab-bar .layui-icon{top:-2px;top:3px\0;-webkit-transform:rotate(180deg);transform:rotate(180deg)}:root .layui-tab-more .layui-tab-bar .layui-icon{top:-2px\0/IE9}.layui-tab-content{padding:15px 0}.layui-tab-title li .layui-tab-close{position:relative;display:inline-block;width:18px;height:18px;line-height:20px;margin-left:8px;top:1px;text-align:center;font-size:14px;color:#c2c2c2;transition:all .2s;-webkit-transition:all .2s}.layui-tab-title li .layui-tab-close:hover{border-radius:2px;background-color:#ff5722;color:#fff}.layui-tab-brief>.layui-tab-title .layui-this{color:#16baaa}.layui-tab-brief>.layui-tab-more li.layui-this:after,.layui-tab-brief>.layui-tab-title .layui-this:after{border:none;border-radius:0;border-bottom:2px solid #16b777}.layui-tab-brief[overflow]>.layui-tab-title .layui-this:after{top:-1px}.layui-tab-card{border-width:1px;border-style:solid;border-radius:2px;box-shadow:0 2px 5px 0 rgba(0,0,0,.1)}.layui-tab-card>.layui-tab-title{background-color:#fafafa}.layui-tab-card>.layui-tab-title li{margin-right:-1px;margin-left:-1px}.layui-tab-card>.layui-tab-title .layui-this{background-color:#fff}.layui-tab-card>.layui-tab-title .layui-this:after{border-top:none;border-width:1px;border-bottom-color:#fff}.layui-tab-card>.layui-tab-title .layui-tab-bar{height:40px;line-height:40px;border-radius:0;border-top:none;border-right:none}.layui-tab-card>.layui-tab-more .layui-this{background:0 0;color:#16b777}.layui-tab-card>.layui-tab-more .layui-this:after{border:none}.layui-timeline{padding-left:5px}.layui-timeline-item{position:relative;padding-bottom:20px}.layui-timeline-axis{position:absolute;left:-5px;top:0;z-index:10;width:20px;height:20px;line-height:20px;background-color:#fff;color:#16b777;border-radius:50%;text-align:center;cursor:pointer}.layui-timeline-axis:hover{color:#ff5722}.layui-timeline-item:before{content:"";position:absolute;left:5px;top:0;z-index:0;width:1px;height:100%}.layui-timeline-item:first-child:before{display:block}.layui-timeline-item:last-child:before{display:none}.layui-timeline-content{padding-left:25px}.layui-timeline-title{position:relative;margin-bottom:10px;line-height:22px}.layui-badge,.layui-badge-dot,.layui-badge-rim{position:relative;display:inline-block;padding:0 6px;font-size:12px;text-align:center;background-color:#ff5722;color:#fff;border-radius:2px}.layui-badge{height:18px;line-height:18px}.layui-badge-dot{width:8px;height:8px;padding:0;border-radius:50%}.layui-badge-rim{height:18px;line-height:18px;border-width:1px;border-style:solid;background-color:#fff;color:#5f5f5f}.layui-btn .layui-badge,.layui-btn .layui-badge-dot{margin-left:5px}.layui-nav .layui-badge,.layui-nav .layui-badge-dot{position:absolute;top:50%;margin:-5px 6px 0}.layui-nav .layui-badge{margin-top:-10px}.layui-tab-title .layui-badge,.layui-tab-title .layui-badge-dot{left:5px;top:-2px}.layui-carousel{position:relative;left:0;top:0;background-color:#f8f8f8}.layui-carousel>[carousel-item]{position:relative;width:100%;height:100%;overflow:hidden}.layui-carousel>[carousel-item]:before{position:absolute;content:'\e63d';left:50%;top:50%;width:100px;line-height:20px;margin:-10px 0 0 -50px;text-align:center;color:#c2c2c2;font-family:layui-icon!important;font-size:30px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-carousel>[carousel-item]>*{display:none;position:absolute;left:0;top:0;width:100%;height:100%;background-color:#f8f8f8;transition-duration:.3s;-webkit-transition-duration:.3s}.layui-carousel-updown>*{-webkit-transition:.3s ease-in-out up;transition:.3s ease-in-out up}.layui-carousel-arrow{display:none\0;opacity:0;position:absolute;left:10px;top:50%;margin-top:-18px;width:36px;height:36px;line-height:36px;text-align:center;font-size:20px;border:none 0;border-radius:50%;background-color:rgba(0,0,0,.2);color:#fff;-webkit-transition-duration:.3s;transition-duration:.3s;cursor:pointer}.layui-carousel-arrow[lay-type=add]{left:auto!important;right:10px}.layui-carousel[lay-arrow=always] .layui-carousel-arrow{opacity:1;left:20px}.layui-carousel[lay-arrow=always] .layui-carousel-arrow[lay-type=add]{right:20px}.layui-carousel[lay-arrow=none] .layui-carousel-arrow{display:none}.layui-carousel-arrow:hover,.layui-carousel-ind ul:hover{background-color:rgba(0,0,0,.35)}.layui-carousel:hover .layui-carousel-arrow{display:block\0;opacity:1;left:20px}.layui-carousel:hover .layui-carousel-arrow[lay-type=add]{right:20px}.layui-carousel-ind{position:relative;top:-35px;width:100%;line-height:0!important;text-align:center;font-size:0}.layui-carousel[lay-indicator=outside]{margin-bottom:30px}.layui-carousel[lay-indicator=outside] .layui-carousel-ind{top:10px}.layui-carousel[lay-indicator=outside] .layui-carousel-ind ul{background-color:rgba(0,0,0,.5)}.layui-carousel[lay-indicator=none] .layui-carousel-ind{display:none}.layui-carousel-ind ul{display:inline-block;padding:5px;background-color:rgba(0,0,0,.2);border-radius:10px;-webkit-transition-duration:.3s;transition-duration:.3s}.layui-carousel-ind ul li{display:inline-block;width:10px;height:10px;margin:0 3px;font-size:14px;background-color:#eee;background-color:rgba(255,255,255,.5);border-radius:50%;cursor:pointer;-webkit-transition-duration:.3s;transition-duration:.3s}.layui-carousel-ind ul li:hover{background-color:rgba(255,255,255,.7)}.layui-carousel-ind ul li.layui-this{background-color:#fff}.layui-carousel>[carousel-item]>.layui-carousel-next,.layui-carousel>[carousel-item]>.layui-carousel-prev,.layui-carousel>[carousel-item]>.layui-this{display:block}.layui-carousel>[carousel-item]>.layui-this{left:0}.layui-carousel>[carousel-item]>.layui-carousel-prev{left:-100%}.layui-carousel>[carousel-item]>.layui-carousel-next{left:100%}.layui-carousel>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel>[carousel-item]>.layui-carousel-prev.layui-carousel-right{left:0}.layui-carousel>[carousel-item]>.layui-this.layui-carousel-left{left:-100%}.layui-carousel>[carousel-item]>.layui-this.layui-carousel-right{left:100%}.layui-carousel[lay-anim=updown] .layui-carousel-arrow{left:50%!important;top:20px;margin:0 0 0 -18px}.layui-carousel[lay-anim=updown] .layui-carousel-arrow[lay-type=add]{top:auto!important;bottom:20px}.layui-carousel[lay-anim=updown] .layui-carousel-ind{position:absolute;top:50%;right:20px;width:auto;height:auto}.layui-carousel[lay-anim=updown] .layui-carousel-ind ul{padding:3px 5px}.layui-carousel[lay-anim=updown] .layui-carousel-ind li{display:block;margin:6px 0}.layui-carousel[lay-anim=updown]>[carousel-item]>*{left:0!important}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this{top:0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-prev{top:-100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-next{top:100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-prev.layui-carousel-right{top:0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this.layui-carousel-left{top:-100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this.layui-carousel-right{top:100%}.layui-carousel[lay-anim=fade]>[carousel-item]>*{left:0!important}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-next,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-prev{opacity:0}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-prev.layui-carousel-right{opacity:1}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-this.layui-carousel-left,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-this.layui-carousel-right{opacity:0}.layui-fixbar{position:fixed;right:16px;bottom:16px;z-index:999999}.layui-fixbar li{width:50px;height:50px;line-height:50px;margin-bottom:1px;text-align:center;cursor:pointer;font-size:30px;background-color:#9f9f9f;color:#fff;border-radius:2px;opacity:.95}.layui-fixbar li:hover{opacity:.85}.layui-fixbar li:active{opacity:1}.layui-fixbar .layui-fixbar-top{display:none;font-size:40px}body .layui-util-face{border:none;background:0 0}body .layui-util-face .layui-layer-content{padding:0;background-color:#fff;color:#5f5f5f;box-shadow:none}.layui-util-face .layui-layer-TipsG{display:none}.layui-util-face ul{position:relative;width:372px;padding:10px;border:1px solid #d9d9d9;background-color:#fff;box-shadow:0 0 20px rgba(0,0,0,.2)}.layui-util-face ul li{cursor:pointer;float:left;border:1px solid #e8e8e8;height:22px;width:26px;overflow:hidden;margin:-1px 0 0 -1px;padding:4px 2px;text-align:center}.layui-util-face ul li:hover{position:relative;z-index:2;border:1px solid #eb7350;background:#fff9ec}.layui-code{display:block;position:relative;padding:15px;line-height:20px;border:1px solid #eee;border-left-width:6px;background-color:#fff;color:#333;font-family:"Courier New",Consolas,"Lucida Console";font-size:12px}.layui-transfer-box,.layui-transfer-header,.layui-transfer-search{border-width:0;border-style:solid;border-color:#eee}.layui-transfer-box{position:relative;display:inline-block;vertical-align:middle;border-width:1px;width:200px;height:360px;border-radius:2px;background-color:#fff}.layui-transfer-box .layui-form-checkbox{width:100%;margin:0!important}.layui-transfer-header{height:38px;line-height:38px;padding:0 11px;border-bottom-width:1px}.layui-transfer-search{position:relative;padding:11px;border-bottom-width:1px}.layui-transfer-search .layui-input{height:32px;padding-left:30px;font-size:12px}.layui-transfer-search .layui-icon-search{position:absolute;left:20px;top:50%;line-height:normal;margin-top:-8px;color:#5f5f5f}.layui-transfer-active{margin:0 15px;display:inline-block;vertical-align:middle}.layui-transfer-active .layui-btn{display:block;margin:0;padding:0 15px;background-color:#16b777;border-color:#16b777;color:#fff}.layui-transfer-active .layui-btn-disabled{background-color:#fbfbfb;border-color:#eee;color:#d2d2d2}.layui-transfer-active .layui-btn:first-child{margin-bottom:15px}.layui-transfer-active .layui-btn .layui-icon{margin:0;font-size:14px!important}.layui-transfer-data{padding:5px 0;overflow:auto}.layui-transfer-data li{height:32px;line-height:32px;margin-top:0!important;padding:0 11px;list-style-type:none!important}.layui-transfer-data li:hover{background-color:#f8f8f8;transition:.5s all}.layui-transfer-data .layui-none{padding:15px 11px;text-align:center;color:#999}.layui-rate,.layui-rate *{display:inline-block;vertical-align:middle}.layui-rate{padding:11px 6px 11px 0;font-size:0}.layui-rate li{margin-top:0!important}.layui-rate li i.layui-icon{font-size:20px;color:#ffb800}.layui-rate li i.layui-icon{margin-right:5px;transition:all .3s;-webkit-transition:all .3s}.layui-rate li i:hover,.layui-rate-hover{cursor:pointer;transform:scale(1.12);-webkit-transform:scale(1.12)}.layui-rate[readonly] li i:hover{cursor:default;transform:scale(1)}.layui-colorpicker{width:38px;height:38px;border:1px solid #eee;padding:5px;border-radius:2px;line-height:24px;display:inline-block;cursor:pointer;transition:all .3s;-webkit-transition:all .3s;box-sizing:border-box}.layui-colorpicker:hover{border-color:#d2d2d2}.layui-colorpicker.layui-colorpicker-lg{width:44px;height:44px;line-height:30px}.layui-colorpicker.layui-colorpicker-sm{width:30px;height:30px;line-height:20px;padding:3px}.layui-colorpicker.layui-colorpicker-xs{width:22px;height:22px;line-height:16px;padding:1px}.layui-colorpicker-trigger-bgcolor{display:block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);border-radius:2px}.layui-colorpicker-trigger-span{display:block;height:100%;box-sizing:border-box;border:1px solid rgba(0,0,0,.15);border-radius:2px;text-align:center}.layui-colorpicker-trigger-i{display:inline-block;color:#fff;font-size:12px}.layui-colorpicker-trigger-i.layui-icon-close{color:#999}.layui-colorpicker-main{position:absolute;left:-999999px;top:-999999px;z-index:77777777;width:280px;margin:5px 0;padding:7px;background:#fff;border:1px solid #d2d2d2;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12)}.layui-colorpicker-main-wrapper{height:180px;position:relative}.layui-colorpicker-basis{width:260px;height:100%;position:relative}.layui-colorpicker-basis-white{width:100%;height:100%;position:absolute;top:0;left:0;background:linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.layui-colorpicker-basis-black{width:100%;height:100%;position:absolute;top:0;left:0;background:linear-gradient(0deg,#000,transparent)}.layui-colorpicker-basis-cursor{width:10px;height:10px;border:1px solid #fff;border-radius:50%;position:absolute;top:-3px;right:-3px;cursor:pointer}.layui-colorpicker-side{position:absolute;top:0;right:0;width:12px;height:100%;background:linear-gradient(red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.layui-colorpicker-side-slider{width:100%;height:5px;box-shadow:0 0 1px #888;box-sizing:border-box;background:#fff;border-radius:1px;border:1px solid #f0f0f0;cursor:pointer;position:absolute;left:0}.layui-colorpicker-main-alpha{display:none;height:12px;margin-top:7px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.layui-colorpicker-alpha-bgcolor{height:100%;position:relative}.layui-colorpicker-alpha-slider{width:5px;height:100%;box-shadow:0 0 1px #888;box-sizing:border-box;background:#fff;border-radius:1px;border:1px solid #f0f0f0;cursor:pointer;position:absolute;top:0}.layui-colorpicker-main-pre{padding-top:7px;font-size:0}.layui-colorpicker-pre{width:20px;height:20px;border-radius:2px;display:inline-block;margin-left:6px;margin-bottom:7px;cursor:pointer}.layui-colorpicker-pre:nth-child(11n+1){margin-left:0}.layui-colorpicker-pre-isalpha{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.layui-colorpicker-pre.layui-this{box-shadow:0 0 3px 2px rgba(0,0,0,.15)}.layui-colorpicker-pre>div{height:100%;border-radius:2px}.layui-colorpicker-main-input{text-align:right;padding-top:7px}.layui-colorpicker-main-input .layui-btn-container .layui-btn{margin:0 0 0 10px}.layui-colorpicker-main-input div.layui-inline{float:left;margin-right:10px;font-size:14px}.layui-colorpicker-main-input input.layui-input{width:150px;height:30px;color:#5f5f5f}.layui-slider{height:4px;background:#eee;border-radius:3px;position:relative;cursor:pointer}.layui-slider-bar{border-radius:3px;position:absolute;height:100%}.layui-slider-step{position:absolute;top:0;width:4px;height:4px;border-radius:50%;background:#fff;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.layui-slider-wrap{width:36px;height:36px;position:absolute;top:-16px;-webkit-transform:translateX(-50%);transform:translateX(-50%);z-index:10;text-align:center}.layui-slider-wrap-btn{width:12px;height:12px;border-radius:50%;background:#fff;display:inline-block;vertical-align:middle;cursor:pointer;transition:.3s}.layui-slider-wrap:after{content:"";height:100%;display:inline-block;vertical-align:middle}.layui-slider-wrap-btn.layui-slider-hover,.layui-slider-wrap-btn:hover{transform:scale(1.2)}.layui-slider-wrap-btn.layui-disabled:hover{transform:scale(1)!important}.layui-slider-tips{position:absolute;top:-42px;z-index:77777777;white-space:nowrap;display:none;-webkit-transform:translateX(-50%);transform:translateX(-50%);color:#fff;background:#000;border-radius:3px;height:25px;line-height:25px;padding:0 10px}.layui-slider-tips:after{content:"";position:absolute;bottom:-12px;left:50%;margin-left:-6px;width:0;height:0;border-width:6px;border-style:solid;border-color:#000 transparent transparent transparent}.layui-slider-input{width:70px;height:32px;border:1px solid #eee;border-radius:3px;font-size:16px;line-height:32px;position:absolute;right:0;top:-14px;box-sizing:border-box}.layui-slider-input-btn{position:absolute;top:0;right:0;width:20px;height:100%;border-left:1px solid #eee}.layui-slider-input-btn i{cursor:pointer;position:absolute;right:0;bottom:0;width:20px;height:50%;font-size:12px;line-height:16px;text-align:center;color:#999}.layui-slider-input-btn i:first-child{top:0;border-bottom:1px solid #eee}.layui-slider-input-txt{height:100%;font-size:14px}.layui-slider-input-txt input{height:100%;border:none;padding-right:21px}.layui-slider-input-btn i:hover{color:#16baaa}.layui-slider-vertical{width:4px;margin-left:33px}.layui-slider-vertical .layui-slider-bar{width:4px}.layui-slider-vertical .layui-slider-step{top:auto;left:0;-webkit-transform:translateY(50%);transform:translateY(50%)}.layui-slider-vertical .layui-slider-wrap{top:auto;left:-16px;-webkit-transform:translateY(50%);transform:translateY(50%)}.layui-slider-vertical .layui-slider-tips{top:auto;left:2px}@media \0screen{.layui-slider-wrap-btn{margin-left:-20px}.layui-slider-vertical .layui-slider-wrap-btn{margin-left:0;margin-bottom:-20px}.layui-slider-vertical .layui-slider-tips{margin-left:-8px}.layui-slider>span{margin-left:8px}}.layui-tree{line-height:22px}.layui-tree .layui-form-checkbox{margin:0!important}.layui-tree-set{width:100%;position:relative}.layui-tree-pack{display:none;padding-left:20px;position:relative}.layui-tree-line .layui-tree-pack{padding-left:27px}.layui-tree-line .layui-tree-set .layui-tree-set:after{content:"";position:absolute;top:14px;left:-9px;width:17px;height:0;border-top:1px dotted #c0c4cc}.layui-tree-entry{position:relative;padding:3px 0;height:26px;white-space:nowrap}.layui-tree-entry:hover{background-color:#eee}.layui-tree-line .layui-tree-entry:hover{background-color:rgba(0,0,0,0)}.layui-tree-line .layui-tree-entry:hover .layui-tree-txt{color:#999;text-decoration:underline;transition:.3s}.layui-tree-main{display:inline-block;vertical-align:middle;cursor:pointer;padding-right:10px}.layui-tree-line .layui-tree-set:before{content:"";position:absolute;top:0;left:-9px;width:0;height:100%;border-left:1px dotted #c0c4cc}.layui-tree-line .layui-tree-set.layui-tree-setLineShort:before{height:13px}.layui-tree-line .layui-tree-set.layui-tree-setHide:before{height:0}.layui-tree-iconClick{display:inline-block;vertical-align:middle;position:relative;height:20px;line-height:20px;margin:0 10px;color:#c0c4cc}.layui-tree-icon{height:14px;line-height:12px;width:14px;text-align:center;border:1px solid #c0c4cc}.layui-tree-iconClick .layui-icon{font-size:18px}.layui-tree-icon .layui-icon{font-size:12px;color:#5f5f5f}.layui-tree-iconArrow{padding:0 5px}.layui-tree-iconArrow:after{content:"";position:absolute;left:4px;top:3px;z-index:100;width:0;height:0;border-width:5px;border-style:solid;border-color:transparent transparent transparent #c0c4cc;transition:.5s}.layui-tree-spread>.layui-tree-entry .layui-tree-iconClick>.layui-tree-iconArrow:after{transform:rotate(90deg) translate(3px,4px)}.layui-tree-txt{display:inline-block;vertical-align:middle;color:#555}.layui-tree-search{margin-bottom:15px;color:#5f5f5f}.layui-tree-btnGroup{visibility:hidden;display:inline-block;vertical-align:middle;position:relative}.layui-tree-btnGroup .layui-icon{display:inline-block;vertical-align:middle;padding:0 2px;cursor:pointer}.layui-tree-btnGroup .layui-icon:hover{color:#999;transition:.3s}.layui-tree-entry:hover .layui-tree-btnGroup{visibility:visible}.layui-tree-editInput{position:relative;display:inline-block;vertical-align:middle;height:20px;line-height:20px;padding:0;border:none;background-color:rgba(0,0,0,.05)}.layui-tree-emptyText{text-align:center;color:#999}.layui-anim{-webkit-animation-duration:.3s;-webkit-animation-fill-mode:both;animation-duration:.3s;animation-fill-mode:both}.layui-anim.layui-icon{display:inline-block}.layui-anim-loop{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.layui-trans,.layui-trans a{transition:all .2s;-webkit-transition:all .2s}@-webkit-keyframes layui-rotate{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@keyframes layui-rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}.layui-anim-rotate{-webkit-animation-name:layui-rotate;animation-name:layui-rotate;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes layui-up{from{-webkit-transform:translate3d(0,100%,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes layui-up{from{transform:translate3d(0,100%,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-anim-up{-webkit-animation-name:layui-up;animation-name:layui-up}@-webkit-keyframes layui-upbit{from{-webkit-transform:translate3d(0,15px,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes layui-upbit{from{transform:translate3d(0,15px,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-anim-upbit{-webkit-animation-name:layui-upbit;animation-name:layui-upbit}@keyframes layui-down{0%{opacity:.3;transform:translate3d(0,-100%,0)}100%{opacity:1;transform:translate3d(0,0,0)}}.layui-anim-down{animation-name:layui-down}@keyframes layui-downbit{0%{opacity:.3;transform:translate3d(0,-5px,0)}100%{opacity:1;transform:translate3d(0,0,0)}}.layui-anim-downbit{animation-name:layui-downbit}@-webkit-keyframes layui-scale{0%{opacity:.3;-webkit-transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1)}}@keyframes layui-scale{0%{opacity:.3;-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-ms-transform:scale(1);transform:scale(1)}}.layui-anim-scale{-webkit-animation-name:layui-scale;animation-name:layui-scale}@-webkit-keyframes layui-scale-spring{0%{opacity:.5;-webkit-transform:scale(.5)}80%{opacity:.8;-webkit-transform:scale(1.1)}100%{opacity:1;-webkit-transform:scale(1)}}@keyframes layui-scale-spring{0%{opacity:.5;transform:scale(.5)}80%{opacity:.8;transform:scale(1.1)}100%{opacity:1;transform:scale(1)}}.layui-anim-scaleSpring{-webkit-animation-name:layui-scale-spring;animation-name:layui-scale-spring}@keyframes layui-scalesmall{0%{opacity:.3;transform:scale(1.5)}100%{opacity:1;transform:scale(1)}}.layui-anim-scalesmall{animation-name:layui-scalesmall}@keyframes layui-scalesmall-spring{0%{opacity:.3;transform:scale(1.5)}80%{opacity:.8;transform:scale(.9)}100%{opacity:1;transform:scale(1)}}.layui-anim-scalesmall-spring{animation-name:layui-scalesmall-spring}@-webkit-keyframes layui-fadein{0%{opacity:0}100%{opacity:1}}@keyframes layui-fadein{0%{opacity:0}100%{opacity:1}}.layui-anim-fadein{-webkit-animation-name:layui-fadein;animation-name:layui-fadein}@-webkit-keyframes layui-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes layui-fadeout{0%{opacity:1}100%{opacity:0}}.layui-anim-fadeout{-webkit-animation-name:layui-fadeout;animation-name:layui-fadeout}html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-wrap{font-size:13px;font-family:"Courier New",Consolas,"Lucida Console"}.layui-code-view{display:block;position:relative;padding:0!important;border:1px solid #eee;border-left-width:6px;background-color:#fff;color:#333}.layui-code-view pre{margin:0!important}.layui-code-header{position:relative;z-index:3;padding:0 11px;height:40px;line-height:40px;border-bottom:1px solid #eee;background-color:#fafafa;font-size:12px}.layui-code-header>.layui-code-header-about{position:absolute;right:11px;top:0;color:#b7b7b7}.layui-code-header-about>a{padding-left:10px}.layui-code-wrap{position:relative;display:block;z-index:1;margin:0!important;padding:11px 0!important;overflow-x:hidden;overflow-y:auto}.layui-code-line{position:relative;line-height:19px;margin:0!important}.layui-code-line-number{position:absolute;left:0;top:0;padding:0 8px;min-width:45px;height:100%;text-align:right;user-select:none;white-space:nowrap;overflow:hidden}.layui-code-line-content{padding:0 11px;word-wrap:break-word;white-space:pre-wrap}.layui-code-ln-mode>.layui-code-wrap>.layui-code-line{padding-left:45px}.layui-code-ln-side{position:absolute;left:0;top:0;bottom:0;z-index:0;width:45px;border-right:1px solid #eee;border-color:rgb(126 122 122 / 15%);background-color:#fafafa;pointer-events:none}.layui-code-nowrap>.layui-code-wrap{overflow:auto}.layui-code-nowrap>.layui-code-wrap>.layui-code-line>.layui-code-line-content{white-space:pre;word-wrap:normal}.layui-code-nowrap>.layui-code-ln-side{border-right-width:0!important;background:0 0!important}.layui-code-fixbar{position:absolute;top:8px;right:11px;padding-right:45px;z-index:5}.layui-code-fixbar>span{position:absolute;right:0;top:0;padding:0 8px;color:#777;transition:all .3s}.layui-code-fixbar>span:hover{color:#16b777}.layui-code-copy{display:none;cursor:pointer}.layui-code-preview>.layui-code-view>.layui-code-fixbar .layui-code-copy{display:none!important}.layui-code-view:hover>.layui-code-fixbar .layui-code-copy{display:block}.layui-code-view:hover>.layui-code-fixbar .layui-code-lang-marker{display:none}.layui-code-theme-dark,.layui-code-theme-dark>.layui-code-header{border-color:rgb(126 122 122 / 15%);background-color:#1f1f1f}.layui-code-theme-dark{border-width:1px;color:#ccc}.layui-code-theme-dark>.layui-code-ln-side{border-right-color:#2a2a2a;background:0 0;color:#6e7681}.layui-code textarea{display:none}.layui-code-preview>.layui-code,.layui-code-preview>.layui-code-view{margin:0}.layui-code-preview>.layui-tab{position:relative;z-index:1;margin-bottom:0}.layui-code-preview>.layui-tab>.layui-tab-title{border-width:0}.layui-code-preview .layui-code-item{display:none}.layui-code-item-preview{position:relative;padding:16px}.layui-code-item-preview>iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:none}.layui-code-tools{position:absolute;right:11px;top:8px;line-height:normal}.layui-code-tools>i{display:inline-block;margin-left:6px;padding:3px;cursor:pointer}.layui-code-tools>i.layui-icon-file-b{color:#999}.layui-code-tools>i:hover{color:#16b777}.layui-code-full{position:fixed;left:0;top:0;z-index:1111111;width:100%;height:100%;background-color:#fff}.layui-code-full .layui-code-item{width:100%!important;border-width:0!important;border-top-width:1px!important}.layui-code-full .layui-code-item,.layui-code-full .layui-code-view,.layui-code-full .layui-code-wrap{height:calc(100vh - 51px)!important;box-sizing:border-box}.layui-code-full .layui-code-item-preview{overflow:auto}.layui-code-view.layui-code-hl{line-height:20px!important;border-left-width:1px}.layui-code-view.layui-code-hl>.layui-code-ln-side{background-color:transparent}.layui-code-theme-dark.layui-code-hl,.layui-code-theme-dark.layui-code-hl>.layui-code-ln-side{border-color:rgb(126 122 122 / 15%)}html #layuicss-laydate{display:none;position:absolute;width:1989px}.layui-laydate *{margin:0;padding:0}.layui-laydate,.layui-laydate *{box-sizing:border-box}.layui-laydate{position:absolute;z-index:99999999;margin:5px 0;border-radius:2px;font-size:14px;line-height:normal;-webkit-animation-duration:.2s;animation-duration:.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-laydate-main{width:272px}.layui-laydate-content td,.layui-laydate-header *,.layui-laydate-list li{transition-duration:.3s;-webkit-transition-duration:.3s}.layui-laydate-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px");position:fixed;_position:absolute;pointer-events:auto}@keyframes laydate-downbit{0%{opacity:.3;transform:translate3d(0,-5px,0)}100%{opacity:1;transform:translate3d(0,0,0)}}.layui-laydate{animation-name:laydate-downbit}.layui-laydate-static{position:relative;z-index:0;display:inline-block;margin:0;-webkit-animation:none;animation:none}.laydate-ym-show .laydate-next-m,.laydate-ym-show .laydate-prev-m{display:none!important}.laydate-ym-show .laydate-next-y,.laydate-ym-show .laydate-prev-y{display:inline-block!important}.laydate-ym-show .laydate-set-ym span[lay-type=month]{display:none!important}.laydate-time-show .laydate-set-ym span[lay-type=month],.laydate-time-show .laydate-set-ym span[lay-type=year],.laydate-time-show .layui-laydate-header .layui-icon{display:none!important}.layui-laydate-header{position:relative;line-height:30px;padding:10px 70px 5px}.layui-laydate-header *{display:inline-block;vertical-align:bottom}.layui-laydate-header i{position:absolute;top:10px;padding:0 5px;color:#999;font-size:18px;cursor:pointer}.layui-laydate-header i.laydate-prev-y{left:15px}.layui-laydate-header i.laydate-prev-m{left:45px}.layui-laydate-header i.laydate-next-y{right:15px}.layui-laydate-header i.laydate-next-m{right:45px}.laydate-set-ym{width:100%;text-align:center;box-sizing:border-box;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.laydate-set-ym span{padding:0 10px;cursor:pointer}.laydate-time-text{cursor:default!important}.layui-laydate-content{position:relative;padding:10px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-laydate-content table{border-collapse:collapse;border-spacing:0}.layui-laydate-content td,.layui-laydate-content th{width:36px;height:30px;padding:0;text-align:center}.layui-laydate-content th{font-weight:400}.layui-laydate-content td{position:relative;cursor:pointer}.laydate-day-mark{position:absolute;left:0;top:0;width:100%;line-height:30px;font-size:12px;overflow:hidden}.laydate-day-mark::after{position:absolute;content:'';right:2px;top:2px;width:5px;height:5px;border-radius:50%}.laydate-day-holidays:before{position:absolute;left:0;top:0;font-size:12px;transform:scale(.7)}.laydate-day-holidays:before{content:'\4F11';color:#ff5722}.laydate-day-holidays[type=work]:before{content:'\73ED';color:inherit}.layui-laydate .layui-this .laydate-day-holidays:before{color:#fff}.layui-laydate-footer{position:relative;height:46px;line-height:26px;padding:10px}.layui-laydate-footer span{display:inline-block;vertical-align:top;height:26px;line-height:24px;padding:0 10px;border:1px solid #c9c9c9;border-radius:2px;background-color:#fff;font-size:12px;cursor:pointer;white-space:nowrap;transition:all .3s}.layui-laydate-footer span:hover{color:#16b777}.layui-laydate-footer span.layui-laydate-preview{cursor:default;border-color:transparent!important}.layui-laydate-footer span.layui-laydate-preview:hover{color:#777}.layui-laydate-footer span:first-child.layui-laydate-preview{padding-left:0}.laydate-footer-btns{position:absolute;right:10px;top:10px}.laydate-footer-btns span{margin:0 0 0 -1px;border-radius:0}.laydate-footer-btns span:first-child{border-radius:2px 0 0 2px}.laydate-footer-btns span:last-child{border-radius:0 2px 2px 0}.layui-laydate-shortcut{width:80px;padding:6px 0;display:inline-block;vertical-align:top;overflow:auto;max-height:276px;text-align:center}.layui-laydate-shortcut+.layui-laydate-main{display:inline-block;border-left:1px solid #e2e2e2}.layui-laydate-shortcut>li{padding:5px 8px;cursor:pointer;line-height:18px}.layui-laydate .layui-laydate-list{position:absolute;left:0;top:0;width:100%;height:100%;padding:10px;box-sizing:border-box;background-color:#fff}.layui-laydate .layui-laydate-list>li{position:relative;display:inline-block;width:33.3%;height:36px;line-height:36px;margin:3px 0;vertical-align:middle;text-align:center;cursor:pointer;list-style:none}.layui-laydate .laydate-month-list>li{width:25%;margin:17px 0}.layui-laydate .laydate-time-list>li{height:100%;margin:0;line-height:normal;cursor:default}.layui-laydate .laydate-time-list p{position:relative;top:-4px;margin:0;line-height:29px}.layui-laydate .laydate-time-list ol{height:181px;overflow:hidden}.layui-laydate .laydate-time-list>li:hover ol{overflow-y:auto}.layui-laydate .laydate-time-list ol li{width:130%;padding-left:33px;height:30px;line-height:30px;text-align:left;cursor:pointer}.layui-laydate-hint{position:absolute;top:115px;left:50%;width:250px;margin-left:-125px;line-height:20px;padding:15px;text-align:center;font-size:12px;color:#ff5722}.layui-laydate-range{width:546px}.layui-laydate-range .layui-laydate-main{display:inline-block;vertical-align:middle;max-width:50%}.layui-laydate-range .laydate-main-list-1 .layui-laydate-content,.layui-laydate-range .laydate-main-list-1 .layui-laydate-header{border-left:1px solid #e2e2e2}.layui-laydate-range.layui-laydate-linkage .laydate-main-list-0 .laydate-next-m,.layui-laydate-range.layui-laydate-linkage .laydate-main-list-0 .laydate-next-y,.layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .laydate-prev-m,.layui-laydate-range.layui-laydate-linkage .laydate-main-list-1 .laydate-prev-y{display:none}.layui-laydate,.layui-laydate-hint{border:1px solid #d2d2d2;box-shadow:0 2px 4px rgba(0,0,0,.12);background-color:#fff;color:#777}.layui-laydate-header{border-bottom:1px solid #e2e2e2}.layui-laydate-header i:hover,.layui-laydate-header span:hover{color:#16b777}.layui-laydate-content{border-top:none 0;border-bottom:none 0}.layui-laydate-content th{color:#333}.layui-laydate-content td{color:#777}.layui-laydate-content td.laydate-day-now{color:#16b777}.layui-laydate-content td.laydate-day-now:after{content:'';position:absolute;width:100%;height:30px;left:0;top:0;border:1px solid #16b777;box-sizing:border-box}.layui-laydate-linkage .layui-laydate-content td.laydate-selected>div{background-color:#00f7de}.layui-laydate-linkage .laydate-selected:hover>div{background-color:#00f7de!important}.layui-laydate-content td.laydate-selected:after,.layui-laydate-content td:hover:after{content:none}.layui-laydate-content td>div:hover,.layui-laydate-list li:hover,.layui-laydate-shortcut>li:hover{background-color:#eee;color:#333}.laydate-time-list li ol{margin:0;padding:0;border:1px solid #e2e2e2;border-left-width:0}.laydate-time-list li:first-child ol{border-left-width:1px}.laydate-time-list>li:hover{background:0 0}.layui-laydate-content .laydate-day-next,.layui-laydate-content .laydate-day-prev{color:#d2d2d2}.layui-laydate-linkage .laydate-selected.laydate-day-next>div,.layui-laydate-linkage .laydate-selected.laydate-day-prev>div{background-color:#f8f8f8!important}.layui-laydate-footer{border-top:1px solid #e2e2e2}.layui-laydate-hint{color:#ff5722}.laydate-day-mark::after{background-color:#16b777}.layui-laydate-content td.layui-this .laydate-day-mark::after{display:none}.layui-laydate-footer span[lay-type=date]{color:#16b777}.layui-laydate .layui-this,.layui-laydate .layui-this>div{background-color:#16baaa!important;color:#fff!important}.layui-laydate .laydate-disabled,.layui-laydate .laydate-disabled:hover{background:0 0!important;color:#d2d2d2!important;cursor:not-allowed!important;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-laydate-content td>div{padding:7px 0;height:100%}.laydate-theme-molv{border:none}.laydate-theme-molv.layui-laydate-range{width:548px}.laydate-theme-molv .layui-laydate-main{width:274px}.laydate-theme-molv .layui-laydate-header{border:none;background-color:#16baaa}.laydate-theme-molv .layui-laydate-header i,.laydate-theme-molv .layui-laydate-header span{color:#f6f6f6}.laydate-theme-molv .layui-laydate-header i:hover,.laydate-theme-molv .layui-laydate-header span:hover{color:#fff}.laydate-theme-molv .layui-laydate-content{border:1px solid #e2e2e2;border-top:none;border-bottom:none}.laydate-theme-molv .laydate-main-list-1 .layui-laydate-content{border-left:none}.laydate-theme-molv .layui-laydate-footer{border:1px solid #e2e2e2}.laydate-theme-grid .laydate-month-list>li,.laydate-theme-grid .laydate-year-list>li,.laydate-theme-grid .layui-laydate-content td,.laydate-theme-grid .layui-laydate-content thead{border:1px solid #e2e2e2}.layui-laydate-linkage.laydate-theme-grid .laydate-selected,.layui-laydate-linkage.laydate-theme-grid .laydate-selected:hover{background-color:#f2f2f2!important;color:#16baaa!important}.layui-laydate-linkage.laydate-theme-grid .laydate-selected.laydate-day-next,.layui-laydate-linkage.laydate-theme-grid .laydate-selected.laydate-day-prev{color:#d2d2d2!important}.laydate-theme-grid .laydate-month-list,.laydate-theme-grid .laydate-year-list{margin:1px 0 0 1px}.laydate-theme-grid .laydate-month-list>li,.laydate-theme-grid .laydate-year-list>li{margin:0 -1px -1px 0}.laydate-theme-grid .laydate-year-list>li{height:43px;line-height:43px}.laydate-theme-grid .laydate-month-list>li{height:71px;line-height:71px}.laydate-theme-grid .layui-laydate-content td>div{height:29px;margin-top:-1px}.laydate-theme-circle .layui-laydate-content td.layui-this>div,.laydate-theme-circle .layui-laydate-content td>div{width:28px;height:28px;line-height:28px;border-radius:14px;margin:0 4px;padding:0}.layui-laydate.laydate-theme-circle .layui-laydate-content table td.layui-this{background-color:transparent!important}.laydate-theme-grid.laydate-theme-circle .layui-laydate-content td>div{margin:0 3.5px}.laydate-theme-fullpanel .layui-laydate-main{width:526px}.laydate-theme-fullpanel .layui-laydate-list{width:252px;left:272px}.laydate-theme-fullpanel .laydate-set-ym span{display:none}.laydate-theme-fullpanel .laydate-time-show .laydate-set-ym span[lay-type=month],.laydate-theme-fullpanel .laydate-time-show .laydate-set-ym span[lay-type=year],.laydate-theme-fullpanel .laydate-time-show .layui-laydate-header .layui-icon{display:inline-block!important}.laydate-theme-fullpanel .laydate-btns-time{display:none}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch}.layui-layer{top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #b2b2b2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-btn a,.layui-layer-setwin span{display:inline-block;vertical-align:middle;*display:inline;*zoom:1}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes layer-slide-down{from{transform:translate3d(0,-100%,0)}to{transform:translate3d(0,0,0)}}@keyframes layer-slide-down-out{from{transform:translate3d(0,0,0)}to{transform:translate3d(0,-100%,0)}}.layer-anim-slide-down{animation-name:layer-slide-down}.layer-anim-slide-down-out{animation-name:layer-slide-down-out}@keyframes layer-slide-left{from{transform:translate3d(100%,0,0)}to{transform:translate3d(0,0,0)}}@keyframes layer-slide-left-out{from{transform:translate3d(0,0,0)}to{transform:translate3d(100%,0,0)}}.layer-anim-slide-left{animation-name:layer-slide-left}.layer-anim-slide-left-out{animation-name:layer-slide-left-out}@keyframes layer-slide-up{from{transform:translate3d(0,100%,0)}to{transform:translate3d(0,0,0)}}@keyframes layer-slide-up-out{from{transform:translate3d(0,0,0)}to{transform:translate3d(0,100%,0)}}.layer-anim-slide-up{animation-name:layer-slide-up}.layer-anim-slide-up-out{animation-name:layer-slide-up-out}@keyframes layer-slide-right{from{transform:translate3d(-100%,0,0)}to{transform:translate3d(0,0,0)}}@keyframes layer-slide-right-out{from{transform:translate3d(0,0,0)}to{transform:translate3d(-100%,0,0)}}.layer-anim-slide-right{animation-name:layer-slide-right}.layer-anim-slide-right-out{animation-name:layer-slide-right-out}.layui-layer-title{padding:0 81px 0 16px;height:50px;line-height:50px;border-bottom:1px solid #f0f0f0;font-size:14px;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:16px;font-size:0;line-height:initial}.layui-layer-setwin span{position:relative;width:16px;height:16px;line-height:18px;margin-left:10px;text-align:center;font-size:16px;cursor:pointer;color:#000;_overflow:hidden;box-sizing:border-box}.layui-layer-setwin .layui-layer-min:before{content:'';position:absolute;width:12px;border-bottom:1px solid #2e2d3c;left:50%;top:50%;margin:-.5px 0 0 -6px;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover:before{background-color:#2d93ca}.layui-layer-setwin .layui-layer-max:after,.layui-layer-setwin .layui-layer-max:before{content:'';position:absolute;left:50%;top:50%;z-index:1;width:9px;height:9px;margin:-5px 0 0 -5px;border:1px solid #2e2d3c}.layui-layer-setwin .layui-layer-max:hover:after,.layui-layer-setwin .layui-layer-max:hover:before{border-color:#2d93ca}.layui-layer-setwin .layui-layer-min:hover:before{background-color:#2d93ca}.layui-layer-setwin .layui-layer-maxmin:after,.layui-layer-setwin .layui-layer-maxmin:before{width:7px;height:7px;margin:-3px 0 0 -3px;background-color:#fff}.layui-layer-setwin .layui-layer-maxmin:after{z-index:0;margin:-5px 0 0 -1px}.layui-layer-setwin .layui-layer-close{cursor:pointer}.layui-layer-setwin .layui-layer-close:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;color:#fff;background-color:#787878;padding:3px;border:3px solid;width:28px;height:28px;font-size:16px;font-weight:bolder;border-radius:50%;margin-left:0;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{opacity:unset;background-color:#3888f6}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:30px;line-height:30px;margin:5px 5px 0;padding:0 16px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none;box-sizing:border-box}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:transparent;background-color:#1e9fff;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:240px}.layui-layer-dialog .layui-layer-content{position:relative;padding:16px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-face{position:absolute;top:18px;left:16px;color:#959595;font-size:32px;_left:-40px}.layui-layer-dialog .layui-layer-content .layui-icon-tips{color:#f39b12}.layui-layer-dialog .layui-layer-content .layui-icon-success{color:#16b777}.layui-layer-dialog .layui-layer-content .layui-icon-error{top:19px;color:#ff5722}.layui-layer-dialog .layui-layer-content .layui-icon-question{color:#ffb800}.layui-layer-dialog .layui-layer-content .layui-icon-lock{color:#787878}.layui-layer-dialog .layui-layer-content .layui-icon-face-cry{color:#ff5722}.layui-layer-dialog .layui-layer-content .layui-icon-face-smile{color:#16b777}.layui-layer-rim{border:6px solid #8d8d8d;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #d3d4d3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-close{color:#fff}.layui-layer-hui .layui-layer-content{padding:11px 24px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:18px 24px 18px 58px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:76px;height:38px;line-height:38px;text-align:center}.layui-layer-loading-icon{font-size:38px;color:#959595}.layui-layer-loading2{text-align:center}.layui-layer-loading-2{position:relative;height:38px}.layui-layer-loading-2:after,.layui-layer-loading-2:before{content:'';position:absolute;left:50%;top:50%;width:38px;height:38px;margin:-19px 0 0 -19px;border-radius:50%;border:3px solid #d2d2d2;box-sizing:border-box}.layui-layer-loading-2:after{border-color:transparent;border-left-color:#1e9fff}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan .layui-layer-title{background:#4476a7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;border-top:1px solid #e9e7e7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#e9e7e7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#c9c5c5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92b8b1}.layui-layer-lan .layui-layer-setwin .layui-icon,.layui-layer-molv .layui-layer-setwin .layui-icon{color:#fff}.layui-layer-win10{border:1px solid #aaa;box-shadow:1px 1px 6px rgba(0,0,0,.3);border-radius:none}.layui-layer-win10 .layui-layer-title{height:32px;line-height:32px;padding-left:8px;border-bottom:none;font-size:12px}.layui-layer-win10 .layui-layer-setwin{right:0;top:0}.layui-layer-win10 .layui-layer-setwin span{margin-left:0;width:32px;height:32px;padding:8px}.layui-layer-win10.layui-layer-page .layui-layer-setwin span{width:38px}.layui-layer-win10 .layui-layer-setwin span:hover{background-color:#e5e5e5}.layui-layer-win10 .layui-layer-setwin span.layui-icon-close:hover{background-color:#e81123;color:#fff}.layui-layer-win10.layui-layer-dialog .layui-layer-content{padding:8px 16px 32px;color:#0033bc}.layui-layer-win10.layui-layer-dialog .layui-layer-padding{padding-top:18px;padding-left:58px}.layui-layer-win10 .layui-layer-btn{padding:5px 5px 10px;border-top:1px solid #dfdfdf;background-color:#f0f0f0}.layui-layer-win10 .layui-layer-btn a{height:20px;line-height:18px;background-color:#e1e1e1;border-color:#adadad;color:#000;font-size:12px;transition:all .3s}.layui-layer-win10 .layui-layer-btn a:hover{border-color:#2a8edd;background-color:#e5f1fb}.layui-layer-win10 .layui-layer-btn .layui-layer-btn0{border-color:#0078d7}.layui-layer-prompt .layui-layer-input{display:block;width:260px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:16px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;display:inline-block;vertical-align:top;border-left:1px solid transparent;border-right:1px solid transparent;min-width:80px;max-width:300px;padding:0 16px;text-align:center;cursor:default;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:51px;border-left-color:#eee;border-right-color:#eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left-color:transparent}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{background:0 0;box-shadow:none}.layui-layer-photos .layui-layer-content{overflow:visible;text-align:center}.layui-layer-photos .layer-layer-photos-main img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-photos-next,.layui-layer-photos-prev{position:fixed;top:50%;width:52px;height:52px;line-height:52px;margin-top:-26px;cursor:pointer;font-size:52px;color:#717171}.layui-layer-photos-prev{left:32px}.layui-layer-photos-next{right:32px}.layui-layer-photos-next:hover,.layui-layer-photos-prev:hover{color:#959595}.layui-layer-photos-toolbar{position:fixed;left:0;right:0;bottom:0;width:100%;height:52px;line-height:52px;background-color:#000\9;filter:Alpha(opacity=60);background-color:rgba(0,0,0,.32);color:#fff;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;font-size:0}.layui-layer-photos-toolbar>*{display:inline-block;vertical-align:top;padding:0 16px;font-size:12px;color:#fff;*display:inline;*zoom:1}.layui-layer-photos-toolbar *{font-size:12px}.layui-layer-photos-header{top:0;bottom:auto}.layui-layer-photos-header>span{cursor:pointer}.layui-layer-photos-header>span:hover{background-color:rgba(51,51,51,.32)}.layui-layer-photos-header .layui-icon{font-size:18px}.layui-layer-photos-footer>h3{max-width:65%;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-layer-photos-footer a:hover{text-decoration:underline}.layui-layer-photos-footer em{font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s} +/*# sourceMappingURL=layui.css.map */ \ No newline at end of file diff --git a/dist/mobiledetect.js b/dist/mobiledetect.js new file mode 100755 index 0000000..031da6a --- /dev/null +++ b/dist/mobiledetect.js @@ -0,0 +1,3 @@ +/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/ +!function(a,b){a(function(){"use strict";function a(a,b){return null!=a&&null!=b&&a.toLowerCase()===b.toLowerCase()}function c(a,b){var c,d,e=a.length;if(!e||!b)return!1;for(c=b.toLowerCase(),d=0;d=0&&(c=c.substring(0,j)+"([\\w._\\+]+)"+c.substring(j+5)),b[e]=new RegExp(c,"i");k.props[a]=b}d(k.oss),d(k.phones),d(k.tablets),d(k.uas),d(k.utils),k.oss0={WindowsPhoneOS:k.oss.WindowsPhoneOS,WindowsMobileOS:k.oss.WindowsMobileOS}}(),g.findMatch=function(a,b){for(var c in a)if(i.call(a,c)&&a[c].test(b))return c;return null},g.findMatches=function(a,b){var c=[];for(var d in a)i.call(a,d)&&a[d].test(b)&&c.push(d);return c},g.getVersionStr=function(a,b){var c,d,e,f,h=g.mobileDetectRules.props;if(i.call(h,a))for(c=h[a],e=c.length,d=0;d1&&(a=b[0]+".",b.shift(),a+=b.join("")),Number(a)},g.isMobileFallback=function(a){return g.detectMobileBrowsers.fullPattern.test(a)||g.detectMobileBrowsers.shortPattern.test(a.substr(0,4))},g.isTabletFallback=function(a){return g.detectMobileBrowsers.tabletPattern.test(a)},g.prepareDetectionCache=function(a,c,d){if(a.mobile===b){var e,h,i;return(h=g.findMatch(g.mobileDetectRules.tablets,c))?(a.mobile=a.tablet=h,void(a.phone=null)):(e=g.findMatch(g.mobileDetectRules.phones,c))?(a.mobile=a.phone=e,void(a.tablet=null)):void(g.isMobileFallback(c)?(i=f.isPhoneSized(d),i===b?(a.mobile=g.FALLBACK_MOBILE,a.tablet=a.phone=null):i?(a.mobile=a.phone=g.FALLBACK_PHONE,a.tablet=null):(a.mobile=a.tablet=g.FALLBACK_TABLET,a.phone=null)):g.isTabletFallback(c)?(a.mobile=a.tablet=g.FALLBACK_TABLET,a.phone=null):a.mobile=a.tablet=a.phone=null)}},g.mobileGrade=function(a){var b=null!==a.mobile();return a.os("iOS")&&a.version("iPad")>=4.3||a.os("iOS")&&a.version("iPhone")>=3.1||a.os("iOS")&&a.version("iPod")>=3.1||a.version("Android")>2.1&&a.is("Webkit")||a.version("Windows Phone OS")>=7||a.is("BlackBerry")&&a.version("BlackBerry")>=6||a.match("Playbook.*Tablet")||a.version("webOS")>=1.4&&a.match("Palm|Pre|Pixi")||a.match("hp.*TouchPad")||a.is("Firefox")&&a.version("Firefox")>=12||a.is("Chrome")&&a.is("AndroidOS")&&a.version("Android")>=4||a.is("Skyfire")&&a.version("Skyfire")>=4.1&&a.is("AndroidOS")&&a.version("Android")>=2.3||a.is("Opera")&&a.version("Opera Mobi")>11&&a.is("AndroidOS")||a.is("MeeGoOS")||a.is("Tizen")||a.is("Dolfin")&&a.version("Bada")>=2||(a.is("UC Browser")||a.is("Dolfin"))&&a.version("Android")>=2.3||a.match("Kindle Fire")||a.is("Kindle")&&a.version("Kindle")>=3||a.is("AndroidOS")&&a.is("NookTablet")||a.version("Chrome")>=11&&!b||a.version("Safari")>=5&&!b||a.version("Firefox")>=4&&!b||a.version("MSIE")>=7&&!b||a.version("Opera")>=10&&!b?"A":a.os("iOS")&&a.version("iPad")<4.3||a.os("iOS")&&a.version("iPhone")<3.1||a.os("iOS")&&a.version("iPod")<3.1||a.is("Blackberry")&&a.version("BlackBerry")>=5&&a.version("BlackBerry")<6||a.version("Opera Mini")>=5&&a.version("Opera Mini")<=6.5&&(a.version("Android")>=2.3||a.is("iOS"))||a.match("NokiaN8|NokiaC7|N97.*Series60|Symbian/3")||a.version("Opera Mobi")>=11&&a.is("SymbianOS")?"B":(a.version("BlackBerry")<5||a.match("MSIEMobile|Windows CE.*Mobile")||a.version("Windows Mobile")<=5.2,"C")},g.detectOS=function(a){return g.findMatch(g.mobileDetectRules.oss0,a)||g.findMatch(g.mobileDetectRules.oss,a)},g.getDeviceSmallerSide=function(){return window.screen.width{function U(i){for(var e={},t=0;t{var t,o={},r=e;if(!_i(e))for(var a in r={},e)for(var s in e[a])r[s]=e[a][s].concat(r[s]||[]);for(t in i)o[t]=r[t]&&r[t].length%2==0?r[t].concat(i[t]):i[t];return o})(Ii,e):Ii,j.call(this,[["getBrowser",(n=function(i){return i==g?function(){return new Bi(i,r,s,a).set("ua",r).set(u,this.getBrowser()).set(h,this.getCPU()).set(p,this.getDevice()).set(m,this.getEngine()).set(f,this.getOS()).get()}:function(){return new Bi(i,r,s[i],a).parseUA().get()}})(u)],["getCPU",n(h)],["getDevice",n(p)],["getEngine",n(m)],["getOS",n(f)],["getResult",n(g)],["getUA",function(){return r}],["setUA",function(i){return H(i)&&(r=i.length>E?Hi(i,E):i),this}]]).setUA(r),this):new I(i,e,t).getResult()}I.VERSION="2.0.3",I.BROWSER=U([v,y,L,k]),I.CPU=U([C]),I.DEVICE=U([T,x,k,G,S,e,r,t,D]),I.ENGINE=I.OS=U([v,y]),typeof exports!==n?(exports=typeof module!==n&&module.exports?module.exports=I:exports).UAParser=I:typeof define===R&&define.amd?define(function(){return I}):Ti&&(i.UAParser=I);var Ri,Vi=Ti&&(i.jQuery||i.Zepto);Vi&&!Vi.ua&&(Ri=new I,Vi.ua=Ri.getResult(),Vi.ua.get=function(){return Ri.getUA()},Vi.ua.set=function(i){Ri.setUA(i);var e,t=Ri.getResult();for(e in t)Vi.ua[e]=t[e]})})("object"==typeof window?window:this); \ No newline at end of file diff --git a/err.txt b/err.txt new file mode 100755 index 0000000..e69de29 diff --git a/f_check.php b/f_check.php new file mode 100755 index 0000000..c96dbbb --- /dev/null +++ b/f_check.php @@ -0,0 +1,157 @@ + 'error', + 'message' => '只允许POST请求' + ]); + exit; +} + +// 获取并解析请求数据 +$hdata = $_POST['hdata'] ?? ''; +$decodedString = base64_decode($hdata, true); +$fingerprint_info = is_string($decodedString) ? json_decode($decodedString, true) : null; + +if (!is_array($fingerprint_info) || empty($fingerprint_info['domain'])) { + http_response_code(400); + echo json_encode([ + 'status' => 'error', + 'message' => '无效的指纹数据', + ]); + exit; +} + +require_once __DIR__ . '/cong.php'; +require_once __DIR__ . '/lib/DbHelper.php'; +require_once __DIR__ . '/lib/bootstrap.php'; +require_once __DIR__ . '/config/ConfigLoader.php'; +require_once __DIR__ . '/lib/Cloak/FpUrlHelper.php'; + +$fp_host = parse_url($fingerprint_info['domain'], PHP_URL_HOST); +if (empty($fp_host)) { + $fp_host = $_SERVER['HTTP_HOST'] ?? ''; +} +$config_name = ConfigLoader::loadByHost($fp_host); + +$jsonData = [ + 'id' => COSTM_IP_SCORE, + 'hdata' => $hdata, + 'referer' => $fingerprint_info['referer'] ?? '', + 'domain' => $fingerprint_info['domain'], + 'ip' => $fingerprint_info['ip'] ?? '', + 'risk_enhanced' => defined('CLOAK_RISK_ENHANCED') && strtoupper(CLOAK_RISK_ENHANCED) === 'ON' ? 1 : 0, + 'risk_number' => CLOAK_RISK_NUMBER, +]; + +$ch = curl_init('https://www.tiktokba.com/cloak/byApiRisk'); + +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); +curl_setopt($ch, CURLOPT_USERAGENT, get_SERVER_value('HTTP_USER_AGENT')); +curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); +curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + +curl_setopt($ch, CURLOPT_ENCODING, ''); +curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-type: application/x-www-form-urlencoded', + 'escloak-key: ' . CHECK_KEY, +]); +curl_setopt($ch, CURLOPT_POST, true); +curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($jsonData)); +curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'forward_response_cookies'); +if ($_COOKIE) { + curl_setopt($ch, CURLOPT_COOKIE, encode_visitor_cookies()); +} +$return = curl_exec($ch); +if ($return === false) { + http_response_code(502); + echo json_encode([ + 'status' => 'error', + 'message' => 'Curl error: ' . curl_error($ch), + ]); + curl_close($ch); + exit; +} +curl_close($ch); +$return = json_decode($return, true); +if (!is_array($return)) { + http_response_code(502); + echo json_encode([ + 'status' => 'error', + 'message' => '风控 API 返回无效', + ]); + exit; +} + +$_SESSION['visit_to_3'] = 3; +$response = []; +$response['reason'] = $return['reason']; +$response['result'] = $return['result']; + +if($return['result']) { + $_SESSION["check_result"] = "true"; // 通过指纹参数 + $resolved = FpUrlHelper::resolve($config_name, true); + $fp_url = $resolved['url']; + $response['link'] = $fp_url; +} else { + $_SESSION["check_result"] = "false"; // 未通过指纹参数 + if(CLOAK_REDIRECT_METHOD == 'curl') { + $response['link'] = ''; + } else { + $zp_url = DB_ZP; + $response['link'] = $zp_url; + } +} + +$log_id = (int) ($fingerprint_info['log_id'] ?? 0); +$update_log = []; + +$update_log['result'] = $response['result'] ? "true" : "false"; +$update_log['reason'] = $response['reason'] ?? ''; +$update_log['fp_url'] = trim((string) ($response['link'] ?? '')); +if ($update_log['fp_url'] === '') { + $update_log['fp_url'] = $update_log['result'] === 'true' + ? FpUrlHelper::fallbackUrl() + : (defined('DB_ZP') ? (string) DB_ZP : ''); +} + +$servername = "localhost"; +$username = DB_USERNAME; +$password = DB_PASSWORD; +$dbname = DB_NAME; + +// Create connection +$conn = new mysqli($servername, $username, $password, $dbname); +// Check connection +if ($conn->connect_error) { + $error = "Connection failed: " . $conn->connect_error; + $handle = fopen(dirname(__FILE__) . "/err.txt", "a+"); + fwrite($handle, date("Y-m-d H:i:s") . ' | ' . $error . "\n"); + fclose($handle); +} elseif ($log_id > 0) { + $resultEsc = cloak_db_escape($conn, $update_log['result'] ?? ''); + $reasonEsc = cloak_db_escape($conn, strip_tags(cloak_db_string($update_log['reason'] ?? ''))); + $fpUrlEsc = cloak_db_escape($conn, strip_tags(cloak_db_string($update_log['fp_url'] ?? ''))); + $sql = "UPDATE `visitor_logs` SET `result`='{$resultEsc}',`reason`='{$reasonEsc}',`fp_url`='{$fpUrlEsc}' WHERE `id`='" . (int) $log_id . "'"; + + if ($conn->query($sql) != TRUE) { + $handle = fopen(dirname(__FILE__) . "/err.txt", "a+"); + fwrite($handle, date("Y-m-d H:i:s") . ' | ' . "Error: " . $sql . "
        " . $conn->error . "\n"); + fclose($handle); + } + $conn->close(); +} + +// 记录日志 +exit(json_encode($response)); \ No newline at end of file diff --git a/index.php b/index.php new file mode 100755 index 0000000..68bb5a5 --- /dev/null +++ b/index.php @@ -0,0 +1,4 @@ +connect_error) { + $errors[] = 'MySQL 连接失败:' . $conn->connect_error; + } else { + require_once __DIR__ . '/lib/InstallSchema.php'; + $schemaResult = InstallSchema::install($conn); + if (!$schemaResult['ok']) { + $errors[] = '数据库建表失败:' . ($schemaResult['error'] ?? '未知错误'); + } else { + $schemaMsg = '已创建/确认数据表:' . implode('、', $schemaResult['tables']); + } + $conn->close(); + } + } + + // Redis 连接测试(可跳过) + $redisOk = null; + $redisMsg = ''; + if (empty($errors) && $redis_enabled === 'ON') { + if (extension_loaded('redis')) { + try { + $r = new Redis(); + if (!@$r->connect($redis_host, $redis_port, 0.5)) { + $redisMsg = 'Redis 连接失败,已跳过(安装仍可继续)。'; + $redisOk = false; + } else { + if ($redis_pwd !== '') $r->auth($redis_pwd); + $r->ping(); + $redisOk = true; + } + } catch (Throwable $e) { + $redisMsg = 'Redis 连接异常:' . $e->getMessage() . '(已跳过)'; + $redisOk = false; + } + } else { + $redisMsg = 'phpredis 扩展未安装,Redis 功能不可用(已跳过)。'; + $redisOk = false; + } + } + + // 写入 cong.php + if (empty($errors)) { + // 备份旧文件 + if (file_exists(CONG_FILE)) { + @copy(CONG_FILE, CONG_BACKUP); + } + + $cong_content = ' + + + + + +IPCLOAKAPI 安装程序 + + + + + + +
        +
        +

        环境初始化配置

        +
        +
        + + +
        + PHP 运行环境: + + + — 满足 Cloaka 要求(>= ) + + — 不满足最低要求,请升级至 PHP + +
          + +
        • + +
        + + +
        + +
        + +
        + +
        + + + +
        +
        🔒
        +

        系统已安装

        +

        安装锁文件存在,安装程序已被禁用,以防止覆盖生产配置。
        如需重新配置,请输入当前登录密码以解锁。

        + 进入管理后台 +
        +
        + ⚙️ 强制重新配置(危险操作,需验证旧密码) +
        +
        此操作将覆盖现有 cong.php,当前配置会备份到 cong.php.bak。
        +
        + +
        + + +
        + +
        +
        +
        + + + +
        + 安装成功! cong.php 已写入,安装锁已创建。 +
        + +
        + + +
        + +

        系统已完成初始化配置,请立即进入后台开始使用。

        + 进入管理后台 → + + + + + +
        +
        +
        + + + +
        + + +
        + + + +
        MySQL 数据库
        +
        + + + 通常为 127.0.0.1 或 localhost +
        +
        + + + 安装时将自动创建 ip_groups、ip_list、visitor_logs 数据表 +
        +
        + + +
        +
        + + +
        + +
        + + +
        Redis 缓存(可选)
        +
        + + + phpredis 扩展✓ 已安装' : ' ✗ 未安装'; ?> +
        +
        +
        + + +
        +
        + + +
        +
        + + +
        +
        + + +
        +
        + +
        + + +
        系统安全
        +
        + + + 用于登录 dashboard.php 后台管理页面 +
        +
        + + + 由服务商提供,可在安装后于 cong.php 中修改 +
        + +
        + + +
        Cloudflare 域名自动化(可选)
        +
        + + + NS 生效后用于创建 proxied 的 A 记录;可安装后在 cong.php 填写 +
        +
        + + + 在 Cloudflare 控制台 → My Profile → API Tokens 创建 +
        +
        + + + 三项均留空时,域名功能保持本地登记(兼容宝塔手动建站) +
        + +
        + + +
        + + + +
        +
        + +

        + 安装完成后请将 install.php 删除或设置服务器禁止访问,以保障安全。 +

        + + + + diff --git a/install/schema.sql b/install/schema.sql new file mode 100755 index 0000000..3638d19 --- /dev/null +++ b/install/schema.sql @@ -0,0 +1,63 @@ +-- Cloaka 安装程序自动执行的表结构(与 lib/InstallSchema.php 保持一致) +-- 使用 CREATE TABLE IF NOT EXISTS,重复安装不会覆盖已有数据 + +CREATE TABLE `cloak_site_domains` ( + `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `hostname` varchar(255) NOT NULL COMMENT '站点域名,不含协议与路径', + `config_name` varchar(64) NOT NULL DEFAULT '' COMMENT '关联 check_config 配置名', + `created_at` timestamp NOT NULL DEFAULT current_timestamp(), + `cf_zone_id` varchar(64) DEFAULT NULL COMMENT 'Cloudflare Zone ID', + `cf_nameservers` text DEFAULT NULL COMMENT 'Cloudflare NS JSON', + `cf_status` varchar(32) NOT NULL DEFAULT 'local' COMMENT 'Cloudflare 状态', + `cf_error` varchar(500) DEFAULT NULL COMMENT '最近错误', + `cf_checked_at` datetime DEFAULT NULL COMMENT '上次检测时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_hostname` (`hostname`), + KEY `idx_config_name` (`config_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE `ip_groups` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL COMMENT '组名', + `type` enum('black','white') NOT NULL COMMENT '类型:black为黑名单,white为白名单', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE `ip_list` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `group_id` int(11) NOT NULL COMMENT '所属组ID', + `ip_address` varchar(45) NOT NULL COMMENT 'IP地址', + PRIMARY KEY (`id`), + KEY `idx_group_ip` (`group_id`,`ip_address`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE `visitor_logs` ( + `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `campagin_id` varchar(20) NOT NULL COMMENT '策略ID', + `visit_md5_code` char(32) NOT NULL DEFAULT 'loss' COMMENT '客户端标记', + `domain` varchar(35) NOT NULL COMMENT '域名', + `visit_date` datetime NOT NULL COMMENT '访问日期', + `IP` varchar(150) NOT NULL COMMENT 'IP', + `country` varchar(10) DEFAULT NULL COMMENT '国家', + `result` char(5) DEFAULT NULL COMMENT '判断结果', + `reason` varchar(100) DEFAULT NULL COMMENT '判断理由', + `referer` text DEFAULT NULL COMMENT '来源', + `vtimes` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '第几次访问', + `client` varchar(20) DEFAULT NULL COMMENT '客户端', + `browser` varchar(20) DEFAULT NULL COMMENT '浏览器', + `device` varchar(300) DEFAULT NULL COMMENT '设备', + `page` text DEFAULT NULL COMMENT '浏览页面', + `fp_url` text DEFAULT NULL COMMENT '跳转页面', + `language` varchar(300) DEFAULT NULL COMMENT '语言', + `user_agent` text DEFAULT NULL COMMENT 'User-Agent 完整值', + `http_referer` text DEFAULT NULL COMMENT 'HTTP Referer 完整值', + `accept_language_raw` text DEFAULT NULL COMMENT 'Accept-Language 完整值', + `judge_timing` text DEFAULT NULL COMMENT '判定用时 JSON', + `add_time` timestamp NOT NULL DEFAULT current_timestamp() COMMENT '日志记录时间', + PRIMARY KEY (`id`), + KEY `IP` (`IP`), + KEY `idx_visit_date` (`visit_date`), + KEY `idx_result` (`result`), + KEY `idx_domain_date` (`domain`,`visit_date`), + KEY `idx_country` (`country`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; diff --git a/ip_black.txt b/ip_black.txt new file mode 100755 index 0000000..8f2267f --- /dev/null +++ b/ip_black.txt @@ -0,0 +1,23911 @@ +223.188.64.251 +223.239.120.76 +27.56.89.19 +171.51.139.193 +152.57.49.58 +103.240.76.142 +223.238.51.166 +132.154.60.170 +42.105.88.5 +49.34.121.239 +103.91.85.4 +106.195.72.145 +43.251.168.157 +103.217.121.191 +132.154.39.191 +157.35.79.105 +110.224.124.208 +223.189.219.167 +152.58.158.249 +223.239.24.92 +106.217.76.93 +122.161.243.40 +202.168.85.79 +157.49.147.251 +157.32.208.208 +122.161.69.75 +47.11.231.69 +157.45.83.27 +202.142.100.212 +1.38.164.75 +49.34.148.220 +106.197.108.108 +157.38.201.225 +122.161.77.240 +182.77.28.144 +152.58.38.84 +106.211.88.12 +122.181.94.76 +223.190.89.190 +157.44.197.196 +49.15.203.166 +157.35.44.95 +132.154.49.213 +171.76.189.115 +47.9.125.23 +106.76.77.133 +106.221.243.134 +157.42.246.138 +47.9.65.245 +42.111.120.2 +106.198.135.206 +106.211.47.203 +49.35.167.52 +103.58.155.186 +49.34.65.200 +157.32.43.154 +49.36.202.204 +223.178.211.160 +223.239.0.251 +157.46.185.49 +157.40.250.201 +152.58.187.10 +132.154.35.121 +157.34.209.254 +47.29.161.205 +27.97.32.174 +47.9.86.230 +106.221.164.134 +157.38.236.208 +152.57.236.187 +49.14.128.131 +169.149.226.60 +117.234.33.229 +45.148.134.39 +152.58.76.120 +49.35.174.29 +106.221.250.14 +152.58.34.27 +49.37.113.146 +27.56.239.149 +42.108.77.126 +106.221.117.217 +49.34.43.204 +47.9.68.248 +103.253.150.228 +157.41.225.147 +157.44.153.80 +157.51.33.45 +132.154.55.203 +110.227.59.145 +157.35.70.202 +103.252.164.144 +49.32.238.147 +157.34.99.177 +42.108.196.110 +49.35.226.126 +139.167.243.42 +122.185.170.170 +152.58.107.126 +49.42.94.23 +223.176.97.38 +49.32.180.11 +110.225.50.19 +106.203.25.237 +157.46.152.125 +106.204.234.214 +42.105.213.60 +106.208.145.46 +103.151.189.248 +117.98.86.136 +47.9.141.188 +106.217.36.169 +106.211.137.30 +47.247.198.145 +152.58.84.113 +157.50.55.164 +47.9.87.29 +157.41.255.36 +157.45.162.21 +157.40.66.183 +106.76.213.151 +117.96.133.131 +152.58.189.105 +157.35.76.28 +157.49.238.33 +223.190.140.65 +223.231.197.51 +152.57.114.206 +49.14.106.35 +157.45.40.157 +49.44.78.137 +157.35.19.250 +42.104.153.71 +152.58.197.50 +49.36.193.119 +106.206.252.238 +223.233.24.54 +117.214.226.241 +137.97.117.63 +157.40.243.152 +152.58.156.107 +157.44.201.55 +150.129.104.163 +117.98.76.26 +106.216.132.100 +106.216.241.130 +59.92.43.6 +47.31.141.14 +223.187.123.128 +183.82.44.252 +157.38.74.118 +1.187.104.152 +157.34.236.2 +103.66.208.182 +157.32.102.48 +157.46.83.252 +103.226.87.90 +106.221.241.228 +157.38.251.36 +223.239.1.81 +223.176.6.37 +106.196.33.212 +117.230.82.206 +117.99.255.27 +106.198.222.48 +223.176.14.77 +47.11.192.99 +202.173.124.198 +117.96.179.254 +106.206.192.246 +223.190.171.198 +1.39.75.136 +157.34.3.7 +152.57.182.157 +47.11.196.145 +157.50.39.140 +171.76.251.200 +223.189.254.121 +27.60.101.217 +152.58.196.5 +157.48.196.155 +106.79.192.202 +122.161.51.239 +223.189.135.107 +110.224.64.124 +223.182.227.3 +106.200.51.91 +106.204.202.180 +106.193.246.41 +223.236.161.116 +106.207.9.232 +157.45.187.145 +157.46.151.235 +42.105.235.142 +106.217.186.81 +49.32.163.97 +42.105.172.254 +49.36.171.145 +106.211.92.190 +157.38.60.72 +157.34.218.13 +157.35.5.212 +152.58.148.45 +106.194.133.219 +157.34.44.21 +106.216.70.42 +49.15.136.201 +27.61.171.120 +157.39.64.160 +1.187.222.197 +223.181.23.160 +157.32.120.189 +223.182.31.191 +157.32.104.93 +223.186.3.29 +157.39.74.17 +157.35.8.145 +106.196.104.252 +49.206.41.2 +106.206.199.26 +47.9.77.66 +47.31.97.133 +157.40.111.78 +103.168.164.50 +157.38.146.114 +49.15.201.175 +49.34.186.244 +152.58.69.115 +106.221.52.19 +49.37.67.223 +171.60.215.68 +47.29.171.177 +152.58.56.162 +152.58.104.128 +152.57.78.191 +1.187.221.196 +49.37.99.8 +42.105.113.111 +117.213.19.148 +152.58.169.20 +157.48.215.197 +223.228.248.143 +157.49.226.211 +47.15.13.204 +152.58.230.0 +103.217.123.28 +152.58.59.200 +27.59.38.130 +49.43.96.113 +157.42.200.181 +157.45.199.108 +49.42.91.28 +1.38.72.159 +157.45.92.71 +157.51.197.173 +223.176.114.36 +106.196.38.218 +132.154.167.234 +49.35.193.231 +106.219.0.255 +47.11.254.59 +106.211.80.249 +223.189.184.5 +27.63.217.175 +106.217.179.39 +152.57.42.42 +223.228.138.62 +47.29.169.24 +157.39.208.180 +152.58.31.181 +106.192.196.55 +157.42.221.55 +157.41.225.119 +117.99.214.243 +106.217.184.27 +49.36.83.185 +157.39.229.6 +202.142.77.57 +223.239.95.171 +116.73.135.182 +49.34.38.11 +157.48.176.10 +106.194.201.230 +157.32.36.131 +106.207.4.230 +110.227.51.84 +27.62.143.108 +157.45.243.35 +152.58.74.158 +157.34.49.47 +132.154.53.225 +152.58.38.194 +157.51.73.100 +223.225.73.149 +1.38.164.41 +223.182.50.80 +106.205.143.59 +47.29.168.236 +103.87.142.161 +157.45.67.215 +42.106.186.235 +106.196.93.134 +117.193.225.110 +157.42.218.39 +122.161.69.113 +49.35.129.86 +106.79.199.7 +47.11.252.133 +157.32.126.182 +49.14.114.253 +223.228.126.126 +157.45.144.142 +152.57.82.106 +117.98.84.105 +47.15.3.62 +157.32.93.250 +106.196.56.209 +169.149.228.122 +157.33.203.49 +43.250.158.202 +157.44.176.184 +157.48.67.233 +106.217.3.52 +152.58.82.141 +106.196.93.22 +223.225.240.82 +103.130.105.169 +49.37.72.133 +49.35.177.35 +49.36.179.108 +223.176.3.162 +157.38.239.205 +157.48.205.146 +223.238.92.89 +49.35.177.218 +157.38.237.192 +103.88.77.166 +49.15.230.175 +223.181.28.185 +106.216.204.176 +152.57.240.182 +117.230.29.220 +117.99.210.81 +139.167.170.99 +157.37.178.7 +106.197.70.104 +49.14.88.191 +106.197.149.240 +157.34.35.164 +47.15.249.163 +157.51.177.239 +152.58.148.84 +1.39.117.40 +47.15.8.38 +47.15.23.249 +223.187.146.78 +157.41.240.59 +27.59.152.240 +106.66.254.200 +49.43.41.40 +117.98.96.123 +49.35.145.173 +42.105.49.199 +152.58.187.163 +49.42.72.28 +42.106.21.104 +223.176.117.81 +27.59.49.29 +49.15.180.189 +223.188.81.215 +223.238.220.134 +223.186.209.229 +152.58.34.38 +157.34.66.203 +152.57.210.87 +1.39.116.25 +223.233.78.144 +157.38.82.217 +27.62.221.245 +223.181.127.61 +47.31.146.50 +106.200.177.77 +152.58.122.98 +223.228.171.24 +49.47.70.131 +49.42.66.238 +42.105.197.193 +152.58.186.58 +223.189.247.153 +157.48.81.159 +152.58.155.38 +59.93.235.190 +122.162.148.43 +106.216.119.115 +205.254.171.32 +106.78.44.190 +157.35.17.12 +157.35.61.232 +157.34.107.215 +112.79.155.165 +152.58.31.6 +223.188.87.38 +49.14.115.116 +223.189.4.88 +49.35.251.51 +157.49.192.60 +103.155.223.175 +152.57.18.134 +103.160.194.11 +103.158.215.174 +157.35.26.241 +47.29.165.77 +42.105.195.128 +157.40.89.20 +106.200.8.149 +103.87.28.75 +157.51.60.0 +106.207.66.178 +106.221.242.48 +223.189.58.36 +157.38.86.197 +223.180.179.185 +116.73.206.172 +106.66.28.72 +106.214.71.236 +47.15.20.71 +157.34.81.72 +223.233.123.216 +110.224.191.46 +42.106.180.9 +157.38.106.219 +223.184.179.104 +152.58.213.93 +103.225.207.14 +223.187.53.184 +27.60.10.62 +61.3.20.40 +106.195.68.163 +122.164.139.200 +122.164.124.6 +157.32.42.6 +110.224.83.100 +106.195.35.36 +152.58.74.3 +106.205.196.235 +49.32.253.143 +103.149.159.155 +103.15.252.46 +157.35.77.2 +110.227.48.225 +106.76.94.104 +114.134.24.97 +42.104.141.132 +171.60.194.174 +157.35.14.0 +157.35.5.33 +42.105.153.95 +117.233.214.201 +157.41.195.180 +106.221.31.237 +117.205.233.27 +157.47.71.64 +157.51.193.247 +103.179.197.210 +106.195.41.71 +27.63.85.104 +42.107.192.189 +45.121.2.238 +157.47.52.73 +157.32.103.65 +157.38.43.149 +49.15.248.24 +132.154.134.245 +110.224.191.95 +106.207.177.217 +47.15.20.87 +223.237.51.103 +47.29.45.243 +157.39.234.112 +103.160.233.184 +47.15.191.65 +169.149.229.47 +49.37.202.35 +157.46.187.141 +152.58.155.169 +49.43.249.150 +49.37.42.226 +106.216.120.249 +49.35.173.219 +137.97.121.140 +103.242.238.110 +152.57.180.171 +157.41.192.222 +49.42.85.234 +110.227.23.2 +157.42.236.193 +157.35.24.167 +106.205.195.4 +223.176.112.47 +182.77.35.181 +223.188.33.101 +223.182.26.189 +157.32.104.79 +1.38.140.235 +47.9.96.179 +157.48.126.54 +157.35.19.201 +157.38.111.65 +49.34.95.225 +139.167.212.61 +178.248.115.101 +157.44.213.15 +42.106.33.179 +106.216.242.214 +110.224.67.232 +49.15.184.52 +47.9.135.34 +152.58.98.108 +152.58.187.132 +47.31.99.113 +103.186.198.134 +103.240.237.180 +47.15.197.73 +171.51.151.19 +103.84.215.90 +49.42.84.114 +157.47.118.206 +157.42.1.221 +49.34.189.176 +152.57.130.48 +132.154.13.89 +42.105.17.14 +49.156.98.98 +49.34.114.250 +157.47.90.120 +103.77.42.50 +157.38.148.224 +47.9.72.153 +223.231.162.103 +122.171.22.29 +106.216.236.114 +169.149.226.165 +152.58.74.83 +42.106.186.19 +117.230.134.65 +157.48.233.14 +157.37.201.242 +106.198.18.158 +152.58.77.47 +47.29.172.160 +49.33.215.252 +152.58.169.207 +152.57.101.68 +42.105.203.166 +157.35.45.59 +106.216.206.1 +117.96.168.49 +110.224.66.119 +171.79.32.188 +49.156.109.94 +152.58.185.3 +49.36.170.61 +157.47.83.7 +106.196.16.108 +223.228.236.31 +103.56.237.108 +42.105.77.12 +106.76.78.69 +157.34.249.65 +223.227.32.191 +49.36.120.126 +103.120.92.195 +42.108.127.71 +223.187.129.241 +117.99.212.206 +49.35.163.173 +157.35.3.244 +106.211.88.59 +106.210.220.136 +157.48.136.70 +223.189.187.37 +152.58.219.252 +106.207.223.210 +157.47.113.237 +47.29.24.153 +47.31.149.150 +210.89.63.140 +49.36.202.112 +103.181.100.160 +117.97.240.106 +49.34.132.216 +171.76.217.238 +152.58.133.98 +157.49.159.83 +49.35.149.250 +223.229.225.195 +223.238.222.12 +157.41.229.53 +183.82.234.163 +49.35.241.222 +223.238.25.127 +157.35.7.1 +27.63.29.11 +49.36.222.219 +124.253.150.21 +49.15.232.90 +106.193.249.233 +47.15.21.168 +122.163.252.182 +49.36.223.120 +106.221.114.69 +103.206.138.88 +47.11.205.32 +117.212.126.115 +122.161.241.12 +106.215.219.78 +157.46.130.97 +49.34.122.48 +117.99.48.232 +157.49.95.167 +223.181.204.176 +157.50.32.206 +115.99.3.248 +42.105.172.244 +47.11.248.195 +223.187.252.141 +47.9.32.31 +106.221.96.231 +49.42.75.129 +157.48.184.104 +49.42.89.124 +1.39.116.95 +157.38.72.71 +110.224.189.41 +157.39.68.161 +157.34.112.45 +27.63.27.207 +45.119.31.3 +223.237.77.101 +106.216.207.210 +27.59.241.208 +103.48.102.142 +223.235.212.126 +49.15.167.2 +157.47.72.23 +1.38.107.42 +49.37.105.87 +157.49.189.126 +157.34.242.125 +27.56.74.161 +223.233.13.235 +152.58.21.246 +182.69.178.24 +157.34.75.58 +117.224.64.41 +103.165.67.240 +152.58.18.106 +182.69.177.111 +223.190.182.177 +157.32.78.228 +49.14.130.166 +157.33.127.237 +117.96.175.6 +49.204.97.246 +42.111.144.131 +157.33.108.135 +157.33.90.223 +157.35.0.209 +1.187.219.143 +157.32.93.122 +152.58.138.26 +152.58.24.186 +27.60.229.81 +157.39.72.27 +157.39.66.246 +117.230.13.228 +49.15.80.205 +42.106.92.130 +223.238.218.169 +106.221.241.3 +180.94.34.94 +223.191.59.234 +106.206.147.120 +157.46.74.28 +157.50.69.125 +157.47.107.100 +1.39.78.208 +157.35.27.192 +106.194.232.247 +106.207.173.233 +49.36.210.112 +157.46.106.45 +49.204.31.49 +152.57.23.15 +117.98.60.85 +223.233.71.122 +49.43.42.47 +106.196.4.3 +60.243.115.197 +47.15.2.164 +157.48.209.211 +106.221.184.89 +27.57.207.131 +137.97.109.228 +47.9.36.231 +182.70.176.217 +42.111.216.146 +106.197.18.95 +110.226.230.228 +106.76.89.10 +106.211.50.30 +157.38.130.13 +157.50.34.139 +223.187.103.126 +47.11.239.61 +117.194.163.236 +106.216.252.112 +152.58.150.63 +157.32.43.40 +157.38.137.167 +152.58.100.117 +157.34.27.193 +157.33.112.172 +157.38.37.15 +106.202.132.43 +106.207.129.83 +110.224.87.87 +210.89.62.189 +152.57.107.74 +106.205.217.193 +42.105.48.4 +106.221.117.0 +47.15.4.196 +110.224.42.155 +157.35.82.37 +157.34.224.10 +49.35.229.44 +117.96.177.181 +27.63.214.251 +157.35.25.69 +223.178.213.31 +117.237.239.36 +157.41.253.122 +157.35.71.174 +117.229.177.202 +27.62.135.168 +157.49.245.133 +152.57.122.26 +27.60.111.58 +106.216.227.211 +49.36.233.164 +157.48.86.20 +27.60.225.104 +223.187.109.128 +106.215.244.247 +223.225.249.146 +117.98.76.157 +103.134.253.163 +49.36.223.10 +157.51.198.65 +223.176.48.113 +106.204.227.57 +152.58.213.132 +1.39.76.207 +49.15.203.240 +122.176.205.186 +157.48.138.106 +106.78.46.239 +117.228.87.77 +223.187.210.146 +106.216.124.187 +223.182.61.176 +112.79.57.103 +117.213.61.205 +152.58.152.169 +223.228.72.94 +157.47.19.183 +42.105.48.188 +42.105.244.130 +42.106.249.121 +152.57.45.174 +157.38.17.140 +132.154.52.119 +157.37.138.70 +117.98.80.22 +157.33.193.103 +49.205.245.234 +49.36.91.202 +152.58.68.87 +157.35.75.154 +223.187.123.64 +152.58.94.109 +223.238.92.44 +42.109.206.134 +106.216.74.65 +47.31.189.140 +223.188.237.22 +60.254.92.211 +183.83.228.45 +157.42.244.153 +49.36.217.139 +152.58.76.45 +117.98.124.96 +157.46.190.74 +49.43.41.112 +49.35.239.165 +223.238.72.58 +45.112.243.194 +106.213.198.12 +47.9.67.217 +223.225.126.9 +223.233.70.253 +49.34.55.194 +157.45.232.170 +1.38.164.107 +157.33.16.119 +49.34.186.126 +47.9.79.234 +110.224.102.223 +49.36.239.196 +106.216.194.139 +157.51.194.4 +157.33.227.135 +157.38.222.92 +157.51.71.185 +152.58.80.124 +103.157.221.36 +223.231.210.16 +1.39.79.167 +132.154.38.177 +106.194.131.238 +110.224.109.65 +106.210.147.14 +106.195.77.56 +110.226.203.19 +59.96.185.35 +47.9.157.104 +223.176.117.25 +106.206.133.185 +49.35.192.207 +49.42.86.61 +47.9.129.251 +42.105.202.112 +132.154.36.55 +47.9.85.151 +152.57.174.41 +106.211.136.241 +157.49.249.226 +157.33.64.195 +42.105.224.88 +49.42.85.15 +223.227.63.72 +171.76.192.181 +223.190.137.113 +157.47.27.140 +49.15.243.155 +47.15.220.48 +157.33.38.209 +202.173.125.250 +152.57.83.168 +157.44.151.12 +47.15.5.157 +106.221.182.144 +157.34.159.35 +49.37.74.211 +223.237.85.169 +223.236.67.65 +223.238.79.211 +49.43.3.244 +157.33.7.55 +157.42.7.143 +47.29.164.131 +103.70.197.187 +157.38.230.60 +223.178.209.147 +117.217.69.213 +106.211.251.151 +47.29.175.125 +49.14.104.4 +27.60.201.255 +132.154.52.2 +152.58.187.26 +223.189.189.139 +49.42.92.218 +157.51.119.154 +157.40.75.158 +157.34.100.17 +157.48.169.220 +223.238.219.102 +106.208.17.172 +106.202.118.87 +106.195.3.20 +223.177.1.158 +47.15.100.87 +106.205.197.228 +152.58.149.201 +49.42.92.138 +47.9.144.95 +223.231.204.210 +223.189.98.64 +47.15.177.161 +152.57.121.255 +47.29.98.223 +223.237.108.73 +103.177.184.96 +132.154.61.207 +117.98.44.45 +47.11.233.108 +117.96.189.100 +152.58.233.246 +123.136.181.211 +157.41.245.207 +47.11.249.152 +49.156.108.3 +106.195.78.101 +223.187.153.89 +49.205.211.192 +103.167.126.23 +157.49.85.118 +223.181.49.233 +157.42.3.80 +171.76.244.71 +45.120.162.229 +103.179.197.253 +42.105.10.132 +152.58.197.66 +42.111.150.6 +157.42.0.3 +59.99.200.126 +106.205.199.251 +49.36.202.243 +223.225.122.98 +157.34.91.110 +106.210.186.96 +106.216.120.228 +117.98.50.104 +106.215.219.57 +47.29.170.195 +47.9.36.192 +49.204.228.110 +106.197.126.103 +103.179.10.21 +169.149.226.162 +152.58.66.128 +157.38.137.63 +112.79.60.27 +157.33.39.220 +103.151.156.172 +117.199.31.224 +157.32.232.230 +152.57.241.240 +157.47.41.34 +223.233.75.99 +223.196.192.237 +49.37.54.141 +49.37.226.81 +106.221.242.146 +106.205.197.128 +157.38.37.185 +106.208.151.39 +49.36.218.1 +223.237.8.122 +106.207.247.126 +47.11.201.90 +106.220.107.120 +223.188.254.170 +49.37.73.63 +47.15.1.17 +106.195.71.21 +27.61.88.244 +49.37.213.189 +42.105.202.201 +132.154.139.87 +152.58.103.209 +106.196.123.29 +157.38.137.18 +152.58.59.226 +49.42.92.206 +223.187.221.217 +223.186.217.206 +157.38.154.207 +182.69.183.50 +106.193.16.112 +110.224.85.7 +171.76.238.197 +49.14.164.13 +27.59.233.253 +42.105.48.177 +171.48.114.14 +47.9.145.36 +42.104.211.204 +137.97.82.26 +157.41.195.113 +49.32.240.129 +103.82.191.140 +157.34.107.250 +42.105.180.9 +152.58.211.31 +157.51.60.131 +223.233.120.115 +106.222.98.83 +223.230.132.144 +1.38.99.65 +157.38.148.55 +183.83.231.161 +47.15.19.68 +106.200.17.89 +223.187.205.50 +171.48.67.55 +157.47.66.206 +223.187.96.86 +27.63.215.228 +103.119.193.118 +152.58.235.110 +157.41.227.61 +152.58.222.252 +27.60.105.0 +49.43.219.147 +110.224.183.186 +106.220.243.244 +106.51.179.216 +1.38.72.17 +110.224.119.176 +223.228.86.236 +42.105.235.136 +139.167.218.15 +106.193.24.19 +49.34.70.210 +223.185.82.33 +106.193.17.24 +49.35.185.15 +163.53.179.0 +106.216.249.59 +47.29.170.139 +157.32.37.219 +169.149.198.41 +47.9.80.139 +157.35.47.215 +106.66.58.102 +152.58.30.190 +106.194.37.91 +47.11.210.115 +117.251.41.99 +157.33.117.128 +157.34.155.71 +223.178.213.71 +106.215.158.84 +103.233.64.123 +117.99.204.210 +47.11.195.156 +157.41.198.108 +157.35.22.85 +106.211.229.14 +157.32.113.140 +47.11.205.105 +47.9.91.232 +42.110.145.205 +137.97.125.6 +106.216.204.204 +49.36.103.227 +27.60.35.90 +49.44.78.41 +106.197.204.6 +157.51.198.103 +49.37.248.108 +103.183.31.27 +223.176.64.164 +117.98.36.21 +49.35.252.174 +47.11.206.239 +117.96.162.34 +114.69.246.90 +223.181.221.8 +49.42.90.25 +152.58.30.177 +157.38.194.242 +157.33.117.22 +106.79.232.117 +223.228.234.66 +47.15.137.25 +223.181.9.58 +132.154.59.25 +42.111.18.245 +42.107.72.198 +106.211.95.252 +203.115.84.189 +169.149.196.15 +106.192.91.21 +157.32.240.71 +47.9.78.28 +106.195.75.223 +114.31.188.132 +49.37.37.161 +106.211.58.57 +49.35.226.137 +157.48.66.12 +47.9.97.61 +1.39.224.9 +106.204.134.197 +152.58.56.85 +157.39.218.250 +112.79.60.127 +49.14.154.136 +157.42.4.76 +132.154.4.70 +157.38.21.164 +152.58.122.206 +152.58.187.223 +117.98.84.104 +223.228.203.174 +106.196.107.203 +42.110.165.28 +157.47.18.173 +157.48.150.44 +42.111.161.185 +117.219.134.180 +157.48.116.121 +152.57.162.187 +157.48.211.35 +223.225.72.249 +49.34.43.167 +106.221.23.242 +157.51.195.189 +49.32.162.192 +157.38.77.101 +110.225.49.143 +223.238.212.144 +106.196.74.128 +42.110.171.213 +49.37.106.39 +47.11.254.224 +157.51.71.231 +47.29.172.93 +49.37.39.36 +152.58.138.74 +223.237.6.132 +106.197.9.108 +223.230.140.133 +42.104.155.4 +47.15.9.236 +157.46.79.62 +157.46.67.197 +110.226.193.5 +223.228.237.32 +27.63.131.185 +106.212.47.126 +49.35.178.93 +137.97.90.195 +106.204.55.96 +157.41.225.91 +49.35.132.225 +122.180.160.9 +157.39.68.120 +152.58.236.163 +27.97.129.235 +49.34.114.232 +49.44.80.107 +157.35.85.126 +106.79.197.125 +49.43.250.139 +152.58.100.101 +42.105.245.169 +103.69.247.225 +47.15.7.191 +171.51.134.23 +110.226.83.213 +223.189.144.16 +106.221.187.167 +152.57.145.81 +157.51.7.189 +152.58.67.128 +157.48.157.66 +223.227.78.91 +103.175.9.227 +106.198.40.192 +117.99.205.38 +45.119.14.76 +106.223.184.160 +223.225.169.83 +106.221.176.222 +49.43.99.37 +106.77.78.64 +152.58.184.228 +42.106.236.140 +117.204.207.156 +205.253.11.195 +27.6.222.76 +223.180.176.218 +47.9.127.85 +157.39.65.107 +122.177.96.129 +42.104.157.40 +152.58.197.93 +49.35.157.142 +137.97.71.83 +117.98.120.66 +42.106.188.6 +223.182.19.176 +157.32.37.250 +223.239.50.123 +42.106.189.10 +171.51.169.179 +157.40.71.183 +152.58.59.43 +117.99.220.37 +223.239.77.148 +157.38.74.7 +49.36.219.86 +157.50.31.86 +157.37.149.135 +106.221.114.27 +117.99.225.200 +171.76.243.199 +106.195.11.31 +49.14.150.12 +106.198.18.166 +223.225.168.25 +223.231.234.251 +152.57.29.116 +106.197.3.13 +157.34.139.68 +106.205.207.157 +157.44.196.177 +106.202.74.73 +103.190.253.30 +152.58.196.212 +157.38.254.53 +117.99.195.25 +157.39.239.235 +157.38.111.184 +157.48.180.144 +43.249.226.50 +117.213.243.229 +157.45.87.72 +106.221.213.193 +157.42.4.221 +223.181.230.177 +157.42.224.25 +106.210.200.179 +205.253.11.224 +152.58.26.135 +49.33.241.207 +47.15.156.209 +157.34.147.207 +157.33.39.75 +157.40.83.166 +49.14.113.196 +106.78.191.4 +49.32.135.178 +106.207.213.143 +223.187.120.218 +103.186.72.132 +152.58.141.121 +223.196.192.99 +27.97.162.31 +124.123.186.247 +42.108.164.180 +49.36.193.184 +49.36.218.151 +157.47.77.204 +49.42.80.64 +106.79.197.128 +223.187.205.230 +49.36.192.185 +49.43.155.199 +42.104.155.169 +49.34.106.181 +223.190.180.83 +103.205.128.162 +27.59.203.93 +152.58.211.95 +106.216.229.75 +152.58.200.26 +49.43.101.43 +117.209.91.247 +49.36.183.232 +49.34.245.104 +157.49.75.254 +106.206.227.206 +157.33.24.255 +42.105.72.108 +106.197.118.97 +152.58.224.60 +157.41.251.117 +152.58.197.194 +152.57.115.79 +103.90.183.253 +106.78.37.124 +157.40.94.114 +47.11.203.157 +157.48.187.49 +1.38.161.184 +157.47.81.54 +171.76.235.104 +157.49.177.3 +106.78.73.195 +47.15.124.50 +27.97.15.86 +49.35.137.169 +157.46.120.0 +157.35.21.218 +106.216.194.85 +157.34.47.174 +106.197.86.74 +157.49.90.212 +49.204.21.144 +27.62.47.31 +47.15.22.158 +157.50.64.189 +27.62.228.213 +157.42.238.30 +157.37.192.45 +157.48.208.192 +157.38.242.39 +49.36.171.54 +152.58.197.172 +157.48.112.243 +117.96.164.4 +223.238.194.227 +122.178.84.252 +47.11.209.144 +106.220.120.246 +223.189.246.229 +157.32.42.156 +117.99.202.254 +223.237.52.78 +42.105.176.34 +182.64.76.87 +27.59.227.121 +157.48.130.218 +106.209.145.76 +1.38.107.138 +112.196.163.34 +106.216.202.78 +157.39.64.226 +47.15.204.80 +139.5.253.121 +47.15.157.94 +152.58.184.106 +124.123.191.127 +157.49.68.141 +223.189.171.17 +139.167.170.47 +106.211.46.129 +157.40.116.217 +42.109.134.26 +223.227.84.27 +47.11.203.107 +157.33.7.75 +223.187.143.178 +183.82.160.162 +49.15.138.29 +137.97.89.119 +157.47.114.228 +223.189.6.127 +117.99.31.178 +110.227.142.102 +106.211.228.24 +157.38.137.235 +152.58.234.100 +223.190.182.197 +205.253.123.230 +157.48.213.36 +103.96.98.2 +27.56.69.228 +223.186.112.7 +117.98.48.116 +157.46.65.199 +117.99.208.141 +49.35.172.136 +223.187.179.82 +152.58.218.189 +157.38.147.243 +152.58.189.26 +223.237.75.122 +202.89.77.74 +47.11.255.48 +1.38.164.169 +223.230.169.205 +42.105.127.132 +171.51.213.205 +106.220.134.83 +205.253.38.68 +110.226.175.62 +157.48.142.107 +157.38.115.84 +114.31.148.63 +223.190.145.116 +27.63.247.83 +106.79.201.2 +106.204.26.10 +1.39.101.116 +1.187.223.220 +106.205.206.182 +106.213.144.10 +132.154.51.124 +49.42.81.159 +49.36.81.143 +103.18.122.61 +103.132.31.122 +157.38.85.129 +157.34.131.21 +223.189.204.8 +223.238.81.65 +223.185.103.93 +132.154.35.99 +202.89.77.91 +103.70.198.71 +223.233.122.252 +223.228.170.218 +157.41.243.250 +47.29.174.172 +106.194.59.120 +169.149.196.140 +124.253.107.40 +27.63.49.79 +223.187.110.91 +117.98.78.202 +106.221.188.201 +106.221.27.51 +122.161.50.250 +1.39.79.62 +157.49.139.229 +157.35.66.234 +42.105.164.127 +106.195.79.180 +49.15.221.128 +157.34.98.113 +110.226.196.136 +157.42.2.136 +103.159.152.111 +103.181.177.118 +49.15.203.83 +47.9.35.155 +182.69.11.199 +157.48.130.123 +205.253.37.222 +157.48.130.79 +27.61.44.145 +152.57.203.13 +132.154.35.163 +157.38.130.37 +117.219.54.63 +47.15.8.133 +157.42.4.242 +42.105.218.1 +157.40.68.50 +152.58.39.40 +223.233.26.182 +152.57.192.11 +49.43.98.227 +47.9.77.69 +132.154.186.23 +157.48.219.70 +106.78.45.189 +49.35.192.94 +132.154.155.92 +157.35.59.42 +47.15.36.83 +106.195.74.135 +157.41.251.68 +171.76.233.14 +49.36.96.28 +223.184.147.102 +152.58.201.143 +157.47.87.190 +42.105.235.157 +152.57.154.159 +49.37.26.16 +103.41.38.220 +171.51.209.61 +47.29.166.78 +117.98.64.51 +137.97.91.75 +110.224.75.72 +157.35.20.157 +117.98.102.3 +110.224.77.185 +42.105.179.234 +157.40.211.90 +49.42.82.49 +49.14.175.9 +106.217.56.127 +152.58.34.173 +157.33.243.21 +223.187.151.170 +157.35.86.40 +171.76.232.66 +223.225.57.77 +117.230.50.4 +157.45.217.213 +157.50.53.101 +49.35.235.76 +106.221.26.41 +223.189.217.171 +49.37.203.72 +157.47.40.92 +157.34.78.208 +49.14.110.14 +110.226.165.133 +106.203.140.163 +110.224.105.80 +223.187.152.219 +152.58.34.42 +117.250.76.193 +152.58.230.81 +223.176.40.90 +157.34.62.222 +157.34.239.244 +171.76.176.113 +47.9.37.178 +223.238.113.5 +157.34.234.212 +157.35.40.184 +117.227.16.15 +106.203.147.151 +106.205.194.189 +42.111.21.74 +152.58.187.154 +223.191.14.221 +110.224.189.190 +157.48.168.10 +106.211.18.74 +106.216.207.185 +152.58.25.212 +122.170.130.16 +223.187.176.55 +49.15.240.216 +27.97.145.154 +157.32.103.9 +49.34.159.7 +223.187.68.35 +192.140.153.200 +49.32.164.255 +171.76.142.242 +157.32.78.170 +223.180.183.46 +49.42.67.70 +157.48.152.181 +49.35.232.40 +132.154.190.3 +106.76.210.131 +47.31.220.221 +157.33.227.60 +49.15.203.199 +157.33.110.239 +202.173.125.61 +223.187.240.110 +152.57.242.95 +49.36.221.25 +157.47.49.95 +47.11.211.114 +49.34.52.100 +49.35.246.207 +223.190.144.65 +47.15.255.99 +157.40.123.236 +122.162.144.80 +1.38.142.84 +49.37.25.132 +47.31.188.163 +117.98.86.101 +122.161.49.111 +157.46.165.245 +106.208.147.33 +42.106.191.12 +106.222.2.85 +157.34.58.178 +49.14.134.113 +106.216.85.65 +132.154.50.70 +223.225.125.185 +110.224.94.104 +157.48.157.29 +152.58.17.13 +49.42.87.183 +49.33.226.21 +157.32.126.172 +157.42.254.100 +110.226.242.68 +49.34.127.153 +117.208.219.227 +157.50.24.150 +103.240.161.153 +152.58.73.143 +157.38.24.58 +117.99.217.82 +106.197.0.176 +49.37.66.144 +49.37.89.85 +223.189.97.61 +110.227.53.15 +49.43.101.109 +171.79.166.80 +152.58.106.231 +157.47.44.211 +42.106.187.227 +110.224.84.57 +47.9.133.49 +106.208.71.176 +169.149.231.22 +42.104.142.82 +49.15.203.104 +157.41.229.112 +47.29.164.242 +157.33.34.238 +157.39.69.71 +157.48.83.76 +103.69.115.50 +106.222.16.209 +27.59.207.129 +42.111.127.2 +47.9.2.228 +157.41.198.39 +117.99.238.229 +152.58.157.181 +47.29.175.217 +106.66.3.170 +223.238.196.201 +223.176.44.188 +157.49.150.123 +106.198.80.42 +110.224.72.59 +47.15.119.156 +47.9.147.245 +49.36.211.120 +223.225.97.87 +157.38.210.76 +157.33.250.0 +152.58.163.89 +117.99.193.49 +157.38.138.121 +49.36.192.17 +49.36.27.117 +49.42.85.79 +223.189.100.152 +157.34.14.37 +103.110.169.68 +106.211.72.131 +47.31.98.146 +47.15.11.247 +152.58.74.77 +42.105.195.16 +152.57.127.173 +223.238.222.202 +106.195.41.60 +42.108.30.69 +27.59.133.228 +103.209.88.41 +223.225.109.107 +122.161.241.246 +132.154.15.170 +42.111.225.8 +157.48.124.248 +157.42.7.5 +223.228.89.0 +223.189.235.159 +157.51.159.49 +223.225.250.227 +122.161.81.127 +117.96.178.12 +117.98.40.165 +223.189.15.63 +106.208.154.171 +103.36.82.56 +117.228.181.47 +171.76.241.217 +47.15.217.230 +171.76.255.124 +49.34.216.64 +223.189.16.37 +157.42.223.245 +122.173.139.101 +42.104.212.136 +106.216.250.225 +132.154.60.137 +157.44.164.107 +152.58.104.166 +152.58.148.18 +223.190.175.188 +103.157.167.60 +157.46.86.81 +157.34.69.123 +27.63.70.65 +152.58.130.75 +106.215.132.60 +157.45.218.201 +49.34.116.155 +47.29.175.171 +157.38.127.113 +103.168.81.135 +103.127.23.114 +152.58.236.173 +106.205.192.95 +120.88.45.205 +152.58.234.228 +157.35.1.239 +157.34.33.3 +106.194.9.180 +49.37.219.158 +106.219.120.134 +49.37.168.83 +152.57.228.107 +49.34.47.251 +152.57.241.242 +103.85.207.1 +49.14.118.8 +103.182.221.162 +152.58.18.25 +171.51.221.101 +106.208.39.43 +117.96.186.178 +47.247.198.110 +106.194.150.227 +115.187.43.170 +106.216.116.196 +137.97.99.222 +106.194.189.15 +157.42.232.193 +117.202.211.96 +103.42.197.187 +27.62.165.229 +152.58.58.29 +157.42.220.95 +223.233.30.135 +106.207.59.76 +223.238.212.49 +49.37.155.57 +42.106.236.103 +47.9.65.52 +157.32.43.112 +106.216.67.126 +157.41.229.114 +223.238.117.176 +117.96.136.181 +103.171.100.190 +106.205.198.141 +223.238.144.244 +110.224.86.9 +152.58.70.169 +152.57.14.252 +152.58.138.97 +106.217.33.10 +157.33.93.146 +152.58.5.63 +106.206.188.226 +157.42.207.138 +49.15.244.219 +157.45.142.40 +152.58.189.217 +47.29.167.115 +157.48.117.8 +157.41.229.17 +106.216.100.13 +47.15.11.237 +157.39.67.113 +157.51.96.174 +157.42.196.170 +106.195.65.75 +152.58.73.204 +157.49.143.156 +152.58.134.221 +110.224.81.149 +157.51.185.76 +112.79.227.193 +152.57.73.109 +106.209.210.149 +27.63.58.69 +110.224.102.154 +223.187.4.1 +157.46.100.100 +132.154.132.250 +103.182.69.44 +49.42.90.94 +223.188.60.43 +49.36.222.148 +49.36.216.62 +139.167.247.66 +47.11.248.13 +152.57.184.158 +152.58.78.131 +223.189.181.164 +223.238.123.110 +106.221.0.165 +42.104.213.9 +27.56.84.224 +122.161.64.56 +152.57.236.169 +157.38.136.115 +106.210.97.23 +103.109.216.103 +223.238.76.106 +106.205.188.67 +103.181.62.109 +1.187.180.169 +157.32.42.178 +27.56.252.44 +27.56.146.180 +106.211.62.5 +223.233.69.176 +157.49.92.150 +223.239.127.95 +47.9.111.230 +152.57.177.120 +106.216.120.200 +49.43.88.12 +106.217.19.244 +157.46.186.123 +42.105.98.222 +157.38.153.219 +110.225.40.184 +223.185.73.203 +47.11.192.130 +47.11.209.66 +47.11.205.102 +157.41.255.244 +49.15.137.46 +103.27.51.115 +27.60.104.122 +157.32.34.177 +152.58.113.138 +47.15.19.59 +152.58.197.35 +49.35.245.184 +157.46.72.242 +152.58.66.206 +157.38.95.188 +157.35.48.54 +152.58.96.50 +106.210.155.104 +106.197.227.104 +49.32.245.91 +106.196.102.164 +157.34.242.86 +1.187.180.122 +223.185.80.73 +132.154.176.56 +152.58.19.52 +223.225.9.71 +152.58.233.190 +27.60.14.171 +157.42.3.47 +103.80.14.136 +223.186.55.235 +157.38.74.241 +106.221.98.181 +106.200.113.245 +132.154.59.131 +47.29.169.8 +101.0.54.126 +117.230.88.167 +49.34.148.90 +152.58.56.116 +47.15.40.207 +152.58.200.43 +47.15.5.255 +106.207.29.84 +152.57.129.85 +106.216.169.41 +106.205.201.3 +47.247.213.29 +47.9.33.64 +49.37.43.175 +132.154.63.128 +103.120.58.244 +157.46.126.138 +49.35.139.122 +27.60.249.232 +152.58.156.45 +137.97.109.41 +157.48.125.191 +106.211.194.8 +202.88.248.20 +42.108.75.43 +152.58.157.114 +157.48.215.255 +106.216.195.189 +223.239.32.22 +106.206.192.192 +110.224.96.8 +106.222.27.117 +223.187.65.186 +152.58.196.119 +223.233.123.40 +171.51.144.145 +27.97.79.245 +117.98.82.41 +106.216.234.34 +47.11.230.15 +117.99.237.21 +117.213.50.6 +49.34.42.1 +171.76.84.83 +157.34.141.68 +117.229.139.145 +152.58.233.61 +157.50.66.171 +117.255.182.190 +157.35.51.179 +103.116.196.38 +103.38.38.160 +223.187.214.213 +223.237.255.25 +36.255.85.249 +47.29.98.19 +103.177.184.15 +223.187.97.133 +169.149.229.99 +42.105.209.251 +157.46.153.15 +152.58.186.0 +112.79.113.96 +42.105.80.137 +47.15.19.0 +103.183.82.250 +106.66.60.41 +223.184.173.222 +106.206.123.65 +27.60.2.250 +106.66.58.55 +152.58.167.163 +42.105.198.129 +47.15.21.254 +106.206.109.244 +106.203.49.235 +157.32.198.236 +1.38.104.66 +49.14.173.12 +106.208.102.199 +223.181.44.114 +223.233.68.11 +157.35.40.51 +152.58.135.163 +106.216.126.0 +223.237.6.143 +152.58.56.50 +49.35.151.16 +106.203.146.148 +152.58.83.181 +169.149.230.200 +112.79.104.69 +106.217.200.137 +171.60.198.244 +106.196.28.240 +106.194.18.209 +171.51.162.54 +117.99.223.187 +223.239.63.252 +137.97.106.209 +106.216.109.102 +49.33.241.78 +116.68.102.63 +42.111.164.15 +157.38.194.148 +152.58.200.240 +47.15.203.169 +157.41.229.64 +47.29.12.221 +223.187.110.98 +106.205.194.94 +49.35.187.43 +106.205.194.53 +117.195.178.216 +47.11.209.80 +157.38.107.216 +106.217.46.87 +152.58.112.98 +49.37.73.59 +47.9.33.71 +49.36.170.90 +106.206.197.120 +1.39.116.184 +49.14.154.99 +157.34.34.81 +42.105.224.8 +106.207.129.98 +157.49.89.228 +132.154.61.251 +47.29.173.40 +47.247.202.167 +152.57.163.74 +132.154.62.247 +223.231.117.212 +47.29.162.133 +49.15.221.73 +223.189.201.115 +157.46.103.186 +152.58.58.117 +42.106.176.95 +157.38.239.135 +49.36.144.235 +152.58.212.252 +47.11.73.181 +47.31.151.56 +139.167.222.32 +122.161.64.51 +47.29.160.139 +223.225.170.16 +223.186.197.196 +152.57.39.81 +132.154.35.20 +47.15.33.188 +122.177.181.230 +27.62.38.234 +223.190.169.53 +106.221.97.17 +157.51.29.165 +157.35.25.16 +223.190.134.158 +1.39.116.82 +157.48.238.242 +47.15.218.182 +47.9.122.34 +106.196.5.194 +106.216.241.36 +103.66.209.80 +106.66.106.209 +49.33.211.186 +47.29.18.26 +42.105.154.36 +223.237.145.32 +223.238.26.110 +157.34.50.83 +106.216.134.151 +45.115.253.198 +106.217.204.145 +223.228.137.252 +157.38.135.24 +112.79.154.167 +106.221.247.167 +171.51.182.227 +157.42.198.159 +1.39.79.213 +106.78.73.246 +157.48.175.131 +47.31.128.81 +202.137.219.99 +47.11.253.132 +152.58.167.235 +157.38.151.176 +223.233.62.72 +110.224.95.112 +103.186.128.228 +106.209.234.68 +110.224.67.107 +152.58.103.207 +169.149.226.235 +117.98.78.146 +117.99.208.237 +157.50.68.146 +157.51.192.36 +47.15.179.62 +49.37.74.224 +47.29.175.10 +157.47.63.152 +157.38.15.101 +103.93.240.125 +110.224.66.28 +157.33.204.36 +1.187.96.255 +157.33.227.36 +157.34.133.172 +157.34.250.98 +157.38.136.111 +157.39.72.108 +27.59.253.74 +223.187.253.83 +42.111.245.105 +106.197.73.8 +157.32.216.91 +139.167.234.247 +223.190.160.168 +171.79.145.225 +27.59.107.194 +223.231.197.180 +47.9.37.104 +122.161.53.39 +49.35.236.184 +106.217.212.197 +42.104.130.102 +47.29.163.30 +152.57.41.227 +157.38.252.8 +117.99.227.88 +206.84.234.159 +106.198.14.196 +117.99.15.37 +47.9.96.56 +114.31.190.27 +157.45.138.15 +157.49.221.89 +157.32.88.185 +223.189.183.65 +47.29.160.58 +205.253.11.82 +103.81.93.168 +157.45.138.176 +223.237.107.143 +106.195.38.214 +157.35.9.204 +157.35.50.52 +157.49.71.255 +106.196.3.219 +49.34.156.179 +106.195.41.20 +47.29.174.142 +117.229.189.204 +157.48.75.102 +49.37.159.147 +157.38.51.172 +47.15.10.59 +42.111.106.64 +157.34.156.76 +157.41.228.205 +223.187.4.4 +157.32.98.32 +117.98.50.50 +139.167.204.155 +182.69.87.162 +182.69.177.234 +152.58.96.61 +223.178.83.138 +152.58.56.56 +152.59.66.114 +106.207.46.130 +47.29.169.223 +157.34.152.46 +152.58.39.150 +171.60.208.85 +49.43.91.71 +152.58.95.201 +106.205.244.75 +132.154.153.65 +106.204.206.41 +106.192.195.86 +152.57.210.238 +106.223.92.249 +205.253.9.82 +47.31.96.107 +1.38.220.63 +110.224.97.156 +49.36.24.132 +49.36.144.252 +106.197.134.9 +157.38.34.247 +122.172.38.115 +182.69.173.98 +49.14.167.132 +42.105.196.117 +157.38.52.255 +157.47.34.9 +106.196.30.139 +223.228.69.54 +114.31.188.18 +47.11.74.81 +106.221.110.199 +152.58.96.73 +152.58.92.47 +103.151.156.42 +157.48.140.211 +117.198.168.255 +49.37.112.13 +103.122.6.48 +223.181.245.47 +122.182.153.61 +157.51.106.7 +1.38.141.88 +223.227.77.74 +157.39.71.193 +157.40.251.84 +106.207.156.21 +106.66.23.154 +49.156.108.202 +223.238.32.150 +223.176.114.242 +117.241.240.14 +139.167.230.16 +42.108.197.12 +152.58.197.48 +49.34.163.181 +47.11.200.186 +169.149.193.62 +157.34.42.77 +157.45.246.100 +1.39.79.40 +157.38.43.27 +157.47.35.128 +223.185.216.141 +49.43.35.125 +157.45.95.34 +157.40.245.247 +42.104.129.137 +106.194.203.187 +1.187.213.164 +157.49.205.245 +157.44.140.144 +139.167.205.115 +47.15.8.168 +223.187.73.72 +42.105.141.130 +42.105.193.186 +157.49.65.56 +203.76.188.163 +42.105.48.29 +157.46.134.54 +152.57.233.39 +106.210.208.232 +157.39.67.144 +157.41.254.23 +27.59.186.119 +152.58.215.4 +47.9.2.117 +122.162.147.183 +27.61.117.220 +223.187.245.238 +157.51.197.73 +117.97.193.40 +49.37.27.16 +106.66.61.149 +106.77.78.126 +182.69.183.78 +157.48.126.41 +47.11.73.137 +47.29.100.102 +49.15.136.193 +47.11.194.237 +223.238.118.161 +106.198.208.19 +223.233.79.243 +114.31.133.202 +49.37.38.214 +223.189.197.58 +42.105.96.25 +132.154.37.85 +223.185.102.117 +152.58.230.70 +106.221.155.211 +152.58.188.114 +223.238.219.55 +49.32.189.114 +223.186.133.114 +110.224.89.193 +47.9.66.149 +103.160.233.20 +47.9.33.101 +42.104.129.240 +137.97.114.239 +42.109.192.57 +169.149.192.250 +117.98.110.153 +157.48.213.139 +49.34.152.213 +152.58.22.31 +152.57.122.33 +49.15.227.128 +223.233.79.57 +47.9.34.58 +157.38.147.253 +157.47.3.193 +157.34.17.227 +117.97.214.55 +47.29.39.57 +47.9.149.92 +49.34.226.239 +157.38.71.14 +106.220.106.235 +49.37.50.109 +132.154.51.109 +27.57.78.233 +117.98.84.81 +157.34.199.4 +152.58.98.98 +106.76.233.118 +157.48.95.4 +157.34.25.168 +60.243.199.127 +157.47.59.19 +157.41.197.119 +47.31.175.15 +157.32.102.198 +157.49.243.235 +152.58.109.194 +152.58.20.194 +157.32.233.173 +157.38.46.118 +42.105.138.136 +103.184.71.241 +106.220.106.87 +223.239.116.210 +152.57.210.233 +47.31.227.90 +157.38.12.250 +47.11.204.133 +152.58.196.175 +157.33.86.54 +117.98.92.80 +49.36.217.208 +103.211.15.167 +1.187.216.235 +27.56.74.179 +152.58.25.150 +106.194.232.101 +45.250.246.250 +47.11.210.154 +152.57.189.211 +157.51.196.32 +223.189.6.53 +106.211.61.57 +157.38.115.60 +47.15.33.138 +157.48.194.144 +59.99.16.22 +47.29.160.51 +157.33.215.88 +49.15.161.207 +49.35.195.167 +47.247.206.254 +117.99.254.21 +106.208.153.195 +157.51.192.6 +152.58.169.129 +152.57.140.24 +157.41.229.221 +103.199.226.22 +152.57.66.24 +171.76.131.227 +223.230.163.58 +27.62.229.150 +223.238.105.128 +103.113.230.241 +27.62.214.14 +117.99.230.253 +157.51.75.202 +157.33.61.39 +106.206.226.200 +47.15.43.237 +117.99.204.125 +47.247.209.244 +106.208.157.25 +152.57.66.125 +152.57.52.67 +223.178.213.96 +27.60.97.217 +117.96.187.79 +49.37.45.195 +47.9.137.224 +106.193.75.108 +152.58.163.177 +106.220.109.252 +49.42.67.28 +223.225.58.17 +157.33.30.11 +106.216.104.27 +157.41.253.169 +49.35.131.196 +47.9.71.1 +106.76.77.155 +49.14.131.12 +157.48.137.184 +152.58.152.240 +110.226.200.169 +42.105.75.33 +27.62.178.10 +157.38.75.164 +106.216.115.69 +152.58.38.99 +157.34.85.162 +106.216.83.250 +157.41.226.12 +42.106.12.218 +152.57.79.211 +1.187.141.106 +106.207.187.187 +43.229.88.53 +110.225.95.121 +49.37.26.181 +117.246.167.176 +157.34.224.52 +49.43.152.136 +223.187.52.88 +157.41.192.229 +132.154.154.41 +42.111.200.120 +1.187.180.72 +117.245.95.59 +157.35.89.7 +103.171.209.20 +152.58.33.101 +47.9.123.191 +122.161.66.91 +49.34.157.164 +106.223.199.85 +110.224.93.159 +223.176.113.105 +157.51.193.198 +106.194.2.229 +114.31.134.26 +117.253.115.92 +157.48.225.118 +117.99.23.208 +157.49.209.50 +152.57.142.48 +171.49.153.47 +27.4.242.72 +157.38.22.229 +157.48.182.255 +103.70.203.121 +223.184.187.133 +157.42.0.252 +171.76.245.88 +122.177.97.219 +106.215.92.198 +157.39.243.170 +106.194.57.220 +27.56.64.49 +106.216.115.140 +42.105.79.36 +152.58.36.98 +152.57.131.174 +157.48.134.13 +157.41.255.28 +117.98.12.172 +49.44.86.199 +223.187.37.173 +117.98.84.84 +106.197.8.248 +223.238.139.192 +42.105.101.76 +157.45.146.151 +152.57.237.253 +182.64.120.248 +42.111.112.20 +223.190.153.43 +122.168.212.67 +103.187.97.53 +1.39.110.20 +117.99.16.67 +152.58.191.231 +157.38.0.100 +223.185.64.139 +157.48.235.201 +106.221.96.59 +106.196.12.247 +157.51.199.113 +137.97.116.249 +117.243.162.61 +132.154.36.2 +106.217.189.177 +47.15.15.180 +27.60.200.242 +223.188.161.199 +146.196.44.6 +223.189.180.154 +157.45.243.24 +152.58.134.184 +106.195.42.121 +124.253.1.164 +157.41.199.190 +157.33.4.246 +110.227.18.36 +152.58.58.109 +171.51.158.187 +157.39.64.74 +157.41.228.55 +106.207.211.223 +49.42.86.208 +223.187.143.10 +152.58.213.61 +178.248.116.77 +157.51.192.170 +152.57.127.67 +49.34.149.99 +47.29.173.139 +106.205.163.233 +103.16.69.159 +223.228.230.119 +106.215.226.180 +223.187.21.174 +117.99.251.228 +106.208.154.141 +27.57.121.208 +106.208.118.25 +42.106.237.249 +117.217.160.168 +152.58.23.23 +223.228.190.232 +157.48.211.14 +106.221.233.192 +106.76.92.249 +157.35.43.251 +157.38.73.208 +106.76.235.81 +47.15.116.236 +157.38.74.226 +152.58.106.200 +49.33.219.119 +122.163.197.216 +152.58.212.247 +103.85.207.68 +157.34.197.85 +59.97.167.12 +157.34.23.255 +106.195.123.189 +223.187.115.224 +157.35.24.235 +47.9.85.79 +122.172.83.161 +152.58.98.236 +27.60.47.212 +27.59.164.1 +47.31.96.251 +47.9.113.252 +106.206.202.122 +157.49.68.13 +106.222.74.234 +157.51.199.102 +27.60.101.101 +106.78.76.155 +49.34.44.217 +223.190.128.8 +157.42.4.10 +157.48.114.170 +152.57.3.90 +106.207.8.24 +42.105.208.14 +171.76.248.253 +47.11.207.211 +157.41.251.37 +27.56.208.185 +157.49.176.32 +1.38.89.153 +171.79.189.218 +27.56.28.183 +49.42.90.227 +132.154.63.239 +103.166.13.81 +157.41.228.111 +157.46.121.51 +42.111.165.249 +223.238.0.4 +157.32.245.86 +106.216.207.13 +132.154.163.3 +1.187.213.211 +106.216.112.100 +106.76.88.42 +202.14.121.163 +157.42.248.107 +49.37.73.137 +106.195.40.182 +49.37.105.20 +106.212.43.172 +42.107.197.128 +103.70.146.74 +171.50.209.255 +157.38.132.101 +47.15.19.204 +157.41.248.217 +27.62.255.92 +47.247.206.119 +42.105.235.27 +106.202.49.227 +223.238.176.66 +49.36.180.9 +110.227.52.235 +47.29.170.49 +106.221.156.66 +169.149.226.74 +42.105.205.201 +49.34.148.51 +117.96.177.230 +47.11.38.137 +47.9.101.52 +223.238.124.227 +49.36.215.51 +1.187.5.103 +152.58.233.74 +49.14.155.176 +152.57.221.16 +157.48.127.18 +117.98.90.154 +152.57.79.171 +223.225.123.249 +152.58.96.254 +157.45.205.116 +223.187.37.212 +157.34.60.184 +152.58.182.195 +157.48.146.44 +157.34.12.67 +106.206.198.90 +106.192.102.121 +117.255.81.20 +223.189.166.213 +157.38.74.106 +103.85.8.163 +106.216.240.240 +223.182.204.81 +157.42.219.242 +106.194.11.49 +1.187.183.150 +152.57.243.199 +106.206.247.197 +49.37.217.10 +157.51.125.224 +103.181.57.177 +43.231.240.192 +49.37.52.41 +157.45.147.100 +47.9.74.229 +157.46.112.25 +47.29.168.218 +106.211.88.211 +157.34.154.14 +42.105.179.53 +132.154.154.11 +157.45.170.201 +223.189.211.179 +157.42.227.215 +106.203.101.104 +103.58.152.158 +103.238.108.205 +49.37.193.4 +106.220.106.82 +47.29.160.77 +152.58.143.31 +49.36.192.153 +106.197.14.235 +157.49.236.87 +152.58.73.112 +152.58.19.235 +47.9.115.245 +152.58.103.55 +106.205.201.17 +157.49.133.105 +106.76.227.202 +27.59.243.235 +157.45.143.57 +49.37.53.192 +103.248.94.95 +106.215.246.134 +157.32.66.94 +106.223.92.129 +47.31.211.217 +49.36.215.55 +157.48.170.207 +157.41.254.125 +101.0.54.235 +223.238.60.95 +157.48.115.163 +157.48.113.69 +49.36.168.246 +106.196.1.70 +157.33.217.107 +152.58.201.245 +27.61.62.11 +49.35.248.20 +47.11.80.219 +106.220.173.22 +49.37.131.69 +157.46.189.125 +223.231.229.69 +223.239.120.11 +132.154.50.73 +157.51.177.204 +106.78.36.114 +49.47.71.166 +1.187.220.164 +106.195.57.243 +103.235.3.97 +106.196.29.253 +223.239.61.140 +157.50.22.60 +157.38.147.106 +106.216.235.204 +106.211.40.62 +110.224.105.165 +157.51.15.197 +157.42.255.48 +157.47.97.208 +152.58.191.134 +223.230.128.70 +1.39.29.155 +157.50.65.55 +157.45.243.91 +157.37.171.240 +157.49.245.160 +152.57.142.159 +223.187.125.89 +1.39.29.68 +157.49.198.159 +106.194.205.192 +157.48.112.212 +171.79.148.102 +42.106.8.32 +43.241.192.212 +157.50.22.236 +106.208.151.2 +183.87.175.131 +110.227.0.33 +106.221.171.123 +152.57.153.214 +205.253.37.137 +106.210.43.184 +106.204.229.126 +157.42.239.200 +49.37.40.169 +157.42.199.73 +152.59.66.243 +106.211.46.197 +152.58.83.211 +106.193.48.254 +152.57.207.78 +157.41.224.244 +106.216.163.134 +223.186.204.15 +157.48.245.61 +132.154.52.66 +157.42.210.95 +152.58.182.224 +49.35.239.213 +223.181.39.234 +1.39.114.198 +117.98.58.234 +49.14.115.98 +152.59.64.49 +42.111.106.85 +152.57.207.149 +152.58.196.133 +106.196.24.3 +106.203.133.221 +106.219.75.97 +157.35.45.185 +137.97.85.72 +49.34.119.105 +223.189.198.150 +49.36.213.51 +152.58.81.159 +103.249.251.32 +106.205.203.142 +152.57.181.21 +42.108.196.227 +223.187.107.80 +103.88.236.138 +49.35.248.203 +106.211.27.105 +106.196.73.193 +117.98.104.100 +106.206.202.20 +117.99.220.70 +106.206.95.21 +103.110.48.171 +49.34.42.238 +106.207.41.132 +152.58.191.88 +103.97.47.248 +157.38.85.146 +157.42.250.93 +47.9.117.202 +27.56.214.31 +223.191.61.177 +117.97.194.18 +139.167.197.167 +223.178.208.180 +106.221.101.41 +117.99.212.131 +205.253.10.36 +157.38.116.175 +152.58.224.41 +152.58.34.104 +171.76.224.112 +101.0.33.125 +49.37.64.118 +49.36.138.95 +106.211.53.238 +106.210.220.19 +117.249.183.221 +106.195.114.200 +106.216.192.30 +223.176.9.35 +157.47.95.83 +157.42.196.80 +157.42.223.130 +223.230.158.118 +157.38.130.134 +157.41.245.152 +106.196.2.72 +47.29.166.25 +61.3.195.155 +49.36.236.93 +152.58.100.201 +169.149.196.149 +49.37.73.92 +106.195.76.48 +49.43.181.2 +157.38.155.143 +152.57.174.140 +157.33.212.31 +152.58.188.147 +223.238.68.224 +106.198.99.188 +103.183.32.245 +106.78.51.101 +157.34.255.234 +157.32.106.108 +157.33.127.49 +157.34.204.200 +106.217.84.251 +132.154.54.117 +223.238.86.142 +49.42.73.95 +223.238.204.148 +49.34.89.137 +49.35.255.138 +157.38.135.63 +47.15.5.189 +42.105.9.138 +223.187.63.235 +103.13.104.245 +223.233.31.161 +49.37.26.113 +223.187.23.149 +152.57.242.78 +49.42.65.250 +27.56.1.248 +103.15.255.171 +110.224.175.97 +182.69.45.132 +106.198.229.228 +157.50.43.197 +106.208.146.53 +106.205.204.136 +42.106.248.170 +42.111.13.76 +49.37.24.38 +157.45.162.78 +152.58.100.146 +106.208.148.197 +110.227.29.84 +47.11.204.191 +106.193.72.138 +157.42.3.147 +49.37.154.198 +157.49.249.98 +117.99.192.210 +47.31.169.216 +106.211.85.186 +49.42.87.134 +223.227.94.237 +157.32.92.75 +101.0.57.30 +157.38.244.212 +157.45.169.89 +47.11.201.176 +106.76.208.51 +152.57.183.130 +47.15.216.106 +49.36.83.76 +117.214.108.149 +47.29.6.18 +157.38.243.248 +106.223.36.48 +42.105.48.25 +106.210.134.35 +223.238.23.115 +223.238.0.129 +223.188.239.228 +27.63.135.43 +157.39.67.240 +27.63.133.87 +157.44.204.45 +152.58.79.7 +106.77.182.241 +106.196.22.186 +152.58.168.52 +106.194.190.38 +47.9.154.49 +152.57.219.102 +47.15.3.90 +117.96.169.4 +49.33.204.57 +42.105.209.63 +106.221.247.105 +42.110.169.143 +152.58.200.133 +103.48.100.15 +103.175.8.54 +106.203.158.185 +223.187.30.203 +157.42.253.211 +49.35.151.61 +157.42.236.230 +47.15.5.139 +106.221.239.25 +47.15.183.252 +117.98.104.30 +157.34.44.60 +152.58.190.16 +152.58.197.74 +157.35.67.101 +157.49.91.5 +223.238.195.98 +157.34.149.66 +27.56.18.56 +157.34.156.16 +49.14.96.45 +152.58.68.137 +171.76.84.151 +157.47.80.21 +103.140.106.202 +157.49.233.236 +45.116.106.185 +117.97.73.165 +49.36.26.116 +27.63.194.65 +157.38.230.203 +152.57.216.222 +157.33.212.143 +117.98.108.122 +132.154.63.77 +106.221.96.105 +47.15.37.195 +157.39.64.33 +152.58.73.165 +59.97.103.133 +42.109.196.28 +49.34.186.221 +157.45.37.159 +157.35.26.50 +157.46.99.106 +120.88.189.225 +49.14.110.247 +49.42.90.89 +110.226.163.92 +106.195.127.41 +47.9.86.30 +117.96.154.84 +157.48.86.171 +106.76.90.211 +103.77.43.159 +49.34.89.57 +106.216.81.66 +157.51.195.169 +157.44.131.151 +223.239.27.238 +157.49.165.133 +27.61.96.175 +42.108.78.51 +1.38.105.17 +106.207.21.149 +49.43.155.224 +106.197.98.118 +157.47.95.70 +157.38.212.69 +157.46.95.201 +157.46.117.111 +223.239.56.226 +157.49.159.119 +49.34.230.169 +106.220.227.174 +106.79.205.50 +171.76.139.183 +223.182.214.19 +157.51.197.117 +49.34.60.119 +223.237.114.240 +106.200.38.105 +106.76.91.17 +103.139.34.163 +47.9.36.56 +42.106.178.73 +132.154.63.205 +223.190.143.23 +49.37.39.150 +42.110.160.18 +47.29.162.223 +157.45.140.37 +152.58.67.192 +106.223.103.98 +223.182.30.127 +157.38.218.225 +106.76.78.239 +49.35.135.151 +157.34.207.120 +157.48.218.221 +27.59.20.10 +223.187.26.206 +157.49.141.147 +157.48.182.103 +106.216.244.9 +49.15.246.39 +223.238.56.60 +42.105.48.197 +205.253.34.112 +223.231.170.180 +106.208.124.92 +157.45.158.175 +106.76.93.41 +157.46.166.69 +27.59.219.18 +169.149.228.240 +223.233.67.31 +49.47.70.210 +42.105.199.33 +42.110.170.63 +49.36.192.220 +223.182.45.206 +47.9.155.119 +106.211.92.234 +106.210.158.185 +47.9.72.248 +106.216.72.123 +157.41.226.99 +49.36.144.68 +223.238.82.164 +47.11.69.153 +152.57.203.188 +103.66.209.130 +47.15.18.201 +106.202.81.66 +157.40.82.247 +47.11.199.224 +49.36.221.198 +106.196.26.138 +47.15.239.22 +42.111.149.14 +157.35.92.208 +157.47.58.150 +139.167.175.248 +157.47.77.133 +157.33.198.171 +47.29.171.150 +223.238.96.195 +47.9.37.227 +157.32.95.185 +110.172.173.254 +223.231.114.117 +157.48.172.159 +157.41.226.94 +223.180.178.136 +157.45.143.78 +49.15.209.112 +103.175.137.248 +106.221.254.149 +27.61.222.214 +205.253.33.116 +106.76.197.18 +110.226.205.3 +152.58.66.36 +42.106.205.16 +152.58.20.224 +1.38.176.2 +49.42.83.177 +42.106.93.2 +49.37.194.66 +157.33.39.160 +157.34.202.67 +169.149.196.32 +1.38.142.249 +157.32.34.180 +27.63.72.147 +49.36.144.8 +117.214.104.143 +157.49.71.178 +157.37.172.159 +117.97.213.165 +110.224.93.128 +110.224.24.211 +115.98.233.170 +132.154.5.89 +106.66.28.11 +157.41.249.224 +157.34.48.178 +223.228.208.171 +106.197.5.164 +49.36.10.180 +223.238.116.240 +42.111.125.26 +157.35.24.8 +223.179.246.193 +49.36.99.69 +157.48.247.212 +27.62.230.40 +103.175.63.201 +152.57.74.218 +157.51.70.86 +223.184.2.77 +152.58.210.123 +103.187.97.153 +106.221.188.80 +106.206.203.96 +223.181.101.50 +157.48.87.18 +47.15.234.193 +47.11.207.244 +42.105.48.46 +49.207.203.149 +157.40.85.86 +49.47.71.121 +106.217.168.17 +110.224.93.236 +223.180.183.148 +152.58.197.17 +106.206.111.247 +47.11.211.42 +42.107.133.30 +106.193.68.205 +106.196.31.199 +49.43.178.183 +152.58.197.33 +106.51.188.111 +152.57.147.20 +152.57.119.14 +150.129.122.99 +49.36.112.200 +110.227.55.203 +117.229.144.164 +106.76.236.41 +27.62.45.119 +157.48.185.38 +157.42.222.206 +49.34.166.122 +49.15.201.193 +152.58.234.60 +47.31.130.142 +157.42.217.235 +27.61.155.65 +106.216.112.23 +223.181.34.33 +157.38.253.10 +42.106.95.128 +152.58.156.223 +157.34.68.106 +49.43.154.44 +49.14.108.166 +182.64.136.134 +49.34.36.90 +152.58.131.30 +223.176.66.33 +223.176.85.175 +47.9.84.121 +106.193.206.239 +103.171.100.225 +223.181.180.176 +117.99.249.115 +47.9.82.117 +157.38.47.223 +27.62.249.132 +106.203.14.208 +157.51.28.22 +110.224.94.9 +106.216.80.186 +164.100.214.89 +132.154.25.231 +47.29.13.224 +106.196.117.136 +157.41.255.93 +103.179.102.219 +152.57.231.214 +47.29.48.170 +103.225.57.11 +139.167.168.207 +132.154.48.27 +132.154.56.214 +49.37.50.6 +152.58.185.143 +106.206.243.114 +110.227.45.250 +152.58.196.163 +152.58.196.189 +110.224.109.101 +132.154.53.51 +47.9.111.248 +106.205.194.112 +223.176.23.161 +122.169.21.150 +27.97.161.54 +27.63.93.53 +157.45.196.200 +157.34.124.211 +49.36.233.94 +223.233.17.113 +152.57.116.147 +106.204.210.194 +49.15.228.247 +157.38.148.56 +122.161.241.175 +42.105.12.243 +223.227.121.2 +106.221.221.237 +171.60.210.83 +157.39.217.166 +152.58.69.205 +49.36.177.208 +157.32.89.166 +49.36.34.77 +49.34.216.47 +1.39.31.222 +223.179.247.191 +49.36.213.40 +106.197.75.40 +223.185.78.233 +106.217.217.135 +223.233.121.30 +110.227.59.218 +157.48.115.69 +152.58.236.209 +49.43.3.144 +49.34.123.96 +106.208.76.176 +157.34.228.169 +152.58.133.92 +157.39.70.149 +106.194.169.88 +103.120.252.166 +157.42.192.57 +110.227.48.138 +223.225.125.138 +47.15.191.178 +152.57.86.236 +103.165.25.25 +49.34.220.85 +223.238.218.229 +47.15.11.155 +157.38.128.166 +103.68.186.154 +157.41.250.211 +103.85.10.43 +27.59.190.173 +117.96.175.209 +1.38.64.161 +110.224.86.73 +101.0.50.132 +106.214.225.208 +59.182.147.116 +47.9.123.59 +223.188.237.16 +152.58.185.60 +157.41.249.61 +157.34.34.45 +157.49.170.144 +117.207.235.251 +27.62.64.87 +103.242.196.209 +152.58.155.234 +49.205.97.129 +223.188.224.89 +49.15.229.217 +49.35.186.34 +103.240.170.58 +157.49.132.126 +103.165.27.167 +49.35.179.207 +49.43.250.119 +223.178.211.72 +106.66.57.163 +152.57.100.217 +117.99.231.222 +106.194.136.68 +106.194.76.23 +43.229.90.228 +157.48.252.225 +223.228.190.131 +27.61.211.62 +223.186.199.123 +152.58.72.247 +157.41.224.142 +49.37.24.209 +45.250.244.142 +157.38.61.49 +49.35.195.155 +27.59.184.62 +117.212.163.85 +152.58.167.109 +157.37.193.210 +49.35.191.233 +27.59.28.253 +223.178.210.193 +47.29.160.165 +42.110.174.29 +27.59.26.166 +157.35.81.60 +49.34.62.60 +43.251.92.17 +223.239.85.169 +157.48.115.96 +106.196.37.40 +157.41.227.148 +157.48.115.10 +157.48.114.239 +157.41.255.111 +106.196.77.71 +152.58.2.5 +157.33.218.237 +157.41.251.46 +103.241.225.164 +42.105.86.127 +223.228.166.102 +223.238.204.195 +49.34.177.75 +42.105.204.216 +106.77.141.54 +110.226.164.149 +106.204.198.144 +117.98.88.106 +47.11.195.38 +49.14.134.104 +182.59.115.185 +157.34.111.159 +106.216.236.85 +47.15.169.244 +117.97.214.97 +110.227.57.205 +157.47.77.84 +42.105.198.98 +103.105.96.216 +157.47.65.10 +106.76.231.248 +27.4.28.184 +152.58.92.25 +152.57.156.8 +49.32.244.25 +157.33.61.185 +157.44.209.242 +157.48.155.223 +124.253.174.204 +49.36.203.250 +106.207.143.178 +106.207.208.109 +106.208.70.133 +223.231.197.240 +157.47.20.57 +49.36.185.9 +152.58.233.151 +157.34.36.54 +106.216.123.94 +132.154.59.253 +223.184.244.195 +47.15.12.72 +106.195.15.250 +157.41.255.223 +47.29.174.78 +45.248.95.58 +157.46.179.105 +42.111.112.76 +106.196.30.34 +106.210.100.113 +47.15.107.121 +125.62.97.155 +49.37.170.63 +223.238.199.231 +120.88.34.29 +139.167.178.154 +47.11.205.27 +223.227.86.111 +42.104.133.11 +1.187.213.27 +106.206.230.101 +157.33.17.29 +49.15.220.23 +157.47.121.61 +157.42.0.242 +152.58.197.80 +103.206.138.174 +223.238.101.163 +157.42.229.210 +152.58.211.139 +42.109.206.156 +157.45.238.91 +157.34.137.211 +203.109.79.99 +157.48.218.238 +171.60.211.255 +223.238.219.10 +223.233.9.54 +27.63.132.156 +47.15.14.234 +157.44.198.177 +106.208.215.150 +182.68.62.151 +27.61.76.55 +112.79.57.183 +152.58.168.38 +157.41.249.199 +49.205.210.209 +152.58.139.148 +47.11.63.141 +27.97.15.235 +157.41.228.186 +27.63.74.206 +106.217.66.143 +42.108.76.195 +157.33.9.249 +157.37.189.118 +49.34.194.203 +180.188.232.147 +117.98.50.133 +132.154.177.24 +223.187.139.112 +42.107.86.74 +157.33.248.93 +106.223.176.96 +47.15.21.88 +42.104.133.24 +49.37.233.149 +49.37.117.221 +49.35.231.75 +49.35.134.235 +223.190.186.139 +152.58.197.90 +157.38.2.132 +157.51.195.91 +110.224.164.63 +157.39.69.235 +103.85.96.90 +111.92.21.99 +106.194.17.17 +152.58.233.217 +106.197.84.93 +49.205.147.134 +106.203.18.229 +157.39.73.90 +59.99.66.37 +27.7.240.127 +112.79.126.94 +106.76.196.44 +42.111.21.3 +152.57.105.219 +47.15.33.125 +223.176.5.170 +49.42.84.251 +157.38.29.125 +223.190.135.193 +157.34.233.84 +49.14.114.0 +169.149.229.54 +157.42.202.135 +42.104.142.19 +157.45.207.52 +157.49.204.57 +49.42.81.102 +106.208.82.120 +157.48.235.212 +152.58.181.205 +203.109.66.105 +47.29.162.26 +157.35.54.206 +223.230.171.192 +157.38.149.189 +42.105.212.11 +157.32.75.192 +182.69.179.103 +157.34.67.161 +157.41.229.155 +223.189.131.73 +152.58.82.35 +49.36.26.207 +117.99.25.217 +157.45.145.4 +106.79.204.170 +122.162.147.241 +223.239.26.126 +49.37.107.176 +49.15.136.222 +223.231.127.238 +106.66.36.71 +223.187.56.48 +203.76.186.184 +106.205.201.117 +223.228.243.81 +152.58.21.241 +114.69.235.110 +111.92.74.12 +106.223.34.200 +152.58.34.11 +157.38.215.85 +223.237.220.196 +157.49.166.101 +27.60.3.198 +49.32.237.151 +42.105.10.104 +47.29.164.170 +106.78.83.172 +152.57.18.43 +117.98.94.137 +157.48.211.52 +157.34.195.83 +47.31.97.80 +122.173.30.73 +43.229.90.74 +157.35.72.136 +157.35.14.145 +106.216.206.47 +157.47.83.198 +157.51.68.253 +157.48.116.140 +157.32.227.210 +157.37.142.35 +27.60.28.117 +49.37.99.7 +103.200.85.69 +157.32.211.34 +106.216.196.186 +110.224.103.20 +157.45.89.101 +47.15.225.109 +157.34.254.229 +106.207.254.159 +157.47.92.8 +110.224.74.105 +157.49.232.229 +47.9.115.186 +106.76.210.210 +47.29.169.144 +47.31.96.172 +49.36.24.66 +157.41.250.130 +106.193.172.247 +157.34.102.11 +27.123.240.109 +157.34.219.11 +49.35.237.184 +223.189.161.121 +47.9.37.82 +171.76.252.84 +139.167.168.128 +157.41.248.121 +47.11.203.127 +117.245.8.252 +157.38.131.56 +157.38.244.219 +205.253.124.76 +223.187.101.22 +223.187.68.38 +103.135.61.38 +106.198.22.226 +47.29.28.116 +47.29.175.245 +106.216.233.174 +139.167.160.195 +1.23.115.24 +117.237.220.232 +223.180.184.167 +157.42.241.119 +146.196.36.221 +152.58.68.65 +106.208.240.211 +117.98.80.119 +1.38.93.28 +157.35.82.206 +117.229.139.122 +27.60.41.234 +106.200.152.57 +45.118.159.215 +47.9.147.164 +47.31.245.18 +132.154.49.34 +157.38.44.201 +49.32.152.247 +49.43.0.136 +49.36.202.17 +117.96.135.106 +47.29.167.75 +223.233.85.65 +106.208.127.225 +157.42.210.46 +157.48.198.208 +112.79.111.80 +117.99.222.231 +171.76.239.210 +49.32.172.71 +115.242.251.234 +103.41.91.241 +103.228.145.73 +223.233.120.111 +157.42.5.190 +223.227.73.2 +157.45.205.250 +223.233.78.161 +152.58.112.37 +110.224.182.157 +106.207.171.242 +110.224.188.23 +49.205.97.87 +152.58.129.10 +157.34.110.253 +157.49.189.177 +223.228.91.62 +152.58.231.226 +103.77.27.37 +157.42.7.203 +49.36.208.184 +171.76.135.177 +49.36.98.80 +157.35.27.119 +157.38.38.227 +47.9.153.17 +49.36.105.215 +110.224.81.1 +1.38.117.74 +157.38.56.122 +157.40.127.248 +157.46.115.27 +157.38.18.84 +132.154.19.227 +106.202.135.100 +106.216.77.111 +157.41.229.194 +106.195.76.51 +106.205.207.209 +106.194.150.96 +103.168.248.115 +110.224.97.26 +157.48.86.46 +171.76.185.133 +223.189.214.226 +49.43.41.243 +49.37.193.37 +49.36.218.154 +157.35.47.49 +103.86.18.143 +122.181.86.42 +157.51.198.26 +106.78.189.140 +1.39.114.220 +223.190.183.68 +103.252.145.11 +49.37.224.92 +49.36.106.232 +49.34.118.205 +47.9.37.181 +103.171.201.31 +223.239.78.63 +103.179.115.228 +152.58.155.253 +157.51.193.234 +157.45.128.139 +49.14.135.90 +223.189.247.52 +139.167.172.161 +49.35.231.234 +223.230.162.68 +152.58.19.88 +106.194.92.71 +49.36.120.168 +49.36.171.126 +122.161.241.202 +27.63.9.170 +49.15.161.254 +157.34.241.31 +106.220.94.238 +132.154.34.196 +157.38.138.254 +157.51.115.84 +152.58.80.37 +223.228.67.137 +47.247.208.181 +117.98.14.139 +47.15.39.200 +106.201.20.186 +157.44.140.236 +157.33.108.125 +157.41.227.204 +157.32.84.242 +169.149.227.198 +49.43.42.121 +117.98.106.170 +157.38.134.61 +106.203.145.228 +49.35.237.148 +106.221.240.21 +157.39.65.224 +157.32.119.185 +47.9.112.212 +223.238.197.4 +47.9.158.2 +103.41.38.135 +152.58.56.225 +223.228.141.34 +42.104.153.28 +223.187.109.112 +157.34.158.254 +106.205.251.254 +132.154.59.213 +223.239.25.95 +47.15.241.101 +42.104.212.207 +157.50.16.231 +42.111.21.92 +223.228.90.237 +223.230.144.188 +152.57.88.43 +139.167.181.180 +203.192.241.229 +106.208.146.16 +49.35.144.180 +42.104.129.2 +157.33.103.54 +157.47.110.255 +103.101.213.73 +106.196.13.170 +106.217.162.141 +122.162.145.145 +171.76.232.92 +49.14.156.190 +1.39.116.129 +27.97.179.83 +157.44.189.165 +182.64.193.206 +223.225.124.2 +157.44.199.247 +223.180.172.24 +157.48.152.67 +110.227.12.198 +49.32.161.244 +132.154.15.107 +106.208.159.33 +122.176.179.129 +117.235.140.241 +157.42.226.98 +106.76.197.78 +157.35.94.96 +152.58.213.243 +152.57.141.173 +106.221.191.196 +157.47.16.170 +157.34.36.117 +47.15.210.74 +157.50.9.245 +106.210.214.111 +132.154.56.55 +47.9.133.163 +106.214.218.250 +106.221.219.126 +223.227.79.158 +117.99.208.157 +106.204.204.33 +137.97.127.180 +157.35.72.178 +152.58.233.244 +180.188.236.232 +49.35.254.49 +106.206.90.207 +58.84.61.35 +106.76.71.65 +49.36.222.179 +110.224.172.157 +49.34.140.219 +106.202.0.199 +106.198.241.86 +47.247.211.186 +157.50.6.167 +49.35.153.98 +223.225.244.163 +49.43.40.248 +223.239.26.144 +157.47.68.73 +106.198.7.252 +27.61.212.113 +117.99.231.37 +49.207.200.225 +152.57.5.237 +223.187.103.75 +157.40.69.104 +223.228.20.114 +157.49.143.63 +223.238.211.164 +103.28.252.72 +27.60.200.124 +49.37.161.55 +157.40.74.224 +152.58.153.244 +152.57.111.108 +157.48.127.34 +223.225.34.133 +103.179.231.124 +49.34.171.49 +103.42.199.27 +117.99.237.233 +157.34.3.114 +157.51.122.239 +157.34.67.78 +223.238.223.183 +110.224.180.180 +49.34.44.149 +157.35.49.122 +117.98.46.90 +157.35.57.45 +157.39.218.105 +223.238.105.127 +157.38.56.99 +117.194.110.179 +132.154.59.187 +117.98.54.173 +137.97.112.62 +223.187.190.252 +106.205.172.242 +117.97.187.231 +106.197.42.139 +223.237.101.15 +49.42.72.219 +47.9.120.133 +42.107.195.22 +106.216.114.104 +152.58.212.206 +49.42.92.4 +1.187.180.13 +152.58.71.233 +27.63.106.36 +110.226.196.100 +132.154.60.120 +152.58.232.84 +106.220.120.150 +132.154.164.126 +117.99.11.212 +152.58.214.220 +103.79.250.172 +169.149.229.186 +152.58.59.162 +111.92.76.248 +157.51.24.21 +223.233.121.96 +157.38.152.5 +157.34.32.83 +171.79.76.78 +223.176.0.176 +171.79.145.213 +157.51.20.200 +110.224.188.204 +47.11.81.226 +106.194.139.18 +47.29.171.92 +157.38.211.113 +137.97.87.247 +47.15.212.232 +132.154.165.206 +157.42.3.139 +152.58.197.99 +152.58.131.58 +157.47.6.46 +42.105.237.251 +47.15.10.157 +157.41.244.219 +47.11.233.39 +157.34.157.37 +1.39.29.183 +223.230.138.230 +152.57.169.215 +110.224.87.48 +106.216.229.128 +157.41.225.140 +106.221.246.61 +49.43.33.52 +106.206.200.42 +49.42.92.85 +223.185.98.72 +157.38.55.57 +157.49.70.238 +152.57.91.163 +49.35.255.46 +117.98.114.42 +106.221.119.224 +1.187.16.25 +223.187.73.115 +106.216.252.216 +106.66.37.18 +223.188.235.143 +157.37.160.240 +157.48.193.124 +157.49.250.55 +157.48.162.8 +132.154.35.150 +157.35.82.102 +106.206.206.26 +42.104.157.45 +106.206.212.132 +114.31.130.76 +152.57.154.177 +111.92.116.171 +106.221.179.201 +152.58.129.236 +49.14.165.80 +112.79.104.104 +223.181.216.255 +152.58.72.76 +157.34.133.215 +47.11.203.68 +103.117.36.8 +223.185.72.171 +157.41.224.207 +132.154.37.29 +49.35.225.144 +157.41.224.89 +106.205.206.254 +106.194.24.212 +157.34.207.88 +152.57.150.88 +223.238.231.238 +110.224.94.169 +157.45.142.84 +117.97.215.91 +27.59.153.147 +106.217.172.8 +106.194.175.5 +47.15.40.154 +27.60.204.220 +49.34.136.162 +27.60.99.254 +49.34.246.6 +223.176.114.137 +106.208.144.104 +27.61.201.88 +152.59.64.169 +152.58.169.18 +49.35.192.177 +157.32.209.252 +223.188.124.36 +103.77.43.143 +106.198.181.81 +106.196.9.153 +42.108.29.205 +106.194.2.17 +223.186.235.160 +103.184.239.220 +157.48.192.86 +152.57.128.246 +103.148.65.252 +106.208.179.206 +106.220.170.44 +132.154.61.0 +157.38.107.157 +117.99.198.66 +152.59.65.87 +210.89.58.192 +47.31.98.237 +157.47.62.160 +47.11.252.39 +157.48.157.149 +157.38.146.237 +27.60.195.28 +47.9.8.145 +223.225.99.36 +106.202.59.188 +103.79.255.94 +106.207.173.85 +223.190.167.138 +171.76.140.189 +117.213.0.11 +106.220.129.189 +152.58.101.20 +106.217.181.5 +157.45.92.188 +157.46.163.120 +47.15.13.28 +27.62.234.181 +157.46.99.22 +106.219.189.224 +157.45.178.19 +157.47.125.248 +137.97.96.89 +106.193.13.10 +117.98.56.217 +49.43.91.159 +49.35.172.248 +42.105.205.226 +152.58.129.157 +169.149.224.158 +223.184.234.136 +223.233.68.36 +103.140.107.252 +47.29.166.235 +223.188.224.129 +203.192.207.6 +106.200.83.29 +111.92.23.124 +106.194.23.216 +169.149.194.142 +106.192.64.219 +132.154.176.51 +157.38.78.216 +223.187.253.165 +49.14.114.92 +106.196.48.116 +106.219.186.64 +103.179.230.163 +137.97.65.62 +103.29.209.168 +27.60.83.240 +169.149.199.144 +106.192.192.243 +27.62.254.224 +60.254.0.246 +110.226.196.221 +223.239.28.153 +49.34.48.241 +157.34.19.190 +27.56.70.136 +106.66.36.214 +223.176.47.197 +110.224.70.99 +119.82.80.97 +202.89.77.25 +1.22.40.57 +223.231.171.69 +182.69.180.200 +223.239.99.132 +157.37.128.7 +157.48.117.65 +49.34.124.101 +1.38.72.197 +110.226.169.10 +152.58.232.227 +223.231.189.75 +49.33.212.80 +157.51.180.132 +223.227.34.16 +106.220.254.224 +112.79.157.56 +106.76.241.249 +106.78.52.96 +106.196.60.232 +49.42.89.21 +169.149.197.151 +157.50.16.64 +157.35.6.192 +152.57.206.211 +157.48.224.12 +157.41.193.12 +157.47.48.32 +106.223.182.213 +106.205.207.137 +103.121.205.19 +152.58.188.226 +132.154.158.99 +106.216.198.150 +106.76.69.68 +223.231.238.197 +42.107.86.255 +171.48.82.198 +27.63.107.11 +223.239.66.133 +223.182.216.136 +152.58.107.1 +106.193.204.63 +223.239.123.44 +152.58.201.22 +171.79.145.163 +106.223.213.102 +171.79.167.253 +106.207.163.26 +106.207.190.90 +117.99.233.77 +157.50.9.57 +157.37.130.194 +157.33.218.235 +152.58.42.63 +157.38.104.147 +49.15.234.181 +157.32.219.166 +157.33.27.35 +47.15.2.29 +157.34.157.179 +103.149.236.183 +157.35.25.137 +47.29.60.161 +110.224.85.234 +27.59.217.24 +106.221.80.232 +139.167.199.1 +169.149.198.144 +103.101.212.174 +223.186.210.127 +49.15.173.168 +49.34.104.153 +157.38.135.101 +157.34.0.131 +171.79.149.66 +106.216.120.122 +47.15.43.165 +223.230.159.165 +49.35.192.242 +157.34.45.253 +106.208.71.59 +157.46.113.227 +152.58.25.45 +103.165.20.181 +157.34.220.68 +157.33.89.228 +49.42.68.17 +157.34.128.239 +103.127.20.145 +157.34.156.104 +106.206.205.24 +152.57.7.148 +112.79.58.89 +223.239.60.35 +47.29.173.254 +106.194.86.34 +111.92.27.157 +157.47.33.144 +117.99.220.200 +45.127.89.85 +157.45.138.173 +49.37.73.83 +42.105.172.242 +106.192.225.220 +157.41.244.147 +157.48.115.141 +157.38.29.228 +202.8.118.35 +157.34.53.19 +152.58.134.188 +157.49.73.16 +139.167.190.53 +122.162.151.129 +47.11.228.49 +157.47.75.50 +132.154.58.205 +132.154.48.21 +157.39.196.47 +106.217.48.231 +223.187.86.72 +42.107.225.157 +106.204.195.202 +132.154.149.83 +106.76.252.140 +49.34.240.116 +117.98.58.100 +157.41.224.159 +157.47.48.219 +106.221.101.54 +157.40.123.183 +49.36.32.35 +157.35.73.93 +223.182.170.255 +157.34.70.63 +47.9.120.249 +223.186.53.213 +157.48.140.83 +132.154.38.123 +169.149.196.5 +152.58.163.174 +157.33.37.44 +27.62.62.138 +49.36.223.187 +152.58.186.178 +106.76.209.172 +205.253.36.137 +27.97.165.77 +106.66.57.18 +157.48.145.112 +157.42.0.201 +152.58.159.201 +152.57.203.217 +117.199.40.97 +1.39.228.35 +157.48.193.137 +171.76.221.215 +157.47.121.111 +157.41.252.248 +106.78.185.231 +49.15.228.202 +139.167.183.42 +152.58.95.45 +223.228.230.242 +110.224.78.1 +49.43.7.201 +223.188.138.154 +106.216.121.103 +49.35.226.162 +117.99.213.41 +49.37.66.84 +49.36.201.32 +152.58.201.243 +157.34.238.164 +106.211.205.83 +152.58.196.24 +42.105.92.7 +157.34.87.179 +157.41.240.9 +117.98.78.152 +1.39.238.24 +152.58.236.165 +157.33.203.33 +157.39.75.163 +49.14.110.83 +116.75.199.221 +117.99.233.232 +223.239.55.9 +1.38.50.7 +47.15.222.152 +171.48.66.23 +223.187.218.249 +49.34.123.188 +157.40.109.85 +106.217.183.227 +103.58.154.71 +117.98.82.67 +157.38.126.234 +110.224.87.204 +157.48.188.204 +157.34.91.4 +49.36.81.150 +103.119.167.123 +171.51.191.144 +139.167.203.233 +49.37.55.143 +106.0.36.109 +1.38.94.154 +157.34.136.202 +49.35.252.98 +157.50.58.83 +157.51.192.164 +106.206.102.116 +47.11.20.123 +106.216.195.49 +157.35.95.41 +137.97.111.122 +106.193.87.210 +132.154.56.49 +202.142.117.200 +106.192.42.228 +49.15.228.37 +152.58.138.68 +103.165.20.82 +42.108.125.49 +14.96.100.194 +47.29.162.76 +47.29.164.66 +157.33.235.67 +103.147.139.179 +106.216.203.33 +49.36.177.181 +223.187.38.17 +223.237.237.172 +42.105.142.252 +49.42.88.74 +106.205.208.43 +49.14.129.22 +106.193.102.239 +157.35.2.126 +157.38.130.184 +157.44.210.148 +106.221.119.52 +157.34.5.79 +106.197.235.141 +49.34.40.201 +49.37.75.74 +47.9.34.4 +223.187.98.196 +152.58.155.190 +106.76.203.141 +106.195.47.83 +27.63.241.68 +157.37.171.134 +223.181.29.117 +152.57.234.191 +110.225.55.104 +152.58.231.149 +49.35.150.158 +27.60.253.165 +103.199.180.70 +106.221.149.12 +27.61.177.56 +42.105.141.20 +157.50.65.90 +223.227.70.35 +223.238.214.202 +169.149.224.236 +106.76.68.19 +157.33.74.186 +49.42.89.82 +157.42.220.181 +103.233.116.138 +103.199.180.75 +157.37.177.6 +210.89.59.21 +169.149.199.154 +47.11.201.33 +157.48.185.166 +157.50.0.225 +223.233.60.151 +49.37.49.81 +223.237.77.2 +157.41.229.203 +223.180.179.215 +182.70.167.156 +1.39.115.18 +49.42.83.72 +157.47.18.113 +157.45.64.209 +106.221.166.221 +59.88.135.144 +49.42.68.214 +152.58.155.50 +47.15.12.61 +106.76.54.58 +106.193.27.156 +117.98.34.15 +223.182.41.119 +110.226.167.199 +157.34.108.102 +157.40.118.49 +47.11.233.111 +110.227.43.42 +106.221.157.243 +106.208.147.111 +223.186.216.15 +42.109.203.32 +117.99.198.169 +27.97.171.40 +157.35.9.107 +223.182.53.70 +157.41.240.68 +110.225.49.5 +205.253.121.254 +106.208.181.24 +106.221.118.173 +59.96.55.109 +43.243.83.7 +157.33.199.145 +106.211.197.186 +157.47.46.47 +117.99.193.121 +152.58.232.223 +223.187.110.20 +223.190.159.222 +117.98.80.11 +47.9.142.154 +171.48.109.90 +106.193.136.231 +137.97.68.237 +157.34.232.5 +223.189.46.119 +152.57.164.229 +47.247.200.205 +27.61.118.161 +171.61.52.141 +152.58.85.187 +157.51.192.9 +27.62.251.254 +157.38.138.239 +157.45.76.200 +49.35.234.46 +152.58.56.107 +157.33.224.62 +223.231.182.218 +157.48.114.64 +157.50.36.220 +117.98.24.107 +157.48.228.246 +157.42.229.182 +106.197.97.34 +112.79.64.54 +152.57.34.187 +157.34.56.220 +157.50.46.230 +42.105.204.84 +157.44.166.219 +157.41.224.85 +223.239.104.54 +152.58.153.58 +106.221.188.198 +117.99.214.255 +152.58.223.138 +122.180.189.196 +47.15.174.136 +152.58.158.54 +157.45.248.188 +157.48.158.228 +157.42.250.119 +152.58.232.72 +106.206.193.154 +157.34.54.51 +223.181.213.220 +106.195.44.74 +223.239.62.74 +157.50.20.141 +223.186.138.92 +152.57.224.111 +106.192.102.50 +49.34.140.152 +223.187.249.16 +157.41.225.221 +117.96.161.48 +157.49.83.62 +110.224.79.14 +157.47.39.50 +106.196.89.224 +157.42.215.21 +110.226.204.113 +152.58.145.245 +157.32.255.77 +117.99.208.51 +223.185.105.87 +101.0.33.227 +106.221.179.32 +106.79.163.176 +27.62.251.5 +169.149.225.119 +157.38.196.189 +106.215.243.192 +157.39.75.112 +106.205.247.92 +157.41.225.217 +152.57.78.243 +106.194.1.241 +152.58.200.46 +47.29.163.0 +157.48.73.214 +152.58.27.75 +157.42.222.65 +103.24.84.127 +202.179.73.130 +47.9.32.50 +132.154.39.24 +223.231.157.176 +42.108.67.5 +49.36.213.5 +139.167.239.223 +110.224.75.222 +152.58.201.183 +106.206.200.100 +152.58.225.165 +115.98.232.205 +117.253.77.240 +223.189.190.207 +152.58.218.135 +1.38.197.126 +27.61.109.37 +49.42.86.200 +49.35.170.233 +223.228.169.131 +1.39.76.159 +106.210.195.192 +42.106.76.11 +152.58.156.114 +106.76.24.189 +47.11.253.234 +132.154.158.214 +157.37.149.167 +223.178.212.220 +157.48.136.44 +157.49.166.67 +157.49.130.82 +106.222.115.111 +49.35.195.10 +49.36.218.94 +223.185.89.140 +223.237.107.253 +117.97.209.150 +106.221.229.249 +157.32.206.182 +110.226.183.118 +157.38.18.132 +106.76.209.113 +49.43.40.198 +157.40.98.235 +49.42.94.26 +117.99.43.176 +157.40.73.115 +27.62.240.67 +152.58.201.56 +106.206.122.135 +106.221.8.150 +223.186.243.114 +223.185.122.138 +152.59.64.59 +157.46.109.124 +122.169.83.107 +49.34.144.221 +157.35.20.87 +157.41.245.100 +223.225.82.231 +157.35.54.9 +157.42.238.36 +223.187.158.22 +152.57.158.61 +152.58.196.51 +47.9.89.248 +157.42.2.60 +27.59.221.214 +106.208.149.166 +137.97.71.96 +157.41.253.68 +49.43.152.196 +152.58.83.228 +157.32.198.72 +223.181.65.97 +106.202.2.189 +49.34.245.81 +157.40.121.140 +152.58.83.114 +42.111.20.61 +106.221.87.72 +42.105.208.212 +42.105.168.233 +27.97.162.196 +157.50.47.204 +223.184.170.143 +157.45.192.160 +117.248.245.119 +106.204.194.96 +49.32.171.52 +49.36.215.211 +157.34.106.201 +47.29.166.52 +1.187.58.83 +47.9.32.140 +223.187.202.145 +223.228.224.235 +157.38.223.147 +157.41.241.189 +47.15.4.118 +114.134.27.181 +106.217.32.83 +27.60.34.45 +205.253.32.133 +223.185.65.129 +106.207.30.243 +152.58.162.114 +110.224.120.196 +157.33.252.214 +132.154.154.172 +152.58.219.201 +110.224.177.76 +223.228.244.41 +157.33.48.70 +157.42.245.147 +157.34.30.87 +110.226.198.225 +152.58.34.206 +157.42.247.227 +157.39.71.55 +152.58.235.252 +157.34.224.31 +106.77.129.71 +122.161.75.96 +152.58.130.132 +122.172.107.105 +157.46.85.207 +49.36.216.207 +132.154.62.166 +110.225.20.151 +163.53.179.119 +139.167.219.91 +106.222.30.146 +205.253.9.104 +117.234.232.226 +27.59.254.59 +157.35.58.147 +49.14.109.95 +157.51.90.56 +157.38.69.185 +110.224.183.70 +47.11.198.170 +49.36.219.236 +223.29.193.107 +152.57.144.237 +47.9.34.108 +1.38.94.71 +152.58.233.224 +223.233.28.142 +101.0.35.188 +152.57.100.20 +157.42.205.21 +152.58.68.194 +157.34.69.175 +49.15.250.18 +106.205.199.127 +110.224.17.12 +106.67.53.141 +152.58.235.139 +223.186.70.221 +157.48.113.25 +157.38.137.61 +157.45.53.216 +117.98.70.117 +157.38.128.157 +47.9.35.29 +132.154.7.36 +106.216.234.253 +223.238.215.40 +49.33.202.132 +47.15.33.192 +49.37.97.29 +157.35.24.22 +157.48.126.83 +117.245.164.110 +223.227.109.98 +157.33.218.135 +42.105.160.179 +106.76.88.20 +157.33.28.82 +106.192.138.68 +157.51.195.1 +49.15.246.74 +152.58.59.213 +42.106.182.8 +137.97.123.139 +223.185.125.122 +139.167.249.218 +223.233.64.167 +160.238.74.99 +157.44.144.34 +49.34.182.236 +1.38.113.151 +49.15.229.18 +223.182.10.240 +42.105.106.159 +49.14.113.161 +43.231.241.173 +106.221.91.235 +203.115.84.3 +49.34.43.131 +157.34.62.154 +42.106.184.252 +106.193.8.171 +152.57.154.223 +132.154.63.157 +157.47.110.6 +106.195.125.127 +157.38.66.158 +152.58.210.96 +49.34.250.252 +139.167.225.151 +47.11.238.136 +122.162.253.17 +152.57.35.212 +106.77.92.35 +157.48.200.171 +106.215.166.157 +152.58.22.117 +152.58.189.247 +223.231.151.150 +152.57.193.208 +47.9.35.179 +106.76.159.131 +223.231.175.233 +106.78.53.63 +106.196.8.18 +223.187.101.142 +42.105.93.194 +1.38.164.249 +42.105.84.234 +42.104.129.90 +157.47.102.69 +117.237.231.127 +152.58.148.186 +152.58.235.177 +223.237.15.111 +49.34.70.160 +223.228.234.201 +157.42.1.113 +152.58.23.203 +106.206.200.233 +223.187.211.180 +42.106.180.235 +132.154.145.140 +152.58.188.62 +27.62.242.94 +42.105.91.84 +157.38.80.23 +49.35.152.200 +157.38.69.36 +152.57.228.95 +27.60.225.31 +43.224.0.232 +49.43.0.124 +106.206.205.65 +47.9.69.20 +157.38.80.139 +152.58.130.16 +157.41.225.67 +182.69.181.46 +42.106.33.224 +223.189.2.57 +106.205.169.41 +49.43.96.223 +223.231.146.202 +27.56.86.96 +49.36.186.34 +103.208.70.220 +152.58.200.123 +110.224.162.46 +157.33.81.238 +106.197.185.8 +171.79.169.34 +47.29.161.45 +47.9.133.23 +157.40.212.182 +42.105.202.156 +106.217.44.169 +106.221.246.99 +152.58.36.227 +223.187.110.101 +110.227.159.231 +157.51.1.64 +47.29.173.89 +157.38.20.245 +103.95.164.208 +110.227.63.157 +157.39.75.178 +223.189.203.71 +112.196.163.151 +157.49.255.223 +110.224.102.92 +157.41.197.121 +157.35.42.42 +117.230.44.51 +157.38.121.30 +152.57.242.126 +117.98.62.71 +49.34.67.108 +42.108.126.1 +47.15.13.94 +27.63.209.224 +106.205.190.101 +106.76.209.128 +106.198.35.240 +157.46.152.90 +169.149.228.49 +223.230.46.38 +223.190.158.59 +106.196.83.233 +106.210.41.230 +157.48.85.244 +157.41.242.58 +49.36.139.226 +47.11.81.245 +223.239.58.32 +223.182.14.230 +49.35.149.164 +157.33.12.180 +117.99.229.9 +27.61.29.240 +223.228.88.162 +223.227.24.50 +171.76.246.132 +157.48.117.196 +157.35.23.0 +152.58.25.189 +47.31.97.44 +27.56.75.191 +157.48.113.245 +42.105.102.194 +223.238.93.60 +157.48.168.197 +47.31.156.13 +157.45.59.151 +47.11.252.195 +49.35.165.41 +132.154.32.112 +171.51.168.194 +223.187.45.161 +117.228.212.229 +47.9.150.126 +223.187.23.134 +47.29.170.135 +47.15.4.191 +223.182.231.148 +157.38.76.126 +1.39.224.229 +27.61.105.172 +27.60.197.54 +1.38.193.85 +152.58.235.216 +49.204.8.157 +103.24.85.14 +117.99.242.142 +152.58.209.99 +47.31.97.166 +117.98.34.197 +116.68.105.53 +106.223.192.164 +106.204.193.158 +122.161.69.106 +42.105.234.10 +27.59.250.247 +157.45.84.122 +171.79.148.179 +110.224.83.211 +103.124.172.81 +171.51.134.242 +49.15.233.20 +132.154.58.241 +27.56.1.145 +49.36.91.111 +152.58.159.20 +27.60.103.14 +157.47.46.29 +49.43.42.157 +122.161.79.32 +42.108.28.232 +157.41.198.5 +27.59.131.222 +114.31.184.16 +157.46.107.180 +106.196.31.179 +137.97.66.78 +157.38.117.74 +27.61.93.129 +157.33.8.108 +106.215.194.99 +157.48.174.77 +152.58.38.138 +152.58.201.44 +157.35.0.188 +223.189.227.66 +152.57.198.193 +106.211.66.37 +157.49.95.171 +132.154.145.253 +110.224.76.255 +27.63.134.136 +157.47.76.195 +157.46.92.204 +106.197.87.84 +152.57.199.139 +47.15.104.244 +106.192.8.79 +106.217.208.217 +171.51.172.189 +157.38.21.145 +223.238.108.220 +152.58.234.5 +157.45.77.216 +223.230.160.8 +157.51.197.55 +106.76.197.225 +106.206.197.199 +49.37.152.142 +117.192.95.132 +49.15.203.89 +132.154.51.38 +114.31.189.216 +139.167.161.93 +59.95.241.86 +223.228.230.234 +42.104.155.23 +43.227.130.168 +42.105.238.5 +157.51.16.45 +122.162.150.15 +42.105.155.58 +49.15.86.46 +122.170.179.22 +47.9.111.36 +223.189.250.179 +106.206.202.237 +47.9.123.166 +157.39.72.8 +103.156.103.23 +49.35.193.249 +139.167.220.47 +152.58.34.236 +117.98.30.52 +103.178.253.28 +49.43.154.9 +223.239.112.210 +223.187.99.85 +49.15.136.95 +223.184.239.241 +132.154.50.98 +103.42.197.74 +47.9.103.42 +157.33.58.246 +169.149.196.122 +27.59.81.100 +49.14.165.171 +157.35.24.170 +152.58.227.151 +223.239.105.216 +117.96.153.5 +157.33.46.13 +49.34.57.75 +157.49.67.208 +47.31.233.180 +27.60.110.103 +117.242.79.20 +49.35.192.184 +132.154.1.182 +106.205.205.84 +157.49.87.177 +157.35.69.228 +157.38.136.187 +117.96.184.226 +157.38.145.224 +157.47.46.211 +223.186.250.103 +106.216.195.23 +223.238.209.172 +106.205.230.62 +182.69.178.91 +110.224.72.35 +106.194.142.151 +110.227.49.109 +49.36.223.112 +157.45.166.90 +157.47.126.215 +49.36.91.76 +42.105.88.81 +110.224.168.39 +117.98.114.49 +152.58.39.95 +157.41.195.103 +157.48.115.166 +42.106.21.229 +152.58.213.144 +47.11.2.44 +49.42.84.198 +157.48.125.22 +157.42.209.111 +110.224.183.245 +47.15.16.226 +223.228.224.215 +103.153.180.84 +106.216.143.0 +47.29.14.134 +47.31.99.66 +47.15.129.253 +49.34.59.2 +49.42.92.33 +47.15.16.100 +49.37.234.72 +157.35.50.98 +106.211.11.119 +110.224.93.98 +223.188.68.60 +103.179.11.87 +106.66.3.71 +110.224.19.185 +49.35.184.255 +27.60.193.193 +106.216.134.99 +110.224.17.163 +47.15.248.85 +49.35.152.61 +47.11.195.194 +49.37.249.219 +223.188.82.0 +27.62.220.128 +157.32.34.14 +152.57.132.173 +157.38.128.134 +103.252.217.195 +106.197.115.110 +106.206.203.62 +42.106.33.192 +42.105.153.138 +223.238.205.252 +117.99.235.54 +157.45.205.99 +42.110.137.139 +223.190.94.102 +157.48.115.178 +157.35.71.157 +157.34.0.49 +157.42.197.163 +157.35.3.216 +157.44.195.47 +157.38.7.96 +49.36.203.68 +152.58.89.20 +152.57.213.30 +157.38.150.36 +157.34.122.208 +27.63.250.243 +110.224.56.230 +157.34.78.22 +42.111.126.15 +117.99.225.6 +106.208.179.83 +157.38.251.104 +106.204.199.162 +152.58.34.150 +157.38.251.163 +47.9.32.231 +47.9.144.110 +106.217.7.156 +49.47.71.168 +157.33.95.52 +125.99.18.165 +152.58.68.232 +103.73.155.29 +1.39.224.215 +106.210.147.36 +183.83.215.51 +152.58.142.219 +223.233.84.185 +152.58.39.201 +122.172.85.18 +47.15.8.254 +106.208.4.134 +49.42.82.78 +106.216.244.6 +223.176.17.79 +103.28.246.98 +157.42.194.160 +106.204.170.244 +106.204.149.235 +122.183.47.65 +106.221.88.146 +49.34.216.6 +157.38.194.212 +106.76.210.33 +152.58.34.34 +42.106.204.128 +49.36.144.117 +152.58.73.113 +49.35.153.237 +47.29.42.236 +157.39.208.130 +42.105.134.85 +103.217.242.93 +106.78.54.226 +47.9.155.159 +152.57.146.159 +152.58.235.56 +106.79.195.42 +47.15.21.48 +106.196.11.19 +157.41.255.147 +27.61.166.18 +106.221.99.247 +171.78.182.142 +223.190.159.198 +49.36.16.102 +47.11.192.20 +157.46.106.5 +157.47.104.33 +106.223.159.115 +60.243.99.200 +27.56.79.59 +223.237.112.171 +103.96.40.194 +117.97.69.156 +49.35.175.132 +157.34.63.104 +106.208.148.241 +49.42.65.141 +106.206.161.46 +171.51.150.1 +157.38.82.248 +49.34.76.25 +223.228.242.86 +132.154.137.204 +169.149.194.63 +157.40.87.164 +223.228.10.33 +152.58.178.160 +49.37.106.205 +43.255.165.214 +223.188.75.12 +117.209.6.129 +47.9.132.177 +157.47.78.27 +157.42.230.174 +106.76.69.23 +27.56.230.25 +223.233.71.235 +47.15.19.201 +152.58.74.152 +106.193.135.49 +157.40.83.111 +47.29.168.154 +157.38.148.252 +106.197.44.145 +152.57.87.184 +110.227.40.180 +157.33.247.26 +223.190.176.219 +157.46.124.41 +106.210.39.109 +106.216.116.195 +223.186.240.84 +223.230.158.224 +223.176.113.139 +223.189.196.223 +157.42.245.73 +106.221.244.71 +47.9.155.80 +47.9.85.135 +42.105.94.25 +157.51.67.235 +42.105.177.115 +157.34.109.217 +157.49.187.124 +157.38.7.246 +157.38.67.108 +157.38.95.198 +117.217.5.85 +103.83.145.195 +157.48.202.32 +157.32.231.195 +110.227.38.56 +152.58.200.168 +117.99.216.164 +223.230.143.120 +157.34.158.203 +106.216.120.227 +157.48.186.104 +223.237.127.99 +223.187.64.80 +157.35.41.107 +106.221.255.53 +117.230.9.128 +106.203.130.229 +49.42.91.7 +157.35.82.3 +47.11.199.122 +106.195.33.75 +157.38.134.228 +157.38.206.88 +152.58.153.85 +220.158.158.243 +157.37.215.155 +106.195.34.100 +106.207.227.152 +106.76.208.216 +157.35.70.208 +157.45.67.95 +122.161.65.154 +152.58.73.180 +223.228.244.60 +157.47.81.143 +27.63.51.45 +47.15.125.151 +117.249.161.1 +106.193.65.118 +157.48.251.239 +106.79.202.73 +157.39.65.4 +157.38.126.196 +205.253.35.207 +157.42.2.66 +106.200.148.130 +27.62.243.10 +47.15.17.51 +42.111.245.135 +157.40.106.194 +157.41.244.85 +171.76.255.49 +49.14.135.134 +103.203.211.232 +47.29.161.203 +157.34.30.207 +110.227.118.193 +49.34.135.217 +106.216.124.73 +157.41.229.157 +1.38.72.44 +122.161.77.57 +152.58.120.185 +157.39.247.79 +106.195.44.93 +117.98.98.166 +223.189.160.248 +152.58.68.189 +103.28.246.222 +49.34.230.20 +106.76.237.231 +152.58.232.191 +157.33.224.103 +157.34.202.107 +223.233.67.122 +223.231.235.5 +157.34.93.255 +152.58.25.222 +42.106.93.87 +157.47.79.88 +110.227.59.105 +47.15.35.57 +157.49.143.209 +152.58.82.224 +157.46.143.207 +103.177.185.184 +157.40.229.212 +42.108.4.195 +152.58.2.255 +106.210.97.157 +157.39.74.208 +157.42.221.211 +49.204.23.67 +1.39.114.129 +103.176.125.10 +157.47.85.92 +157.33.52.29 +47.247.207.229 +110.227.32.13 +152.57.48.46 +157.48.90.86 +152.58.16.153 +152.58.39.200 +157.51.179.182 +223.176.113.122 +223.184.137.105 +103.217.121.78 +157.48.116.248 +47.9.148.119 +223.187.131.28 +157.45.78.165 +47.29.167.187 +157.47.24.113 +106.221.71.227 +157.48.173.135 +106.206.50.27 +132.154.140.151 +223.231.86.200 +49.32.234.7 +49.32.166.110 +157.48.65.184 +60.243.145.107 +157.37.189.44 +157.41.224.137 +106.195.101.63 +223.228.130.171 +157.47.75.70 +47.9.144.4 +106.76.78.201 +1.38.94.106 +157.50.47.45 +106.200.145.211 +106.216.196.229 +27.63.51.142 +27.63.10.24 +157.40.226.250 +152.58.145.16 +1.187.139.177 +47.15.0.51 +27.63.133.63 +157.35.92.215 +157.33.231.87 +169.149.229.83 +157.41.229.143 +157.41.252.36 +152.58.19.212 +157.35.41.76 +106.196.61.61 +223.179.239.77 +49.34.95.231 +110.227.62.221 +27.61.164.0 +152.58.180.165 +47.9.36.201 +132.154.48.127 +49.35.176.68 +103.44.138.213 +157.46.188.178 +152.58.189.151 +223.196.193.53 +157.45.222.221 +103.217.79.254 +47.31.208.158 +223.186.159.94 +49.204.116.242 +223.130.30.217 +1.39.79.239 +152.57.98.115 +106.211.73.149 +49.37.104.54 +223.233.70.178 +157.40.120.91 +42.109.212.38 +223.239.116.182 +47.9.137.184 +157.47.93.157 +223.187.101.8 +132.154.50.222 +106.221.117.95 +42.111.13.202 +152.57.156.255 +49.14.113.13 +116.74.127.12 +117.235.50.146 +49.43.203.145 +117.96.184.15 +42.105.6.145 +42.105.136.186 +47.29.101.142 +223.187.83.206 +157.42.207.84 +157.47.73.249 +183.83.234.217 +103.102.29.20 +49.35.251.113 +47.31.170.50 +223.238.127.169 +106.197.26.115 +157.34.85.232 +117.98.116.38 +223.238.114.211 +117.96.133.254 +112.79.108.247 +223.239.87.162 +1.38.91.88 +157.38.66.69 +106.221.80.115 +157.33.23.34 +157.47.47.255 +47.9.121.164 +49.36.171.6 +47.29.165.117 +152.57.227.253 +47.9.149.62 +27.61.21.5 +157.50.69.242 +27.60.206.21 +152.58.26.107 +106.207.29.198 +152.57.20.197 +47.11.7.250 +152.58.31.117 +157.38.128.150 +152.58.169.179 +106.79.233.41 +49.14.157.184 +49.34.120.55 +152.58.145.170 +106.215.197.80 +157.41.245.247 +49.14.113.165 +152.58.58.188 +49.33.197.173 +152.58.41.101 +49.14.113.233 +49.34.254.56 +139.167.237.72 +157.51.170.114 +116.75.198.72 +169.149.229.214 +157.35.25.219 +157.34.159.108 +122.163.171.141 +47.29.175.69 +117.203.22.42 +106.207.253.236 +27.56.93.166 +205.253.33.115 +27.61.164.134 +103.44.174.210 +106.205.31.159 +152.58.158.0 +106.193.41.50 +106.219.66.53 +106.208.64.247 +103.71.195.116 +1.187.129.98 +157.49.69.207 +157.48.204.193 +152.57.111.64 +157.49.225.7 +49.15.230.7 +106.216.122.228 +106.195.6.203 +157.46.162.66 +139.167.216.205 +157.38.131.206 +223.233.19.185 +27.59.218.152 +47.9.84.179 +42.105.198.95 +157.46.91.220 +43.229.88.144 +106.221.222.49 +27.63.36.248 +152.58.208.101 +157.45.217.194 +157.35.77.171 +157.45.152.37 +152.58.88.69 +27.61.73.232 +223.225.59.10 +223.233.24.46 +110.224.70.35 +157.33.92.88 +157.33.108.27 +137.97.75.122 +42.108.65.4 +117.99.228.109 +157.34.138.242 +152.58.153.119 +223.228.224.209 +49.35.195.39 +49.34.167.117 +103.190.13.170 +223.188.64.92 +49.42.82.38 +223.237.49.230 +106.203.19.134 +223.190.180.166 +47.29.171.46 +27.61.171.148 +157.34.79.13 +152.58.205.227 +205.253.9.70 +49.42.35.245 +157.32.210.15 +106.66.28.81 +47.15.13.109 +103.66.209.19 +157.42.4.223 +157.41.251.198 +49.34.189.83 +223.189.239.79 +47.15.12.24 +157.33.61.145 +117.99.198.200 +27.0.168.183 +49.34.117.57 +49.36.169.154 +49.36.233.77 +157.45.63.152 +47.15.180.75 +117.99.220.3 +157.47.97.82 +202.89.71.126 +152.58.99.175 +47.29.173.68 +114.31.130.115 +117.99.237.230 +106.221.96.123 +1.39.76.221 +110.224.187.69 +117.245.224.131 +223.231.209.191 +132.154.59.158 +171.76.175.192 +223.189.177.159 +223.177.242.6 +223.238.11.105 +223.176.117.85 +49.15.226.99 +132.154.140.221 +152.57.236.70 +157.41.229.186 +106.196.0.22 +117.99.63.58 +1.39.233.216 +103.110.144.181 +49.47.69.155 +157.34.31.24 +152.58.36.174 +152.58.76.188 +49.34.243.146 +152.58.58.148 +157.48.115.45 +106.217.145.20 +47.31.178.231 +122.161.61.7 +117.98.42.112 +106.216.195.2 +223.225.28.247 +157.48.70.91 +132.154.186.53 +47.29.171.146 +152.58.231.247 +106.209.224.20 +223.182.39.246 +49.37.52.109 +106.192.230.144 +157.38.101.70 +117.99.253.13 +157.42.203.176 +152.58.183.208 +157.40.66.179 +157.39.73.215 +157.45.163.151 +110.225.168.166 +223.187.136.132 +106.206.203.165 +152.57.47.128 +106.76.94.198 +157.42.237.214 +42.111.12.236 +49.37.75.53 +47.31.223.222 +49.34.152.9 +223.228.163.112 +117.221.125.101 +106.196.10.208 +106.206.201.236 +42.111.115.10 +157.37.154.112 +152.58.144.225 +157.41.227.50 +157.33.236.7 +49.32.234.91 +27.62.149.50 +152.58.38.30 +106.194.80.222 +42.105.100.199 +59.95.67.207 +49.15.91.96 +202.142.125.103 +49.37.242.118 +152.58.38.24 +106.221.83.201 +157.41.253.80 +223.187.24.10 +49.42.75.104 +106.221.39.37 +1.38.216.168 +47.9.33.208 +157.42.1.197 +171.60.210.43 +117.230.158.151 +152.58.196.236 +157.33.115.86 +47.9.37.221 +157.34.141.89 +152.57.219.130 +49.32.231.138 +223.229.172.152 +49.34.147.79 +47.15.190.158 +106.216.72.101 +106.208.183.91 +171.76.247.89 +117.97.214.212 +183.82.206.191 +106.205.244.128 +157.35.89.89 +157.48.166.210 +47.11.198.98 +117.251.51.219 +103.187.249.132 +49.34.71.247 +157.41.249.69 +157.46.84.47 +106.216.201.100 +47.9.144.238 +47.15.1.11 +223.233.71.162 +1.38.94.36 +106.193.83.157 +157.34.74.129 +106.197.109.24 +110.224.78.46 +49.36.209.39 +106.216.124.225 +223.238.215.249 +152.57.147.119 +157.46.94.125 +110.224.92.230 +49.15.250.173 +223.180.202.70 +157.49.241.62 +152.57.208.254 +42.105.212.249 +27.56.222.67 +152.58.103.11 +152.58.214.125 +223.239.60.44 +169.149.226.244 +132.154.54.6 +117.98.114.51 +1.187.214.90 +106.204.197.15 +202.142.107.251 +152.58.232.26 +49.36.191.186 +106.195.34.233 +157.38.145.47 +110.224.180.79 +49.35.232.232 +157.34.45.118 +49.36.170.190 +157.44.211.144 +223.187.75.174 +1.38.140.75 +157.38.125.124 +157.39.73.12 +27.61.162.135 +223.185.73.125 +49.36.88.241 +27.56.23.241 +47.11.88.24 +157.40.98.4 +223.231.178.71 +1.187.139.117 +157.42.210.58 +49.42.93.161 +152.57.140.56 +157.38.121.104 +49.35.169.214 +106.66.249.132 +223.182.59.141 +157.33.34.54 +47.15.237.221 +106.206.246.95 +103.85.207.183 +106.221.190.124 +106.195.75.125 +106.223.158.88 +47.29.12.248 +223.239.50.32 +152.58.201.99 +150.129.237.120 +157.35.19.231 +111.92.45.45 +206.84.233.23 +152.58.186.157 +157.45.162.51 +157.48.195.189 +106.207.147.194 +42.105.232.120 +47.29.160.86 +157.38.134.68 +27.60.45.199 +223.187.64.153 +103.77.153.182 +157.41.253.193 +223.228.220.45 +42.110.148.197 +49.43.42.217 +47.29.63.105 +106.221.53.63 +47.11.255.15 +157.38.128.154 +152.58.98.246 +223.185.232.57 +117.245.240.154 +157.41.225.51 +223.186.229.8 +152.58.162.66 +47.29.162.239 +157.42.7.97 +117.96.128.185 +152.58.92.130 +106.76.210.225 +157.35.52.146 +103.170.54.216 +106.221.255.23 +106.217.212.189 +61.0.95.102 +49.36.178.182 +27.97.65.78 +27.59.244.177 +223.227.52.249 +106.220.71.16 +223.190.187.207 +117.209.171.125 +106.217.59.251 +47.11.192.217 +157.32.105.130 +157.35.46.236 +157.48.246.183 +157.32.112.63 +49.37.74.165 +49.15.174.223 +171.76.216.117 +223.176.7.67 +110.226.194.167 +152.58.235.243 +205.253.34.24 +106.216.119.229 +160.238.74.71 +157.38.75.227 +27.63.222.56 +223.181.94.169 +47.29.170.105 +223.238.118.124 +157.38.131.33 +152.58.78.103 +106.213.146.78 +117.96.184.81 +49.37.153.80 +157.45.82.199 +117.96.163.151 +169.149.227.146 +223.187.136.150 +106.210.164.254 +157.34.33.180 +47.15.8.186 +103.50.82.194 +117.99.11.210 +223.187.2.110 +106.204.7.171 +106.208.62.156 +157.32.108.46 +125.21.170.166 +223.186.241.105 +152.58.71.126 +106.77.95.62 +106.221.96.82 +152.58.97.124 +152.58.197.16 +1.38.64.97 +106.220.250.138 +42.110.164.28 +139.167.227.232 +223.182.4.217 +106.216.195.124 +106.216.106.26 +157.42.1.143 +47.9.36.81 +223.189.22.64 +27.63.132.87 +157.35.3.99 +223.233.41.137 +49.34.163.93 +47.29.172.112 +47.9.85.157 +49.36.220.76 +47.29.162.244 +47.15.175.39 +223.178.211.7 +47.11.59.230 +115.97.245.119 +103.102.117.66 +49.205.37.197 +103.104.181.178 +47.29.37.245 +157.34.64.76 +152.58.72.123 +42.108.64.21 +49.15.201.234 +47.9.155.18 +106.200.151.82 +106.76.196.11 +223.238.118.13 +157.41.226.140 +106.196.2.85 +137.97.71.244 +27.60.102.173 +49.35.132.25 +157.37.186.45 +139.167.230.105 +223.228.23.95 +49.42.73.197 +223.238.202.104 +106.204.41.32 +157.41.255.204 +47.247.205.89 +152.57.242.79 +103.142.10.89 +120.138.12.61 +152.58.210.101 +152.58.90.235 +49.36.192.215 +106.196.5.43 +42.105.213.236 +27.60.203.213 +117.98.104.119 +106.205.176.79 +152.58.182.74 +49.42.32.227 +106.205.193.73 +61.1.24.170 +106.208.76.252 +157.41.250.185 +157.46.177.84 +49.14.114.113 +223.178.208.16 +223.185.85.85 +171.48.75.189 +49.34.245.164 +152.58.59.10 +106.210.43.143 +132.154.52.37 +106.208.149.157 +106.79.233.56 +157.41.228.123 +157.39.250.249 +103.42.196.47 +110.224.92.181 +169.149.192.252 +223.176.1.60 +103.40.196.175 +49.36.218.22 +152.58.56.181 +1.38.196.216 +157.34.118.208 +106.217.190.143 +117.99.195.31 +103.171.168.206 +202.8.117.143 +223.189.146.55 +220.158.158.238 +106.216.230.66 +117.99.220.175 +47.9.147.224 +106.76.230.130 +117.96.165.26 +49.34.68.252 +49.43.41.203 +157.50.14.216 +49.35.147.123 +223.187.106.206 +106.216.139.168 +157.35.41.97 +223.178.212.224 +157.33.93.5 +117.98.96.2 +223.189.101.1 +171.76.237.113 +223.181.37.23 +157.38.105.79 +157.38.39.242 +152.58.188.214 +132.154.59.121 +223.196.169.205 +157.38.251.41 +157.51.24.58 +169.149.231.173 +47.9.70.1 +152.58.98.151 +157.42.247.81 +49.34.123.37 +103.179.230.244 +132.154.63.137 +49.35.139.210 +223.187.101.181 +49.35.128.225 +157.46.81.208 +1.39.113.4 +103.182.166.41 +157.34.232.34 +49.204.132.163 +139.167.184.174 +106.211.94.123 +103.151.188.121 +157.41.197.163 +157.46.84.148 +152.58.34.197 +223.235.134.251 +152.58.130.134 +157.41.228.121 +106.196.110.65 +122.161.77.184 +223.233.23.25 +106.198.24.149 +27.61.34.38 +157.38.245.108 +223.238.211.235 +47.11.202.158 +49.35.147.59 +47.15.248.150 +106.217.176.196 +49.14.129.69 +157.32.111.60 +137.97.77.86 +157.41.254.156 +110.227.56.52 +157.49.80.156 +152.58.222.101 +157.38.203.168 +111.92.77.116 +171.76.173.42 +157.38.127.170 +106.197.216.249 +122.169.21.139 +49.36.168.129 +157.40.234.254 +47.15.180.15 +106.77.190.8 +223.187.109.12 +223.176.37.172 +106.221.246.127 +43.254.176.169 +103.42.163.146 +157.34.106.139 +132.154.51.55 +157.33.65.201 +106.208.44.182 +47.15.240.76 +152.58.236.142 +106.223.210.125 +45.249.83.88 +157.35.90.184 +103.195.80.195 +157.46.69.66 +47.29.166.159 +157.32.95.21 +106.193.169.196 +103.38.13.97 +106.200.90.139 +106.198.43.99 +27.56.87.69 +157.45.200.21 +152.57.233.215 +42.106.84.116 +49.36.16.35 +157.34.67.22 +49.15.247.140 +42.105.195.138 +49.35.159.143 +106.76.208.239 +157.48.217.233 +157.38.136.63 +117.99.197.134 +47.15.16.238 +157.35.48.51 +110.225.46.94 +47.15.33.163 +157.47.16.107 +42.105.226.102 +152.58.70.229 +157.39.72.61 +47.29.167.251 +42.111.145.254 +117.99.230.12 +157.38.71.28 +157.51.159.244 +152.58.201.213 +42.108.66.14 +152.58.99.158 +171.79.186.66 +117.237.241.56 +152.58.34.218 +157.38.129.66 +47.15.10.5 +157.48.117.92 +110.225.32.66 +157.34.135.211 +117.198.94.100 +103.49.117.181 +106.76.222.98 +169.149.229.82 +152.58.130.4 +157.47.121.195 +117.99.25.198 +132.154.57.165 +122.161.65.29 +223.187.250.239 +27.63.118.215 +106.221.180.145 +157.45.204.255 +47.11.206.184 +157.34.43.171 +157.39.65.76 +157.35.3.179 +49.42.83.132 +42.104.130.67 +103.178.212.129 +49.42.91.156 +157.48.139.17 +103.166.15.217 +223.180.176.74 +106.66.28.94 +49.34.129.202 +223.228.228.204 +49.42.87.139 +27.56.72.242 +106.216.196.134 +132.154.30.188 +157.35.6.150 +106.198.39.109 +117.99.230.245 +152.58.31.192 +117.99.244.47 +157.39.68.85 +132.154.60.141 +47.9.138.248 +47.11.234.2 +49.34.168.220 +157.49.71.136 +202.83.40.195 +47.29.168.105 +152.57.163.43 +47.29.175.121 +47.11.248.81 +157.41.251.203 +106.208.178.222 +152.57.210.137 +106.204.199.219 +42.105.132.24 +157.38.48.103 +106.220.109.29 +139.167.249.202 +152.58.68.244 +117.230.92.73 +157.51.198.37 +115.96.127.232 +157.48.234.177 +49.34.79.219 +157.33.81.239 +47.29.168.65 +49.34.190.187 +49.36.80.46 +157.38.225.100 +106.194.26.7 +49.15.138.247 +171.79.189.181 +27.63.219.42 +42.105.139.118 +152.58.109.253 +106.208.217.43 +106.221.157.88 +27.56.23.189 +106.66.59.192 +106.205.52.69 +106.216.167.87 +223.227.99.196 +106.216.225.108 +223.225.83.188 +152.59.65.64 +152.58.155.209 +106.206.215.48 +47.11.193.101 +49.34.124.82 +152.58.69.118 +152.59.65.170 +42.105.170.187 +157.35.88.115 +42.106.177.86 +106.195.64.156 +223.231.103.201 +110.224.83.197 +117.98.44.167 +106.221.183.91 +157.38.30.166 +122.176.240.81 +103.95.167.184 +157.45.173.207 +47.9.102.230 +47.15.130.47 +157.41.226.165 +171.76.163.162 +47.15.113.152 +157.34.98.25 +49.14.156.17 +152.58.191.152 +152.58.37.145 +49.42.66.32 +152.58.70.137 +47.31.170.198 +157.48.210.88 +152.58.138.194 +49.15.136.15 +106.66.250.82 +106.205.191.207 +47.31.178.64 +132.154.25.93 +47.9.36.140 +49.42.86.9 +106.216.233.90 +157.45.188.149 +110.224.75.150 +223.228.231.51 +223.190.190.143 +106.79.163.102 +157.51.199.219 +157.48.77.193 +106.195.6.40 +223.178.208.41 +49.14.128.243 +223.233.76.111 +152.58.215.143 +47.15.140.125 +152.58.235.57 +152.58.71.216 +42.105.183.85 +110.227.51.80 +103.95.83.99 +117.98.106.43 +157.34.100.115 +110.227.50.33 +152.58.197.167 +49.34.136.78 +157.35.18.206 +42.106.183.157 +110.224.76.139 +27.62.168.143 +49.37.24.198 +157.34.197.86 +157.34.142.206 +106.211.227.101 +112.79.241.244 +110.224.71.152 +106.196.85.98 +106.67.28.43 +223.238.85.163 +106.196.12.72 +49.42.92.144 +223.236.193.163 +223.238.96.216 +171.60.210.82 +49.42.89.96 +223.189.208.115 +157.34.7.195 +223.228.37.237 +42.107.193.156 +157.32.203.122 +157.49.130.113 +49.35.181.52 +110.224.67.237 +157.48.186.147 +157.34.21.184 +103.179.0.159 +1.38.220.40 +171.48.124.187 +157.41.255.20 +106.206.240.241 +223.225.168.93 +106.210.230.202 +157.33.248.156 +137.97.76.141 +152.57.52.1 +152.58.200.233 +152.58.210.103 +106.78.53.170 +42.104.157.199 +157.47.70.56 +171.76.220.213 +106.194.227.46 +49.36.214.166 +157.34.3.28 +157.38.219.175 +117.99.227.102 +171.60.193.24 +106.205.193.208 +152.57.9.106 +47.31.98.230 +27.62.189.0 +103.141.133.8 +106.196.109.233 +106.216.251.105 +49.42.90.148 +42.104.144.133 +27.63.241.122 +49.34.180.235 +103.192.117.224 +47.15.155.62 +223.237.104.201 +47.9.99.192 +157.35.87.213 +49.35.231.59 +49.42.68.238 +106.221.88.117 +49.37.98.157 +152.58.196.61 +157.48.112.176 +223.176.6.27 +42.108.160.44 +47.11.211.138 +27.57.244.123 +49.204.198.245 +152.58.191.237 +157.32.104.0 +42.105.92.11 +157.51.76.113 +49.35.226.15 +157.32.110.204 +106.206.77.85 +106.194.223.107 +223.239.24.11 +47.11.210.236 +152.58.201.36 +27.63.209.247 +117.96.40.2 +157.39.230.189 +202.191.1.196 +106.194.184.35 +157.35.58.59 +47.9.35.191 +157.48.222.88 +106.77.162.32 +223.182.44.172 +157.46.107.146 +152.58.185.41 +157.47.72.187 +49.34.133.59 +117.209.159.116 +139.167.228.167 +157.34.49.205 +157.34.141.176 +157.35.69.36 +106.193.71.165 +106.78.51.92 +49.204.191.207 +49.37.72.222 +106.195.36.50 +49.36.144.173 +152.58.114.171 +152.58.134.201 +171.48.113.220 +27.62.183.124 +223.227.93.95 +103.154.9.118 +111.92.22.219 +27.56.249.120 +106.78.51.168 +106.207.148.192 +106.66.254.171 +117.210.166.40 +152.58.106.153 +157.47.127.253 +47.29.160.137 +103.113.98.31 +139.167.237.234 +157.41.224.73 +122.161.241.142 +157.32.115.87 +49.36.209.246 +171.51.212.102 +47.9.35.51 +157.45.167.203 +42.107.89.26 +106.197.3.10 +139.167.185.83 +137.97.89.67 +157.33.196.11 +152.58.167.105 +106.213.187.9 +152.58.186.126 +106.219.5.9 +106.196.7.173 +152.58.196.46 +49.14.128.65 +106.211.4.219 +223.238.221.210 +157.48.187.101 +106.195.39.184 +157.38.148.94 +1.39.115.134 +152.58.124.202 +47.31.151.18 +47.9.35.121 +152.59.64.225 +223.186.118.176 +49.37.36.247 +117.99.240.238 +49.35.179.151 +152.57.93.5 +1.38.117.127 +157.51.66.174 +223.182.6.102 +157.49.150.132 +47.9.122.214 +49.35.192.199 +106.206.207.224 +106.217.190.239 +223.189.202.198 +157.51.32.107 +152.58.21.86 +223.225.17.152 +106.76.71.70 +110.227.37.69 +157.51.199.16 +152.57.192.66 +106.195.11.216 +27.56.200.176 +47.9.35.225 +106.206.18.212 +117.225.20.53 +106.221.189.233 +157.35.2.57 +152.58.33.243 +157.38.237.190 +49.34.194.232 +49.14.157.13 +152.58.95.79 +157.38.21.114 +115.98.10.41 +202.168.85.36 +49.37.114.42 +152.58.185.51 +223.189.9.174 +27.61.103.123 +27.59.179.231 +47.15.20.123 +103.179.171.170 +157.45.135.254 +27.97.33.163 +47.29.162.8 +157.37.196.40 +157.45.67.237 +139.167.187.25 +152.57.187.236 +103.81.93.171 +157.41.240.228 +152.57.239.80 +117.99.11.248 +106.66.223.215 +59.96.111.25 +223.189.6.66 +182.69.180.220 +157.42.203.210 +117.96.161.137 +157.39.206.119 +106.79.195.198 +157.33.19.41 +27.63.246.38 +106.193.37.69 +106.221.85.250 +152.58.83.237 +132.154.147.92 +42.105.9.211 +49.35.130.166 +202.133.60.74 +49.43.7.233 +152.58.170.32 +223.187.137.161 +157.40.237.30 +152.57.175.61 +152.58.208.85 +157.38.234.228 +27.62.239.86 +106.206.200.144 +106.216.114.205 +49.15.242.128 +49.43.179.174 +106.195.107.73 +152.57.110.248 +157.38.225.134 +139.167.207.55 +152.58.200.221 +157.34.29.92 +152.57.65.171 +106.217.178.242 +132.154.51.49 +169.149.193.165 +117.99.193.132 +171.48.120.197 +103.175.89.14 +122.169.168.238 +152.58.96.104 +152.58.235.124 +49.34.244.29 +106.216.124.76 +157.41.250.73 +157.33.194.197 +106.217.245.186 +152.58.222.236 +157.47.84.168 +106.78.52.18 +223.237.71.214 +157.35.68.180 +49.37.72.27 +157.32.206.215 +223.239.2.138 +205.253.32.37 +157.35.64.184 +47.15.96.124 +106.195.33.203 +223.239.68.47 +47.15.5.81 +157.49.217.205 +1.38.72.87 +223.189.252.82 +223.188.226.160 +43.241.194.48 +27.61.66.152 +223.189.144.9 +157.47.48.90 +152.58.40.231 +117.96.170.239 +122.161.241.79 +110.224.96.177 +223.178.209.192 +47.9.34.180 +49.36.212.183 +152.57.124.76 +180.188.236.207 +106.217.0.85 +132.154.37.204 +49.15.172.25 +117.255.253.48 +112.79.56.17 +157.34.59.214 +152.58.189.119 +110.227.58.84 +49.35.155.215 +47.11.50.32 +157.38.111.146 +106.216.200.159 +45.127.45.5 +223.239.28.33 +117.212.96.156 +47.9.126.125 +223.181.47.86 +49.34.39.103 +137.97.69.250 +157.32.115.156 +157.41.253.108 +157.32.231.251 +132.154.51.102 +132.154.50.144 +47.29.167.235 +103.181.100.116 +103.161.144.184 +157.34.89.188 +106.210.105.10 +27.61.113.117 +223.185.91.74 +152.58.73.215 +152.58.27.133 +171.79.151.228 +106.213.61.61 +157.38.109.66 +220.158.141.189 +157.45.57.135 +117.230.134.71 +157.32.126.86 +106.196.76.189 +106.221.89.73 +47.29.170.224 +27.63.108.1 +106.208.6.203 +103.165.167.44 +163.53.179.104 +42.105.206.67 +117.98.104.116 +111.92.39.22 +117.98.38.35 +106.195.109.23 +49.37.233.102 +223.190.133.137 +49.43.33.146 +157.42.0.2 +110.226.202.190 +106.76.196.100 +49.34.217.228 +42.108.4.49 +152.57.208.24 +106.210.197.166 +157.39.216.209 +152.58.37.233 +157.34.61.95 +157.45.212.145 +210.56.98.176 +223.233.44.159 +171.79.160.28 +106.206.205.221 +47.9.138.103 +60.254.70.41 +106.221.109.7 +157.47.57.45 +49.34.61.194 +106.213.84.39 +157.45.214.149 +157.47.66.81 +223.190.166.141 +124.253.244.182 +152.58.90.77 +42.107.193.19 +106.221.108.157 +106.221.251.86 +157.50.31.145 +122.173.30.91 +152.58.72.101 +42.111.17.60 +223.181.42.216 +106.78.176.126 +106.76.95.44 +157.34.103.109 +106.221.241.252 +106.222.31.183 +157.38.137.191 +157.47.119.176 +27.59.107.158 +223.178.210.202 +106.192.46.30 +157.37.142.90 +157.45.205.126 +152.57.172.2 +157.38.220.170 +157.33.18.4 +157.40.228.235 +27.61.120.18 +103.165.167.179 +42.106.188.5 +171.79.134.134 +42.105.98.248 +132.154.33.158 +27.61.43.208 +110.224.69.180 +157.40.123.12 +157.50.64.165 +223.225.60.228 +106.216.84.59 +157.34.92.48 +152.57.132.238 +223.238.124.233 +117.213.139.96 +152.58.92.128 +59.88.226.209 +27.60.202.195 +152.58.24.99 +103.16.30.160 +157.49.94.251 +157.35.24.117 +157.34.217.192 +223.189.203.198 +152.58.56.71 +223.238.119.46 +106.193.9.116 +171.76.179.11 +49.33.220.200 +157.47.108.39 +182.56.199.164 +47.29.98.111 +152.58.149.43 +49.42.83.10 +1.38.160.111 +27.62.215.53 +103.140.16.23 +223.187.70.148 +157.34.221.202 +152.58.236.195 +47.9.37.106 +122.162.150.203 +122.163.242.182 +43.224.3.231 +223.228.228.50 +152.58.19.11 +106.217.180.104 +47.9.129.182 +47.29.170.173 +157.34.249.190 +103.209.220.188 +42.105.233.187 +42.105.128.106 +42.110.137.219 +132.154.63.227 +117.96.171.150 +157.40.74.111 +157.46.188.69 +152.57.31.95 +106.216.123.114 +157.34.73.148 +132.154.59.168 +157.37.148.86 +110.227.49.24 +106.196.127.27 +110.224.121.155 +157.35.43.185 +171.79.149.211 +106.210.214.220 +106.78.78.38 +106.195.40.211 +106.196.5.71 +106.217.93.106 +103.139.56.188 +49.37.134.178 +139.167.189.219 +106.216.119.27 +157.51.133.196 +49.36.91.118 +49.15.136.84 +1.187.216.212 +157.32.33.166 +117.98.84.16 +169.149.225.155 +157.50.65.245 +171.79.160.83 +1.38.220.52 +117.98.78.47 +223.233.57.193 +169.149.195.13 +152.57.143.14 +157.39.64.189 +137.97.78.246 +117.99.220.13 +14.139.180.166 +27.62.49.237 +173.252.83.5 +173.252.83.3 +173.252.83.2 +157.48.131.109 +157.41.227.219 +223.238.107.193 +152.58.99.145 +47.15.171.231 +47.9.7.121 +171.76.215.130 +49.35.165.66 +157.35.56.32 +122.168.213.226 +49.15.231.85 +106.220.108.177 +157.35.7.25 +47.15.11.174 +152.57.224.147 +152.58.25.220 +152.57.126.161 +106.210.135.198 +152.58.180.22 +42.105.238.41 +110.227.32.80 +157.48.173.129 +49.14.157.52 +47.9.134.230 +157.34.199.58 +152.58.75.76 +1.39.29.77 +47.29.164.231 +157.44.194.160 +223.187.117.241 +152.58.143.123 +146.196.37.70 +42.105.216.33 +27.61.67.69 +106.221.116.222 +49.35.227.122 +157.39.69.231 +47.9.64.178 +223.189.224.57 +49.34.196.235 +157.47.109.172 +157.38.135.33 +103.184.127.96 +47.9.37.64 +152.57.207.58 +223.228.165.222 +106.211.65.180 +47.9.93.195 +157.49.128.21 +152.58.189.43 +106.195.85.97 +157.33.116.58 +106.198.147.237 +202.142.125.198 +223.188.58.180 +47.9.37.118 +47.31.140.40 +1.39.115.214 +132.154.59.181 +152.57.25.18 +47.9.156.39 +157.34.26.18 +103.226.241.181 +152.58.103.8 +106.215.141.41 +106.79.178.104 +223.227.34.42 +223.180.191.211 +157.32.109.165 +106.193.190.129 +110.227.32.19 +157.47.124.121 +223.227.104.37 +1.39.250.23 +106.221.99.85 +223.238.93.28 +157.46.79.107 +157.38.20.56 +49.32.185.228 +27.61.207.165 +110.224.72.98 +106.195.89.98 +157.32.233.195 +27.63.217.158 +42.105.203.111 +49.36.201.250 +152.58.73.10 +157.32.81.235 +49.37.75.137 +47.31.236.13 +49.34.120.138 +106.204.41.246 +103.164.211.130 +152.58.189.179 +42.111.144.91 +42.108.10.3 +157.38.81.192 +47.15.102.38 +152.57.246.152 +103.172.72.181 +157.49.64.70 +106.211.79.59 +152.57.176.56 +152.57.195.226 +157.41.251.150 +49.36.83.46 +106.216.239.223 +27.59.163.153 +223.228.239.245 +47.15.2.58 +223.186.122.235 +157.34.19.238 +223.187.139.67 +157.37.222.37 +106.66.37.229 +122.167.239.21 +157.40.236.101 +223.228.174.53 +157.38.215.83 +115.124.45.119 +27.60.200.127 +223.233.72.132 +152.58.24.127 +223.187.215.65 +157.48.168.76 +132.154.54.214 +49.34.241.70 +152.58.151.28 +49.43.152.106 +103.181.169.73 +47.11.192.25 +49.42.85.249 +49.35.138.183 +106.216.119.22 +157.41.226.37 +117.96.169.87 +223.238.28.205 +106.209.203.101 +106.202.103.248 +106.195.67.104 +157.50.65.225 +114.31.164.43 +223.231.154.91 +106.78.51.64 +106.195.109.136 +42.106.236.242 +223.185.81.249 +106.205.225.37 +223.187.82.172 +157.35.74.39 +42.106.217.98 +42.105.206.79 +152.58.100.27 +47.9.80.111 +110.226.204.151 +157.51.113.241 +106.194.12.70 +106.205.206.226 +115.98.19.113 +152.58.40.37 +223.190.161.158 +42.107.193.34 +47.247.213.88 +117.99.43.72 +157.38.114.56 +106.193.139.49 +157.48.190.95 +152.58.76.29 +157.47.7.205 +157.38.222.195 +152.57.135.95 +157.45.172.78 +223.189.197.173 +47.15.175.162 +1.38.160.222 +49.35.133.63 +106.216.224.189 +157.49.151.208 +152.57.14.169 +132.154.55.98 +103.181.91.79 +106.193.192.24 +223.239.59.208 +152.58.158.29 +49.37.224.198 +106.78.51.164 +157.37.202.144 +152.57.235.225 +106.198.187.78 +27.62.240.87 +106.211.141.83 +49.43.88.60 +47.9.105.158 +49.15.39.172 +223.130.28.150 +27.62.241.14 +47.15.109.82 +157.48.190.153 +157.48.243.166 +106.76.236.146 +106.197.120.122 +49.37.98.76 +223.227.66.235 +106.216.237.239 +157.35.45.104 +49.15.228.172 +47.15.14.221 +171.51.161.141 +152.58.34.191 +152.58.196.134 +49.42.80.188 +117.230.155.162 +59.182.149.158 +223.186.226.41 +106.78.53.94 +106.195.97.1 +49.42.67.80 +49.42.93.26 +157.47.89.3 +157.38.113.79 +106.193.10.200 +1.187.180.199 +49.42.84.3 +110.224.163.238 +106.208.153.50 +49.37.8.6 +106.208.5.8 +49.35.227.146 +152.58.81.75 +139.167.215.216 +110.226.169.66 +106.221.97.89 +42.105.159.33 +157.50.65.183 +157.38.203.72 +157.33.80.93 +139.167.209.179 +117.216.12.4 +152.58.72.199 +106.76.237.242 +171.51.146.173 +106.221.11.91 +157.35.6.172 +157.39.233.212 +110.224.79.34 +157.38.156.220 +47.15.10.207 +157.49.224.139 +157.34.145.162 +157.49.132.43 +49.32.242.196 +152.58.70.203 +101.0.62.124 +152.58.79.166 +27.61.55.64 +152.58.235.143 +223.233.73.118 +152.58.186.65 +106.211.122.121 +47.9.91.249 +124.253.133.246 +106.223.134.213 +47.15.6.193 +47.31.239.172 +223.187.72.7 +157.33.236.123 +106.194.236.118 +223.184.155.144 +106.221.189.72 +152.58.155.95 +49.33.211.85 +49.43.97.111 +223.187.66.83 +27.61.133.185 +152.58.81.47 +157.48.149.205 +106.221.218.116 +157.49.206.105 +223.181.198.97 +157.40.213.17 +117.96.189.30 +116.68.84.122 +106.219.57.114 +103.181.57.105 +106.205.202.128 +47.11.192.200 +157.46.92.197 +157.51.199.225 +152.58.27.128 +171.76.234.33 +223.225.120.80 +106.197.32.15 +106.77.94.178 +49.42.80.30 +171.76.80.37 +223.233.126.139 +152.58.149.45 +49.205.101.209 +157.33.85.47 +152.57.190.119 +106.196.15.152 +157.40.226.228 +157.47.113.221 +49.35.145.101 +223.190.182.139 +106.76.198.189 +137.97.72.130 +157.39.65.50 +157.45.199.185 +152.58.190.190 +47.29.169.201 +49.34.142.214 +152.58.24.8 +42.105.159.244 +106.77.133.186 +223.239.34.200 +49.37.46.234 +106.66.58.2 +106.76.94.87 +117.98.110.107 +157.32.123.191 +49.37.64.35 +49.37.97.151 +106.195.67.36 +152.57.198.24 +157.49.160.72 +152.58.80.33 +157.41.225.152 +157.37.145.148 +157.45.77.149 +106.221.1.60 +157.49.164.227 +132.154.151.33 +223.178.209.167 +59.95.109.233 +106.203.59.96 +45.115.89.84 +49.35.149.106 +106.223.89.45 +103.41.26.196 +47.15.1.118 +157.39.71.229 +42.105.168.40 +157.34.211.90 +42.108.127.42 +152.58.212.14 +152.57.214.227 +106.77.134.119 +42.105.122.72 +137.97.103.188 +106.194.52.247 +27.59.134.164 +139.167.187.13 +106.197.125.249 +49.36.89.192 +106.66.61.74 +157.51.195.137 +106.223.106.221 +106.205.31.215 +47.9.5.138 +110.224.179.6 +157.50.69.110 +47.9.75.189 +157.34.95.188 +152.58.94.26 +157.38.200.193 +49.34.69.26 +157.41.255.88 +103.181.91.67 +42.108.125.12 +49.35.247.96 +157.48.127.139 +157.51.171.211 +47.9.126.223 +103.232.239.215 +49.36.233.168 +106.205.67.189 +106.205.56.94 +223.187.100.133 +106.217.226.237 +152.58.67.123 +117.199.129.134 +42.111.204.62 +106.196.28.175 +49.14.115.214 +223.187.247.179 +47.9.33.252 +117.224.200.67 +103.151.156.153 +157.45.130.173 +157.38.71.216 +47.15.120.250 +117.233.252.80 +137.97.91.31 +1.187.181.179 +106.216.65.215 +106.206.5.190 +152.58.18.147 +223.196.193.80 +49.36.193.55 +152.58.139.255 +157.38.145.245 +27.62.191.111 +157.42.242.76 +223.227.65.150 +223.233.103.74 +106.216.245.200 +223.231.219.160 +49.35.128.78 +117.98.106.38 +171.76.219.139 +157.41.228.183 +152.58.232.249 +49.37.128.108 +152.58.210.153 +132.154.59.17 +49.32.133.241 +47.15.42.30 +223.231.204.112 +47.11.193.219 +106.194.184.116 +139.167.206.209 +110.227.21.43 +152.58.196.233 +47.31.162.36 +132.154.50.148 +106.211.82.231 +106.198.36.138 +157.40.239.156 +106.196.116.181 +137.97.106.38 +152.58.71.177 +157.49.81.246 +152.58.143.201 +47.31.144.239 +47.31.140.54 +152.58.163.56 +49.35.158.24 +49.15.233.24 +106.217.28.11 +117.98.78.62 +49.15.184.197 +223.239.75.196 +152.58.142.222 +47.15.34.0 +49.35.254.221 +152.58.145.249 +137.97.68.110 +152.58.113.226 +103.170.182.118 +157.44.159.34 +1.187.217.182 +117.99.211.234 +223.187.74.243 +47.9.124.106 +223.186.62.200 +171.76.220.73 +157.49.89.226 +27.59.208.33 +49.35.137.209 +152.58.72.220 +43.229.88.139 +27.61.246.38 +106.192.26.132 +152.58.157.178 +117.99.202.146 +157.51.199.53 +110.224.190.227 +49.34.245.241 +223.239.65.67 +49.37.66.133 +117.234.95.249 +49.35.183.6 +101.0.34.52 +47.9.92.220 +106.206.236.76 +106.206.132.197 +223.181.17.128 +49.34.153.139 +157.38.69.197 +106.66.3.231 +157.39.72.218 +117.99.200.68 +1.187.63.182 +42.110.166.129 +49.36.221.94 +27.63.25.255 +223.238.85.37 +223.186.111.102 +223.228.142.65 +223.189.228.43 +106.216.196.86 +106.194.142.168 +106.196.22.252 +223.228.254.29 +157.38.146.157 +49.33.196.242 +47.9.135.119 +106.203.136.174 +132.154.137.52 +47.29.29.86 +110.225.122.171 +47.247.211.92 +106.76.208.112 +132.154.48.64 +117.251.239.178 +157.45.195.41 +47.11.196.250 +106.77.94.106 +47.11.203.134 +47.9.136.8 +152.58.72.250 +152.57.93.8 +223.231.209.33 +223.238.206.248 +117.212.175.254 +157.38.129.10 +42.108.196.108 +122.161.241.229 +157.37.158.115 +106.206.210.39 +223.186.27.97 +223.189.243.216 +157.48.113.211 +49.35.229.229 +157.38.125.168 +106.207.59.149 +47.29.162.243 +106.208.218.118 +223.239.24.31 +106.207.247.138 +49.36.18.168 +27.62.159.224 +47.31.199.224 +47.11.199.33 +106.207.243.80 +152.57.196.108 +106.197.145.224 +106.216.201.61 +49.35.243.141 +152.58.33.131 +157.35.85.22 +117.99.223.55 +157.37.211.251 +157.40.124.157 +27.63.238.39 +157.47.89.81 +106.206.233.29 +27.97.252.181 +47.247.210.108 +157.38.229.18 +42.105.199.49 +223.176.85.73 +157.50.58.122 +47.9.119.242 +157.42.4.44 +110.224.94.17 +223.238.179.45 +157.38.99.224 +117.96.182.211 +106.76.89.155 +152.57.199.16 +132.154.50.79 +152.58.214.244 +106.205.164.126 +157.48.129.28 +223.239.65.116 +223.226.172.178 +157.45.212.215 +106.205.195.163 +223.187.2.43 +150.107.179.141 +157.38.241.123 +132.154.55.87 +47.15.203.42 +157.34.33.195 +47.15.36.158 +157.34.118.164 +47.11.236.182 +42.105.48.81 +205.253.32.192 +157.40.100.74 +103.149.58.72 +223.185.84.233 +60.243.6.213 +106.196.87.67 +49.34.235.242 +110.227.51.119 +47.11.249.191 +132.154.50.66 +157.37.184.41 +203.109.83.26 +157.38.132.216 +106.210.36.2 +106.222.81.87 +47.9.6.84 +157.38.251.51 +157.44.187.226 +106.77.191.120 +223.179.255.113 +152.58.197.238 +49.36.223.116 +157.34.157.14 +106.221.117.37 +49.35.244.30 +157.49.238.178 +157.51.45.97 +223.228.38.168 +49.34.146.129 +106.216.199.150 +157.35.0.107 +157.45.142.227 +106.200.181.129 +157.35.7.204 +47.9.32.150 +106.193.1.54 +223.233.23.21 +223.130.29.206 +223.228.171.148 +103.68.176.86 +157.34.148.73 +157.33.112.151 +152.58.58.122 +112.79.117.100 +106.217.8.120 +223.189.188.192 +27.61.65.124 +49.37.159.121 +106.216.245.132 +117.98.44.41 +106.192.139.216 +106.213.217.31 +103.47.18.100 +202.177.226.179 +49.34.202.39 +106.216.174.162 +47.9.32.224 +223.233.10.17 +152.58.91.177 +106.219.187.252 +47.247.198.123 +106.210.173.105 +49.42.68.99 +49.42.90.115 +106.193.46.202 +157.48.114.62 +157.33.247.164 +106.216.229.156 +152.57.8.226 +223.231.195.122 +157.38.116.162 +116.68.96.82 +106.217.167.145 +223.184.220.129 +27.59.250.116 +137.97.109.33 +110.224.187.235 +103.248.120.70 +117.98.50.44 +202.65.144.41 +157.35.74.194 +101.0.32.50 +157.50.3.199 +47.15.105.206 +117.98.92.165 +106.216.112.174 +157.48.155.88 +110.224.76.159 +106.216.136.202 +47.11.205.235 +49.15.242.138 +47.15.41.71 +106.66.63.14 +103.179.223.198 +103.181.91.81 +152.58.201.86 +132.154.37.165 +106.221.243.30 +223.233.39.31 +157.32.121.119 +47.9.86.134 +49.36.212.252 +157.38.67.56 +152.58.202.253 +49.35.154.66 +47.9.129.16 +117.97.213.253 +42.104.129.160 +157.50.53.167 +152.58.197.248 +47.29.174.243 +223.187.191.98 +152.58.182.101 +110.226.204.70 +157.48.92.16 +47.9.3.105 +47.11.26.116 +157.41.254.253 +157.32.105.140 +27.61.78.102 +157.33.207.153 +106.196.33.252 +106.215.90.147 +49.37.54.129 +223.187.133.114 +49.37.27.19 +157.38.12.118 +106.216.136.113 +117.220.142.151 +47.15.15.190 +42.105.237.62 +106.194.225.41 +27.63.29.26 +223.186.5.179 +157.42.216.237 +47.31.184.16 +103.211.10.2 +157.39.70.118 +152.59.67.124 +157.40.81.136 +42.105.77.212 +152.57.208.58 +42.105.21.238 +110.226.174.109 +157.41.226.179 +49.35.175.213 +27.59.88.65 +202.131.138.206 +106.194.39.81 +223.190.169.196 +117.209.220.189 +49.34.130.126 +49.34.90.146 +157.35.26.254 +49.43.97.2 +49.37.153.153 +157.34.78.27 +49.36.218.149 +223.233.4.149 +157.51.58.239 +122.172.12.24 +49.36.182.208 +137.97.82.15 +106.216.127.252 +152.58.163.113 +106.78.78.120 +125.62.125.33 +157.47.115.50 +101.0.41.224 +49.37.65.102 +157.35.62.117 +157.51.103.28 +223.181.120.152 +223.230.166.235 +106.221.119.58 +223.187.115.148 +106.206.142.82 +47.31.199.101 +106.208.20.39 +223.189.161.250 +223.228.250.87 +152.57.48.13 +157.35.43.243 +157.50.11.196 +47.9.34.247 +157.33.62.93 +117.254.139.190 +27.61.147.124 +223.231.178.152 +117.246.57.127 +47.29.161.49 +106.204.60.127 +49.35.153.28 +42.105.142.164 +157.38.125.106 +223.187.185.63 +49.35.194.91 +103.214.60.57 +47.15.22.57 +223.187.120.177 +152.58.222.117 +106.66.28.89 +157.48.132.77 +106.196.8.150 +106.196.98.141 +223.227.51.234 +49.34.216.233 +157.47.50.232 +49.36.138.46 +49.36.25.60 +223.189.245.16 +47.31.231.215 +223.178.212.247 +157.51.196.88 +132.154.50.12 +106.221.52.146 +223.182.2.180 +117.228.42.249 +1.187.216.55 +49.34.234.127 +157.38.146.0 +27.59.252.164 +49.35.149.42 +157.41.226.63 +157.33.27.136 +47.31.163.138 +157.48.173.55 +27.63.72.45 +106.66.36.16 +171.79.151.115 +106.213.144.19 +157.38.128.181 +132.154.50.53 +157.50.64.219 +223.190.134.33 +132.154.144.243 +157.42.237.4 +152.58.224.14 +157.34.43.100 +157.42.247.7 +157.48.146.5 +223.187.100.12 +152.58.59.211 +157.44.209.254 +132.154.48.37 +157.42.194.141 +183.82.161.220 +106.221.86.125 +223.225.120.111 +152.57.159.1 +157.47.11.172 +47.9.127.71 +106.214.251.211 +106.193.1.18 +103.164.204.193 +157.34.58.239 +47.31.198.206 +42.105.218.2 +152.58.200.33 +157.39.69.91 +49.42.86.57 +27.60.198.80 +106.196.119.79 +106.210.177.165 +106.208.216.29 +157.44.169.66 +152.57.226.63 +157.45.153.68 +47.9.90.177 +49.36.33.77 +117.98.18.167 +157.47.7.204 +47.15.17.104 +152.58.189.64 +27.59.46.4 +223.233.86.134 +106.217.139.123 +157.38.71.3 +223.239.105.110 +42.108.77.223 +152.58.212.85 +137.97.109.67 +132.154.50.3 +223.238.217.112 +106.192.225.16 +157.32.67.88 +49.14.112.32 +157.41.254.241 +117.98.48.144 +106.217.184.4 +47.15.149.159 +157.38.93.179 +117.230.135.113 +152.58.169.28 +152.58.184.246 +59.90.40.28 +106.204.199.191 +122.161.240.23 +157.41.253.38 +106.210.43.94 +47.29.175.162 +103.146.175.216 +49.42.87.187 +223.185.96.39 +42.105.15.105 +152.58.232.181 +47.11.230.44 +169.149.227.70 +223.187.25.152 +132.154.162.53 +106.222.94.52 +223.238.116.54 +42.105.196.80 +110.227.41.147 +132.154.54.37 +106.196.114.75 +157.48.245.86 +106.216.240.202 +42.105.159.1 +47.9.33.115 +223.225.171.18 +223.239.119.71 +139.167.170.66 +106.207.73.112 +157.48.177.69 +116.75.81.53 +49.42.95.59 +47.29.166.133 +157.35.20.188 +157.49.237.217 +157.38.78.116 +157.35.8.140 +47.15.160.68 +106.221.245.150 +137.97.64.20 +171.76.231.53 +49.14.157.190 +47.15.119.5 +152.58.70.88 +157.38.128.149 +106.66.40.206 +42.105.238.245 +47.29.47.1 +117.98.30.77 +223.178.209.252 +152.59.65.172 +202.179.66.240 +49.15.93.210 +157.33.85.55 +157.34.125.169 +157.34.148.125 +117.98.6.81 +117.234.40.179 +139.167.170.115 +106.216.171.158 +103.173.194.60 +122.161.52.166 +157.33.125.182 +125.62.117.69 +106.221.252.62 +157.46.75.87 +117.220.134.139 +42.105.234.43 +180.188.246.183 +152.57.140.243 +157.47.74.19 +49.34.192.138 +106.196.67.234 +157.42.218.33 +157.39.74.222 +223.228.239.197 +157.38.25.223 +223.225.29.39 +150.129.170.209 +27.56.220.71 +106.203.136.126 +139.167.189.36 +157.33.76.44 +117.99.202.140 +117.99.200.57 +117.98.32.35 +157.38.37.223 +157.33.124.40 +163.53.208.160 +110.227.60.254 +223.231.117.200 +47.11.255.66 +223.190.130.124 +117.99.233.120 +157.34.105.196 +47.15.33.196 +117.230.186.167 +106.211.47.82 +223.231.159.34 +27.63.10.184 +157.39.69.199 +42.105.199.240 +106.195.113.157 +106.206.194.254 +106.210.142.62 +106.206.111.56 +157.48.181.49 +42.104.158.59 +202.78.236.111 +117.99.224.49 +157.42.2.112 +42.105.199.27 +47.15.9.34 +157.38.208.218 +49.42.83.5 +182.77.27.81 +157.49.194.194 +106.205.201.98 +49.37.49.61 +47.15.6.233 +223.238.146.10 +47.29.175.49 +49.34.93.20 +42.110.166.133 +157.38.137.95 +103.218.103.206 +106.195.0.166 +157.48.114.12 +157.51.7.229 +157.34.119.191 +1.38.104.47 +223.187.123.151 +157.33.201.139 +152.58.79.131 +106.195.68.214 +47.29.167.158 +157.35.58.0 +223.239.101.160 +152.57.144.202 +106.216.162.65 +152.58.191.85 +157.34.27.216 +117.98.66.76 +27.62.24.153 +47.11.253.209 +115.99.21.63 +106.77.92.18 +157.48.130.139 +152.57.243.234 +47.15.5.103 +223.238.108.204 +157.46.105.109 +47.9.110.191 +49.35.174.111 +106.66.251.115 +223.189.223.207 +106.206.197.234 +117.98.28.75 +157.34.26.177 +43.250.41.146 +47.29.171.87 +106.78.85.120 +106.192.81.93 +106.193.238.246 +157.38.11.62 +157.46.184.177 +27.56.227.181 +47.15.252.221 +49.47.70.208 +157.42.200.150 +117.242.106.154 +106.66.28.33 +45.250.49.82 +223.227.93.48 +49.37.45.142 +47.31.97.235 +49.35.184.217 +106.222.41.81 +132.154.49.253 +223.196.174.154 +112.79.140.163 +157.48.197.35 +49.36.18.161 +223.225.246.127 +49.35.164.171 +117.200.150.89 +152.58.166.28 +152.57.58.184 +157.37.183.187 +117.99.49.41 +157.45.207.1 +152.58.143.191 +106.198.24.87 +152.58.19.217 +106.77.79.182 +117.237.242.240 +106.210.231.79 +103.238.108.162 +152.58.101.157 +152.58.188.190 +106.208.171.172 +132.154.61.189 +106.205.212.81 +157.41.250.133 +157.34.83.44 +49.35.194.146 +110.225.83.101 +157.38.139.42 +42.111.208.100 +106.213.187.3 +152.57.189.208 +152.58.210.90 +157.34.131.75 +49.15.83.155 +103.170.182.66 +122.171.217.32 +106.200.3.225 +42.106.181.148 +152.58.68.216 +49.32.230.195 +106.77.76.175 +136.185.105.127 +103.228.147.9 +106.208.55.184 +223.189.244.34 +47.15.40.18 +47.15.159.214 +47.11.201.194 +223.189.204.65 +205.253.32.220 +106.66.58.248 +157.38.108.29 +103.211.115.144 +152.58.230.167 +152.58.188.38 +171.76.233.228 +106.221.82.214 +47.247.217.15 +42.105.78.36 +47.29.57.206 +106.222.39.216 +157.41.228.241 +152.58.148.32 +152.58.191.69 +103.213.214.157 +223.225.56.134 +152.57.29.228 +157.38.251.110 +157.48.117.195 +117.97.206.88 +152.58.16.42 +157.34.123.27 +106.195.71.112 +49.15.136.216 +152.58.197.137 +171.76.234.29 +47.11.203.12 +117.99.208.213 +47.31.199.153 +106.193.134.1 +49.36.192.74 +103.10.226.147 +157.47.93.75 +117.241.253.71 +157.33.233.243 +152.58.129.154 +106.76.250.211 +152.58.154.104 +205.253.32.242 +106.207.82.222 +152.57.195.102 +157.32.245.222 +42.111.204.76 +106.211.2.148 +152.58.232.20 +157.34.2.57 +106.208.145.218 +157.33.11.59 +171.76.245.34 +27.63.133.192 +157.48.217.250 +223.181.125.61 +157.42.246.129 +157.41.197.13 +110.224.183.163 +117.98.36.3 +157.48.116.67 +42.105.236.127 +122.172.118.9 +117.99.231.29 +110.225.62.77 +106.216.204.117 +106.213.84.181 +49.34.118.135 +106.203.144.28 +223.189.252.113 +157.51.158.239 +106.195.70.139 +223.188.243.73 +43.251.94.255 +171.79.159.250 +106.215.206.185 +157.33.58.106 +157.47.55.36 +157.34.209.198 +223.190.132.225 +223.182.10.76 +223.189.201.158 +106.206.168.55 +223.239.99.122 +157.33.89.184 +106.197.2.36 +157.48.221.221 +157.38.90.163 +49.35.167.107 +157.47.125.111 +146.196.32.158 +157.35.46.152 +106.210.32.133 +152.59.67.17 +122.172.35.251 +157.35.77.224 +110.224.165.57 +157.41.224.201 +27.60.96.234 +106.76.249.242 +106.208.251.7 +157.38.149.115 +117.98.46.136 +103.139.56.247 +223.237.121.128 +106.216.254.214 +49.43.179.133 +106.222.109.30 +152.58.78.181 +152.58.234.173 +157.38.30.187 +106.207.191.148 +49.34.225.18 +132.154.159.116 +117.228.198.145 +27.59.191.20 +47.11.249.2 +49.36.16.227 +157.47.55.174 +157.33.251.226 +223.176.99.82 +47.9.100.91 +152.58.188.180 +42.105.168.17 +223.187.32.224 +106.208.230.222 +157.32.32.189 +49.15.138.71 +157.38.116.52 +49.15.228.45 +106.198.122.75 +106.206.199.176 +27.59.219.49 +152.58.30.246 +132.154.20.173 +1.39.238.34 +110.225.35.224 +157.38.128.253 +202.164.139.59 +42.105.49.68 +106.204.50.164 +49.42.83.60 +47.15.235.203 +49.43.217.22 +49.14.154.234 +152.58.187.117 +157.50.54.191 +106.215.92.68 +223.186.158.55 +152.58.67.77 +157.46.115.15 +42.110.197.85 +152.58.89.114 +223.225.60.199 +157.44.137.39 +157.33.35.151 +106.205.194.125 +157.39.67.145 +114.134.24.141 +157.50.20.45 +42.104.152.11 +27.62.54.134 +203.134.211.66 +132.154.39.170 +157.47.100.196 +47.15.2.210 +49.15.89.77 +42.105.12.224 +47.9.5.175 +223.190.159.218 +106.208.53.126 +106.196.45.111 +117.99.213.165 +157.51.175.250 +117.96.175.70 +157.38.202.182 +152.58.210.77 +103.1.103.69 +47.11.209.74 +49.35.162.220 +42.104.157.62 +47.31.210.120 +106.192.174.38 +157.41.242.36 +132.154.55.246 +157.38.144.95 +49.32.167.19 +223.182.214.190 +106.203.131.108 +27.61.123.66 +157.40.238.21 +152.58.67.160 +152.58.23.162 +157.48.125.26 +157.32.34.251 +169.149.229.92 +106.221.249.6 +117.98.98.129 +47.9.155.200 +137.97.79.100 +106.213.188.166 +47.31.248.5 +223.181.230.182 +157.38.55.116 +223.188.86.100 +103.232.185.130 +106.195.127.145 +223.187.83.221 +157.45.189.30 +157.33.198.186 +132.154.35.60 +106.216.114.176 +223.225.254.178 +49.42.64.15 +106.205.197.83 +157.38.2.113 +106.194.41.199 +47.9.109.4 +49.43.99.53 +110.227.42.104 +47.15.4.207 +223.189.22.221 +1.187.216.17 +132.154.50.96 +202.14.120.8 +223.189.248.170 +157.47.119.200 +47.9.89.97 +110.225.43.83 +47.29.51.246 +157.47.31.79 +157.38.113.93 +182.69.41.216 +47.11.193.251 +106.221.104.57 +223.233.84.64 +1.187.217.15 +132.154.22.100 +157.45.252.17 +152.58.236.234 +157.45.47.70 +106.205.234.149 +157.33.102.226 +106.197.122.119 +112.79.118.157 +106.195.44.118 +223.176.21.38 +1.187.180.238 +152.57.219.231 +1.39.30.14 +106.216.193.118 +106.196.127.224 +152.58.154.187 +47.9.137.33 +106.196.103.229 +152.58.157.238 +223.233.77.151 +106.217.64.22 +157.38.147.211 +1.38.88.7 +49.36.90.5 +106.194.199.77 +160.202.38.255 +117.98.78.92 +152.58.196.223 +157.42.209.45 +106.210.197.151 +157.48.240.81 +152.58.26.144 +139.167.193.33 +49.34.184.128 +27.60.197.70 +152.58.107.62 +47.9.126.175 +106.76.221.185 +42.104.154.74 +47.15.160.254 +157.47.71.20 +117.97.208.244 +106.205.244.105 +106.208.148.9 +106.198.241.155 +157.41.228.122 +106.196.104.112 +42.111.245.196 +157.38.244.234 +223.239.57.81 +157.42.225.239 +117.98.110.173 +110.224.18.71 +103.159.47.62 +49.35.226.116 +152.58.123.96 +223.233.0.24 +223.238.91.237 +157.42.2.75 +157.35.45.196 +157.33.38.232 +49.35.129.106 +27.56.201.1 +152.58.154.0 +111.92.75.171 +152.57.36.217 +49.37.52.123 +223.227.79.99 +113.193.73.27 +157.35.90.223 +171.51.140.190 +49.42.90.224 +49.42.69.147 +223.187.186.109 +132.154.59.212 +106.205.196.184 +152.57.176.92 +152.58.214.50 +152.57.3.247 +117.204.214.55 +106.76.208.124 +223.227.83.209 +106.197.12.52 +47.11.192.188 +157.35.27.147 +152.58.58.99 +223.187.105.237 +152.57.131.182 +106.203.110.231 +157.46.155.197 +157.40.96.58 +152.58.79.186 +152.58.71.71 +106.197.200.190 +132.154.63.75 +49.42.85.82 +42.105.131.206 +152.58.22.92 +157.50.65.197 +223.182.221.222 +157.34.68.123 +223.188.118.51 +223.187.248.44 +223.231.205.237 +223.228.94.50 +106.204.197.217 +223.190.157.154 +27.62.6.83 +106.192.222.253 +106.216.67.41 +49.32.129.254 +203.192.253.152 +49.35.161.86 +42.108.4.113 +49.35.194.5 +223.179.205.22 +106.193.100.48 +49.36.213.36 +42.105.142.78 +169.149.228.46 +47.11.89.211 +157.45.93.125 +157.33.111.118 +117.96.154.28 +152.58.196.204 +106.77.184.28 +157.39.70.57 +47.31.169.205 +49.34.120.194 +157.35.41.79 +157.51.198.204 +47.9.136.217 +27.61.177.227 +139.167.239.64 +49.36.114.101 +157.42.237.224 +223.237.8.95 +106.66.249.231 +42.108.4.77 +202.142.117.142 +117.98.70.154 +157.45.76.181 +106.203.138.192 +106.206.244.129 +157.34.146.54 +157.47.62.101 +106.217.26.91 +47.11.58.0 +152.58.58.126 +47.29.168.38 +47.9.122.105 +106.220.193.159 +49.36.187.21 +47.29.171.98 +106.213.235.73 +157.34.149.40 +47.29.174.57 +157.40.199.214 +223.231.226.193 +223.185.111.200 +1.38.118.29 +157.48.177.25 +42.106.9.53 +157.49.84.153 +157.44.187.111 +132.154.56.137 +49.37.153.157 +103.137.194.12 +47.31.97.121 +152.58.167.147 +106.216.72.68 +47.31.242.40 +132.154.56.228 +1.187.215.128 +157.48.77.169 +139.167.225.15 +152.58.2.104 +106.195.39.85 +49.37.115.139 +132.154.150.66 +49.34.255.72 +47.9.82.114 +223.186.221.87 +49.37.150.17 +42.105.214.139 +117.205.174.21 +47.11.206.213 +106.210.172.181 +47.9.34.17 +49.35.167.38 +27.61.170.138 +117.246.143.248 +47.9.67.52 +49.36.122.170 +152.58.94.193 +157.32.41.154 +47.29.174.63 +47.247.214.125 +106.202.100.242 +106.196.89.193 +157.46.87.191 +103.40.199.85 +157.38.86.149 +47.11.91.191 +42.109.192.46 +182.69.178.240 +49.42.81.123 +157.39.75.235 +49.35.153.67 +157.48.253.194 +47.15.3.49 +106.221.255.219 +157.35.78.12 +43.229.201.148 +117.98.30.153 +42.108.9.222 +42.108.28.56 +223.190.41.226 +49.15.245.238 +223.180.181.92 +223.227.15.197 +42.105.198.14 +157.33.65.205 +106.196.4.69 +157.34.85.169 +45.64.223.239 +205.253.122.63 +47.15.9.112 +157.41.192.71 +117.98.98.135 +157.50.30.35 +115.187.43.222 +27.60.108.95 +152.58.31.14 +106.206.151.240 +110.226.198.58 +152.58.184.243 +49.34.54.3 +157.46.110.4 +171.79.161.201 +103.195.249.48 +152.58.233.227 +106.221.254.163 +152.57.126.59 +106.216.247.146 +157.34.24.204 +157.41.253.58 +157.49.93.186 +152.58.233.90 +42.105.164.221 +27.61.166.245 +152.58.236.82 +152.58.181.177 +27.61.102.111 +106.197.135.197 +117.99.212.203 +49.35.156.155 +157.41.225.173 +157.50.15.103 +106.216.195.136 +223.239.50.98 +47.9.154.202 +110.227.47.246 +223.225.124.24 +152.58.129.49 +157.50.26.206 +152.58.234.109 +47.31.164.233 +157.34.11.166 +157.38.197.111 +49.37.48.112 +152.58.233.2 +42.105.198.138 +47.15.246.72 +117.99.205.26 +45.114.159.88 +103.112.106.5 +223.185.79.22 +42.105.204.78 +49.35.240.250 +171.51.143.30 +223.228.253.16 +157.32.222.253 +106.204.193.237 +152.58.119.126 +223.231.136.18 +106.221.180.111 +157.41.227.155 +49.14.134.241 +47.15.156.56 +49.37.233.64 +157.38.219.22 +157.48.253.69 +157.49.128.90 +152.58.168.185 +117.247.171.215 +49.42.86.3 +223.185.107.79 +47.11.252.129 +49.42.64.27 +157.48.162.67 +117.99.236.208 +117.98.78.39 +106.208.138.135 +47.15.15.151 +169.149.227.88 +152.58.103.54 +223.189.195.74 +223.228.171.221 +27.62.35.252 +157.45.162.209 +157.32.255.100 +157.45.172.225 +106.221.94.230 +152.58.176.161 +49.34.150.132 +152.58.104.179 +47.15.4.79 +117.98.34.192 +106.213.211.94 +106.66.221.242 +103.160.216.220 +106.221.12.168 +157.49.213.58 +117.99.243.66 +47.9.111.31 +157.45.43.40 +106.216.244.64 +47.11.91.167 +157.44.151.18 +223.231.209.176 +49.14.112.231 +152.58.147.59 +223.187.32.165 +157.51.67.79 +106.219.3.18 +103.155.222.1 +223.185.98.150 +157.33.233.9 +157.41.224.49 +49.32.235.107 +112.79.118.13 +137.97.81.39 +152.58.214.154 +106.79.134.17 +106.216.200.198 +49.32.188.213 +106.197.125.113 +157.39.65.94 +106.221.245.218 +223.186.78.38 +157.48.125.77 +152.58.67.95 +122.163.73.26 +49.14.71.18 +42.105.177.62 +49.37.45.63 +49.36.99.108 +157.38.87.180 +47.11.77.155 +171.79.191.32 +152.58.75.145 +157.48.191.221 +42.111.96.2 +152.58.197.207 +49.42.95.209 +106.221.52.109 +157.38.243.17 +157.51.195.121 +42.105.142.237 +49.37.88.115 +223.186.131.140 +157.47.87.210 +49.35.135.24 +223.176.42.152 +110.224.106.148 +137.97.121.81 +157.45.136.195 +223.225.124.246 +152.57.213.47 +137.97.72.6 +183.82.26.167 +223.179.251.141 +157.38.149.2 +42.110.148.246 +223.225.247.77 +157.46.100.24 +27.60.204.181 +103.87.56.76 +157.48.243.189 +157.34.200.158 +106.213.203.71 +223.176.11.204 +49.37.88.152 +223.176.114.200 +103.90.45.222 +106.76.238.29 +110.224.99.233 +47.9.86.218 +47.9.35.227 +223.228.160.246 +169.149.226.112 +152.58.72.66 +132.154.5.254 +157.35.1.166 +157.39.64.147 +47.31.195.48 +27.97.32.215 +157.48.164.224 +157.41.228.159 +157.51.8.162 +223.186.250.203 +49.36.210.24 +106.193.213.89 +171.76.224.254 +157.38.118.12 +132.154.157.243 +110.224.69.15 +223.231.194.80 +106.195.66.55 +42.105.233.236 +157.39.67.236 +157.41.229.174 +49.35.190.189 +47.29.163.154 +103.203.72.12 +124.40.246.98 +171.76.224.163 +157.39.74.150 +169.149.229.109 +157.38.151.182 +157.33.29.200 +152.58.230.122 +49.32.155.243 +106.76.208.150 +49.36.218.65 +49.14.156.69 +157.32.40.245 +157.34.98.90 +157.34.243.234 +49.35.144.4 +137.97.89.87 +157.34.58.17 +137.97.81.153 +106.196.9.39 +49.15.246.57 +132.154.62.226 +223.228.26.36 +210.89.58.245 +223.228.86.182 +117.98.42.123 +106.221.110.238 +152.58.116.225 +157.49.67.146 +223.190.149.200 +49.34.195.190 +106.76.151.10 +157.35.25.212 +157.49.88.26 +223.187.135.194 +223.191.16.127 +103.42.199.154 +117.246.205.111 +106.78.83.162 +47.11.73.124 +42.105.202.5 +132.154.13.224 +223.187.183.42 +47.9.114.122 +106.196.71.9 +223.187.202.18 +157.45.218.140 +157.42.214.130 +1.187.18.38 +117.98.40.198 +157.33.80.131 +27.61.78.166 +157.34.32.154 +169.149.231.169 +223.230.173.35 +157.41.251.69 +106.76.212.237 +27.62.157.245 +106.193.142.190 +157.51.193.107 +49.43.202.96 +110.224.107.177 +152.57.240.74 +152.57.217.43 +223.187.214.16 +106.196.8.57 +152.58.162.218 +152.58.150.61 +152.57.146.23 +223.239.24.167 +152.58.218.90 +106.202.62.175 +49.15.81.39 +106.217.77.74 +157.49.226.73 +49.42.68.128 +117.98.38.176 +117.228.218.197 +42.109.207.121 +106.211.80.13 +223.187.152.200 +157.42.209.231 +223.189.187.237 +157.38.75.80 +106.207.191.226 +42.105.178.227 +47.11.211.170 +1.187.59.131 +157.35.7.107 +117.229.151.181 +117.99.231.90 +42.105.48.7 +139.167.205.89 +49.14.104.6 +152.58.138.127 +157.32.42.205 +157.34.84.237 +117.255.220.6 +47.9.114.224 +49.35.141.114 +59.180.168.12 +103.203.72.14 +106.76.210.213 +47.9.135.113 +47.9.92.211 +223.186.191.186 +223.187.58.23 +117.99.196.58 +223.225.173.161 +106.216.200.209 +223.189.146.233 +157.38.212.135 +27.56.89.204 +59.88.238.123 +171.76.146.78 +42.105.138.70 +110.224.89.156 +157.35.61.57 +117.97.210.42 +157.39.75.226 +157.42.246.25 +157.34.14.216 +49.42.89.211 +183.82.29.151 +157.46.87.242 +157.38.135.151 +106.79.192.88 +106.200.89.96 +152.58.212.93 +157.38.5.239 +137.97.87.123 +110.226.164.48 +152.58.201.80 +152.57.6.223 +106.193.104.87 +106.208.148.155 +106.207.147.175 +223.176.52.121 +103.52.247.253 +223.196.174.54 +122.162.144.56 +223.238.70.17 +47.11.237.85 +106.193.104.12 +152.57.158.230 +106.208.149.238 +157.35.27.161 +106.221.184.152 +27.255.221.55 +223.188.117.56 +223.239.59.148 +106.211.222.115 +152.58.232.214 +106.77.190.71 +49.36.235.60 +106.221.31.145 +106.217.190.26 +110.224.68.244 +117.98.26.26 +157.39.74.4 +152.58.166.98 +106.211.92.160 +49.42.89.166 +49.37.65.236 +106.217.137.77 +152.58.56.152 +106.204.201.54 +27.60.81.17 +157.33.125.9 +117.230.82.74 +106.76.209.200 +106.207.247.49 +106.211.234.111 +132.154.23.247 +223.231.232.243 +49.35.132.184 +103.10.116.64 +42.105.158.116 +171.76.228.90 +157.38.144.211 +157.49.87.11 +157.49.212.42 +117.220.27.130 +27.60.80.58 +157.47.7.137 +106.216.127.182 +106.66.37.33 +137.97.125.85 +157.51.100.138 +106.211.191.76 +157.34.119.46 +47.11.209.135 +117.252.142.255 +110.224.68.239 +157.33.34.178 +169.149.226.49 +157.47.106.176 +106.216.234.15 +152.58.56.172 +152.58.106.67 +157.48.131.125 +106.66.60.205 +106.197.121.95 +157.38.135.132 +122.162.146.31 +157.41.241.104 +112.79.56.201 +110.225.46.247 +157.50.67.174 +223.231.92.181 +106.194.25.137 +223.190.173.16 +117.98.94.1 +106.221.47.157 +137.97.111.241 +49.34.187.81 +110.224.90.37 +106.66.3.161 +49.35.136.173 +152.58.132.124 +106.194.190.92 +223.187.184.230 +42.106.216.98 +103.185.237.133 +47.11.192.157 +117.99.239.83 +157.49.163.180 +122.182.208.229 +157.45.195.109 +157.35.61.151 +157.46.82.93 +49.35.194.54 +49.34.121.232 +47.11.51.210 +157.49.88.213 +106.211.93.11 +27.7.76.214 +49.35.235.200 +110.226.200.248 +115.187.46.18 +157.39.73.124 +103.253.150.225 +47.31.219.66 +139.5.242.80 +47.15.42.155 +106.78.52.172 +157.39.72.174 +122.170.5.148 +27.62.99.106 +152.58.21.119 +49.37.113.200 +152.58.30.1 +106.223.111.235 +157.38.129.196 +157.48.148.226 +202.88.248.207 +157.45.240.52 +47.29.30.39 +47.9.32.113 +106.192.20.172 +223.231.102.192 +152.57.160.101 +117.237.215.197 +106.216.249.33 +223.238.118.112 +115.98.234.11 +42.108.4.42 +157.49.68.140 +47.15.33.109 +42.105.164.16 +49.15.224.27 +157.35.0.196 +106.208.183.108 +1.187.180.172 +47.11.197.147 +223.233.125.237 +157.38.34.114 +42.105.180.128 +157.47.68.78 +106.194.21.231 +42.106.176.179 +49.43.241.160 +223.182.207.11 +42.105.232.14 +106.207.220.112 +106.202.4.22 +157.47.47.3 +152.58.58.93 +169.149.197.236 +152.58.26.48 +157.44.143.61 +132.154.37.37 +223.182.3.67 +47.31.170.254 +49.14.97.32 +47.11.249.196 +106.208.14.154 +106.195.76.255 +157.38.152.160 +106.213.175.36 +157.38.134.104 +106.194.13.111 +106.197.67.244 +59.178.144.223 +132.154.23.66 +47.15.133.4 +27.60.105.142 +223.187.127.184 +110.224.81.82 +223.187.183.44 +106.223.140.138 +157.47.85.131 +47.247.195.250 +152.58.58.105 +49.35.192.134 +157.34.79.127 +157.34.62.191 +171.76.191.133 +49.43.96.180 +152.58.59.212 +42.110.210.118 +157.47.101.29 +49.34.92.11 +139.167.217.128 +223.189.183.127 +49.36.209.69 +27.63.198.38 +152.58.210.234 +103.66.208.163 +106.66.37.122 +106.205.172.169 +49.35.167.163 +152.58.39.143 +49.42.80.0 +157.51.124.146 +152.57.226.169 +117.96.173.7 +103.229.129.168 +49.37.99.145 +106.194.144.127 +49.34.167.10 +223.187.132.43 +152.57.153.81 +49.37.67.150 +157.46.123.197 +110.227.53.2 +47.29.167.162 +171.48.104.236 +139.167.163.155 +223.178.210.42 +117.98.14.65 +1.38.141.148 +117.194.64.96 +47.11.249.216 +157.35.50.80 +223.187.32.209 +59.98.175.191 +122.173.221.254 +106.194.191.174 +27.97.33.9 +106.202.49.140 +47.29.167.99 +117.211.79.36 +132.154.50.94 +47.11.195.13 +27.97.65.19 +106.205.38.200 +223.233.16.61 +106.222.18.177 +152.58.150.133 +171.48.120.164 +49.36.169.106 +171.76.182.232 +49.15.186.116 +49.35.165.12 +223.227.102.71 +110.224.73.35 +223.187.177.79 +106.192.94.85 +150.107.182.162 +157.38.135.202 +182.70.214.138 +152.58.219.223 +42.111.111.10 +157.47.63.213 +42.105.228.36 +157.38.76.24 +110.225.53.184 +180.188.232.58 +223.176.116.179 +1.39.244.29 +49.37.45.115 +132.154.23.68 +49.36.215.176 +223.227.57.162 +157.46.123.12 +106.220.241.32 +157.47.55.232 +223.186.72.195 +223.237.109.220 +117.99.225.191 +157.40.212.197 +106.206.233.198 +117.98.36.19 +106.77.132.50 +27.60.206.226 +106.211.184.218 +106.195.83.81 +132.154.156.25 +49.34.198.245 +157.45.195.194 +122.162.146.157 +117.204.131.38 +157.48.132.186 +157.32.34.28 +157.48.127.169 +106.76.197.139 +152.57.205.5 +152.58.191.226 +27.62.3.31 +183.87.198.19 +152.58.169.93 +106.206.203.168 +42.104.154.62 +152.59.65.168 +106.208.220.239 +223.190.136.33 +157.48.113.5 +49.36.223.219 +152.57.53.58 +106.77.160.76 +117.99.221.47 +171.48.125.116 +171.76.252.175 +106.195.124.45 +157.48.82.27 +152.58.151.66 +223.189.162.133 +27.97.78.43 +106.200.172.79 +157.33.41.46 +106.207.146.193 +157.48.117.26 +27.61.205.98 +223.187.12.194 +106.216.199.198 +152.57.150.191 +27.62.70.52 +157.48.154.163 +49.14.113.156 +47.29.173.124 +110.224.91.173 +110.224.96.216 +157.41.249.18 +152.58.25.147 +157.39.67.218 +223.189.189.203 +157.49.148.252 +49.34.122.234 +152.57.55.133 +157.35.91.110 +223.228.245.21 +117.96.58.194 +47.15.9.237 +49.36.218.101 +106.219.179.64 +152.58.153.224 +132.154.133.193 +132.154.62.219 +47.29.162.32 +223.187.117.93 +157.48.117.182 +27.59.173.111 +117.246.194.181 +152.58.235.141 +152.58.33.219 +47.31.128.251 +106.193.229.17 +47.9.79.2 +157.48.159.243 +49.43.99.139 +157.37.148.132 +106.223.46.136 +157.46.134.200 +49.35.151.24 +223.239.124.98 +171.76.176.185 +106.196.5.243 +110.224.71.66 +49.34.180.97 +157.42.200.223 +106.202.62.176 +157.50.45.236 +152.58.20.231 +117.230.135.144 +106.222.0.156 +42.106.205.21 +47.9.33.135 +42.105.198.42 +103.188.219.143 +132.154.157.133 +152.58.208.54 +106.223.219.115 +157.41.241.7 +117.99.207.45 +157.35.93.42 +157.35.95.178 +47.15.17.13 +106.220.87.86 +152.57.218.143 +49.14.109.3 +42.105.79.35 +49.36.24.173 +152.58.180.229 +106.210.145.182 +157.34.104.115 +137.97.68.253 +106.221.255.31 +152.57.21.87 +106.215.167.8 +157.33.56.210 +106.211.62.164 +157.34.134.56 +106.76.210.138 +47.15.9.226 +157.37.166.70 +223.187.57.243 +223.180.178.28 +152.58.74.209 +116.193.134.211 +103.15.252.109 +27.56.86.177 +110.226.176.16 +152.58.189.155 +157.49.206.187 +223.238.95.154 +223.238.99.132 +152.57.241.71 +103.217.121.109 +117.225.34.17 +157.34.227.163 +27.56.206.55 +223.230.138.128 +152.58.197.85 +49.36.98.252 +103.92.121.186 +49.35.189.195 +157.49.252.34 +47.9.112.236 +110.224.66.160 +157.41.224.141 +171.79.166.196 +223.238.120.128 +223.231.145.183 +49.35.179.109 +152.57.195.2 +47.9.103.19 +49.42.85.133 +117.251.177.152 +47.31.155.224 +169.149.199.175 +1.38.136.46 +223.189.215.1 +157.38.234.247 +223.230.163.80 +157.47.72.161 +106.221.210.119 +47.9.78.100 +103.221.79.239 +49.15.224.86 +110.227.63.40 +106.206.175.38 +49.36.187.85 +157.34.133.133 +117.99.194.92 +202.91.77.226 +152.57.73.52 +49.43.97.232 +117.230.141.191 +47.9.126.58 +157.35.86.240 +106.200.55.189 +157.40.206.238 +132.154.158.110 +157.38.88.142 +106.66.23.220 +61.1.59.81 +49.36.219.155 +223.233.121.223 +42.105.204.234 +157.41.225.174 +106.221.222.238 +47.9.108.101 +157.51.128.66 +27.63.200.217 +47.9.116.193 +223.190.140.236 +223.237.16.207 +42.106.177.108 +157.47.119.141 +152.57.27.81 +106.216.125.139 +152.58.232.253 +106.192.197.174 +47.9.137.214 +103.240.207.118 +27.60.62.246 +42.105.164.80 +27.63.193.227 +157.44.137.98 +106.76.208.173 +110.224.114.214 +132.154.36.188 +223.177.80.237 +157.38.218.76 +47.15.15.97 +42.105.175.96 +49.42.32.254 +106.210.185.20 +152.57.49.203 +157.51.74.218 +117.96.189.181 +42.105.218.9 +157.45.242.248 +47.29.173.229 +157.34.74.251 +132.154.48.59 +157.32.127.149 +106.216.254.248 +103.85.9.68 +106.210.134.24 +152.58.21.249 +157.34.85.154 +42.111.114.49 +157.33.209.178 +182.69.178.57 +157.47.74.236 +152.58.82.33 +110.224.93.105 +27.63.111.98 +223.180.183.56 +117.98.52.44 +157.39.74.142 +106.197.107.191 +157.39.74.56 +49.42.36.61 +49.35.226.135 +103.94.138.110 +110.227.60.236 +117.98.98.28 +117.98.112.88 +49.34.102.104 +106.76.238.80 +157.40.211.212 +202.14.121.253 +27.63.51.65 +157.51.48.240 +157.38.216.169 +106.194.148.112 +106.211.74.126 +152.58.200.36 +223.189.160.241 +106.207.37.216 +152.57.133.202 +49.42.91.88 +47.11.198.51 +152.58.142.155 +157.47.78.35 +106.193.77.168 +152.58.27.122 +47.29.163.29 +49.34.62.103 +152.57.222.108 +152.57.77.102 +42.105.210.252 +139.167.220.106 +157.34.42.88 +49.43.3.250 +171.76.30.151 +106.194.179.224 +42.105.172.55 +110.224.161.198 +106.196.100.209 +106.197.4.107 +152.58.112.221 +106.76.197.104 +122.161.52.96 +157.45.144.86 +49.37.107.235 +47.29.164.221 +157.47.62.100 +157.48.182.91 +223.237.109.46 +49.14.130.56 +157.42.237.248 +223.231.239.23 +106.210.220.248 +49.36.170.140 +157.49.79.36 +49.42.82.115 +157.34.56.46 +152.57.119.108 +157.51.176.129 +152.58.211.96 +47.9.35.165 +223.176.38.53 +106.207.226.54 +42.111.241.129 +157.38.63.99 +49.15.230.220 +223.189.23.244 +223.190.156.156 +157.49.184.141 +106.208.55.103 +47.9.118.82 +157.46.134.226 +47.15.17.189 +106.194.146.168 +42.105.245.124 +152.58.101.170 +223.237.108.27 +49.37.25.226 +223.182.210.72 +157.39.196.242 +106.77.178.148 +157.48.126.65 +223.228.241.217 +106.197.160.245 +110.224.177.167 +106.216.116.145 +157.38.24.252 +106.76.93.125 +152.58.37.47 +117.98.72.189 +157.44.177.218 +157.38.50.236 +152.58.185.126 +223.189.144.199 +157.35.90.110 +47.9.96.134 +157.38.119.170 +157.48.240.82 +47.9.149.115 +106.194.155.34 +157.42.238.145 +157.49.75.37 +47.29.169.60 +27.5.185.75 +157.46.155.176 +110.224.82.95 +47.9.150.121 +47.15.164.123 +110.224.114.92 +114.31.135.65 +223.186.196.118 +223.238.235.129 +49.42.84.152 +117.99.218.122 +49.35.156.228 +117.237.205.97 +110.225.80.79 +157.38.243.44 +157.38.33.122 +157.46.145.163 +106.222.117.212 +49.36.80.103 +47.31.144.205 +157.50.3.36 +152.57.74.245 +103.178.145.44 +47.9.94.178 +160.238.93.68 +157.38.131.120 +27.61.87.26 +47.9.107.98 +103.5.134.168 +157.42.3.163 +157.45.253.108 +49.42.69.83 +223.187.106.79 +106.194.222.186 +152.57.235.117 +49.35.194.76 +223.239.71.226 +157.47.89.110 +27.56.87.144 +152.58.36.132 +137.97.67.154 +157.41.224.83 +157.48.198.93 +223.231.192.2 +157.35.75.195 +157.35.4.142 +47.15.15.217 +152.57.68.233 +106.77.186.231 +152.58.89.79 +157.47.127.140 +106.78.46.207 +106.206.124.155 +106.202.120.12 +106.211.67.38 +42.111.11.219 +27.60.199.159 +152.58.140.34 +49.34.107.25 +117.99.41.109 +152.58.234.41 +223.187.77.231 +106.216.238.252 +152.58.133.61 +49.15.203.33 +27.61.113.188 +157.47.58.34 +152.58.75.41 +152.58.222.154 +206.84.236.37 +152.58.184.192 +152.58.200.17 +157.34.7.99 +106.76.89.3 +117.98.40.113 +157.38.210.141 +223.188.123.215 +106.211.109.46 +223.190.102.80 +47.31.223.216 +106.208.158.241 +223.237.81.218 +59.89.152.43 +157.48.94.119 +223.238.195.124 +223.178.210.101 +157.38.129.112 +47.15.139.178 +110.227.63.208 +1.39.16.120 +223.228.17.238 +49.35.249.110 +27.59.217.59 +152.58.189.31 +157.34.254.74 +42.106.248.206 +117.98.58.123 +152.58.26.35 +106.196.23.132 +132.154.182.62 +223.239.110.212 +110.227.13.175 +106.206.230.245 +152.58.34.238 +152.58.185.56 +157.48.134.190 +47.31.255.98 +43.241.192.128 +27.62.234.65 +132.154.60.247 +49.42.88.178 +106.221.155.78 +157.38.79.103 +157.33.3.57 +223.238.98.83 +47.15.183.239 +42.105.178.6 +152.57.157.248 +157.38.36.144 +223.188.178.68 +223.182.58.114 +157.44.166.224 +223.190.191.198 +117.99.31.148 +47.15.13.76 +47.15.34.151 +49.36.104.67 +49.156.103.204 +47.9.81.216 +110.224.75.14 +49.35.178.13 +110.224.90.183 +202.173.125.19 +106.200.153.192 +117.234.50.151 +183.82.238.28 +106.201.186.103 +27.61.101.164 +42.107.224.28 +49.34.153.133 +42.104.213.155 +49.35.146.128 +157.51.199.136 +223.187.24.90 +157.34.106.173 +223.188.176.209 +47.9.64.152 +157.35.81.159 +106.216.181.50 +223.178.209.13 +47.29.173.185 +49.35.192.26 +152.58.197.62 +117.98.106.154 +223.187.245.228 +157.47.37.53 +117.198.95.136 +152.58.34.53 +1.38.165.1 +223.238.132.221 +47.11.207.203 +223.238.97.180 +223.236.239.51 +139.167.220.88 +49.14.164.134 +157.42.0.129 +49.35.161.230 +45.127.44.110 +117.97.205.73 +117.98.20.80 +223.186.206.215 +157.47.23.202 +106.211.52.185 +152.58.169.33 +47.29.170.183 +157.34.210.171 +106.200.92.227 +157.35.61.243 +27.63.240.186 +150.107.26.149 +110.226.180.29 +157.38.211.197 +106.207.36.107 +49.42.74.165 +49.36.81.174 +103.206.137.39 +47.29.165.162 +132.154.54.42 +27.62.123.43 +152.58.218.22 +152.58.38.254 +47.29.40.106 +117.99.228.43 +42.105.155.36 +157.48.196.68 +132.154.52.187 +106.217.46.202 +223.225.170.67 +106.194.26.31 +157.46.71.140 +157.38.137.132 +49.35.235.231 +157.46.84.144 +157.44.211.152 +49.37.106.178 +152.57.198.64 +157.44.199.67 +223.237.121.83 +157.39.68.47 +152.58.133.19 +49.34.63.238 +47.9.94.26 +157.41.240.211 +223.188.55.239 +106.195.121.69 +47.15.1.119 +157.51.198.153 +106.204.52.75 +49.14.140.218 +47.11.198.2 +106.194.59.37 +27.62.13.104 +152.57.95.138 +106.77.185.55 +157.33.19.40 +47.29.44.94 +117.208.169.200 +49.35.145.247 +49.42.66.143 +157.47.36.170 +137.97.81.210 +106.195.32.41 +157.47.74.245 +49.42.89.249 +49.34.235.159 +106.196.11.99 +47.9.32.135 +117.99.231.71 +132.154.173.113 +106.223.85.139 +106.217.215.30 +112.79.69.33 +157.40.226.101 +106.206.202.143 +49.36.181.23 +223.239.103.238 +106.205.206.67 +49.15.229.125 +157.41.196.125 +157.34.122.224 +47.29.168.51 +49.14.129.11 +223.238.214.178 +122.169.111.239 +27.63.24.245 +152.59.66.86 +152.58.83.146 +49.37.222.14 +132.154.55.253 +1.187.183.184 +157.41.251.191 +47.15.1.155 +132.154.62.17 +47.31.223.178 +103.47.72.111 +106.192.206.33 +223.238.196.107 +42.105.164.183 +47.15.0.91 +117.99.222.122 +59.178.70.204 +106.76.76.11 +49.36.234.123 +157.42.229.117 +157.41.193.216 +106.205.202.251 +122.168.253.64 +157.35.58.57 +111.92.74.76 +47.11.225.206 +202.148.59.170 +157.51.76.252 +106.67.11.76 +157.33.205.231 +157.51.173.123 +106.194.12.44 +106.196.68.64 +157.48.148.170 +27.63.229.159 +117.99.9.176 +106.205.184.16 +223.231.192.172 +47.15.4.201 +47.29.169.150 +152.57.202.66 +157.48.253.208 +169.149.225.10 +182.68.177.71 +223.225.59.229 +49.35.229.159 +152.58.114.195 +42.108.30.12 +157.33.14.192 +157.41.254.83 +223.225.120.192 +117.241.56.164 +157.40.125.169 +47.15.185.167 +47.11.38.217 +103.158.120.150 +47.29.23.153 +49.35.246.78 +106.211.95.40 +106.79.204.15 +106.197.164.182 +117.96.136.110 +171.60.194.145 +157.34.78.244 +47.31.196.47 +157.46.140.87 +157.33.12.22 +157.47.56.43 +157.34.107.183 +157.33.234.63 +157.42.234.102 +103.27.49.147 +106.211.99.161 +106.205.130.26 +47.29.167.141 +157.38.101.240 +106.205.226.203 +171.76.213.216 +132.154.142.13 +49.14.159.15 +157.42.196.234 +42.105.183.215 +223.230.149.205 +157.34.12.12 +106.206.248.113 +27.56.71.153 +117.98.28.43 +157.51.193.18 +122.168.95.120 +223.236.253.105 +157.35.44.215 +157.34.68.182 +42.111.98.19 +117.96.160.84 +47.15.36.188 +152.58.30.10 +49.37.41.89 +157.41.226.104 +157.51.198.102 +152.57.12.247 +110.224.98.37 +27.62.145.161 +27.56.235.98 +157.41.248.207 +157.34.62.140 +157.44.145.28 +106.220.108.142 +157.38.36.252 +49.42.82.253 +157.42.215.48 +122.162.149.141 +49.15.246.47 +103.247.54.209 +106.207.164.22 +106.217.40.254 +47.9.159.231 +223.238.234.162 +157.35.82.93 +152.58.156.140 +152.58.235.135 +106.196.100.127 +27.60.157.27 +42.111.110.31 +152.58.184.162 +157.34.139.38 +157.38.131.165 +117.204.58.148 +152.58.148.253 +103.5.132.101 +106.207.28.183 +157.45.245.117 +47.15.33.25 +132.154.5.199 +152.58.200.60 +49.42.83.228 +47.9.142.39 +110.225.43.209 +152.58.38.39 +106.77.79.216 +49.37.47.230 +116.74.138.191 +47.9.126.218 +110.227.62.36 +106.203.76.209 +47.29.164.181 +110.225.52.122 +157.45.254.48 +152.58.177.127 +106.196.12.237 +106.77.76.29 +223.186.103.163 +157.47.109.14 +103.196.54.98 +137.97.108.97 +223.187.206.73 +157.32.42.115 +152.58.186.228 +110.226.204.182 +47.11.227.123 +157.32.231.133 +132.154.171.61 +152.57.240.203 +117.98.34.153 +117.96.182.224 +42.106.186.207 +152.58.56.26 +49.15.95.150 +106.212.66.202 +157.44.214.13 +103.164.211.136 +157.47.39.173 +157.50.47.37 +117.99.252.197 +132.154.188.223 +157.38.206.200 +117.249.215.213 +106.194.126.8 +106.203.32.5 +106.211.98.136 +49.37.117.241 +106.196.34.247 +223.233.67.118 +223.185.117.151 +157.34.92.235 +117.98.90.108 +106.196.2.95 +47.9.86.48 +157.46.188.51 +223.239.114.198 +157.49.142.87 +157.48.64.184 +106.216.237.121 +27.63.46.30 +152.58.155.114 +106.217.6.82 +49.35.193.10 +103.181.59.56 +152.57.138.195 +49.34.151.187 +139.167.254.184 +157.32.100.223 +157.44.192.151 +157.41.194.74 +157.33.31.56 +106.214.95.13 +47.11.45.191 +157.48.159.149 +103.172.158.111 +157.48.124.31 +47.9.91.202 +103.186.72.113 +42.105.155.66 +157.48.87.133 +106.205.193.190 +47.15.14.156 +106.207.202.116 +157.35.92.241 +1.187.223.79 +223.178.86.61 +42.105.213.49 +223.180.179.100 +117.98.66.135 +157.50.34.75 +106.215.91.201 +49.32.248.121 +106.194.56.109 +157.40.105.225 +106.221.102.185 +157.33.36.109 +223.233.122.251 +223.187.96.30 +152.58.213.40 +137.97.113.61 +223.182.213.63 +152.58.234.107 +47.9.122.58 +157.33.103.89 +223.239.83.123 +106.197.113.249 +117.99.227.199 +49.35.171.85 +152.58.36.47 +103.132.3.146 +27.61.112.90 +206.84.235.69 +49.37.25.237 +223.228.236.187 +49.34.174.144 +110.225.205.45 +171.61.34.94 +49.34.252.46 +157.35.41.85 +223.187.14.172 +132.154.52.52 +223.231.197.126 +157.41.243.126 +106.194.166.7 +157.34.117.238 +106.76.209.209 +132.154.63.46 +106.195.108.101 +152.58.70.212 +223.186.140.2 +42.105.164.136 +106.205.206.247 +137.97.91.194 +111.92.75.81 +157.40.80.137 +106.216.203.232 +103.81.210.42 +47.9.34.53 +106.214.113.231 +106.221.113.92 +114.31.144.60 +106.193.61.128 +117.97.64.160 +157.46.92.240 +27.63.72.25 +49.37.51.114 +157.40.221.77 +49.36.218.84 +27.63.26.201 +42.111.161.228 +132.154.130.225 +47.29.168.177 +157.47.61.79 +152.58.32.147 +106.194.58.241 +49.14.168.9 +157.35.64.171 +152.58.105.182 +223.225.39.131 +157.42.218.126 +157.32.36.128 +103.201.139.117 +49.14.115.46 +49.15.187.202 +106.66.3.164 +157.48.112.187 +223.188.180.219 +152.58.68.150 +106.221.180.68 +47.11.253.18 +152.57.170.73 +157.32.119.183 +106.79.185.72 +171.76.236.88 +157.33.70.135 +157.38.233.243 +223.237.22.21 +139.167.239.221 +157.34.62.151 +47.11.201.87 +103.217.121.235 +157.48.70.145 +110.225.60.104 +223.189.210.12 +152.57.49.220 +49.43.32.131 +157.39.74.151 +157.38.237.49 +117.198.45.71 +114.31.168.111 +205.253.10.149 +157.51.196.183 +42.105.164.98 +157.45.87.195 +157.33.211.39 +110.224.71.23 +103.53.165.108 +223.233.67.247 +157.38.146.130 +106.211.32.2 +47.15.216.231 +117.99.254.13 +49.15.247.141 +49.34.197.11 +223.187.52.5 +157.49.191.114 +47.11.195.220 +152.58.167.183 +106.207.106.56 +203.192.214.117 +152.58.103.36 +106.220.115.82 +157.32.37.163 +106.66.57.110 +223.225.98.74 +49.37.227.240 +157.45.94.40 +106.223.50.86 +106.221.250.246 +169.149.225.25 +47.11.208.118 +27.62.163.221 +152.57.227.238 +152.58.82.146 +157.34.78.223 +122.180.38.152 +152.57.243.179 +157.33.199.193 +223.187.46.101 +110.227.38.78 +116.193.129.42 +157.35.26.15 +47.29.174.31 +122.164.85.118 +157.32.85.211 +49.15.245.23 +117.99.205.11 +42.105.96.16 +47.9.111.181 +112.79.153.252 +42.104.156.70 +152.58.234.35 +106.77.187.254 +157.34.82.124 +110.224.74.236 +27.58.88.203 +49.34.177.36 +106.76.210.220 +47.15.3.31 +106.208.4.83 +110.224.80.95 +157.34.71.10 +106.211.91.200 +1.38.220.175 +47.11.253.93 +157.34.158.255 +157.45.43.75 +223.186.24.99 +157.41.228.249 +49.15.234.243 +157.48.126.136 +106.216.243.255 +157.42.252.109 +106.194.58.133 +1.38.137.18 +106.216.251.28 +117.230.87.184 +157.48.137.216 +47.29.163.64 +223.189.144.234 +223.190.189.220 +103.146.175.155 +106.197.42.145 +157.34.227.239 +152.58.34.99 +103.92.43.103 +49.47.70.194 +103.178.209.4 +103.41.37.190 +106.210.176.179 +42.111.204.56 +49.42.83.223 +223.231.229.125 +223.189.207.149 +106.198.11.136 +117.98.36.106 +152.58.24.143 +223.238.96.73 +106.195.33.87 +49.36.208.172 +157.44.129.245 +157.45.95.153 +157.50.69.61 +157.37.157.246 +152.58.34.147 +106.207.170.31 +157.51.2.137 +157.47.101.19 +106.219.137.221 +157.41.225.126 +152.57.9.196 +47.29.161.35 +223.188.74.85 +157.48.82.74 +182.70.203.181 +106.76.245.177 +42.109.149.171 +1.187.180.192 +152.57.111.49 +106.215.234.165 +27.60.14.153 +49.37.152.197 +157.42.1.230 +157.42.0.25 +152.58.167.169 +157.48.175.127 +47.11.50.235 +106.223.94.91 +157.34.57.1 +106.219.93.174 +157.45.40.249 +223.187.143.43 +223.186.61.195 +157.33.101.154 +223.180.183.5 +106.216.126.29 +106.223.46.95 +49.35.181.237 +106.204.136.50 +49.32.171.148 +152.58.72.141 +152.57.189.66 +223.225.171.252 +152.58.3.236 +42.105.196.209 +112.79.251.13 +106.207.123.35 +49.43.96.225 +132.154.1.27 +47.15.18.222 +152.58.141.135 +223.227.65.225 +132.154.33.37 +27.62.152.135 +103.155.223.134 +106.207.165.254 +106.194.185.193 +157.46.70.255 +157.48.65.128 +27.59.244.41 +157.38.89.218 +47.15.191.223 +152.58.77.27 +157.35.44.243 +223.238.212.70 +116.206.201.41 +137.97.115.123 +1.38.122.21 +122.171.19.80 +157.34.80.35 +223.190.143.234 +47.11.249.251 +157.38.102.243 +49.32.249.241 +49.35.193.179 +152.58.138.111 +157.48.144.243 +47.15.10.253 +157.38.147.207 +223.188.21.174 +106.216.192.83 +49.42.92.185 +223.230.134.252 +137.97.99.134 +152.58.188.59 +223.228.178.72 +117.96.137.0 +110.224.121.112 +169.149.228.145 +115.96.162.133 +152.58.37.106 +103.148.21.101 +49.15.245.163 +157.38.104.192 +223.187.208.248 +47.11.238.25 +110.226.167.56 +117.98.58.89 +49.37.39.49 +47.31.141.42 +169.149.227.160 +47.9.143.120 +152.58.36.142 +223.239.26.240 +223.187.178.131 +152.58.24.206 +157.50.17.33 +157.38.54.15 +106.197.13.26 +223.187.2.35 +27.59.34.227 +49.35.249.252 +49.37.135.18 +157.34.38.193 +152.57.27.53 +223.187.121.7 +122.161.90.203 +106.203.142.127 +42.105.140.18 +106.216.122.38 +137.97.122.168 +106.194.187.16 +110.227.38.112 +157.50.66.196 +157.35.61.206 +112.79.125.124 +157.45.207.199 +47.11.224.170 +223.228.225.121 +106.196.16.46 +49.42.87.34 +157.46.180.245 +157.49.223.198 +47.15.217.7 +152.58.19.137 +157.49.71.117 +1.38.216.179 +157.41.250.186 +27.60.110.26 +157.47.119.121 +157.41.248.63 +157.44.202.65 +157.44.172.78 +49.42.83.106 +106.216.113.123 +223.239.68.195 +152.58.38.192 +106.221.252.23 +157.42.3.116 +27.63.10.145 +117.240.129.173 +42.105.194.120 +150.129.60.18 +137.97.117.154 +106.195.46.42 +169.149.230.140 +171.79.163.48 +157.35.93.137 +171.76.240.69 +157.38.117.223 +157.47.127.192 +223.237.60.175 +132.154.54.251 +132.154.59.206 +106.205.192.0 +157.51.4.87 +110.224.99.183 +157.34.89.133 +132.154.63.22 +157.46.68.50 +157.49.193.67 +106.203.156.125 +106.217.196.151 +223.196.192.168 +27.63.135.122 +106.76.198.18 +106.207.187.163 +152.58.23.230 +157.49.156.252 +45.118.157.162 +47.15.243.135 +49.34.48.104 +152.58.99.255 +106.208.178.114 +27.97.15.150 +49.42.95.96 +106.221.219.108 +157.48.134.52 +110.224.184.249 +42.105.237.40 +49.36.219.143 +101.0.62.153 +27.56.255.99 +103.161.98.92 +106.204.196.56 +117.204.82.128 +223.188.255.239 +117.96.168.39 +223.187.119.218 +106.223.47.129 +157.49.143.64 +103.171.247.189 +49.43.1.7 +223.189.188.198 +117.98.118.21 +152.58.186.64 +223.191.56.60 +157.38.73.237 +49.37.146.168 +106.78.93.247 +47.11.79.231 +223.228.185.9 +106.216.241.163 +223.181.235.181 +106.78.51.9 +1.187.220.240 +223.189.207.183 +114.31.184.137 +103.221.208.170 +106.222.52.3 +106.206.59.37 +223.239.62.124 +157.48.65.167 +223.176.15.130 +157.51.113.174 +47.29.171.116 +152.58.100.208 +106.205.198.77 +157.49.70.93 +106.221.95.217 +106.200.187.41 +157.32.202.167 +110.224.16.21 +117.220.57.53 +223.238.109.14 +157.35.62.122 +157.35.40.126 +180.188.247.196 +157.34.54.22 +47.29.165.220 +106.216.255.187 +112.79.58.249 +27.62.30.51 +106.197.119.251 +106.217.53.142 +152.57.208.210 +106.203.158.249 +106.197.97.153 +157.45.39.150 +157.34.82.10 +157.51.15.82 +103.104.47.16 +47.9.34.144 +157.44.158.45 +106.195.4.127 +103.242.199.89 +27.56.242.60 +223.239.64.61 +49.35.194.161 +49.15.201.127 +157.35.85.9 +132.154.49.99 +110.224.84.241 +157.34.1.196 +27.60.12.129 +42.105.164.168 +157.47.79.24 +49.34.247.207 +106.208.47.110 +117.98.96.130 +106.213.208.54 +157.47.10.159 +157.42.227.175 +106.221.248.49 +106.196.59.214 +106.194.83.26 +106.205.213.195 +117.98.38.159 +157.41.228.53 +157.38.148.121 +152.58.129.241 +117.246.173.160 +103.184.239.47 +106.206.191.105 +106.76.238.244 +223.231.81.115 +152.58.169.17 +117.253.108.159 +169.149.228.73 +157.45.202.141 +106.195.117.211 +202.142.71.84 +157.48.201.231 +103.253.149.118 +157.32.209.42 +157.35.50.20 +157.50.2.243 +152.57.108.247 +42.106.184.43 +152.58.31.119 +223.187.245.66 +202.8.118.239 +182.69.179.124 +157.33.61.189 +1.187.219.3 +223.239.39.90 +49.47.69.61 +223.238.52.158 +157.48.114.145 +47.29.175.4 +47.9.148.66 +182.69.179.140 +103.102.117.17 +106.193.60.10 +139.167.168.68 +59.91.115.14 +47.9.69.186 +106.211.38.157 +49.15.227.179 +49.34.51.69 +110.225.82.243 +152.58.59.41 +106.200.172.14 +47.15.176.208 +223.238.221.201 +157.32.198.121 +106.198.20.3 +106.78.52.141 +157.32.210.217 +157.44.150.163 +117.99.228.154 +157.33.118.220 +223.190.182.135 +139.167.221.187 +157.51.95.76 +139.167.217.195 +157.45.164.10 +157.40.118.6 +49.206.123.241 +223.191.2.119 +157.119.86.151 +49.36.213.116 +157.34.53.202 +117.99.197.24 +157.41.224.196 +106.216.122.60 +223.238.15.255 +110.227.136.140 +42.106.92.174 +110.224.167.2 +152.58.92.150 +205.253.122.31 +106.195.6.129 +110.224.102.207 +106.206.250.67 +223.176.53.8 +42.104.148.10 +106.215.163.30 +47.15.38.189 +117.99.239.202 +106.204.54.242 +47.9.64.13 +157.48.144.192 +47.9.138.46 +49.43.6.249 +157.34.56.197 +49.35.169.81 +157.45.232.98 +157.34.33.140 +132.154.59.192 +47.9.152.249 +157.46.146.123 +49.15.137.173 +103.26.51.42 +27.6.211.234 +223.238.113.152 +27.56.13.230 +157.34.244.99 +106.198.10.214 +27.61.136.230 +223.189.4.100 +106.206.244.140 +137.97.92.51 +157.47.47.198 +157.38.133.249 +152.57.217.45 +106.195.77.53 +139.167.165.218 +157.32.64.182 +49.15.242.248 +157.32.194.43 +42.105.202.183 +49.42.68.151 +27.62.219.147 +223.231.129.42 +106.196.39.33 +49.14.106.18 +157.47.84.51 +47.29.171.169 +202.168.86.18 +106.195.33.196 +157.48.117.95 +152.58.166.8 +223.191.5.140 +223.187.39.140 +47.15.35.142 +157.38.134.4 +223.187.247.71 +49.37.74.163 +106.205.189.95 +103.99.199.133 +157.51.196.35 +106.217.174.199 +152.58.163.242 +117.98.52.43 +27.63.135.50 +152.57.57.53 +47.15.116.190 +106.221.251.241 +157.38.219.121 +106.216.247.182 +42.111.216.122 +157.50.42.53 +103.110.145.51 +49.42.74.90 +157.49.183.190 +106.222.116.195 +117.230.153.124 +223.239.71.156 +203.115.68.163 +106.206.142.215 +152.58.113.171 +49.36.25.37 +223.227.108.134 +1.38.113.4 +49.34.101.14 +205.253.11.10 +157.49.130.63 +157.33.199.79 +157.34.60.107 +157.49.87.60 +49.42.95.137 +1.39.75.164 +152.58.200.167 +1.187.180.46 +223.189.4.1 +49.44.80.42 +49.34.198.217 +122.177.103.155 +1.39.97.154 +152.58.99.108 +223.185.69.152 +223.181.82.61 +157.47.4.209 +157.48.116.86 +157.42.4.158 +223.238.127.32 +223.178.213.160 +49.15.220.136 +106.195.33.17 +152.58.197.143 +223.225.240.64 +223.176.105.114 +106.217.198.180 +223.187.103.86 +171.76.254.205 +110.224.99.83 +106.219.15.68 +27.63.9.145 +103.165.20.69 +157.34.220.136 +117.233.133.55 +157.50.2.124 +122.161.65.104 +157.46.121.48 +49.35.179.81 +152.58.79.239 +152.58.166.21 +49.15.196.82 +47.15.119.40 +42.105.199.45 +27.63.11.17 +180.149.227.123 +106.198.103.10 +106.195.70.156 +42.105.16.165 +106.210.247.241 +124.123.185.31 +223.189.204.63 +152.58.208.109 +157.34.113.255 +103.211.12.43 +42.105.176.211 +110.224.107.19 +47.31.220.244 +171.76.241.133 +223.233.123.107 +49.14.164.41 +49.43.100.176 +47.15.96.239 +106.76.76.4 +157.39.75.18 +152.58.38.71 +152.57.198.239 +117.98.106.25 +160.238.92.198 +47.29.27.23 +152.57.31.126 +117.96.176.57 +157.48.113.83 +49.36.222.30 +157.32.33.67 +152.57.100.131 +152.58.236.146 +157.38.133.228 +106.203.129.49 +47.31.166.247 +223.228.74.217 +139.167.167.4 +223.191.27.173 +49.34.111.194 +144.48.226.149 +157.41.253.241 +157.47.116.217 +47.15.36.214 +132.154.20.191 +152.58.236.89 +106.207.40.77 +106.198.25.153 +112.79.120.43 +157.47.69.90 +110.224.169.5 +49.34.39.77 +47.29.161.232 +49.43.1.149 +157.35.19.139 +157.51.51.171 +106.194.230.190 +42.105.228.42 +49.37.202.49 +47.9.158.156 +47.15.42.46 +42.105.234.138 +106.221.86.86 +223.231.112.139 +171.79.176.115 +223.186.187.170 +42.110.168.59 +157.34.231.4 +47.9.75.228 +171.51.162.48 +157.38.6.12 +223.238.131.171 +223.237.100.177 +152.58.100.171 +106.221.246.247 +157.32.42.251 +106.78.51.251 +171.79.148.44 +14.140.192.101 +117.98.46.62 +157.50.67.216 +152.58.66.76 +157.45.217.131 +157.34.143.195 +106.207.36.165 +106.220.107.158 +103.244.244.120 +106.196.13.158 +49.43.43.148 +106.200.61.104 +171.79.187.192 +152.57.93.54 +49.42.90.2 +171.76.186.57 +42.111.107.13 +49.15.247.192 +117.252.136.252 +157.42.248.208 +106.211.88.19 +47.29.165.92 +49.15.241.147 +223.187.209.27 +47.11.89.37 +157.34.90.116 +106.79.204.141 +49.35.150.60 +122.161.242.229 +157.51.199.144 +223.228.224.142 +157.34.211.216 +49.42.89.112 +152.58.26.2 +152.57.47.136 +49.35.177.189 +47.15.223.40 +152.58.34.231 +157.40.93.187 +157.49.95.223 +49.15.247.145 +205.253.36.102 +137.97.69.173 +137.97.92.50 +152.58.223.126 +117.99.210.24 +49.14.115.178 +152.58.213.211 +152.58.189.224 +122.162.149.21 +49.43.155.176 +223.228.250.176 +106.195.33.144 +47.9.83.49 +157.38.239.178 +116.206.222.172 +157.34.82.171 +223.182.3.38 +106.208.100.51 +49.42.84.225 +47.9.36.52 +117.98.46.216 +152.58.23.153 +152.58.56.145 +103.158.149.143 +157.45.223.92 +152.58.168.88 +205.253.38.157 +106.223.147.72 +152.57.48.126 +106.195.114.254 +106.208.101.234 +157.38.128.212 +152.57.227.215 +49.15.193.180 +132.154.49.106 +106.216.71.97 +157.33.101.177 +157.44.199.136 +157.47.90.2 +106.207.48.68 +1.187.214.47 +171.76.240.161 +157.38.207.117 +223.228.91.144 +106.207.49.93 +27.61.70.180 +49.15.246.100 +157.40.123.216 +112.196.163.0 +49.14.153.11 +157.51.192.107 +157.38.144.46 +49.36.121.170 +157.51.198.148 +117.99.14.137 +47.29.163.189 +106.211.20.194 +152.57.128.26 +106.193.138.195 +1.38.93.239 +106.221.190.103 +110.226.204.105 +117.225.2.218 +157.35.63.71 +117.99.232.65 +117.230.164.102 +49.42.83.231 +157.47.2.9 +223.231.157.67 +157.33.63.126 +106.216.239.0 +152.58.208.220 +152.57.111.218 +157.35.81.75 +152.58.231.154 +132.154.150.79 +152.58.19.135 +47.11.11.129 +110.224.92.144 +157.45.198.86 +152.58.211.122 +49.35.177.122 +152.58.32.76 +106.217.144.217 +223.187.94.141 +106.205.219.146 +157.39.249.38 +157.41.225.137 +110.224.85.203 +152.58.17.85 +157.38.100.109 +152.58.235.52 +117.195.56.17 +49.35.232.81 +137.97.78.75 +47.9.128.235 +106.204.181.109 +157.41.244.216 +157.51.126.30 +106.76.223.111 +106.195.7.233 +152.58.214.52 +157.40.126.254 +117.98.60.7 +157.33.71.121 +157.37.187.59 +49.37.195.218 +157.42.7.115 +106.221.239.112 +106.76.249.220 +152.58.25.12 +157.44.205.136 +110.224.109.125 +49.37.36.113 +106.195.45.245 +152.58.71.107 +132.154.52.254 +157.48.213.118 +103.160.239.113 +47.9.158.86 +106.197.86.114 +157.41.226.184 +223.237.93.66 +223.239.106.14 +106.193.8.26 +106.203.156.78 +106.194.16.232 +106.195.70.244 +106.78.51.208 +49.37.220.250 +171.76.8.220 +103.70.197.166 +106.217.226.52 +152.58.38.174 +106.76.210.144 +157.45.70.241 +49.42.95.109 +106.203.143.26 +157.47.104.36 +157.47.21.144 +49.14.114.136 +117.246.133.124 +47.11.230.122 +157.35.41.75 +47.9.127.21 +27.97.72.101 +157.47.2.220 +132.154.53.76 +157.39.68.188 +106.200.47.69 +157.48.113.248 +49.32.174.196 +106.206.204.59 +43.231.242.250 +157.37.156.31 +157.48.71.34 +117.234.51.211 +49.35.131.186 +132.154.63.179 +152.58.190.15 +223.238.67.246 +152.57.166.213 +103.110.48.41 +42.105.168.201 +106.220.208.106 +157.48.130.111 +157.40.72.14 +157.46.110.153 +157.46.70.113 +117.98.104.50 +106.220.109.32 +157.34.43.53 +103.171.247.12 +157.42.241.62 +106.211.119.232 +157.33.71.179 +157.47.79.231 +106.204.195.41 +106.197.21.101 +157.33.16.175 +49.37.67.19 +27.60.11.68 +223.188.233.187 +49.35.225.165 +157.40.93.176 +223.190.157.125 +223.238.101.197 +49.42.95.218 +117.99.214.250 +47.11.207.85 +157.45.62.94 +157.42.4.46 +27.61.188.241 +157.41.225.2 +157.35.56.186 +139.5.27.187 +152.58.100.185 +157.45.240.231 +106.216.95.250 +27.59.255.5 +47.15.136.196 +106.206.244.71 +157.46.126.5 +122.170.198.123 +106.220.109.223 +223.238.25.113 +103.70.197.245 +223.179.216.210 +106.76.197.77 +205.253.10.151 +106.195.11.245 +157.47.17.239 +117.230.82.47 +157.47.66.232 +223.187.105.198 +49.36.16.26 +169.149.231.232 +223.237.51.61 +157.48.226.58 +157.34.80.122 +106.208.153.224 +42.107.224.51 +117.234.205.223 +157.49.228.85 +169.149.227.174 +157.48.137.163 +49.36.234.4 +132.154.175.144 +223.228.255.153 +132.154.52.204 +152.58.181.192 +182.68.136.117 +106.216.173.2 +1.38.220.25 +132.154.49.132 +49.32.181.85 +110.225.54.25 +106.208.103.190 +157.42.252.155 +152.58.56.129 +157.35.8.199 +49.35.180.149 +42.105.181.104 +157.37.159.103 +103.181.56.40 +157.35.83.241 +152.58.139.6 +223.185.91.234 +157.41.250.18 +49.34.97.60 +157.47.110.4 +27.62.244.48 +106.210.138.175 +42.105.92.228 +202.142.115.127 +47.9.32.118 +223.189.145.233 +157.49.218.108 +157.38.146.115 +49.42.87.231 +114.31.148.35 +157.41.225.228 +157.42.252.101 +223.239.17.116 +157.45.137.103 +152.58.139.193 +42.107.193.42 +47.29.169.242 +117.245.107.94 +117.99.225.64 +157.41.252.224 +157.41.228.136 +47.29.37.194 +157.32.33.252 +47.11.205.153 +103.189.57.43 +42.105.216.38 +106.215.151.191 +157.33.75.59 +223.238.71.50 +223.239.61.224 +132.154.189.185 +157.38.36.240 +106.197.45.179 +157.40.118.53 +157.34.65.73 +157.48.115.149 +47.11.194.48 +1.38.182.242 +157.38.222.69 +157.45.254.137 +152.58.39.47 +1.38.84.70 +157.42.5.234 +42.109.151.95 +47.29.99.101 +1.38.104.178 +49.35.251.32 +157.49.240.233 +106.219.12.99 +132.154.18.41 +106.207.38.42 +122.161.78.186 +223.187.100.86 +49.35.177.237 +49.32.237.4 +157.33.227.118 +157.45.38.57 +110.224.97.175 +157.50.69.253 +157.34.134.16 +157.34.110.199 +152.58.22.159 +42.105.101.148 +157.34.144.242 +42.105.14.185 +152.57.72.133 +103.203.144.111 +49.35.168.161 +49.36.185.124 +47.11.79.182 +223.231.172.228 +152.58.96.141 +157.42.0.160 +157.40.112.130 +106.216.204.208 +169.149.226.199 +152.58.32.7 +106.221.34.54 +223.187.42.58 +42.108.4.102 +152.58.72.48 +117.97.211.70 +106.211.47.212 +106.208.153.20 +157.33.216.230 +157.48.155.222 +223.233.20.134 +157.32.125.133 +157.50.4.56 +223.181.44.176 +49.43.41.77 +157.34.244.140 +106.221.245.177 +202.88.249.83 +114.31.128.144 +123.201.214.80 +117.96.231.32 +223.239.26.12 +47.9.82.30 +117.98.78.162 +110.224.107.48 +152.58.158.220 +42.105.235.81 +157.49.227.184 +223.185.120.206 +157.34.39.253 +49.43.96.111 +42.107.132.191 +223.231.227.65 +171.79.190.89 +42.106.176.121 +27.63.29.72 +223.237.36.5 +49.42.81.89 +157.33.36.206 +157.51.65.209 +152.57.87.194 +106.223.177.62 +157.32.213.92 +223.239.26.107 +157.33.231.22 +157.34.227.39 +106.77.78.92 +106.223.179.108 +157.34.9.40 +157.38.254.13 +157.51.101.140 +42.105.118.114 +106.217.152.77 +47.31.135.156 +223.176.49.225 +157.41.254.80 +157.38.147.38 +106.212.0.165 +106.196.29.47 +59.183.43.51 +106.66.3.222 +157.38.224.88 +106.195.114.109 +152.57.29.8 +117.99.236.219 +49.37.75.167 +152.58.183.57 +49.15.129.55 +157.46.76.153 +42.105.74.32 +1.38.216.159 +106.192.61.224 +157.33.233.17 +152.58.56.12 +47.9.70.101 +106.197.17.172 +157.35.56.59 +152.58.181.221 +122.162.146.108 +47.11.205.21 +49.35.150.47 +47.9.122.55 +45.117.180.132 +110.224.180.165 +106.196.28.51 +47.9.98.104 +157.48.67.11 +157.34.36.57 +106.76.95.185 +223.231.187.123 +117.96.140.210 +122.172.30.133 +47.11.208.247 +49.36.238.139 +106.216.246.95 +124.253.176.218 +157.47.13.70 +49.14.109.31 +42.105.1.130 +180.188.242.1 +152.58.196.141 +106.221.182.178 +49.36.219.127 +49.156.79.21 +117.235.231.26 +132.154.57.192 +106.215.150.13 +106.198.33.23 +47.15.18.45 +223.187.134.94 +49.34.186.93 +171.60.197.254 +157.49.73.67 +106.210.143.246 +47.15.42.216 +106.66.56.54 +223.238.22.81 +157.42.240.44 +157.34.231.160 +223.238.20.156 +49.34.54.17 +106.211.92.14 +106.76.236.167 +106.220.105.196 +223.231.182.60 +27.56.77.112 +49.36.232.244 +223.189.18.165 +106.216.250.103 +152.57.201.73 +110.224.118.225 +157.47.86.76 +106.207.24.51 +157.42.2.87 +157.48.168.81 +103.61.108.133 +223.178.110.250 +106.207.66.136 +106.78.184.127 +47.31.196.244 +49.14.131.243 +223.181.96.13 +27.63.11.157 +152.58.25.55 +152.58.59.139 +223.238.112.129 +157.33.90.219 +47.29.175.158 +223.237.107.75 +157.45.69.19 +157.38.12.125 +103.211.12.55 +152.57.254.70 +110.227.63.99 +49.34.185.226 +49.36.218.191 +152.59.64.175 +49.15.183.251 +157.34.140.236 +42.106.181.102 +152.58.226.146 +1.38.140.146 +42.105.138.153 +157.41.253.52 +157.47.96.133 +157.41.225.232 +106.79.134.30 +103.182.166.254 +116.72.20.62 +169.149.224.156 +169.149.228.201 +152.57.59.154 +47.29.168.68 +157.41.242.175 +49.42.83.253 +106.76.196.244 +106.198.101.62 +132.154.58.177 +47.11.92.132 +157.47.51.53 +106.210.46.2 +117.99.210.239 +132.154.155.228 +106.66.41.120 +152.58.34.0 +106.205.240.252 +116.193.134.197 +157.34.56.82 +152.58.109.241 +157.32.42.65 +157.51.23.146 +106.197.121.123 +106.208.7.143 +157.34.56.222 +27.61.70.35 +47.15.188.105 +152.58.21.129 +49.14.112.177 +42.105.211.144 +47.29.173.76 +157.51.114.52 +223.184.167.184 +169.149.226.172 +117.99.241.243 +157.41.243.223 +223.190.129.56 +157.33.126.110 +117.207.237.198 +157.34.93.204 +106.220.93.230 +223.231.133.246 +152.58.79.146 +27.62.167.239 +152.57.126.136 +152.58.80.61 +49.36.101.68 +157.34.129.103 +106.210.32.104 +223.188.42.198 +157.49.198.147 +106.221.245.25 +106.210.149.138 +157.49.89.7 +152.57.192.70 +157.35.20.169 +47.15.38.177 +152.58.38.48 +152.58.130.137 +106.207.6.183 +103.177.185.144 +157.49.229.146 +47.29.175.15 +106.216.230.34 +157.38.28.111 +49.15.201.235 +152.58.185.33 +103.157.183.179 +117.99.193.192 +106.197.143.207 +223.185.109.119 +110.226.193.236 +106.216.100.163 +152.58.130.86 +152.58.181.71 +152.58.165.54 +117.98.106.148 +106.79.205.168 +157.46.90.170 +103.195.16.72 +223.238.91.81 +157.49.75.171 +157.34.158.187 +152.58.34.149 +152.58.83.76 +157.46.129.182 +110.224.125.181 +49.34.70.171 +112.79.73.80 +223.230.163.147 +157.32.116.164 +117.97.74.200 +152.58.48.248 +169.149.229.74 +47.15.6.184 +106.206.194.252 +157.33.28.10 +47.9.137.206 +137.97.102.63 +157.48.112.238 +116.72.14.130 +157.47.122.37 +157.38.80.104 +112.79.123.15 +157.48.117.71 +223.191.18.218 +117.201.63.154 +157.38.150.79 +106.221.188.191 +42.105.225.29 +223.187.251.4 +182.64.82.251 +152.58.157.7 +49.15.185.107 +152.58.26.56 +117.99.211.231 +47.29.165.36 +103.55.98.109 +47.11.68.235 +152.58.58.248 +49.37.235.236 +106.220.255.225 +106.208.14.82 +122.179.61.50 +223.190.131.86 +152.58.142.48 +103.114.246.18 +157.41.198.217 +106.217.78.127 +157.47.94.24 +106.66.59.254 +106.207.41.200 +49.15.244.9 +117.98.110.59 +202.142.121.212 +152.58.163.163 +157.45.181.210 +152.58.24.210 +106.223.180.109 +106.211.10.169 +106.76.158.13 +106.210.221.238 +157.38.2.239 +157.38.134.132 +157.38.54.195 +49.35.227.131 +157.39.66.165 +157.34.199.194 +106.76.210.83 +157.47.63.238 +157.45.188.133 +106.198.104.195 +157.34.206.96 +157.34.133.240 +103.57.252.207 +106.220.96.179 +157.35.77.194 +49.37.54.51 +47.29.167.108 +103.172.253.65 +49.35.188.183 +106.220.91.120 +152.58.168.143 +112.79.124.103 +223.189.219.175 +157.33.234.119 +117.233.91.79 +132.154.25.12 +157.35.15.60 +106.211.141.35 +152.58.38.150 +157.42.218.144 +152.58.186.147 +103.57.84.35 +169.149.231.15 +137.97.67.171 +117.99.44.7 +132.154.162.119 +157.38.19.102 +157.44.191.212 +157.35.25.208 +103.121.153.111 +106.195.64.18 +106.195.2.65 +106.77.132.106 +223.187.121.208 +106.207.246.55 +157.42.246.59 +223.238.22.128 +152.58.150.234 +223.180.176.225 +117.196.55.245 +137.97.114.59 +157.47.114.243 +157.34.205.162 +47.9.72.15 +152.58.33.7 +47.9.37.229 +106.200.156.112 +157.45.81.191 +157.45.243.28 +157.45.85.149 +157.48.117.157 +106.210.36.9 +106.192.191.104 +152.58.132.117 +157.49.165.28 +45.117.67.130 +49.34.86.44 +49.15.232.70 +157.48.220.210 +169.149.226.156 +106.206.5.195 +223.238.195.185 +106.205.157.212 +157.46.169.88 +49.35.157.24 +157.40.211.82 +47.29.175.225 +205.253.38.247 +157.38.150.80 +157.33.250.48 +157.42.3.40 +110.224.100.214 +122.161.66.251 +152.57.66.89 +117.234.39.149 +223.189.206.73 +223.182.28.139 +157.32.215.37 +171.60.209.128 +152.58.98.119 +103.120.209.186 +47.15.23.169 +157.38.240.67 +152.58.27.71 +106.216.203.87 +157.34.3.175 +223.237.105.89 +47.31.220.81 +47.9.68.169 +157.51.134.144 +117.98.126.136 +43.225.195.163 +106.208.131.60 +157.44.202.132 +223.239.84.38 +103.195.201.123 +49.14.135.31 +152.58.150.131 +157.47.109.134 +152.58.31.252 +49.36.221.230 +1.39.114.78 +106.216.68.15 +157.41.225.18 +223.182.44.215 +106.206.162.72 +223.239.25.137 +106.220.67.136 +106.193.134.178 +157.35.75.192 +106.204.204.5 +152.58.96.7 +106.195.70.37 +106.216.195.52 +157.40.95.173 +137.97.123.247 +49.35.135.216 +27.62.137.30 +27.61.136.163 +157.33.221.139 +27.56.22.27 +106.206.131.157 +106.216.225.145 +157.50.66.29 +106.76.197.159 +47.15.14.19 +106.206.223.150 +157.38.104.175 +152.58.191.75 +103.54.27.157 +47.15.15.175 +157.35.58.42 +157.47.29.145 +152.58.38.92 +157.44.154.53 +42.108.28.15 +106.216.114.156 +27.62.160.68 +223.188.19.166 +49.37.98.138 +157.35.58.46 +106.223.178.191 +42.106.177.172 +157.48.112.117 +157.45.232.207 +27.56.86.239 +157.34.66.198 +42.105.234.34 +117.98.100.233 +49.32.139.188 +157.45.236.26 +47.29.166.152 +152.58.184.223 +49.42.94.156 +49.206.120.142 +223.225.246.123 +42.111.160.62 +171.76.193.164 +157.47.57.51 +117.98.4.100 +103.149.21.13 +157.48.114.51 +103.211.179.139 +106.216.115.190 +106.216.243.170 +169.149.199.97 +152.58.224.51 +157.33.248.215 +49.32.151.248 +152.58.197.98 +157.49.135.236 +47.29.160.94 +152.58.38.236 +157.37.178.98 +152.58.32.109 +106.202.67.82 +103.99.218.84 +110.226.179.236 +110.226.197.209 +106.196.100.161 +157.38.30.126 +106.195.99.253 +152.58.56.233 +152.58.225.60 +223.233.80.125 +157.33.5.87 +42.105.228.7 +103.140.27.119 +106.195.70.182 +157.41.229.71 +223.239.94.55 +152.58.159.14 +223.186.209.175 +106.204.48.181 +103.68.21.142 +157.47.13.164 +106.195.40.98 +49.14.159.31 +157.38.149.46 +106.221.188.246 +223.228.123.19 +132.154.56.199 +117.98.114.58 +157.50.67.88 +106.208.22.213 +110.226.199.131 +157.32.127.140 +223.189.224.235 +106.216.108.216 +223.187.33.183 +223.233.120.155 +106.206.129.184 +47.29.174.107 +157.48.225.186 +157.51.199.35 +106.223.156.69 +152.58.52.42 +223.187.170.92 +47.11.46.84 +47.11.252.88 +117.99.195.104 +157.50.67.255 +157.38.26.37 +223.238.111.219 +106.221.2.44 +157.40.118.58 +47.9.122.164 +106.195.12.214 +49.34.136.188 +106.208.196.141 +47.11.249.65 +157.38.39.129 +110.224.89.159 +157.38.145.121 +47.11.89.131 +157.32.237.151 +157.47.44.139 +203.81.243.154 +27.59.23.95 +47.29.18.230 +110.226.200.165 +106.197.94.225 +152.58.40.255 +223.187.187.116 +106.197.240.171 +106.221.153.235 +117.99.251.59 +183.82.207.36 +106.207.186.37 +117.98.122.51 +1.38.164.99 +117.99.225.85 +157.34.1.149 +110.226.167.254 +106.221.174.175 +223.187.111.196 +49.37.117.100 +169.149.229.201 +117.221.170.42 +122.173.18.182 +42.106.237.205 +106.210.168.94 +152.58.185.114 +157.37.219.117 +152.58.97.57 +157.45.233.209 +152.58.215.242 +27.60.106.136 +157.41.252.249 +42.105.140.85 +117.98.104.92 +106.196.16.118 +152.58.167.18 +152.58.135.227 +157.45.136.215 +106.76.242.163 +157.38.192.207 +157.48.245.161 +106.205.199.158 +106.78.53.181 +152.57.10.236 +49.36.218.215 +117.99.229.50 +157.35.78.146 +47.15.33.255 +110.225.34.209 +110.227.62.220 +152.58.100.198 +157.48.249.185 +157.35.43.130 +47.9.144.76 +223.187.125.97 +157.49.64.93 +171.51.153.134 +106.222.72.165 +42.105.232.202 +27.56.231.21 +27.61.103.139 +47.9.121.102 +42.104.133.10 +49.37.209.23 +49.42.87.87 +110.224.66.61 +1.187.214.43 +152.58.234.64 +223.189.61.70 +106.216.143.114 +117.222.203.228 +106.216.231.174 +106.221.98.103 +106.207.142.109 +171.51.147.152 +103.66.205.65 +106.192.158.75 +157.32.41.208 +157.39.75.134 +152.58.81.43 +157.47.93.187 +106.221.251.191 +49.32.146.134 +152.58.16.69 +223.237.119.247 +49.35.170.11 +42.108.17.6 +117.209.190.159 +152.57.74.102 +157.34.60.178 +49.34.139.95 +110.224.98.82 +49.36.233.29 +42.105.244.97 +157.38.63.168 +110.224.66.20 +117.98.44.71 +42.106.32.92 +106.76.241.254 +106.197.248.94 +223.228.157.40 +152.58.101.145 +157.41.240.69 +106.221.86.98 +42.105.102.94 +152.58.148.141 +152.58.76.158 +49.34.233.167 +137.97.101.219 +223.187.252.26 +47.15.165.43 +106.204.242.134 +157.34.87.181 +106.195.102.201 +45.115.89.220 +117.99.209.56 +152.58.155.109 +223.177.244.34 +47.29.165.218 +116.74.141.43 +47.31.203.122 +152.57.160.127 +157.42.211.255 +106.77.186.201 +110.227.50.5 +132.154.1.4 +106.208.230.53 +152.57.153.182 +47.15.204.46 +157.38.209.234 +171.79.148.59 +223.187.46.120 +132.154.12.109 +49.42.92.23 +157.34.146.112 +47.29.162.173 +106.219.156.204 +157.34.151.108 +157.51.24.121 +132.154.181.80 +42.105.49.30 +106.208.45.160 +152.58.121.41 +106.196.90.84 +103.87.59.25 +152.58.58.121 +157.47.48.139 +157.119.208.113 +49.43.202.113 +49.34.48.214 +49.37.74.123 +42.105.142.121 +49.34.104.64 +110.227.39.162 +110.225.32.231 +157.35.12.121 +106.66.40.105 +157.45.77.15 +202.173.127.23 +106.221.216.221 +106.198.87.52 +116.193.141.210 +139.167.187.73 +47.15.2.23 +117.98.38.109 +157.46.177.174 +117.99.233.93 +223.230.136.247 +157.38.79.244 +223.230.168.78 +205.253.127.24 +106.78.44.188 +122.179.116.250 +117.99.245.88 +152.58.166.93 +106.223.179.160 +106.203.140.15 +27.62.242.63 +171.51.144.178 +103.233.93.39 +106.211.66.29 +42.106.92.225 +106.196.23.127 +103.183.82.54 +117.230.84.111 +42.104.146.133 +49.37.24.142 +42.111.220.125 +49.35.191.147 +169.149.230.244 +152.58.197.192 +139.167.184.109 +27.57.201.137 +47.11.205.128 +157.34.148.1 +106.221.251.143 +152.58.106.196 +49.36.35.76 +157.33.234.82 +47.9.105.49 +223.231.224.218 +223.181.88.47 +157.38.199.39 +49.34.126.152 +47.9.70.106 +152.58.230.188 +152.58.168.234 +47.9.150.8 +106.208.158.36 +137.97.101.195 +137.97.106.227 +47.11.231.160 +49.34.173.87 +157.35.8.177 +157.38.150.211 +42.105.11.129 +106.207.250.45 +1.38.141.60 +157.33.118.114 +42.111.161.2 +152.58.179.84 +157.48.213.3 +152.58.37.70 +106.194.3.203 +157.39.72.11 +157.46.118.98 +223.189.243.62 +223.228.225.201 +157.50.8.196 +27.60.109.138 +152.58.73.51 +106.200.178.207 +106.211.19.57 +157.38.127.109 +152.58.38.233 +49.35.246.156 +103.135.63.209 +103.185.160.56 +157.34.193.87 +106.221.218.65 +202.8.119.18 +101.0.33.207 +106.221.93.61 +157.47.13.73 +106.202.55.14 +42.107.196.121 +157.40.105.213 +223.189.215.182 +49.42.86.194 +157.49.241.111 +110.227.63.255 +110.227.52.163 +223.187.103.156 +223.238.199.104 +114.31.148.129 +27.62.147.254 +103.211.14.142 +152.58.98.0 +157.33.248.127 +169.149.196.173 +157.50.67.17 +49.43.155.5 +157.37.157.138 +47.15.41.192 +106.204.33.109 +27.58.86.186 +49.34.201.190 +157.34.58.28 +27.56.31.135 +157.50.15.91 +157.32.86.37 +171.48.76.217 +152.58.197.61 +106.195.65.43 +157.42.212.57 +106.206.196.235 +157.44.142.115 +117.233.96.64 +157.45.181.209 +152.58.39.151 +157.48.137.98 +132.154.129.209 +47.11.210.179 +106.208.170.95 +152.58.70.142 +157.51.199.242 +106.205.48.161 +110.224.56.122 +152.58.226.175 +223.237.93.199 +106.194.34.238 +27.97.225.77 +137.97.98.121 +132.154.7.84 +103.220.212.96 +157.32.70.147 +223.231.138.12 +49.35.189.93 +106.76.220.94 +106.76.90.23 +171.76.170.101 +152.58.16.35 +106.223.2.191 +106.216.120.89 +49.35.246.198 +106.207.212.39 +157.48.236.15 +49.36.193.87 +150.107.21.220 +110.224.180.36 +115.97.100.255 +137.97.92.55 +103.251.59.124 +152.58.32.240 +49.36.169.142 +27.60.102.115 +223.190.143.144 +47.9.147.114 +223.185.102.0 +106.194.94.252 +31.13.127.19 +31.13.127.15 +116.193.141.51 +157.44.152.118 +31.13.127.9 +31.13.127.119 +31.13.127.1 +49.15.175.205 +157.38.154.239 +157.49.95.113 +106.217.154.134 +47.15.2.157 +157.48.114.70 +157.38.137.154 +117.220.3.113 +42.109.206.241 +157.33.47.9 +157.47.33.36 +157.38.55.178 +49.15.243.71 +157.32.87.17 +114.31.160.78 +157.35.45.37 +106.195.36.223 +43.249.235.19 +152.58.233.146 +103.167.127.110 +157.48.138.52 +223.236.169.101 +42.105.159.87 +49.43.99.161 +157.40.214.252 +49.15.209.250 +116.68.78.103 +120.88.34.99 +152.58.16.65 +157.42.2.157 +106.204.140.17 +27.60.101.108 +157.49.151.32 +152.58.231.122 +49.37.38.59 +152.58.185.92 +106.200.152.154 +223.228.234.110 +152.58.185.54 +49.15.247.249 +49.34.221.99 +42.106.185.217 +171.79.101.1 +157.51.54.247 +49.14.164.97 +42.105.212.229 +106.216.124.214 +157.34.137.241 +157.34.20.144 +117.235.104.6 +157.44.162.238 +152.59.65.147 +47.15.236.227 +223.190.176.91 +42.104.157.28 +42.105.77.80 +47.247.219.255 +49.42.66.133 +122.161.220.151 +157.34.95.161 +49.36.138.66 +152.58.186.190 +27.63.53.138 +106.211.63.128 +106.76.202.140 +137.97.75.75 +157.41.245.194 +157.34.26.151 +157.38.48.9 +157.34.127.71 +106.194.61.150 +157.51.196.2 +132.154.51.227 +223.185.107.130 +157.35.27.248 +47.247.223.168 +47.9.36.28 +117.98.66.100 +47.11.209.13 +223.238.215.198 +122.161.50.178 +106.221.183.3 +103.112.16.49 +103.70.199.76 +157.35.86.221 +152.58.71.240 +152.58.218.36 +47.15.166.237 +106.221.57.65 +106.77.92.152 +49.36.17.173 +117.98.100.166 +106.76.77.118 +117.230.82.146 +152.58.196.103 +106.77.77.116 +223.233.76.203 +106.221.86.177 +42.111.165.98 +157.48.141.239 +152.58.34.60 +106.205.193.0 +42.105.227.167 +157.38.252.224 +132.154.183.115 +171.76.229.98 +42.105.159.42 +157.38.19.108 +49.35.185.106 +47.11.201.162 +49.14.68.25 +110.226.162.219 +132.154.177.206 +157.48.172.115 +49.42.68.63 +223.231.92.89 +132.154.51.3 +152.57.236.251 +223.238.124.249 +106.208.144.111 +103.15.254.136 +152.58.34.241 +106.208.68.60 +106.203.145.9 +49.15.243.32 +49.36.211.169 +157.48.117.134 +42.105.129.109 +152.57.31.62 +106.196.3.137 +157.35.55.154 +47.11.211.242 +112.79.165.91 +106.198.148.43 +42.106.182.28 +157.33.203.233 +117.98.90.65 +47.31.96.209 +169.149.197.59 +223.233.68.130 +106.202.6.166 +106.221.41.108 +157.41.254.84 +223.231.189.10 +106.216.193.14 +152.58.31.214 +106.76.232.147 +110.224.90.25 +110.224.92.30 +152.57.246.104 +106.206.198.30 +157.47.91.202 +42.106.190.89 +114.31.138.148 +106.77.156.198 +157.35.72.186 +157.48.117.115 +49.32.248.188 +47.9.158.77 +157.33.114.49 +223.182.45.142 +223.180.178.170 +42.105.12.192 +110.224.74.219 +157.35.43.224 +152.58.17.133 +103.99.9.62 +157.51.30.60 +116.68.74.225 +49.37.146.33 +106.216.234.170 +157.47.13.66 +106.77.187.238 +117.97.212.140 +157.48.125.181 +103.92.43.105 +223.228.225.8 +132.154.35.168 +162.12.246.205 +42.104.146.12 +106.221.146.84 +223.227.77.100 +157.45.236.106 +47.29.167.208 +106.196.126.141 +157.38.99.86 +114.31.172.40 +157.34.130.149 +106.220.173.54 +223.189.191.247 +49.36.211.4 +47.29.166.93 +157.50.23.107 +152.58.153.254 +171.79.187.97 +49.34.36.73 +157.34.115.191 +106.211.19.35 +49.36.144.67 +106.203.103.168 +110.224.17.226 +49.42.82.100 +117.98.112.81 +223.187.184.209 +152.57.224.191 +49.35.156.216 +106.78.52.55 +49.37.99.21 +42.105.122.57 +49.43.178.154 +223.233.66.140 +152.57.139.130 +157.48.149.28 +157.44.223.249 +106.208.217.215 +27.59.36.142 +117.230.168.244 +106.215.221.192 +157.39.71.209 +42.105.133.84 +106.217.250.176 +110.226.167.71 +157.42.196.27 +132.154.171.198 +157.38.106.50 +106.211.21.240 +111.92.22.40 +49.36.193.160 +157.41.250.223 +157.49.81.24 +110.225.60.10 +157.51.3.240 +47.9.107.72 +132.154.32.217 +152.59.64.179 +157.41.254.24 +157.40.90.83 +49.42.64.185 +106.207.177.73 +27.63.223.249 +223.187.136.192 +157.38.107.28 +42.109.212.21 +205.253.37.42 +47.9.67.182 +157.39.67.44 +49.33.253.113 +132.154.39.10 +106.221.177.14 +106.76.252.126 +106.221.152.52 +223.188.70.70 +111.92.119.17 +112.79.252.148 +157.33.108.54 +103.121.234.40 +132.154.138.56 +223.182.244.126 +47.11.228.214 +106.207.228.158 +110.224.18.115 +157.51.192.158 +106.195.32.206 +223.239.61.178 +152.57.12.206 +49.15.247.24 +152.59.65.253 +61.1.79.103 +106.76.90.170 +223.231.147.199 +106.221.118.73 +157.45.240.145 +157.50.35.114 +157.40.66.25 +106.217.240.8 +157.38.29.153 +27.4.34.6 +106.216.201.65 +157.45.242.247 +27.62.206.40 +157.41.255.172 +106.78.46.30 +132.154.10.13 +157.35.24.220 +49.42.80.206 +27.63.214.1 +157.39.74.57 +171.60.194.5 +132.154.52.50 +152.58.56.231 +103.184.236.216 +152.58.82.45 +106.216.202.178 +49.206.118.180 +157.33.237.206 +157.41.228.105 +117.98.16.142 +49.32.134.228 +157.45.208.37 +49.36.26.94 +47.15.13.60 +169.149.199.4 +157.34.85.223 +117.97.68.181 +152.58.33.157 +223.238.192.234 +157.41.243.109 +49.34.136.13 +117.99.232.16 +157.35.0.10 +106.213.134.91 +157.38.69.16 +157.42.221.117 +47.247.195.194 +157.48.211.225 +27.62.241.127 +124.253.221.240 +27.97.45.169 +223.231.158.24 +106.79.200.216 +42.111.208.132 +152.58.142.115 +110.226.163.85 +106.196.51.98 +169.149.227.252 +157.41.255.184 +169.149.231.32 +117.99.254.247 +152.58.18.185 +157.47.7.128 +160.238.74.97 +47.29.167.70 +47.11.210.206 +175.101.68.52 +157.38.55.193 +157.47.28.144 +157.39.75.102 +152.58.107.236 +157.33.209.253 +103.122.6.50 +132.154.176.140 +42.105.159.81 +152.58.99.31 +47.29.164.119 +152.59.67.5 +47.11.211.189 +223.237.96.103 +152.57.237.127 +157.46.111.69 +42.107.65.244 +106.221.59.101 +117.99.21.2 +157.41.225.82 +42.106.176.29 +106.206.110.142 +182.69.179.67 +136.185.66.211 +106.211.51.139 +117.98.118.29 +110.224.161.34 +152.58.234.170 +157.32.41.60 +49.36.169.102 +152.58.215.165 +157.49.180.166 +106.77.76.16 +157.32.40.35 +223.239.77.87 +157.50.12.94 +171.51.154.25 +47.15.7.143 +152.58.26.114 +157.48.169.214 +157.34.62.74 +106.206.197.65 +122.162.150.172 +223.182.10.226 +152.58.34.243 +157.34.249.124 +157.45.226.155 +157.34.26.128 +49.42.65.213 +157.39.66.122 +42.110.136.18 +223.238.70.253 +42.109.196.62 +169.149.226.144 +132.154.59.202 +106.66.41.1 +157.42.250.99 +49.42.81.219 +103.92.43.180 +171.79.144.183 +122.161.241.16 +157.51.193.158 +27.61.189.130 +49.35.151.178 +117.225.234.36 +117.99.208.254 +27.97.32.253 +157.48.214.43 +106.77.162.50 +157.40.242.32 +106.194.76.115 +110.224.74.190 +152.57.61.34 +106.221.244.253 +223.187.119.97 +152.58.32.2 +49.35.192.189 +157.44.190.33 +152.58.221.143 +132.154.159.182 +47.15.251.156 +103.181.40.122 +106.211.9.70 +42.111.192.113 +152.58.74.42 +223.233.33.98 +152.58.121.53 +223.187.32.155 +106.223.102.209 +117.96.180.0 +152.57.146.56 +139.167.247.241 +106.203.131.181 +157.34.25.106 +117.99.210.148 +117.97.245.118 +157.50.34.45 +47.31.227.75 +157.35.44.246 +47.11.211.166 +223.187.151.139 +157.45.171.238 +223.227.55.209 +157.34.103.149 +49.34.133.203 +49.35.248.46 +157.32.35.86 +117.99.217.207 +152.58.158.170 +49.14.134.30 +106.216.118.246 +132.154.59.30 +106.207.64.83 +103.50.82.104 +223.238.139.134 +103.101.100.129 +115.97.137.153 +223.238.194.212 +27.56.86.36 +49.15.213.91 +139.167.221.2 +27.59.160.93 +132.154.35.202 +223.188.170.137 +152.58.70.89 +223.227.53.133 +223.238.208.0 +45.118.105.181 +157.47.58.56 +47.15.185.99 +223.178.211.86 +157.42.254.151 +49.15.249.233 +223.239.104.25 +106.193.18.2 +152.58.180.66 +122.161.67.32 +205.253.122.99 +106.217.22.113 +47.29.173.9 +106.202.118.163 +223.187.25.47 +157.42.210.27 +223.186.211.81 +27.62.148.168 +223.176.11.76 +106.78.93.223 +157.35.56.101 +103.42.157.47 +223.187.67.0 +106.221.146.201 +223.190.157.251 +157.48.127.10 +27.60.205.82 +137.97.73.127 +223.187.77.157 +152.58.188.107 +106.206.63.26 +132.154.175.210 +117.99.224.13 +49.33.235.38 +157.42.229.229 +157.34.13.192 +106.77.134.170 +157.47.19.65 +49.42.69.0 +117.98.66.7 +47.15.3.18 +117.98.58.8 +223.187.103.166 +157.45.37.162 +223.226.206.81 +157.33.235.100 +175.101.68.55 +106.207.173.254 +132.154.34.15 +157.38.129.155 +110.224.92.190 +49.205.34.51 +117.212.143.70 +116.68.83.9 +27.61.28.212 +171.48.92.216 +27.60.248.1 +49.43.101.95 +106.221.113.61 +223.233.10.153 +112.79.113.127 +223.237.120.196 +47.15.158.158 +106.206.25.229 +223.187.71.250 +106.194.89.104 +157.40.100.35 +110.224.161.154 +223.231.163.63 +152.58.98.106 +106.66.59.35 +152.57.112.97 +106.221.88.40 +132.154.135.249 +223.181.16.70 +49.34.178.34 +49.37.91.25 +42.108.4.14 +42.104.129.22 +117.199.47.76 +223.238.211.9 +157.48.204.97 +103.253.202.221 +106.216.113.59 +152.58.72.206 +223.186.30.206 +103.70.197.67 +223.189.185.128 +106.194.0.161 +157.48.150.62 +106.66.57.56 +106.76.76.38 +49.14.134.206 +157.49.189.8 +157.47.96.207 +223.185.124.46 +106.196.30.63 +117.98.32.208 +157.32.40.99 +157.47.4.110 +106.221.165.61 +103.48.181.33 +202.179.69.144 +45.127.45.9 +157.42.0.7 +1.38.140.192 +157.38.15.33 +42.106.217.57 +152.58.73.230 +106.207.136.94 +47.247.196.11 +132.154.54.176 +157.34.40.58 +171.60.213.236 +117.96.174.29 +152.57.39.221 +137.97.122.158 +157.34.28.12 +49.32.247.115 +157.51.147.186 +117.99.215.230 +152.57.169.217 +157.32.114.250 +27.62.30.244 +152.58.188.219 +117.99.194.23 +49.35.192.220 +157.51.194.0 +171.76.240.254 +139.167.250.24 +47.11.193.121 +106.222.122.241 +27.62.249.209 +223.225.1.180 +152.58.34.79 +157.48.215.238 +47.11.62.186 +157.34.7.75 +106.194.221.144 +106.194.181.55 +106.207.163.90 +117.230.175.78 +223.225.168.45 +157.48.78.89 +157.49.151.4 +223.230.158.173 +157.48.253.114 +42.109.206.22 +132.154.33.201 +157.45.89.200 +157.45.60.81 +106.217.76.113 +223.233.50.89 +157.32.114.153 +117.98.120.142 +157.34.144.220 +157.35.27.118 +171.51.141.109 +157.38.74.100 +139.167.252.140 +157.51.192.239 +42.105.129.194 +106.76.210.230 +157.42.245.4 +42.106.33.168 +157.48.251.126 +42.107.132.47 +106.216.203.119 +152.58.71.153 +157.45.178.116 +49.36.71.10 +110.227.58.26 +110.224.188.105 +49.35.150.119 +157.38.148.232 +106.77.79.78 +49.32.167.234 +152.58.83.187 +47.11.203.251 +106.193.174.206 +114.31.150.16 +47.9.156.90 +157.34.30.244 +157.38.90.223 +117.201.115.22 +47.247.199.37 +27.63.202.217 +157.37.173.30 +106.198.41.249 +106.203.155.243 +223.233.6.199 +180.188.243.179 +115.96.72.131 +1.38.52.3 +110.224.72.205 +157.35.41.241 +106.194.158.87 +157.34.146.180 +106.211.43.150 +152.58.134.50 +152.57.114.202 +152.58.200.252 +223.239.121.110 +117.96.186.36 +117.99.219.23 +137.97.105.24 +157.35.50.51 +152.58.167.63 +171.76.247.157 +106.220.167.100 +106.211.43.156 +47.15.14.233 +157.42.225.58 +27.63.208.163 +157.34.116.79 +49.14.130.102 +27.61.141.4 +152.58.159.25 +152.57.26.148 +117.98.44.67 +223.233.17.252 +106.78.52.115 +152.58.183.200 +223.227.53.164 +117.225.168.191 +1.38.80.117 +157.33.250.31 +106.195.76.27 +132.154.56.101 +42.105.206.23 +47.29.165.146 +157.38.111.70 +157.39.64.28 +157.34.91.102 +106.192.69.194 +157.32.37.25 +223.176.37.124 +183.82.163.140 +169.149.227.179 +223.187.64.52 +152.57.200.239 +152.58.129.140 +157.40.71.130 +157.48.129.66 +1.39.109.165 +110.227.10.176 +203.109.45.40 +157.34.0.59 +103.102.99.241 +42.106.76.49 +132.154.38.35 +106.198.33.28 +157.35.66.1 +49.42.91.45 +132.154.48.250 +146.196.32.75 +150.129.55.136 +49.37.73.79 +132.154.61.112 +106.79.168.95 +152.58.234.239 +49.34.204.207 +106.195.0.191 +106.223.180.145 +27.63.28.86 +223.181.56.172 +110.224.109.76 +157.34.76.129 +106.220.152.192 +116.74.132.158 +122.163.135.11 +157.50.67.141 +157.48.209.70 +106.217.170.234 +106.194.20.87 +169.149.194.140 +223.228.15.113 +117.98.36.254 +157.41.192.203 +49.35.138.160 +157.42.203.115 +106.210.131.159 +157.38.132.37 +122.178.52.108 +42.105.205.4 +223.228.68.99 +106.216.77.165 +157.38.55.118 +117.96.173.238 +42.105.73.38 +157.35.57.98 +180.188.236.253 +157.38.206.223 +106.198.30.7 +223.225.125.144 +152.58.66.77 +42.105.97.126 +49.35.253.110 +122.172.81.217 +157.40.103.186 +223.238.115.7 +157.38.91.66 +106.79.207.23 +106.200.23.136 +157.39.68.94 +157.33.253.161 +47.29.166.191 +47.11.24.218 +152.58.184.212 +27.61.165.118 +157.48.143.66 +117.99.206.222 +110.224.24.200 +157.48.206.235 +157.38.98.208 +106.213.235.212 +152.57.173.44 +157.49.212.140 +47.15.39.22 +47.11.204.54 +132.154.62.156 +49.35.194.67 +157.45.212.196 +152.58.188.60 +119.42.59.225 +27.97.79.60 +157.37.187.64 +157.41.229.246 +157.49.255.221 +157.45.236.154 +106.223.28.4 +106.197.118.84 +111.92.30.116 +132.154.61.150 +157.50.50.31 +106.193.230.227 +223.186.13.24 +157.34.28.222 +157.49.215.113 +106.77.191.29 +157.50.41.194 +49.42.64.246 +106.216.254.68 +152.57.64.231 +49.42.67.123 +157.51.193.9 +106.221.213.14 +157.38.64.249 +49.42.37.232 +117.99.219.55 +152.57.66.184 +49.35.236.76 +157.42.196.18 +106.76.89.50 +110.227.51.20 +157.45.225.220 +157.39.242.161 +106.194.38.205 +157.34.148.207 +223.188.76.86 +47.11.197.159 +223.233.85.169 +223.187.81.182 +47.9.110.22 +49.34.35.131 +132.154.9.65 +49.34.80.159 +223.237.8.96 +157.44.177.133 +223.239.57.208 +106.211.211.250 +205.253.37.157 +157.34.226.94 +49.35.254.173 +106.196.10.74 +157.48.146.99 +152.58.38.188 +152.57.72.50 +49.36.210.108 +47.11.200.182 +47.9.36.234 +157.40.246.187 +106.79.202.134 +223.188.232.73 +152.58.31.81 +103.175.169.43 +42.110.166.145 +106.198.29.42 +106.76.90.229 +49.34.195.68 +223.187.96.226 +157.38.29.178 +205.253.35.235 +103.134.161.99 +223.190.140.103 +49.37.113.84 +106.216.123.69 +106.221.49.0 +171.79.160.95 +106.204.197.169 +152.58.197.180 +47.15.14.167 +157.48.247.252 +49.36.235.231 +157.40.73.107 +132.154.60.110 +152.58.59.99 +139.167.181.122 +157.50.10.41 +152.58.188.113 +132.154.58.82 +49.32.174.216 +112.79.113.52 +47.15.8.163 +157.33.38.238 +223.189.192.62 +157.35.1.200 +42.104.156.136 +45.121.2.29 +49.14.153.15 +223.182.27.172 +47.9.37.117 +103.98.209.192 +47.9.78.98 +157.45.152.52 +152.57.211.112 +157.38.150.10 +42.105.203.232 +157.42.5.128 +152.57.240.180 +157.47.46.224 +223.189.235.158 +106.193.13.192 +157.48.89.236 +223.237.9.29 +106.202.56.158 +49.15.163.164 +157.39.74.155 +106.206.225.34 +106.193.24.18 +106.221.2.73 +157.38.135.130 +42.105.201.2 +157.48.166.183 +47.29.9.92 +110.225.60.213 +101.0.33.143 +106.208.153.38 +42.105.169.33 +42.104.213.210 +103.38.13.46 +152.57.170.248 +117.99.199.88 +47.9.86.2 +157.34.221.51 +106.221.249.190 +223.185.110.76 +152.58.209.249 +157.32.37.101 +223.228.244.249 +106.200.189.169 +106.197.66.57 +47.29.7.18 +106.195.64.66 +157.38.223.185 +223.225.244.152 +110.224.85.186 +117.98.112.46 +49.43.96.173 +157.48.186.95 +157.37.148.212 +47.11.46.54 +157.47.115.26 +110.224.93.53 +157.39.75.106 +157.48.112.145 +152.57.225.182 +49.34.226.118 +1.39.116.23 +152.58.200.242 +157.47.110.76 +117.98.116.16 +157.33.94.26 +117.208.97.58 +106.221.153.220 +27.61.70.249 +106.195.39.239 +111.92.45.239 +106.76.197.101 +152.58.157.8 +42.109.211.153 +157.39.227.52 +157.35.46.205 +152.58.162.189 +157.48.163.25 +223.228.70.158 +152.58.235.115 +47.9.123.179 +157.34.28.216 +47.11.209.102 +169.149.224.48 +132.154.59.77 +152.57.96.183 +47.31.97.22 +152.58.58.95 +157.48.116.155 +157.48.201.76 +47.11.202.34 +106.206.182.167 +106.206.207.212 +106.206.173.24 +157.32.85.238 +117.99.209.89 +49.42.64.82 +157.32.34.215 +1.39.114.228 +27.56.92.11 +47.9.104.167 +47.11.85.155 +117.99.44.227 +157.40.104.162 +110.226.177.78 +171.48.122.184 +223.225.249.245 +223.186.5.182 +49.33.253.61 +103.55.98.84 +117.230.162.72 +49.35.172.216 +49.44.81.201 +106.205.180.242 +157.41.250.79 +152.58.34.190 +42.111.12.192 +157.35.92.91 +106.221.145.180 +137.97.90.34 +157.32.221.171 +106.221.85.79 +132.154.39.145 +106.221.222.125 +152.57.174.134 +47.11.206.87 +157.47.88.233 +169.149.226.45 +106.76.231.162 +49.36.214.60 +49.43.98.248 +157.39.72.207 +152.57.36.16 +27.61.91.141 +157.51.49.146 +223.235.127.60 +110.227.62.170 +157.34.229.205 +110.224.186.157 +157.45.174.151 +106.196.4.153 +157.48.197.23 +152.58.213.83 +103.153.104.75 +171.48.110.182 +47.15.2.147 +223.181.204.166 +27.62.97.135 +132.154.176.127 +157.49.233.208 +47.15.6.239 +49.34.92.87 +49.15.89.19 +106.203.16.162 +110.226.167.135 +152.58.236.40 +157.38.20.82 +103.70.197.219 +223.181.74.228 +106.195.64.239 +110.224.93.204 +110.226.183.66 +150.129.181.5 +49.15.228.131 +117.98.70.66 +106.221.253.19 +152.58.197.49 +223.187.1.25 +106.216.196.108 +1.38.220.91 +47.31.164.0 +106.77.156.143 +223.189.196.141 +117.98.120.76 +157.47.67.88 +152.57.178.31 +110.226.182.61 +152.58.223.61 +114.31.139.56 +152.58.212.87 +152.58.143.109 +157.41.228.76 +223.187.108.134 +106.207.151.253 +157.45.231.17 +157.40.84.237 +106.197.6.34 +139.167.176.16 +106.203.144.248 +132.154.62.67 +27.61.160.114 +157.42.233.134 +152.58.25.87 +106.195.2.69 +106.76.89.220 +157.46.97.18 +106.206.248.217 +157.33.4.97 +157.32.102.100 +47.247.209.227 +122.171.22.64 +117.233.85.133 +49.34.183.182 +157.33.36.82 +47.15.7.237 +152.58.99.236 +223.227.29.187 +157.37.189.57 +47.15.43.147 +59.178.82.143 +49.32.178.48 +157.44.141.170 +152.58.82.137 +223.228.138.14 +42.111.11.108 +106.193.190.123 +110.226.160.182 +223.238.107.57 +47.11.38.144 +152.58.201.40 +106.206.252.78 +106.193.34.45 +106.205.166.95 +49.34.136.232 +42.105.129.212 +106.195.46.200 +47.9.148.221 +136.185.99.85 +223.186.234.0 +106.222.28.226 +49.37.37.223 +223.238.125.118 +132.154.175.120 +157.51.194.232 +106.216.249.171 +106.202.2.165 +157.34.9.210 +106.195.4.52 +49.15.247.29 +132.154.48.104 +106.194.46.14 +152.57.23.189 +157.49.244.155 +47.31.150.150 +49.34.70.50 +106.219.50.192 +47.247.204.99 +157.42.1.112 +106.78.54.69 +49.35.229.70 +152.58.184.152 +110.226.200.245 +112.79.60.197 +223.182.45.203 +47.11.52.88 +47.15.34.117 +157.48.114.222 +157.35.84.90 +223.182.62.144 +117.230.157.38 +223.239.25.48 +27.62.164.63 +157.38.134.93 +117.99.197.240 +1.38.165.129 +223.225.171.180 +223.187.177.0 +27.60.246.187 +152.57.38.247 +106.216.224.10 +106.197.167.194 +106.220.157.150 +117.98.38.73 +157.49.192.250 +223.228.179.41 +49.34.166.24 +106.223.152.108 +152.57.38.212 +152.57.106.77 +43.229.88.189 +157.48.151.84 +152.58.56.220 +106.207.254.211 +223.233.71.236 +157.32.255.169 +106.77.79.9 +106.192.131.109 +110.224.169.223 +152.57.168.73 +223.228.184.124 +152.57.23.56 +171.51.190.153 +42.105.133.74 +42.108.196.199 +1.38.140.60 +223.182.4.117 +49.34.151.151 +110.224.78.142 +1.38.92.78 +47.15.6.227 +106.79.205.8 +169.149.198.140 +157.45.203.77 +157.41.250.77 +157.34.141.111 +152.58.70.146 +117.204.80.107 +106.217.175.111 +47.9.64.109 +106.196.16.107 +106.193.59.156 +157.45.156.47 +47.9.139.233 +117.96.170.166 +106.77.182.251 +47.29.167.214 +117.226.169.180 +103.158.144.157 +49.35.188.75 +49.42.88.184 +139.167.236.26 +152.58.72.229 +169.149.226.181 +132.154.139.204 +106.76.70.82 +49.42.92.126 +157.48.163.65 +157.40.200.226 +152.58.152.5 +106.77.132.14 +152.58.219.214 +152.58.96.51 +49.35.159.203 +49.34.161.182 +47.9.80.248 +106.211.14.13 +157.50.49.30 +157.34.207.43 +49.32.161.18 +106.223.59.37 +117.96.253.97 +49.35.192.228 +106.205.199.218 +47.15.97.135 +27.61.249.244 +157.34.15.198 +152.58.83.169 +47.29.101.112 +150.129.102.123 +152.57.209.88 +112.79.127.142 +103.249.236.22 +157.38.200.56 +117.96.185.63 +152.57.37.105 +223.228.4.143 +49.42.93.154 +157.119.214.25 +157.35.89.211 +152.57.92.98 +106.196.2.190 +49.35.235.21 +223.187.157.33 +49.34.59.156 +157.38.35.198 +42.107.83.113 +152.58.236.56 +106.211.91.247 +152.58.191.109 +101.0.42.232 +47.15.179.175 +157.38.40.162 +152.57.243.184 +59.89.26.163 +106.197.107.88 +49.205.231.34 +47.15.22.208 +157.39.74.217 +157.38.157.175 +157.34.148.79 +122.162.145.35 +42.105.164.38 +152.58.157.93 +157.33.237.32 +106.206.197.125 +223.225.24.233 +47.29.169.92 +27.61.223.72 +42.106.176.125 +157.51.75.194 +223.233.12.88 +27.61.205.179 +117.205.28.145 +223.228.61.119 +157.41.252.98 +106.76.90.171 +42.108.165.106 +117.99.232.121 +223.227.84.90 +110.225.37.206 +160.238.74.50 +49.35.225.108 +110.224.91.191 +157.42.4.241 +47.31.243.21 +152.58.34.117 +42.106.92.182 +157.38.139.94 +106.207.115.0 +42.105.139.16 +152.58.58.3 +49.42.73.97 +157.34.107.172 +42.106.32.168 +47.29.174.157 +106.221.78.56 +106.200.36.51 +157.48.148.176 +27.59.130.147 +157.34.72.219 +223.238.108.135 +157.38.134.149 +157.49.150.195 +1.39.114.118 +117.99.196.92 +132.154.50.61 +110.224.70.94 +106.195.79.206 +157.32.105.160 +117.98.90.53 +132.154.157.251 +157.50.10.149 +49.34.99.254 +157.48.137.218 +47.29.165.171 +117.99.236.130 +42.110.160.14 +49.14.108.245 +223.180.185.232 +106.76.244.179 +157.38.94.159 +106.203.80.25 +101.0.35.50 +103.251.51.162 +42.109.196.13 +157.42.254.202 +139.167.222.92 +139.167.255.63 +117.233.86.170 +49.14.109.117 +157.38.208.235 +152.58.188.30 +157.44.151.125 +157.40.221.179 +27.56.17.127 +152.58.27.205 +157.51.97.37 +47.11.196.241 +49.42.67.150 +106.211.25.125 +110.224.75.186 +157.51.198.173 +27.63.85.168 +157.42.228.67 +157.38.240.239 +223.237.141.135 +223.187.70.11 +49.15.243.226 +106.197.242.33 +42.105.14.220 +152.58.212.24 +171.51.170.200 +117.228.64.82 +106.195.127.9 +106.76.233.165 +223.182.102.60 +157.38.152.242 +117.236.179.165 +1.187.216.220 +103.167.123.109 +223.181.219.83 +223.189.183.236 +157.39.75.201 +157.38.129.25 +106.216.125.235 +59.98.23.68 +117.98.98.177 +49.42.92.148 +49.35.135.170 +42.105.133.227 +157.38.19.37 +157.38.236.21 +157.33.210.155 +106.207.132.210 +47.29.166.43 +157.50.66.6 +49.35.234.215 +106.206.195.66 +173.252.79.118 +173.252.79.7 +110.224.119.53 +173.252.79.6 +173.252.79.119 +173.252.79.9 +49.37.53.135 +117.98.106.71 +152.58.225.166 +27.61.46.187 +223.231.198.135 +117.96.139.42 +157.34.252.9 +49.35.168.164 +49.15.184.5 +106.196.31.245 +223.187.211.94 +152.58.132.57 +106.195.14.20 +49.15.229.71 +122.171.16.119 +49.37.213.20 +49.34.135.85 +157.33.10.8 +157.48.114.45 +223.228.228.58 +223.190.248.43 +49.34.161.175 +117.230.91.166 +152.57.189.226 +106.211.9.169 +42.107.76.14 +223.231.121.63 +157.41.228.2 +106.220.175.72 +42.105.238.34 +42.105.208.45 +110.227.49.116 +42.111.241.90 +27.61.190.68 +157.41.254.242 +106.216.236.160 +1.38.96.23 +157.38.15.229 +223.187.180.199 +117.99.206.144 +47.15.15.111 +157.41.248.193 +49.37.53.200 +106.216.253.22 +223.238.112.86 +169.149.199.16 +157.50.1.204 +47.15.249.240 +49.14.133.69 +106.204.195.97 +27.63.68.65 +117.98.62.99 +132.154.173.235 +152.58.213.147 +49.37.48.252 +112.79.246.241 +27.62.214.224 +106.202.235.19 +106.205.206.221 +171.76.146.150 +49.14.156.133 +106.77.76.212 +49.35.130.198 +157.38.137.96 +106.220.149.3 +117.208.98.132 +122.161.242.27 +106.215.225.13 +42.110.245.18 +101.0.38.193 +49.37.37.63 +157.38.223.205 +103.40.199.150 +157.42.3.172 +157.38.137.12 +49.42.83.173 +132.154.53.240 +152.57.134.147 +157.32.74.19 +157.33.72.14 +42.105.211.39 +157.49.198.201 +169.149.228.66 +103.212.147.243 +157.48.91.2 +157.48.125.198 +110.226.200.95 +106.194.158.247 +171.60.208.178 +47.11.208.174 +103.178.205.19 +103.161.99.80 +157.38.97.195 +42.108.126.6 +103.211.18.230 +49.15.221.30 +106.216.251.84 +223.238.207.89 +27.97.248.93 +157.34.25.85 +49.35.233.178 +49.14.114.72 +106.196.2.70 +47.15.199.208 +49.34.53.231 +157.39.70.238 +112.79.122.232 +27.59.146.12 +171.51.185.162 +157.33.14.132 +117.99.213.231 +42.110.201.19 +117.98.54.116 +42.105.196.185 +106.206.199.61 +47.9.37.88 +223.187.132.158 +157.45.235.219 +42.104.156.66 +223.238.111.166 +27.63.223.209 +47.31.173.68 +157.40.118.2 +49.205.121.168 +157.42.212.106 +152.57.31.174 +157.49.235.54 +106.193.139.235 +152.58.138.249 +117.98.108.161 +49.35.192.119 +103.238.110.28 +157.35.46.112 +157.47.37.219 +49.14.157.161 +223.238.142.165 +117.98.92.123 +223.238.23.70 +157.38.91.111 +49.43.155.134 +152.58.202.136 +49.42.64.53 +157.34.87.68 +157.34.121.157 +106.77.128.210 +152.58.156.134 +157.51.53.61 +117.99.204.228 +223.191.57.28 +116.74.105.239 +106.195.99.177 +106.77.186.102 +103.241.226.208 +157.34.27.134 +49.36.222.199 +103.214.62.210 +132.154.34.101 +223.237.168.156 +106.196.27.226 +152.57.81.60 +152.57.2.112 +106.195.121.129 +171.50.176.69 +152.58.157.123 +210.89.62.110 +47.15.188.55 +223.182.60.8 +157.38.134.24 +171.76.244.242 +110.224.19.252 +169.149.225.174 +152.58.93.30 +110.224.178.44 +106.216.248.69 +106.194.42.131 +157.35.49.25 +110.224.98.162 +152.58.232.75 +49.37.33.149 +27.61.117.65 +152.58.4.221 +1.39.252.79 +157.35.14.69 +47.11.62.18 +157.45.85.251 +27.60.38.149 +157.38.67.238 +157.41.250.47 +157.33.15.126 +103.190.5.119 +47.29.174.28 +47.31.238.61 +152.57.207.179 +47.11.59.192 +106.196.20.179 +110.224.89.254 +27.6.219.104 +157.51.90.245 +157.34.111.2 +169.149.225.95 +157.35.61.64 +1.187.56.41 +157.42.242.125 +157.48.177.154 +157.42.2.111 +110.224.106.18 +157.49.248.58 +106.211.195.67 +122.175.127.249 +106.210.104.158 +49.43.99.70 +42.105.238.56 +223.231.200.159 +157.33.210.122 +152.57.98.71 +106.202.11.73 +157.45.211.221 +157.41.249.8 +152.57.217.216 +152.58.169.139 +106.221.51.178 +152.58.189.187 +157.41.227.121 +223.233.32.153 +157.42.255.239 +205.253.39.98 +157.46.66.26 +157.44.154.4 +152.58.155.15 +157.39.65.120 +157.51.8.41 +106.221.239.69 +110.227.44.157 +157.48.189.189 +49.36.27.234 +223.239.29.67 +47.9.74.131 +137.97.121.179 +157.51.194.215 +106.66.28.85 +169.149.230.254 +47.29.172.241 +152.57.223.89 +144.48.50.33 +157.37.189.154 +157.33.202.172 +157.50.20.139 +157.34.193.196 +103.161.33.175 +42.109.206.44 +27.63.113.91 +1.38.105.63 +157.34.249.148 +157.51.55.216 +106.205.135.192 +49.35.224.1 +1.38.64.155 +152.57.179.185 +139.167.186.137 +223.185.76.65 +223.189.241.174 +106.198.21.49 +27.60.241.25 +157.34.75.198 +106.211.210.214 +157.34.51.7 +106.206.173.11 +152.58.165.171 +223.187.104.223 +110.224.100.183 +45.250.245.74 +152.57.220.255 +49.34.104.13 +152.58.23.4 +27.59.49.108 +157.48.181.133 +114.29.226.234 +152.58.36.239 +157.38.4.250 +47.15.7.123 +132.154.62.68 +157.33.104.56 +223.187.120.44 +106.206.249.83 +157.45.224.151 +106.221.242.77 +157.38.212.161 +152.59.66.43 +103.164.211.245 +106.194.53.39 +157.33.79.160 +157.42.3.199 +106.203.144.14 +106.210.103.33 +49.34.166.29 +1.39.250.41 +49.34.122.147 +47.11.208.20 +157.41.240.193 +157.40.97.95 +157.38.62.169 +157.39.75.131 +223.239.2.14 +49.35.228.25 +152.58.196.71 +152.57.235.226 +27.97.170.65 +117.96.172.200 +117.254.198.99 +157.34.23.34 +157.45.193.215 +223.187.5.63 +157.34.128.212 +117.97.199.153 +157.35.94.140 +223.186.254.87 +157.49.220.189 +114.31.141.218 +117.99.59.240 +157.51.195.234 +49.34.152.71 +106.208.146.91 +106.77.156.127 +110.226.192.248 +117.98.96.11 +27.63.26.7 +103.97.47.210 +152.58.135.251 +157.34.107.127 +169.149.192.198 +157.35.8.32 +103.87.56.14 +152.57.222.76 +205.253.38.198 +106.211.45.57 +106.206.231.29 +152.58.22.76 +42.105.245.116 +152.58.99.24 +157.38.116.164 +157.47.43.120 +49.34.161.3 +157.119.86.3 +27.59.221.168 +152.58.34.16 +157.45.159.34 +117.230.190.206 +49.15.137.58 +49.35.150.147 +157.42.192.161 +103.87.25.198 +157.48.125.237 +152.57.203.126 +157.35.47.173 +49.14.128.111 +157.34.82.45 +157.38.82.4 +42.106.180.226 +223.233.82.0 +223.189.100.94 +157.46.114.78 +157.34.117.121 +157.51.12.60 +106.220.109.51 +169.149.198.17 +106.211.23.189 +49.42.87.121 +122.169.111.190 +49.34.217.172 +106.208.116.243 +38.41.74.113 +49.14.155.168 +157.32.32.48 +223.231.181.201 +157.34.243.102 +171.76.226.199 +152.58.168.194 +157.35.8.162 +47.11.194.210 +152.57.194.164 +152.58.93.37 +157.35.41.38 +117.99.192.81 +117.98.42.131 +157.42.244.162 +103.136.92.203 +223.225.65.238 +157.38.31.15 +152.58.37.230 +139.5.229.191 +47.15.150.141 +117.97.211.191 +106.220.166.132 +122.161.68.254 +42.104.155.8 +117.207.93.47 +47.11.238.154 +103.16.30.35 +106.211.27.52 +106.220.120.70 +42.104.152.167 +49.42.90.18 +157.35.0.21 +157.34.149.87 +49.37.104.130 +110.227.48.80 +139.167.238.177 +49.34.253.216 +223.189.60.134 +157.48.238.197 +157.47.69.122 +42.105.133.196 +49.35.181.76 +110.224.104.123 +157.51.93.84 +106.195.8.229 +157.45.158.123 +106.211.43.217 +180.94.34.151 +120.88.34.16 +103.183.82.248 +106.207.213.180 +106.221.84.223 +157.46.120.47 +157.47.16.220 +106.197.15.184 +117.205.217.190 +223.190.181.208 +49.37.41.148 +157.44.168.8 +106.195.41.243 +152.58.134.162 +139.167.221.222 +223.228.164.54 +47.11.200.216 +157.45.63.112 +42.106.240.71 +120.138.12.179 +157.41.227.99 +202.142.81.198 +171.76.237.212 +202.78.236.55 +27.60.228.25 +45.115.89.231 +1.39.76.57 +171.48.72.239 +27.56.65.39 +117.99.249.138 +152.57.247.16 +110.224.83.41 +182.77.100.233 +106.217.188.168 +106.216.114.199 +223.239.111.13 +47.31.194.244 +157.45.150.69 +223.187.241.243 +42.105.224.41 +49.43.0.185 +223.238.12.67 +1.38.92.38 +157.32.37.157 +157.48.210.48 +157.34.208.35 +152.58.197.117 +157.45.145.130 +152.58.56.139 +106.76.203.109 +49.15.167.184 +223.182.217.160 +122.161.240.156 +169.149.197.46 +157.45.246.119 +157.47.48.140 +157.35.57.10 +117.228.200.204 +110.225.51.162 +47.11.209.110 +106.216.127.57 +106.208.148.178 +157.40.230.190 +43.250.159.186 +157.39.64.166 +139.167.199.136 +157.41.240.8 +117.98.58.149 +106.220.105.206 +205.253.121.90 +157.33.22.250 +106.205.239.204 +117.99.216.184 +47.9.152.118 +152.58.23.251 +157.34.222.171 +223.225.170.105 +49.35.192.73 +49.15.187.86 +49.15.244.70 +106.192.94.30 +42.106.185.58 +157.34.116.96 +47.11.210.25 +157.50.35.214 +49.34.101.116 +223.228.152.115 +157.33.57.4 +49.35.193.82 +49.42.68.86 +152.57.89.174 +223.238.205.82 +223.189.242.62 +157.50.27.33 +152.57.9.42 +106.77.134.196 +106.76.197.48 +152.58.157.36 +223.187.99.244 +152.58.138.73 +157.51.110.179 +223.188.25.10 +157.32.100.241 +223.237.3.114 +117.237.252.35 +110.224.8.130 +157.35.46.65 +157.50.67.158 +106.194.103.186 +49.36.237.136 +106.205.193.220 +49.35.164.15 +157.48.189.99 +157.34.22.147 +157.34.124.70 +106.76.95.38 +42.105.116.57 +106.205.34.74 +157.33.82.131 +157.33.242.228 +117.96.191.202 +106.206.199.163 +223.190.172.5 +223.189.208.236 +157.45.252.162 +49.15.231.124 +157.34.74.244 +117.97.204.165 +152.58.215.201 +103.119.193.147 +117.96.178.220 +42.106.177.232 +171.48.93.231 +106.221.88.204 +150.107.241.118 +157.33.238.107 +157.47.108.181 +103.171.58.102 +157.39.67.246 +27.60.7.206 +106.204.201.224 +42.105.175.91 +106.221.188.115 +157.45.179.30 +49.42.85.170 +202.83.21.202 +117.98.62.173 +49.37.52.103 +152.58.33.84 +157.38.135.216 +49.32.233.37 +171.48.120.228 +205.253.10.189 +122.162.150.190 +132.154.61.142 +110.226.183.230 +223.186.117.74 +42.105.135.159 +106.206.203.2 +152.57.231.46 +223.190.160.60 +42.105.134.111 +157.38.58.76 +42.104.157.215 +183.82.160.16 +117.98.28.33 +106.206.245.122 +157.51.197.233 +61.0.138.50 +103.46.201.63 +157.44.216.35 +157.37.183.17 +42.105.237.9 +106.211.21.20 +157.42.206.194 +49.34.157.234 +106.205.203.211 +106.211.91.222 +157.37.211.229 +49.15.202.184 +223.186.81.252 +120.88.35.235 +117.98.34.178 +152.58.184.123 +49.35.251.136 +157.41.224.64 +223.176.114.194 +157.47.104.101 +157.42.0.142 +110.224.93.16 +152.57.47.76 +117.239.117.20 +157.34.41.198 +49.37.90.219 +157.49.155.43 +152.57.242.210 +47.15.34.104 +110.224.68.5 +152.58.58.241 +49.37.157.187 +106.221.96.14 +49.42.90.248 +106.66.28.73 +152.58.19.57 +157.34.195.223 +223.189.237.68 +223.239.53.105 +157.40.78.69 +106.221.30.125 +47.15.36.234 +157.35.60.65 +47.15.103.49 +112.79.225.123 +152.58.183.238 +137.97.94.15 +152.57.174.192 +106.205.206.255 +27.62.83.1 +223.191.54.130 +47.15.3.235 +106.223.28.49 +49.34.138.241 +152.58.159.230 +223.186.200.1 +183.87.13.59 +117.254.140.59 +106.206.58.106 +110.224.105.217 +27.56.156.75 +157.38.129.190 +47.9.5.179 +223.238.228.59 +49.35.137.247 +152.58.154.145 +223.187.98.200 +152.57.209.254 +47.11.201.78 +157.51.44.179 +223.196.170.223 +223.238.46.228 +49.37.66.147 +106.66.58.100 +132.154.0.24 +157.38.43.90 +223.191.47.60 +203.194.98.194 +106.192.165.95 +157.38.128.132 +157.33.193.35 +1.38.165.68 +106.206.204.12 +152.58.219.239 +157.49.135.130 +157.47.108.213 +152.57.82.21 +157.33.19.144 +27.60.81.11 +157.49.249.172 +106.66.36.253 +223.188.178.90 +49.37.224.87 +171.76.167.17 +157.38.113.8 +49.14.113.63 +106.208.108.112 +106.78.77.19 +132.154.172.220 +157.41.255.67 +47.29.175.211 +157.45.156.0 +103.170.62.144 +223.187.216.151 +42.105.162.61 +152.58.213.210 +106.205.221.97 +223.225.168.5 +223.187.240.180 +47.11.50.217 +103.131.27.87 +117.98.56.158 +139.167.203.116 +106.194.166.11 +223.238.218.216 +152.57.50.67 +223.189.212.14 +132.154.63.42 +157.35.89.232 +110.226.202.254 +152.57.227.84 +157.32.71.143 +223.190.173.13 +27.97.143.119 +223.179.193.87 +117.98.106.100 +152.58.231.93 +47.15.184.178 +157.38.14.45 +157.45.198.147 +106.215.247.229 +106.196.55.92 +152.57.67.196 +106.196.86.222 +223.236.168.172 +106.213.216.52 +1.39.78.225 +117.228.91.224 +106.216.123.250 +157.45.87.169 +49.36.193.208 +152.58.148.95 +152.58.133.75 +42.105.238.234 +157.45.250.201 +205.253.38.174 +223.187.59.94 +117.99.199.236 +117.97.166.117 +223.182.0.43 +157.40.90.53 +117.230.14.64 +106.216.248.42 +47.11.54.90 +171.79.189.104 +117.98.122.177 +223.231.198.85 +106.211.9.1 +152.58.96.34 +223.185.239.163 +103.178.177.158 +110.224.94.147 +106.76.92.46 +106.205.193.158 +106.221.190.239 +47.9.36.208 +47.9.33.202 +106.221.159.169 +171.76.10.114 +152.58.105.110 +49.35.130.218 +223.225.169.216 +205.253.32.101 +49.34.244.55 +152.58.99.139 +117.99.202.207 +157.35.90.16 +122.161.67.107 +106.79.192.75 +152.58.107.38 +103.41.36.38 +49.34.164.43 +223.238.101.141 +223.238.116.130 +152.58.218.209 +47.15.215.62 +223.239.91.89 +157.38.148.73 +132.154.11.187 +27.61.205.134 +157.35.7.87 +49.37.113.210 +47.29.169.203 +47.9.103.39 +106.219.78.85 +106.194.86.1 +106.198.115.125 +49.205.210.36 +157.45.94.146 +223.190.136.176 +171.79.149.154 +42.105.231.2 +157.34.78.172 +106.203.136.65 +157.42.192.12 +157.49.240.103 +157.38.151.125 +122.176.79.29 +223.189.118.240 +103.164.246.2 +152.58.58.159 +223.187.189.82 +157.38.241.180 +157.33.57.162 +106.200.86.20 +157.49.194.214 +139.167.237.247 +47.15.3.203 +157.34.68.216 +152.58.19.250 +27.63.60.67 +157.38.134.14 +157.38.100.137 +106.220.160.185 +110.224.177.210 +49.35.168.61 +117.98.68.18 +106.195.3.166 +132.154.37.133 +157.34.195.89 +106.77.141.15 +106.77.140.25 +171.79.181.146 +223.226.219.55 +49.36.83.225 +157.38.128.220 +152.58.231.249 +157.32.242.164 +223.178.80.205 +106.216.240.27 +157.33.52.48 +106.208.158.181 +47.11.206.49 +117.233.111.200 +132.154.52.222 +103.245.12.165 +157.33.232.199 +106.195.37.200 +47.29.166.245 +157.40.218.163 +106.195.70.71 +47.9.102.58 +157.48.115.92 +106.196.94.52 +49.35.131.59 +157.38.151.93 +223.237.64.180 +152.58.213.107 +106.221.10.7 +49.35.238.33 +152.58.25.98 +106.217.182.26 +103.87.57.90 +152.58.93.198 +42.105.203.182 +47.11.78.91 +103.67.233.195 +223.233.116.211 +106.207.89.95 +42.105.181.19 +152.58.166.134 +157.34.220.109 +47.11.193.64 +49.32.174.214 +103.8.167.10 +132.154.12.166 +157.40.247.123 +103.87.94.145 +103.40.197.99 +47.11.79.252 +157.35.27.143 +223.181.21.63 +157.47.16.162 +106.192.220.126 +157.48.93.96 +103.154.37.204 +106.193.4.239 +49.14.108.250 +152.58.73.239 +106.197.230.250 +152.58.236.199 +157.38.131.169 +223.187.75.13 +157.34.99.36 +103.245.106.125 +157.49.92.159 +106.221.50.215 +110.224.174.208 +223.225.168.107 +27.59.45.55 +106.196.15.10 +157.34.73.212 +223.176.20.23 +103.82.223.53 +49.35.245.146 +49.43.96.10 +157.33.96.74 +157.48.125.124 +103.170.229.164 +42.106.178.195 +27.56.202.61 +223.238.41.0 +157.51.168.129 +157.35.60.186 +49.34.237.154 +49.43.100.197 +106.196.36.144 +47.9.145.99 +157.47.55.118 +42.105.116.40 +152.58.200.94 +42.111.160.11 +223.238.111.61 +157.38.32.230 +47.15.16.75 +137.97.80.91 +106.198.115.227 +223.186.28.236 +157.34.230.116 +106.66.3.94 +106.207.39.213 +205.253.124.203 +157.41.227.250 +152.58.114.132 +152.58.67.238 +171.51.151.21 +110.227.63.164 +223.238.122.103 +106.206.239.70 +132.154.33.111 +171.76.216.204 +117.99.208.81 +49.37.55.57 +157.46.119.84 +103.103.162.23 +157.41.225.158 +157.32.36.59 +152.59.66.50 +49.35.182.183 +27.63.24.242 +117.99.254.104 +106.203.109.31 +117.220.111.131 +223.189.4.219 +117.230.159.145 +106.206.117.94 +49.35.187.219 +110.224.84.253 +157.41.244.145 +59.178.79.134 +157.38.252.89 +157.34.129.211 +49.43.154.25 +157.33.71.88 +117.98.86.168 +49.37.158.177 +47.29.5.8 +117.234.170.206 +117.234.49.199 +152.58.88.235 +49.36.80.131 +157.38.112.120 +157.44.182.248 +152.57.64.99 +157.38.210.99 +152.57.38.148 +223.228.198.254 +157.47.37.72 +157.37.174.102 +223.230.136.236 +49.35.159.46 +106.216.250.7 +157.48.185.57 +157.35.84.52 +223.239.78.175 +49.14.134.91 +106.219.228.49 +117.99.199.68 +157.34.5.202 +42.105.89.246 +27.62.188.83 +47.11.211.60 +157.45.211.217 +106.220.254.138 +42.105.236.190 +157.34.117.173 +157.34.158.27 +106.220.105.192 +171.76.87.108 +106.221.49.106 +27.61.176.6 +117.225.11.144 +103.157.168.165 +47.15.42.101 +106.206.201.8 +157.50.61.76 +157.33.7.87 +157.47.50.229 +42.105.141.18 +27.63.46.101 +157.42.0.236 +47.9.69.149 +152.58.31.137 +106.202.12.64 +223.178.210.213 +171.76.180.107 +47.15.5.85 +223.231.102.11 +152.58.236.200 +157.45.222.228 +47.9.152.213 +223.190.191.155 +152.58.125.189 +106.211.89.203 +157.38.15.171 +171.48.110.245 +49.14.113.153 +49.35.248.241 +157.34.209.56 +152.57.76.217 +223.187.152.4 +106.193.46.130 +157.34.214.14 +157.34.140.131 +117.98.60.72 +152.58.187.138 +27.63.34.8 +27.56.195.164 +157.44.221.112 +157.41.255.222 +106.198.21.57 +117.230.184.223 +157.49.230.238 +47.15.34.248 +152.58.138.173 +49.36.210.215 +223.196.175.176 +106.206.240.185 +152.58.232.137 +202.148.59.154 +49.36.237.210 +106.195.51.23 +42.105.49.235 +47.31.98.71 +27.63.9.105 +152.58.19.124 +157.42.242.217 +152.58.201.68 +157.44.144.124 +157.34.61.81 +103.203.73.14 +157.38.72.75 +49.36.217.254 +110.225.46.127 +110.224.87.47 +157.46.173.253 +157.51.196.96 +47.31.147.157 +49.15.234.83 +223.227.107.49 +157.38.129.158 +157.33.6.184 +157.51.194.240 +49.207.244.255 +157.38.69.186 +152.58.169.223 +157.32.237.203 +114.31.142.158 +106.216.202.254 +169.149.231.109 +103.51.148.166 +152.58.190.199 +106.207.77.121 +112.79.164.246 +49.35.151.106 +157.38.146.111 +157.34.205.95 +157.48.113.250 +157.46.97.164 +157.46.124.231 +157.48.197.178 +106.210.231.65 +49.35.131.157 +47.31.154.41 +223.190.166.198 +152.58.158.11 +223.187.75.140 +122.173.25.113 +49.37.55.77 +157.49.160.194 +157.51.153.203 +157.33.96.83 +157.41.240.26 +223.184.199.218 +223.239.7.160 +49.34.91.42 +152.57.184.0 +49.35.229.93 +223.181.24.120 +114.31.184.42 +137.97.120.74 +223.187.23.196 +49.35.228.27 +157.38.82.192 +157.34.73.162 +47.15.37.50 +27.60.107.193 +116.74.160.18 +157.32.69.220 +42.111.9.127 +117.230.89.48 +42.105.11.164 +103.44.48.82 +106.205.206.12 +171.76.253.55 +157.40.216.5 +157.49.151.52 +106.205.201.5 +110.226.163.72 +103.157.149.175 +157.38.148.244 +115.99.179.94 +152.58.16.236 +106.206.195.38 +106.211.57.69 +42.106.33.1 +49.36.217.71 +152.58.197.140 +42.104.144.94 +157.34.85.152 +106.77.141.27 +223.228.92.180 +49.35.233.194 +106.76.253.246 +157.46.69.2 +157.51.194.32 +152.58.79.119 +157.38.150.120 +171.76.226.234 +223.182.18.124 +106.208.173.233 +103.149.159.255 +27.97.44.47 +171.76.135.93 +157.49.148.66 +27.63.51.214 +61.3.220.104 +106.216.120.0 +157.38.219.151 +157.32.221.169 +152.58.213.199 +49.36.212.4 +157.45.192.197 +27.63.25.115 +223.187.98.105 +117.99.238.110 +171.76.240.147 +223.229.221.128 +106.207.242.180 +49.36.239.248 +106.208.148.247 +47.9.158.118 +106.221.14.206 +152.58.84.4 +112.79.116.8 +157.38.199.221 +49.34.159.141 +122.161.72.220 +106.77.142.66 +152.57.113.205 +157.48.240.151 +139.167.225.118 +157.34.198.219 +157.47.119.145 +106.216.171.109 +157.47.8.228 +106.197.71.161 +169.149.225.43 +152.57.230.99 +157.33.228.30 +152.58.233.85 +47.15.3.110 +49.42.74.136 +49.42.88.56 +152.58.16.3 +157.34.59.20 +152.58.34.244 +157.42.245.143 +106.194.142.47 +106.195.118.88 +157.42.196.164 +152.58.197.205 +47.11.196.197 +157.38.214.97 +152.58.211.233 +157.47.75.27 +42.105.236.66 +49.35.133.108 +157.48.183.214 +171.60.192.217 +175.101.93.35 +47.15.1.204 +152.58.102.12 +117.99.244.41 +49.35.227.27 +49.37.44.122 +106.76.212.131 +157.46.86.169 +49.37.114.180 +110.224.30.223 +106.195.10.165 +223.188.237.104 +106.203.155.40 +42.105.214.78 +157.34.21.226 +117.98.102.86 +157.37.134.113 +157.49.135.8 +157.40.80.148 +117.98.18.156 +106.221.175.135 +49.34.236.177 +157.42.1.94 +157.41.249.63 +139.167.218.214 +47.29.163.207 +47.9.35.54 +49.37.9.147 +27.63.104.188 +27.62.190.86 +42.104.211.7 +42.105.214.242 +223.231.155.63 +152.57.219.163 +117.99.194.254 +106.216.118.116 +223.231.195.249 +1.38.160.113 +110.224.97.93 +157.47.83.110 +157.47.55.41 +117.228.222.85 +223.186.202.75 +47.29.167.106 +47.15.237.191 +42.110.148.153 +106.211.40.39 +106.207.247.200 +157.45.208.175 +49.36.27.27 +157.38.214.254 +42.105.132.168 +157.51.77.146 +42.105.142.171 +223.187.255.164 +157.41.251.82 +223.233.122.212 +110.224.90.145 +49.35.148.246 +157.34.214.154 +157.35.3.3 +106.207.16.146 +49.36.217.24 +47.11.233.197 +157.44.192.199 +106.210.48.192 +223.239.27.254 +106.76.238.209 +42.105.168.25 +49.34.218.219 +49.37.25.228 +223.223.132.7 +137.97.75.206 +223.225.242.193 +157.47.108.92 +152.58.78.85 +152.59.66.168 +157.48.92.249 +106.207.7.151 +117.96.161.43 +106.78.44.45 +157.48.116.97 +157.37.202.219 +157.35.21.11 +106.76.208.52 +47.11.231.210 +27.63.67.189 +47.29.160.100 +157.34.59.87 +152.58.89.233 +223.185.64.61 +103.203.73.254 +103.141.112.230 +137.97.105.155 +122.161.81.202 +223.231.134.171 +47.11.85.70 +47.9.133.57 +152.58.36.136 +49.15.242.43 +152.57.182.75 +157.41.226.115 +27.61.18.153 +152.58.223.6 +27.56.24.137 +106.217.55.71 +106.216.112.198 +223.187.204.42 +152.58.58.144 +152.58.58.235 +223.187.114.233 +223.187.97.196 +49.36.219.42 +114.31.136.132 +49.42.95.121 +169.149.225.146 +106.205.188.229 +157.38.137.142 +152.58.34.17 +47.9.74.213 +42.105.197.28 +157.48.216.43 +47.11.92.190 +49.34.89.212 +103.42.197.245 +152.58.97.61 +169.149.230.96 +110.226.224.40 +122.162.211.234 +223.187.244.223 +157.33.34.9 +157.45.62.233 +157.34.3.209 +106.196.57.232 +117.99.220.114 +103.251.56.151 +152.57.109.176 +103.226.7.3 +157.38.72.162 +47.9.144.241 +106.196.82.21 +157.48.114.150 +106.200.79.175 +106.198.20.106 +223.238.121.2 +132.154.60.29 +223.225.58.234 +106.207.60.32 +157.35.27.48 +47.15.209.206 +157.34.135.116 +47.11.207.147 +101.0.50.136 +178.248.115.11 +223.189.247.116 +49.35.193.164 +157.45.65.78 +157.45.196.77 +117.98.98.144 +157.32.108.233 +152.58.25.172 +106.211.94.214 +152.58.232.173 +157.44.190.196 +223.188.72.41 +117.98.104.127 +47.11.207.71 +223.227.114.216 +223.185.84.247 +106.216.115.76 +169.149.197.71 +122.162.149.230 +157.38.24.105 +106.76.209.80 +114.31.137.4 +152.58.153.14 +157.35.68.251 +223.238.210.38 +101.0.49.179 +157.33.224.202 +106.204.232.248 +122.161.48.133 +106.208.155.66 +137.97.114.56 +157.38.148.136 +103.154.239.82 +171.76.255.123 +137.97.113.254 +117.217.45.29 +27.59.49.234 +157.48.144.142 +157.42.219.144 +157.38.62.79 +223.186.207.120 +49.43.33.253 +116.73.219.176 +49.36.191.34 +106.216.226.104 +157.38.77.36 +139.167.188.77 +1.39.75.92 +106.223.185.13 +157.38.86.31 +152.58.94.125 +157.35.71.22 +110.224.105.196 +49.37.227.222 +47.11.193.21 +152.57.98.221 +27.97.72.255 +106.196.7.197 +223.176.38.2 +157.34.82.211 +152.58.144.95 +106.200.155.18 +223.239.82.46 +117.96.173.10 +152.58.236.246 +103.215.156.51 +157.45.61.171 +49.34.92.164 +157.37.132.137 +49.43.155.21 +157.42.201.239 +171.76.169.207 +171.61.21.164 +49.35.192.174 +152.58.25.145 +49.34.85.7 +210.89.59.191 +157.40.71.225 +117.216.164.27 +157.40.101.53 +157.41.241.24 +106.194.26.65 +171.76.243.77 +1.38.220.20 +152.58.36.91 +157.40.243.34 +27.62.115.231 +49.35.159.189 +47.15.32.10 +223.238.71.240 +157.48.244.255 +103.70.36.209 +115.96.154.170 +27.62.223.255 +157.41.228.48 +47.11.77.123 +157.49.193.94 +106.211.95.201 +106.205.41.55 +106.206.139.140 +157.38.211.157 +157.48.116.196 +49.15.92.72 +27.56.80.175 +152.58.17.89 +106.208.77.163 +157.34.111.112 +49.35.192.91 +49.14.157.194 +152.57.23.27 +152.58.31.45 +157.41.224.152 +157.51.193.182 +47.29.9.56 +152.57.226.177 +42.104.154.171 +106.78.52.196 +106.66.58.193 +157.38.75.9 +157.44.215.164 +169.149.230.210 +49.36.18.139 +106.211.224.188 +152.58.232.250 +47.29.160.19 +47.9.83.33 +117.234.238.23 +203.81.242.185 +106.78.52.23 +223.238.102.190 +103.171.100.202 +152.58.197.15 +157.47.59.234 +157.45.202.192 +49.34.119.125 +132.154.3.136 +132.154.170.77 +157.38.242.210 +49.33.199.88 +106.207.165.1 +152.58.58.199 +110.225.75.8 +106.198.87.155 +117.98.106.59 +106.201.187.8 +42.105.230.28 +157.45.238.153 +157.34.114.79 +106.207.148.185 +157.38.139.239 +117.98.114.154 +106.210.189.134 +152.58.186.80 +106.76.220.219 +117.99.46.182 +223.177.95.0 +117.98.86.18 +106.208.54.196 +152.57.2.197 +106.206.195.169 +223.238.227.94 +169.149.229.207 +157.48.88.81 +157.47.47.50 +106.216.195.98 +103.157.12.22 +47.9.33.55 +169.149.225.129 +103.181.167.49 +223.187.134.194 +157.35.0.199 +223.181.118.243 +152.58.168.164 +106.221.75.42 +157.34.105.198 +152.58.31.138 +157.42.202.94 +223.231.160.226 +106.193.247.56 +223.238.200.34 +1.187.213.144 +152.58.20.227 +42.105.13.201 +106.196.74.132 +157.34.236.71 +1.39.115.221 +1.23.150.133 +1.39.77.75 +223.184.244.230 +42.105.162.245 +106.197.105.249 +157.41.245.37 +157.34.112.167 +157.38.107.101 +42.106.187.12 +45.114.251.140 +47.15.99.30 +47.15.137.35 +157.51.196.249 +122.173.29.87 +49.15.231.83 +117.254.33.146 +223.187.10.107 +106.196.26.204 +106.216.251.202 +157.47.56.25 +117.98.50.182 +106.222.14.6 +152.58.156.94 +47.11.201.30 +150.242.199.142 +157.39.243.194 +106.223.202.60 +152.58.16.228 +1.39.78.66 +47.9.106.255 +47.15.21.161 +132.154.148.168 +152.57.171.216 +157.49.214.193 +157.47.40.26 +192.140.153.207 +110.227.63.199 +106.195.71.53 +106.76.77.88 +47.29.162.201 +152.58.236.96 +157.46.70.216 +47.11.253.166 +152.58.200.82 +106.203.30.201 +152.58.76.143 +157.38.68.57 +49.36.217.182 +152.57.86.20 +106.200.160.90 +157.51.193.138 +157.33.41.168 +42.111.216.66 +157.35.10.12 +49.42.82.16 +157.34.218.95 +117.192.47.128 +106.194.171.170 +171.79.147.21 +152.57.231.144 +157.48.169.50 +45.119.30.11 +157.41.252.204 +157.44.135.88 +106.76.197.176 +152.57.41.152 +223.181.78.41 +157.48.125.157 +132.154.36.150 +106.221.94.21 +152.58.33.21 +157.46.145.220 +42.107.133.66 +157.42.7.209 +106.197.79.164 +137.97.118.16 +223.187.125.145 +106.223.204.234 +223.230.168.186 +106.216.234.179 +47.29.3.179 +157.41.228.176 +49.34.212.46 +157.45.245.104 +157.32.234.78 +132.154.187.249 +169.149.229.235 +223.187.70.122 +106.195.78.170 +157.38.51.59 +157.45.201.235 +47.15.126.166 +49.43.100.213 +223.189.226.139 +106.213.131.63 +171.79.145.161 +106.77.142.78 +132.154.58.37 +223.228.18.188 +157.40.121.237 +157.33.255.90 +59.93.145.136 +47.15.7.116 +106.220.84.199 +157.35.77.157 +223.238.98.121 +42.109.192.45 +49.34.122.36 +157.38.134.136 +223.186.252.217 +157.33.96.80 +157.48.125.215 +152.58.154.170 +152.58.107.44 +106.203.4.146 +152.57.243.38 +152.58.196.139 +152.58.25.92 +157.38.202.72 +47.11.198.245 +157.45.234.199 +106.195.34.46 +106.194.2.225 +49.37.107.152 +223.188.50.184 +157.42.200.122 +106.221.39.131 +169.149.192.28 +42.105.164.163 +49.36.222.68 +157.44.210.14 +47.11.48.107 +106.197.5.43 +157.34.71.152 +106.204.231.30 +103.15.60.90 +47.15.237.63 +152.58.131.199 +42.105.135.45 +223.180.176.1 +157.42.6.107 +162.216.140.25 +1.38.165.140 +157.33.51.62 +223.187.100.230 +103.161.231.249 +103.15.255.89 +157.45.244.60 +106.192.77.1 +157.39.238.174 +47.9.106.221 +115.96.161.100 +27.62.226.243 +157.42.2.108 +152.58.138.240 +157.38.86.217 +117.98.50.60 +110.224.92.199 +106.207.128.14 +152.57.205.189 +152.58.187.100 +169.149.195.116 +47.11.248.132 +106.205.204.234 +103.215.226.225 +42.105.15.9 +110.224.18.183 +202.142.101.61 +42.105.98.117 +49.15.198.34 +47.9.108.87 +152.58.180.5 +103.28.246.21 +49.34.147.88 +47.15.247.40 +49.34.145.226 +152.57.70.242 +137.97.101.23 +106.206.131.81 +47.31.150.216 +117.97.210.89 +157.50.67.177 +49.42.66.227 +132.154.147.160 +117.217.192.164 +152.58.149.92 +49.42.80.98 +152.57.100.212 +223.187.72.9 +103.219.44.121 +171.51.221.129 +152.58.56.178 +223.239.48.7 +117.207.105.90 +103.209.64.217 +223.189.237.50 +106.77.129.206 +117.96.186.225 +49.42.88.7 +42.105.88.42 +157.48.113.53 +152.57.89.78 +223.189.61.107 +157.32.76.85 +106.207.38.5 +223.176.21.43 +157.38.130.248 +157.50.58.9 +103.179.197.219 +49.42.88.71 +157.38.35.234 +106.223.182.30 +157.38.132.43 +49.42.75.229 +157.34.123.79 +106.217.143.162 +152.58.222.123 +42.108.196.239 +152.58.143.187 +223.238.222.242 +157.41.248.151 +106.216.236.178 +223.231.167.70 +157.46.176.149 +152.58.196.132 +49.43.216.183 +49.15.163.130 +106.196.76.80 +43.251.72.23 +49.43.100.105 +117.199.226.253 +110.227.51.161 +152.58.144.238 +157.50.69.36 +152.58.138.12 +49.35.227.53 +157.38.156.58 +27.61.142.31 +110.225.87.75 +42.106.206.10 +117.98.22.14 +49.37.74.241 +106.221.242.230 +49.37.113.82 +49.37.44.0 +106.193.17.49 +157.33.216.19 +223.191.47.65 +223.228.146.225 +106.197.125.177 +171.48.90.243 +49.32.141.178 +106.221.90.30 +106.221.243.217 +223.187.25.217 +117.204.80.7 +112.79.113.79 +106.216.194.68 +223.176.18.204 +49.35.195.204 +106.205.199.170 +157.42.3.17 +106.216.118.17 +132.154.163.137 +106.206.208.49 +157.38.244.64 +106.78.93.255 +223.187.101.68 +106.206.160.192 +157.34.10.224 +106.200.169.253 +157.34.0.62 +110.224.178.68 +117.97.215.17 +137.97.118.36 +157.48.117.242 +27.60.248.31 +157.32.122.227 +139.167.211.215 +157.41.252.151 +157.42.221.143 +106.211.46.63 +106.77.179.222 +47.9.122.222 +49.36.210.179 +42.105.203.155 +223.187.107.98 +106.216.233.183 +157.38.132.227 +152.58.34.227 +42.111.196.54 +106.217.249.82 +27.63.220.168 +49.43.100.22 +47.15.21.226 +49.37.45.158 +106.66.57.218 +106.195.73.186 +157.41.251.50 +223.180.183.74 +157.35.51.43 +152.58.36.205 +42.111.204.32 +157.47.50.114 +223.228.103.47 +157.45.131.248 +117.243.220.114 +223.181.109.99 +117.219.223.42 +117.98.64.84 +106.220.125.219 +169.149.229.240 +157.38.222.227 +49.15.249.95 +106.78.78.73 +49.36.33.159 +47.247.200.210 +106.217.31.127 +47.29.165.240 +157.42.5.75 +157.38.12.62 +169.149.225.166 +152.58.184.43 +1.187.214.138 +223.238.6.27 +103.104.53.193 +47.9.98.21 +106.77.182.186 +47.11.199.54 +47.15.153.89 +223.227.86.106 +103.67.232.226 +157.47.102.92 +106.198.81.34 +106.76.230.15 +157.34.49.71 +106.216.120.101 +157.39.72.164 +223.182.204.217 +157.38.96.28 +223.190.169.166 +157.47.62.15 +152.58.27.35 +49.42.90.20 +223.187.108.22 +152.57.115.235 +103.185.244.35 +117.99.205.235 +106.216.202.234 +47.11.21.214 +152.58.133.103 +152.58.209.122 +106.197.80.251 +157.38.139.185 +49.42.67.52 +152.58.30.183 +152.58.221.65 +106.206.253.138 +106.195.115.200 +27.57.255.198 +106.220.183.21 +42.105.89.214 +103.238.106.238 +49.42.95.156 +43.250.159.162 +117.98.126.112 +47.11.255.223 +106.196.89.105 +47.9.6.9 +157.46.89.97 +47.9.35.40 +157.48.176.168 +157.34.105.238 +106.221.82.95 +106.76.197.76 +157.41.226.85 +106.77.185.135 +223.186.231.13 +223.187.132.63 +152.58.157.56 +47.15.117.127 +157.34.144.69 +47.15.32.104 +223.228.69.110 +157.38.26.183 +157.48.168.199 +27.63.27.248 +49.34.136.123 +157.45.224.98 +49.34.151.13 +106.211.95.39 +106.203.145.184 +106.193.43.35 +223.185.108.172 +45.249.42.82 +49.15.83.250 +110.226.218.217 +106.204.192.10 +110.227.39.33 +106.206.164.43 +152.57.116.65 +223.178.211.217 +112.79.111.210 +106.195.36.239 +152.58.102.16 +1.39.16.4 +14.192.29.94 +106.208.186.174 +103.164.143.42 +152.58.189.116 +42.105.116.96 +157.49.144.156 +117.209.6.197 +106.76.93.90 +47.29.173.204 +157.34.79.17 +47.15.228.26 +47.15.131.135 +157.46.95.79 +106.76.91.169 +106.206.245.252 +157.47.89.112 +152.57.235.205 +49.14.113.17 +110.224.69.106 +223.233.57.182 +157.35.19.41 +152.58.40.195 +47.11.84.99 +27.61.122.204 +103.2.135.35 +132.154.15.15 +106.193.65.195 +103.223.8.101 +139.167.246.221 +42.110.172.132 +157.33.52.217 +157.41.224.189 +157.32.111.140 +42.105.233.181 +152.58.156.30 +223.187.34.18 +106.216.127.90 +152.58.196.106 +157.38.130.29 +205.253.11.86 +157.51.78.107 +157.50.41.210 +152.57.242.26 +152.57.90.216 +157.42.210.214 +49.205.103.159 +157.51.17.145 +117.99.13.86 +1.38.142.80 +47.29.169.146 +157.48.83.108 +106.216.137.247 +157.35.18.96 +106.195.98.70 +152.58.197.84 +42.105.196.179 +59.89.67.211 +106.222.106.193 +42.111.160.15 +205.253.34.100 +106.78.51.121 +157.35.2.38 +106.207.236.67 +117.233.120.178 +157.41.253.239 +117.197.252.66 +27.60.45.53 +49.34.45.191 +110.226.168.246 +117.99.248.239 +47.9.2.25 +49.15.173.218 +103.149.194.254 +106.76.248.48 +117.98.66.128 +110.227.54.135 +157.46.161.201 +132.154.60.87 +49.35.140.41 +106.221.173.179 +152.57.45.64 +157.34.35.3 +101.0.57.101 +157.42.7.48 +146.196.37.205 +152.58.18.22 +152.57.136.55 +42.105.178.75 +152.58.215.141 +106.222.100.113 +139.5.30.194 +139.167.241.226 +47.11.192.34 +117.99.238.71 +49.35.130.233 +223.187.137.95 +117.99.44.10 +223.178.211.166 +106.210.163.142 +157.35.68.175 +157.41.241.92 +47.15.6.131 +49.42.85.101 +157.34.78.199 +49.34.112.60 +106.195.63.92 +223.185.113.204 +223.188.46.118 +47.29.164.167 +47.11.208.212 +152.58.34.144 +27.60.101.67 +27.61.32.53 +223.182.61.226 +223.233.120.157 +152.58.21.84 +157.46.176.51 +49.37.224.49 +157.49.64.164 +106.193.10.223 +49.15.229.132 +47.15.11.53 +106.194.68.207 +103.154.39.112 +139.167.240.131 +152.58.19.146 +106.194.132.156 +223.176.41.112 +157.38.62.249 +157.50.64.147 +47.29.175.45 +223.188.120.143 +152.58.99.122 +49.36.144.167 +27.59.222.94 +106.216.169.89 +157.51.199.184 +106.204.163.205 +49.15.233.29 +42.106.238.32 +106.198.27.142 +106.222.97.140 +110.224.107.7 +27.56.236.234 +132.154.134.182 +157.40.81.238 +1.39.76.158 +117.98.92.72 +106.220.119.101 +42.106.185.49 +152.57.62.50 +157.33.88.51 +42.111.149.94 +117.227.61.164 +106.206.196.208 +157.47.121.119 +106.211.92.109 +180.94.34.109 +106.213.248.225 +47.9.35.135 +223.187.164.11 +152.57.224.85 +152.58.34.81 +157.49.189.181 +106.193.191.99 +110.224.91.253 +223.185.97.103 +106.216.251.145 +49.32.139.180 +117.98.92.14 +157.47.42.62 +157.51.149.88 +106.76.31.88 +49.36.213.21 +49.37.225.3 +47.9.152.204 +49.14.98.152 +49.15.203.209 +157.32.115.28 +106.207.174.234 +152.58.56.70 +171.60.215.150 +223.238.179.181 +47.247.206.42 +27.60.227.93 +47.9.98.194 +106.197.150.143 +169.149.197.11 +43.229.90.185 +117.209.247.31 +223.186.97.49 +112.79.164.113 +223.233.120.97 +47.9.92.188 +49.34.196.244 +157.40.74.20 +106.195.47.194 +152.58.70.141 +157.33.215.83 +49.36.170.21 +106.219.218.11 +157.32.99.12 +117.249.153.70 +106.220.130.241 +106.196.8.134 +106.217.195.90 +152.57.194.25 +157.48.73.154 +157.34.6.51 +157.48.162.87 +152.58.59.97 +106.221.101.229 +152.58.189.23 +106.206.204.80 +47.9.37.165 +1.187.221.177 +106.197.2.58 +47.29.175.39 +49.32.250.138 +47.29.167.149 +42.105.206.28 +223.186.186.61 +106.221.106.179 +106.221.188.148 +106.221.255.36 +152.58.236.155 +106.221.188.136 +152.58.113.201 +117.223.92.101 +157.38.104.83 +132.154.61.42 +110.224.101.64 +157.47.121.216 +27.60.192.57 +223.229.199.49 +117.98.96.86 +157.37.218.143 +106.202.113.185 +157.33.105.58 +157.34.14.40 +1.187.183.69 +106.198.80.141 +1.187.138.5 +157.45.220.198 +27.62.140.67 +117.224.117.87 +106.210.36.110 +152.58.189.106 +49.37.65.14 +110.226.165.208 +157.33.99.46 +43.229.88.179 +152.58.185.125 +106.195.43.159 +106.207.247.223 +49.42.72.246 +106.79.204.122 +152.58.132.21 +117.227.47.138 +106.222.28.249 +47.15.12.116 +157.49.80.133 +106.76.78.203 +106.194.30.71 +110.224.189.33 +106.200.1.237 +49.35.240.121 +152.57.77.51 +49.15.231.63 +49.34.232.99 +157.35.9.30 +137.97.112.65 +106.193.98.76 +223.189.146.135 +152.58.184.211 +152.57.241.8 +106.216.124.235 +157.38.146.124 +106.208.124.151 +157.44.166.217 +42.105.169.0 +157.38.14.7 +171.79.176.209 +106.66.59.67 +152.58.236.57 +157.51.51.109 +106.216.114.22 +106.196.86.172 +106.205.31.131 +157.44.163.70 +47.15.39.61 +49.36.179.204 +169.149.225.89 +110.226.173.232 +169.149.194.54 +110.227.136.231 +49.34.38.232 +132.154.168.139 +152.57.154.227 +106.195.51.236 +223.188.238.170 +27.63.209.69 +106.211.2.240 +157.40.252.78 +157.44.142.25 +103.135.189.222 +59.178.65.15 +152.58.191.92 +49.34.174.185 +157.33.76.0 +106.205.197.116 +223.225.127.176 +106.211.72.125 +152.58.152.255 +117.230.94.32 +157.33.213.249 +106.203.106.178 +103.211.53.216 +157.34.146.35 +223.239.5.222 +152.58.152.202 +47.11.255.181 +106.216.124.103 +157.49.163.179 +47.11.254.92 +47.11.253.189 +106.220.202.142 +106.210.166.33 +152.58.197.243 +223.186.79.228 +157.41.225.75 +49.34.36.21 +106.207.243.202 +49.15.249.3 +152.57.211.31 +112.79.165.242 +103.211.53.231 +157.47.126.217 +223.189.165.60 +42.106.205.88 +157.33.115.26 +27.63.134.157 +49.34.230.255 +49.14.131.59 +106.194.84.146 +157.45.240.87 +223.190.132.178 +106.221.221.238 +106.206.168.104 +42.111.98.16 +106.207.214.119 +157.37.165.117 +49.14.145.31 +47.9.85.122 +49.36.42.20 +157.45.192.110 +223.190.182.92 +117.97.72.121 +157.34.69.11 +106.203.88.14 +103.164.199.247 +152.58.235.210 +157.34.13.213 +1.187.221.229 +157.49.87.158 +106.210.142.25 +106.78.181.158 +103.211.12.225 +42.111.164.85 +106.205.205.36 +132.154.3.240 +157.33.227.8 +49.36.18.68 +157.48.112.49 +106.193.206.207 +223.181.28.179 +47.11.210.53 +106.76.245.114 +223.231.218.32 +49.37.67.199 +223.231.172.208 +106.211.204.120 +27.62.79.71 +117.98.16.23 +157.47.55.8 +106.76.198.232 +157.48.117.166 +49.15.246.133 +157.48.112.12 +152.58.90.111 +1.38.140.250 +106.194.52.251 +106.204.133.124 +117.245.209.83 +27.62.150.156 +106.208.7.247 +157.40.195.192 +171.76.239.82 +152.58.188.193 +106.77.142.43 +106.216.251.216 +171.76.229.164 +157.49.201.208 +223.188.146.248 +1.187.82.253 +169.149.231.130 +42.105.198.227 +1.38.160.246 +110.226.167.157 +157.42.214.107 +223.187.113.102 +223.187.38.232 +49.14.97.160 +106.204.15.251 +42.105.141.136 +157.35.44.157 +223.187.10.249 +122.163.80.121 +223.237.91.164 +169.149.193.150 +152.58.25.37 +157.38.137.56 +157.42.0.189 +157.48.116.224 +157.41.193.205 +117.228.41.110 +49.42.73.70 +106.77.133.217 +157.48.66.184 +157.45.214.2 +223.188.169.116 +157.41.226.93 +157.40.252.93 +152.58.219.238 +42.105.16.71 +152.58.179.94 +157.34.195.225 +157.44.129.209 +171.51.142.219 +152.58.72.195 +157.49.67.140 +117.228.6.218 +42.105.133.118 +106.193.35.22 +223.185.90.143 +157.32.201.124 +106.204.201.3 +101.0.42.215 +157.38.149.20 +157.38.134.144 +42.104.129.100 +106.204.192.218 +117.96.188.88 +171.76.157.119 +152.58.230.96 +106.216.200.156 +106.207.83.123 +27.62.133.91 +152.57.237.123 +157.47.26.80 +106.197.105.48 +106.206.200.244 +42.105.226.84 +47.9.86.152 +106.207.26.22 +47.29.175.175 +157.34.89.93 +157.48.85.42 +137.97.111.187 +106.220.108.170 +157.37.170.74 +157.33.73.100 +152.57.211.225 +120.88.34.13 +157.35.57.228 +152.58.134.35 +106.196.87.186 +42.107.193.58 +223.182.28.27 +139.5.253.212 +132.154.38.191 +169.149.225.103 +47.15.4.128 +157.34.55.192 +103.16.29.63 +47.29.167.209 +42.111.21.180 +59.92.83.55 +47.9.117.66 +152.58.185.178 +49.14.165.146 +152.58.17.211 +42.109.222.25 +223.237.121.153 +223.187.24.238 +42.105.49.26 +106.217.146.209 +106.66.28.67 +157.45.177.169 +152.58.0.60 +49.36.122.101 +47.15.15.57 +157.40.252.208 +137.97.87.9 +157.45.160.105 +132.154.169.129 +157.48.74.9 +49.37.97.184 +157.47.46.131 +223.184.204.84 +117.98.116.89 +171.76.164.118 +49.15.226.249 +117.98.34.98 +47.15.210.236 +49.36.209.226 +42.105.19.56 +103.175.169.78 +49.35.139.187 +1.39.245.13 +106.79.192.89 +47.11.5.105 +49.15.227.171 +223.186.240.71 +47.31.143.8 +106.211.43.23 +157.47.0.166 +103.182.69.48 +47.15.119.114 +106.221.42.2 +61.3.250.80 +106.222.81.4 +152.57.30.230 +157.38.59.28 +103.81.182.106 +117.99.52.46 +117.230.148.206 +223.187.9.169 +157.51.198.70 +117.98.50.20 +223.238.104.27 +157.35.7.215 +27.60.105.236 +152.58.30.237 +47.11.195.225 +110.225.54.121 +157.32.119.173 +106.210.205.200 +49.43.34.43 +49.35.228.30 +47.15.33.98 +106.76.77.110 +1.39.78.120 +152.57.81.55 +117.230.150.58 +157.35.1.97 +157.32.211.152 +49.34.205.77 +157.42.248.121 +106.196.5.98 +157.34.124.229 +1.187.220.46 +106.76.94.97 +157.38.39.121 +106.221.255.228 +171.79.157.221 +106.210.181.109 +132.154.141.183 +157.35.83.229 +152.58.4.180 +152.58.18.116 +47.11.203.172 +47.11.76.102 +110.226.193.127 +49.35.233.122 +152.57.92.33 +223.228.75.85 +47.9.92.11 +106.207.81.34 +47.11.211.74 +157.32.70.244 +106.194.37.245 +157.39.66.133 +49.43.40.91 +49.36.223.217 +49.34.225.144 +27.61.41.122 +152.58.191.6 +47.9.124.238 +223.189.198.107 +117.201.156.220 +223.182.18.197 +152.57.47.73 +223.190.154.194 +157.51.125.63 +103.196.54.154 +47.29.174.217 +137.97.101.91 +152.58.154.183 +132.154.38.106 +27.60.193.120 +106.206.28.127 +47.15.146.119 +106.79.148.41 +47.9.88.74 +117.201.149.66 +157.41.241.183 +157.34.23.244 +223.187.111.94 +106.211.53.173 +106.221.178.176 +157.39.235.79 +112.79.157.174 +157.38.22.174 +137.97.117.135 +49.42.80.185 +106.205.205.172 +27.60.100.169 +106.195.87.67 +223.225.124.163 +157.39.65.151 +106.207.42.150 +152.57.195.64 +27.61.182.141 +152.57.65.60 +106.192.24.125 +106.221.112.108 +157.44.137.21 +49.34.136.55 +103.158.218.138 +47.15.113.199 +223.225.78.84 +106.66.250.42 +223.231.134.165 +49.37.72.211 +47.15.41.241 +223.180.184.63 +49.36.144.213 +157.33.254.77 +152.58.168.92 +47.29.171.4 +106.205.49.35 +113.21.70.145 +152.58.74.154 +152.58.74.240 +106.215.243.149 +157.34.0.215 +49.36.211.170 +49.37.75.208 +106.221.89.17 +110.224.76.102 +103.176.116.199 +157.40.242.31 +124.253.219.50 +157.49.251.176 +49.15.171.22 +106.216.228.13 +223.230.160.156 +47.9.36.8 +47.31.172.10 +157.34.150.47 +49.37.50.36 +223.237.112.210 +117.99.231.150 +49.36.211.72 +152.57.201.43 +110.224.87.54 +223.225.83.55 +106.216.118.214 +157.48.127.98 +157.48.131.182 +47.11.199.32 +47.9.77.72 +182.64.175.95 +49.42.82.29 +157.41.227.55 +157.42.0.238 +157.34.157.4 +106.195.0.85 +157.38.135.253 +152.58.156.136 +106.221.251.118 +49.36.184.181 +171.76.212.200 +223.225.251.29 +123.201.9.118 +106.194.33.204 +1.38.182.181 +103.40.198.172 +157.48.225.35 +49.35.192.57 +106.200.43.96 +106.198.40.51 +106.203.107.160 +103.155.222.113 +157.45.53.186 +47.11.197.210 +47.9.144.65 +202.142.104.185 +117.99.195.26 +157.45.195.61 +223.187.97.67 +47.11.199.78 +132.154.49.229 +106.192.43.34 +1.187.214.86 +49.36.27.240 +47.9.71.100 +157.38.203.48 +139.167.205.0 +106.207.189.134 +152.57.118.41 +171.76.233.187 +157.34.221.251 +49.34.185.11 +157.46.103.189 +106.221.28.194 +49.35.252.139 +49.34.224.241 +157.34.73.44 +157.38.118.156 +117.219.223.60 +157.34.109.12 +42.110.195.20 +49.32.240.82 +42.105.195.33 +223.237.103.237 +152.58.56.27 +132.154.143.48 +202.78.235.110 +157.32.36.47 +157.38.52.58 +223.239.48.168 +157.35.67.248 +157.41.229.81 +157.39.66.171 +27.62.223.179 +223.233.72.193 +157.35.69.224 +122.177.178.38 +45.249.86.71 +106.208.102.202 +42.106.16.26 +27.56.74.95 +122.167.115.35 +49.15.90.216 +157.45.184.95 +152.58.212.75 +106.208.84.143 +152.57.10.132 +106.206.206.36 +27.60.111.88 +27.63.221.71 +106.207.215.103 +223.182.40.168 +223.228.190.36 +157.33.121.135 +106.196.2.112 +132.154.133.166 +47.11.43.152 +106.193.14.148 +47.11.193.193 +42.111.196.2 +49.35.193.90 +157.41.229.232 +171.76.225.177 +116.68.72.73 +157.45.247.83 +157.46.78.43 +106.204.194.67 +157.35.26.156 +106.205.34.14 +223.238.208.211 +103.105.152.87 +152.58.191.223 +157.33.76.61 +1.187.57.243 +223.238.119.197 +106.206.27.161 +122.173.248.44 +157.42.224.110 +106.195.39.33 +110.227.29.167 +157.39.199.253 +122.171.20.53 +27.60.195.17 +110.224.67.197 +157.40.240.57 +157.38.196.70 +171.77.146.233 +157.50.66.79 +157.38.129.48 +223.231.237.181 +106.221.84.135 +49.35.238.151 +47.15.2.252 +157.48.206.44 +132.154.11.65 +132.154.49.150 +106.221.106.203 +132.154.49.82 +157.34.86.209 +106.216.118.175 +103.167.194.224 +106.206.46.3 +42.105.193.109 +49.34.232.116 +42.107.196.120 +223.230.165.102 +223.188.235.85 +157.39.72.92 +223.237.19.216 +169.149.225.113 +157.32.42.246 +42.104.153.40 +157.48.144.206 +152.58.17.93 +223.239.51.127 +106.220.70.103 +27.97.145.57 +157.41.229.158 +152.57.150.142 +157.45.37.3 +106.76.198.254 +106.76.245.138 +106.204.155.194 +117.96.154.129 +49.34.38.116 +157.35.16.225 +1.187.221.246 +49.36.105.5 +47.31.218.246 +223.182.30.240 +111.223.29.141 +157.45.130.116 +157.47.47.117 +106.220.155.105 +157.51.30.234 +103.136.64.252 +157.48.126.223 +117.99.223.205 +106.205.245.246 +132.154.154.92 +157.38.84.46 +103.89.60.59 +106.216.123.204 +106.76.214.208 +27.97.44.165 +117.230.138.166 +117.98.40.91 +47.247.199.2 +152.58.150.78 +157.41.229.216 +106.203.36.135 +106.207.52.34 +42.105.192.163 +157.41.229.82 +27.61.240.215 +47.11.75.182 +157.39.72.213 +223.225.243.201 +106.206.235.249 +157.35.2.99 +163.53.178.249 +106.196.70.205 +49.34.33.211 +47.11.199.16 +223.187.71.96 +106.203.29.49 +152.57.39.69 +49.15.176.172 +106.205.226.199 +106.194.165.219 +152.58.128.98 +27.56.223.141 +157.38.34.96 +106.66.56.9 +117.96.175.137 +106.216.245.140 +157.48.247.75 +49.15.250.9 +106.210.129.168 +157.38.145.66 +157.35.7.249 +49.35.155.106 +117.99.236.55 +47.31.99.226 +47.31.152.187 +157.38.151.0 +117.99.232.29 +106.79.201.58 +157.34.148.152 +157.48.89.140 +152.58.99.220 +157.49.177.64 +157.47.122.177 +223.190.185.234 +106.215.191.245 +171.76.83.142 +49.15.225.78 +1.39.79.104 +157.33.4.37 +49.35.230.123 +152.58.156.184 +157.40.231.185 +49.42.94.106 +106.223.96.37 +49.42.69.57 +157.50.48.50 +157.51.197.32 +114.31.131.85 +152.58.93.186 +1.187.57.31 +1.38.176.8 +157.35.2.146 +106.217.168.15 +49.37.66.4 +110.225.41.34 +49.14.128.92 +106.216.231.37 +223.227.90.34 +223.225.173.21 +106.221.191.249 +49.34.155.24 +112.79.154.180 +103.98.191.26 +152.58.23.185 +103.76.11.146 +47.15.22.182 +152.58.71.12 +106.206.200.51 +152.58.168.12 +152.58.21.70 +47.15.15.120 +49.42.93.14 +157.32.92.21 +27.63.58.133 +117.98.96.71 +106.223.140.220 +152.58.236.169 +157.32.40.3 +42.107.132.105 +42.108.125.35 +157.34.95.110 +157.42.3.33 +223.230.133.79 +157.47.117.165 +110.224.165.23 +157.48.255.56 +49.35.146.131 +106.211.101.73 +115.98.235.4 +157.38.193.80 +152.57.205.59 +223.186.189.120 +157.46.86.239 +106.211.195.15 +110.224.178.12 +157.34.154.129 +157.41.253.73 +42.105.194.103 +110.224.83.205 +112.133.246.34 +157.42.197.202 +157.48.130.247 +27.59.245.244 +106.221.63.238 +45.113.64.187 +152.58.190.77 +132.154.35.157 +106.213.240.203 +169.149.228.27 +117.99.22.161 +152.58.148.46 +49.32.250.189 +110.224.69.192 +157.35.5.65 +106.195.86.177 +27.63.32.83 +110.224.202.204 +157.51.195.205 +106.206.204.75 +157.38.207.201 +157.48.223.42 +117.235.9.52 +49.15.249.114 +49.14.106.19 +152.59.66.185 +47.29.0.37 +223.189.255.112 +110.227.57.136 +47.15.236.247 +106.78.51.112 +49.14.154.215 +49.43.101.113 +106.206.204.0 +110.224.171.12 +45.113.103.28 +1.38.80.108 +42.104.155.211 +152.58.34.155 +117.228.191.154 +157.48.115.107 +157.39.236.106 +152.58.210.170 +27.63.28.152 +223.182.12.185 +110.225.36.123 +110.226.201.120 +106.207.181.184 +157.38.139.219 +117.98.106.155 +157.38.220.207 +117.98.64.13 +27.56.15.201 +106.197.113.242 +49.15.212.177 +1.23.250.220 +132.154.22.65 +106.194.178.84 +47.11.10.216 +152.58.32.200 +157.33.36.234 +152.58.149.147 +157.37.176.78 +171.48.106.50 +157.47.38.30 +223.187.15.67 +117.249.252.132 +49.35.246.13 +49.35.139.240 +103.85.207.6 +106.192.130.147 +42.105.154.38 +103.181.15.239 +122.169.36.47 +106.198.4.57 +106.221.38.78 +171.76.136.2 +49.34.79.1 +106.221.46.118 +157.39.69.129 +157.32.35.195 +157.40.94.154 +152.58.19.75 +49.34.54.208 +47.247.220.134 +47.15.12.64 +139.167.163.82 +152.58.138.145 +223.184.175.66 +157.48.173.113 +157.47.20.124 +106.208.15.202 +223.187.243.15 +106.221.165.17 +157.47.86.166 +152.58.197.43 +157.34.117.60 +117.96.170.114 +157.42.209.200 +47.9.70.248 +157.34.4.33 +223.238.204.102 +223.187.142.215 +49.15.161.142 +152.58.231.171 +171.51.131.129 +157.45.94.252 +110.227.179.129 +27.60.207.222 +132.154.52.217 +178.248.114.122 +152.58.234.128 +157.49.231.130 +223.187.118.25 +152.59.65.234 +157.51.197.79 +223.238.146.229 +42.105.97.36 +49.15.228.46 +152.59.67.128 +106.193.218.20 +157.41.224.128 +27.5.157.174 +152.58.95.74 +152.57.84.84 +106.208.158.132 +157.39.68.31 +106.210.179.129 +27.59.173.128 +157.34.157.55 +49.204.113.244 +103.109.74.22 +117.253.78.163 +139.167.199.239 +115.187.40.67 +106.195.15.69 +157.38.99.54 +103.15.252.17 +47.9.89.233 +152.58.200.216 +223.227.92.120 +157.41.251.154 +157.34.67.75 +110.227.56.59 +47.9.139.183 +157.38.3.88 +112.79.114.97 +42.104.158.57 +152.57.149.49 +49.42.87.120 +106.221.113.16 +42.105.137.69 +106.211.96.210 +106.195.9.216 +106.216.254.11 +42.111.196.11 +157.34.82.58 +171.79.149.148 +117.210.201.154 +49.14.113.67 +171.76.210.231 +106.77.187.200 +47.9.9.52 +152.58.56.185 +157.40.230.222 +157.46.117.112 +47.9.86.24 +157.41.251.115 +152.57.235.33 +103.212.158.17 +157.34.16.99 +47.15.165.126 +106.76.253.212 +157.32.244.132 +103.40.198.37 +223.230.129.206 +106.216.235.13 +152.59.66.82 +103.229.129.122 +49.37.65.178 +157.38.136.157 +152.57.171.158 +49.32.241.60 +157.42.200.235 +223.188.169.173 +152.57.231.222 +111.223.26.79 +106.76.31.99 +157.47.44.37 +157.47.63.63 +106.204.233.39 +42.105.96.2 +42.105.175.120 +49.15.230.53 +103.72.217.53 +106.198.163.185 +47.11.226.252 +106.206.243.200 +49.14.151.10 +157.34.35.24 +27.59.253.19 +47.9.139.134 +152.57.143.90 +157.33.209.207 +223.230.150.247 +117.206.45.40 +103.183.35.135 +157.48.237.38 +157.38.31.110 +117.234.153.128 +152.58.196.209 +47.9.152.169 +157.34.86.244 +152.58.214.196 +103.170.54.152 +157.38.109.107 +27.59.182.132 +106.211.145.45 +117.96.141.7 +42.106.188.208 +117.97.214.13 +106.221.211.142 +157.119.82.182 +223.186.34.76 +106.76.210.81 +42.105.3.198 +223.187.143.135 +47.11.209.204 +47.29.169.158 +106.208.176.15 +152.57.237.13 +42.105.88.177 +157.35.57.95 +27.61.106.11 +47.15.3.186 +106.216.253.8 +152.58.189.103 +42.108.196.176 +27.62.194.222 +160.202.37.212 +106.223.194.83 +157.33.125.215 +157.34.133.89 +137.97.86.192 +169.149.230.115 +152.58.83.162 +157.41.249.45 +49.35.157.196 +157.32.40.192 +42.104.158.95 +106.207.214.212 +49.14.154.242 +106.200.82.30 +152.58.49.17 +152.58.197.168 +150.129.53.169 +157.35.26.223 +106.200.86.193 +223.187.178.129 +223.190.249.176 +152.58.34.176 +157.45.71.28 +223.187.184.30 +152.57.115.84 +157.51.187.231 +49.15.94.230 +223.186.228.246 +117.99.238.87 +223.188.30.106 +117.96.176.30 +47.9.143.168 +49.32.246.40 +106.205.14.94 +106.200.92.151 +47.9.82.171 +117.98.108.98 +152.57.30.109 +49.15.136.235 +139.5.28.35 +106.78.37.231 +47.9.153.140 +171.51.169.95 +223.186.34.218 +117.98.62.78 +152.58.89.221 +223.238.158.59 +49.35.194.35 +106.217.46.183 +157.38.48.20 +157.35.3.223 +47.11.196.99 +47.9.93.219 +42.108.196.109 +42.108.196.70 +106.206.202.136 +49.36.209.81 +157.38.29.20 +117.230.180.196 +110.227.56.30 +49.34.246.172 +106.222.57.183 +42.111.107.6 +106.221.247.158 +103.165.20.140 +157.35.2.103 +117.99.2.44 +169.149.225.118 +157.38.147.151 +223.186.204.75 +106.78.53.232 +106.209.243.144 +106.197.133.150 +152.58.200.141 +49.205.249.79 +157.35.20.22 +106.195.34.252 +27.60.98.187 +223.233.32.40 +49.35.235.147 +47.11.197.51 +27.61.107.13 +106.206.218.204 +152.58.21.91 +122.169.18.177 +117.98.44.70 +157.41.192.102 +106.197.67.79 +117.98.104.163 +42.105.18.211 +157.41.252.37 +157.38.49.52 +117.249.228.55 +117.96.172.179 +106.220.86.86 +157.39.64.50 +137.97.71.155 +157.49.186.128 +49.15.187.84 +157.39.65.242 +117.97.211.187 +157.42.197.195 +132.154.18.135 +42.105.177.183 +49.37.25.218 +157.48.151.76 +106.207.39.69 +103.217.116.109 +171.79.149.27 +152.57.71.123 +103.148.20.28 +47.11.225.241 +47.15.32.46 +152.58.236.1 +49.37.49.53 +106.197.114.69 +157.45.195.133 +223.187.97.229 +223.190.135.246 +157.41.248.199 +157.34.65.154 +47.11.253.248 +157.35.15.179 +223.237.100.140 +139.5.36.101 +157.45.156.46 +223.187.15.223 +110.226.178.5 +157.48.156.210 +42.111.107.19 +139.167.178.127 +157.34.17.254 +106.76.250.189 +106.197.3.237 +157.41.224.6 +223.185.115.11 +42.111.9.107 +157.46.143.241 +157.32.101.93 +103.124.109.77 +137.97.109.210 +223.239.26.24 +132.154.162.229 +132.154.55.175 +152.58.231.81 +157.38.23.180 +47.29.163.244 +106.203.48.74 +49.43.251.87 +152.58.109.42 +157.38.137.119 +117.230.89.253 +106.196.14.133 +106.208.22.97 +157.51.158.238 +223.225.121.36 +157.42.242.144 +157.45.231.86 +223.230.157.199 +157.33.100.135 +106.77.165.155 +110.224.91.53 +157.39.75.32 +47.15.109.108 +223.189.193.140 +106.206.234.54 +106.206.249.128 +169.149.231.19 +106.208.157.202 +61.3.213.206 +106.66.239.222 +152.58.151.202 +42.105.129.34 +47.29.171.65 +152.58.139.38 +152.58.128.181 +157.33.240.245 +106.211.88.27 +157.48.219.210 +1.39.98.7 +49.35.234.200 +223.187.101.182 +157.35.27.94 +152.57.180.82 +117.214.117.77 +110.227.32.112 +157.34.48.149 +117.98.52.25 +152.58.162.206 +157.46.83.216 +152.58.196.82 +157.45.163.255 +223.187.33.33 +223.225.161.117 +106.216.114.222 +47.15.7.4 +42.105.180.72 +106.221.83.41 +157.32.103.127 +110.224.103.228 +42.111.127.11 +49.36.219.197 +205.253.11.1 +182.68.138.239 +157.41.254.182 +132.154.49.128 +42.105.172.151 +49.43.5.14 +122.163.88.144 +45.119.31.36 +49.32.179.1 +110.227.48.181 +27.62.238.228 +106.206.219.140 +106.221.97.73 +157.39.65.86 +47.15.10.7 +139.167.200.89 +157.34.26.145 +49.15.231.216 +223.238.102.228 +157.34.19.208 +106.221.14.29 +106.217.69.57 +223.181.226.157 +157.32.65.240 +157.48.162.133 +27.57.196.178 +157.39.250.180 +157.44.192.7 +106.211.90.159 +106.206.182.22 +169.149.230.168 +157.51.197.22 +110.225.53.68 +49.35.243.48 +42.108.124.33 +152.57.226.12 +152.58.105.29 +157.38.128.160 +110.224.177.83 +223.188.230.150 +106.76.209.61 +157.48.179.103 +152.57.64.77 +223.189.47.178 +42.105.48.251 +152.58.129.216 +203.115.84.213 +47.31.218.147 +152.59.65.236 +223.189.179.251 +27.62.217.229 +157.42.215.118 +110.224.86.65 +42.107.193.181 +106.217.169.178 +157.42.211.109 +49.15.213.190 +42.105.202.21 +152.58.162.145 +27.62.171.2 +27.59.237.192 +106.219.107.55 +47.9.140.75 +106.207.169.79 +202.78.232.114 +42.105.14.34 +106.207.194.224 +106.196.77.176 +49.42.87.102 +117.96.184.48 +103.240.205.61 +157.35.46.138 +157.48.191.47 +132.154.29.159 +59.96.200.151 +132.154.49.164 +42.106.160.167 +47.11.238.63 +49.36.71.194 +223.233.27.208 +49.14.155.123 +157.51.193.147 +45.127.88.223 +223.237.108.155 +152.58.138.29 +136.185.38.126 +1.38.194.88 +157.44.156.129 +152.58.16.77 +223.185.101.82 +223.189.172.72 +106.217.21.43 +117.234.53.203 +103.87.105.63 +49.32.253.9 +106.194.189.231 +152.57.10.115 +152.58.167.36 +42.106.184.202 +223.187.67.211 +205.253.39.99 +106.76.209.144 +157.44.183.141 +42.105.206.134 +223.225.170.81 +47.9.72.61 +182.69.178.64 +171.76.211.52 +152.58.123.149 +49.34.130.193 +42.111.161.6 +106.220.109.58 +49.207.202.238 +223.238.94.67 +157.38.93.159 +42.105.203.27 +42.105.207.200 +205.253.9.19 +106.210.225.26 +43.241.144.253 +47.11.0.111 +106.195.79.238 +49.37.226.58 +106.208.238.176 +157.34.208.251 +157.45.194.253 +106.76.71.66 +117.98.116.23 +49.35.163.240 +152.58.24.61 +117.96.128.205 +152.58.118.168 +49.15.136.180 +106.66.3.238 +106.207.67.80 +47.15.42.160 +157.45.202.163 +157.41.227.174 +106.221.230.222 +110.226.161.238 +152.58.17.96 +103.178.204.110 +157.35.45.148 +49.35.233.209 +49.36.136.38 +157.38.130.113 +1.39.76.71 +124.253.169.203 +152.58.197.179 +106.221.242.36 +152.58.162.212 +47.11.59.231 +49.32.135.143 +157.34.26.119 +157.46.94.142 +103.102.87.131 +223.187.103.108 +157.51.83.197 +106.79.207.88 +152.58.226.163 +47.9.130.73 +171.48.90.104 +106.200.88.145 +49.32.153.50 +106.211.72.56 +110.224.104.213 +183.87.6.197 +157.33.23.102 +49.35.139.87 +103.172.130.70 +106.198.41.244 +157.35.6.74 +42.108.196.255 +223.187.159.37 +47.15.4.216 +117.98.14.110 +47.247.222.211 +157.41.227.126 +103.85.206.61 +157.34.0.254 +106.192.207.194 +47.15.211.193 +106.194.13.180 +49.15.213.72 +117.243.205.200 +110.227.60.19 +106.205.43.224 +110.224.78.31 +106.194.28.46 +152.58.88.123 +42.104.155.101 +157.47.49.84 +42.105.49.8 +157.38.135.104 +157.51.192.146 +157.34.207.81 +223.187.155.233 +157.33.3.224 +106.223.220.53 +223.187.99.114 +223.188.47.239 +152.58.88.158 +223.231.223.195 +152.57.101.5 +223.231.132.89 +49.43.33.97 +152.58.188.24 +106.223.206.198 +106.220.104.254 +157.34.198.189 +49.35.167.112 +157.33.247.205 +49.36.210.15 +47.15.14.186 +42.105.177.37 +157.33.2.23 +1.39.28.236 +106.220.83.139 +157.45.223.13 +157.51.195.40 +122.161.92.41 +152.58.25.111 +157.40.198.234 +47.9.148.19 +223.186.190.39 +203.81.240.27 +49.15.185.33 +106.195.15.161 +157.49.79.239 +223.188.55.6 +106.216.251.134 +117.97.76.50 +47.9.110.179 +223.186.193.94 +59.93.23.127 +106.216.118.211 +157.47.20.133 +110.227.52.125 +110.225.95.250 +47.11.73.235 +152.58.34.25 +42.105.17.79 +47.29.175.136 +157.38.242.58 +157.35.42.250 +171.51.136.242 +152.58.98.225 +157.47.30.67 +157.47.51.52 +47.11.252.130 +106.194.215.175 +223.189.184.58 +47.29.162.135 +157.41.225.7 +157.35.81.102 +169.149.227.46 +106.207.251.156 +49.34.149.152 +152.57.185.171 +106.211.9.94 +106.194.200.136 +27.61.106.70 +171.48.116.212 +223.188.159.62 +42.106.178.5 +47.11.193.51 +157.48.131.54 +106.193.136.155 +106.216.202.69 +157.35.1.169 +116.193.136.84 +27.60.34.99 +117.214.195.85 +157.40.109.185 +157.38.103.100 +157.33.31.126 +47.9.4.88 +106.221.208.88 +114.31.164.91 +47.11.248.197 +106.77.166.243 +47.15.0.18 +42.105.73.182 +103.251.226.93 +157.33.11.125 +117.99.18.10 +114.31.151.168 +152.58.163.66 +152.58.59.73 +157.45.63.248 +157.50.69.167 +1.38.48.3 +132.154.35.22 +49.36.191.68 +27.61.114.4 +223.228.251.226 +223.187.97.11 +42.105.157.130 +203.115.103.182 +49.34.185.107 +117.99.228.75 +47.9.95.177 +152.58.178.130 +47.15.102.128 +49.42.90.63 +49.42.85.197 +106.217.201.77 +223.233.116.92 +223.189.243.203 +47.15.11.196 +157.45.63.50 +117.99.232.217 +49.34.87.19 +132.154.52.190 +69.162.75.9 +49.42.66.14 +117.98.116.87 +122.171.16.209 +47.9.64.41 +27.59.248.251 +223.189.207.144 +106.76.76.5 +223.225.248.188 +157.47.116.105 +61.1.231.81 +45.249.85.39 +152.58.166.141 +106.202.62.54 +157.34.218.75 +27.59.16.226 +106.221.180.80 +47.11.252.59 +27.63.9.104 +223.176.22.25 +152.58.153.132 +152.58.128.74 +106.198.119.95 +157.41.242.75 +106.196.19.235 +117.99.205.66 +157.48.124.129 +152.58.70.225 +132.154.162.15 +111.92.117.223 +106.204.38.43 +47.29.166.247 +106.194.145.206 +157.47.86.114 +103.232.239.182 +152.58.88.82 +157.32.92.172 +27.57.48.214 +157.48.246.144 +103.253.151.101 +49.14.157.110 +49.36.218.208 +106.194.107.55 +117.210.170.182 +157.34.221.155 +157.42.194.230 +106.206.96.79 +1.187.180.86 +169.149.198.135 +157.41.242.9 +47.29.167.98 +157.32.37.125 +132.154.56.249 +115.96.155.245 +27.63.25.1 +139.167.244.206 +42.105.205.108 +106.216.240.200 +42.108.4.95 +27.63.9.202 +157.42.6.188 +106.220.254.32 +49.36.144.63 +152.58.70.84 +152.58.34.187 +223.187.111.4 +157.42.1.145 +110.226.202.96 +171.76.232.230 +47.11.199.21 +223.228.242.158 +106.207.13.174 +223.237.97.142 +157.42.4.146 +157.47.53.252 +157.33.56.126 +106.206.238.33 +152.58.104.45 +49.35.190.209 +132.154.57.20 +157.34.240.175 +117.96.178.128 +132.154.57.29 +157.47.63.225 +106.216.79.232 +49.42.90.144 +152.58.34.88 +106.222.123.121 +106.193.51.74 +157.45.88.161 +49.43.90.40 +223.228.41.58 +106.210.208.145 +110.227.62.174 +110.225.58.108 +152.58.97.138 +49.36.208.1 +103.170.55.64 +106.216.118.209 +223.188.123.17 +103.157.127.229 +103.250.164.225 +223.190.174.188 +223.233.120.106 +157.38.251.204 +49.35.135.223 +47.15.1.44 +157.40.87.244 +106.221.187.96 +47.9.112.30 +152.58.157.188 +152.58.159.207 +117.98.118.50 +157.33.214.190 +106.76.197.51 +157.42.253.213 +157.33.249.138 +157.35.63.208 +117.98.36.65 +157.39.68.112 +49.37.177.218 +157.49.226.216 +47.11.198.73 +103.57.85.100 +157.38.130.226 +152.58.34.184 +42.111.165.179 +42.104.211.69 +157.34.35.45 +157.39.207.216 +223.226.27.97 +106.208.237.145 +106.66.41.12 +157.47.37.246 +47.15.209.137 +117.99.212.190 +157.35.23.146 +152.58.125.238 +106.198.36.108 +106.208.94.209 +42.105.232.187 +49.42.73.236 +152.57.243.247 +157.34.251.63 +223.187.38.161 +157.32.234.81 +157.50.53.207 +157.34.24.201 +49.205.242.197 +106.79.204.195 +117.98.124.14 +106.207.64.40 +114.31.148.17 +152.58.169.65 +59.96.177.213 +223.186.54.216 +49.34.144.181 +49.35.133.55 +157.39.75.209 +152.58.38.9 +106.205.207.185 +223.187.17.93 +49.36.169.181 +223.185.127.235 +49.34.253.56 +47.11.197.105 +223.231.161.165 +122.182.162.49 +223.230.133.205 +106.220.83.174 +117.98.122.119 +157.50.38.112 +106.208.182.22 +157.49.194.234 +152.58.59.81 +157.42.248.191 +103.206.100.232 +223.189.234.26 +49.15.246.81 +1.39.100.85 +152.58.179.146 +106.206.198.229 +106.221.24.58 +114.31.137.134 +157.42.4.45 +117.99.229.140 +223.177.81.195 +157.38.38.195 +152.57.195.176 +171.48.114.210 +42.105.73.92 +132.154.151.55 +122.175.147.192 +157.42.230.25 +223.227.35.9 +27.56.229.148 +157.39.73.24 +49.34.58.0 +106.206.254.245 +152.58.34.54 +27.56.1.74 +106.77.135.146 +157.38.253.123 +106.204.192.135 +152.58.0.30 +106.200.45.49 +106.211.208.140 +117.98.52.10 +157.48.85.43 +42.105.102.184 +223.185.78.49 +117.99.249.83 +47.15.173.132 +157.40.240.87 +157.47.123.122 +171.76.209.7 +1.187.87.106 +110.224.67.44 +223.187.43.175 +106.196.12.139 +157.38.32.57 +49.43.153.58 +42.105.197.142 +223.189.252.43 +47.9.150.152 +1.38.72.96 +157.48.170.174 +49.35.236.47 +132.154.53.244 +117.98.64.184 +103.167.194.166 +106.76.48.196 +171.48.96.119 +152.58.187.84 +223.187.19.227 +27.59.253.223 +117.97.208.239 +223.188.174.6 +171.51.164.132 +157.35.53.223 +106.216.195.95 +223.186.95.11 +157.48.231.95 +103.49.54.47 +152.57.46.27 +157.47.65.205 +103.83.222.142 +139.167.233.71 +223.237.8.103 +106.196.123.96 +132.154.61.253 +106.219.177.88 +152.58.17.218 +223.187.23.110 +152.58.118.79 +157.42.245.40 +171.76.212.157 +49.35.170.85 +103.183.54.148 +106.197.106.64 +183.87.13.224 +110.224.122.167 +157.40.79.196 +110.226.204.39 +106.195.12.85 +157.35.40.61 +223.182.221.174 +152.58.94.110 +152.57.51.95 +47.11.35.242 +223.237.8.201 +157.42.217.109 +157.34.140.253 +49.42.75.49 +49.34.244.125 +49.206.35.165 +169.149.227.155 +110.224.66.122 +42.106.80.237 +157.49.214.110 +117.98.48.129 +139.167.173.7 +42.106.189.241 +157.34.138.212 +157.45.187.105 +132.154.59.46 +106.221.240.243 +103.170.177.131 +157.42.194.124 +106.207.250.171 +49.204.17.81 +112.79.121.31 +152.58.78.147 +110.227.60.249 +152.57.100.102 +125.99.241.119 +106.215.141.183 +157.45.60.111 +47.15.8.216 +157.40.240.66 +132.154.60.30 +59.182.154.181 +157.34.34.169 +117.96.186.132 +27.56.255.145 +117.96.184.2 +47.9.99.66 +106.196.6.254 +106.67.104.59 +223.196.193.41 +49.32.137.48 +117.194.97.152 +223.187.111.18 +27.60.40.203 +132.154.170.187 +106.200.37.216 +106.205.243.97 +27.60.111.90 +106.217.179.90 +106.211.109.30 +117.205.42.110 +157.35.48.118 +106.77.184.18 +43.249.235.216 +157.42.234.174 +103.55.96.109 +42.105.172.33 +223.180.186.144 +49.35.251.92 +157.45.178.111 +157.39.64.130 +157.51.189.252 +106.216.101.82 +132.154.52.244 +157.39.69.131 +47.29.169.197 +106.196.116.99 +112.79.112.159 +157.38.226.151 +1.38.98.160 +157.41.199.100 +49.34.103.103 +223.187.99.43 +157.34.219.45 +117.234.236.1 +49.35.243.196 +157.50.49.78 +169.149.195.27 +106.193.43.23 +103.155.210.2 +42.105.13.150 +116.206.201.20 +42.104.134.21 +106.216.138.242 +152.57.163.29 +157.45.153.240 +110.224.78.13 +106.202.91.165 +42.105.12.223 +106.216.246.224 +106.205.195.158 +152.58.39.61 +103.91.72.76 +157.37.135.215 +42.106.16.4 +49.37.146.3 +157.38.196.236 +157.32.215.36 +47.15.43.84 +139.167.222.248 +117.98.46.215 +157.48.112.166 +157.45.221.31 +152.58.162.81 +223.237.113.198 +49.36.111.157 +42.105.225.21 +223.190.184.55 +1.187.220.73 +49.36.16.135 +223.225.122.152 +157.46.83.103 +223.225.252.168 +157.39.219.65 +110.224.16.109 +1.39.79.66 +1.38.80.52 +171.76.237.134 +42.109.192.169 +152.57.149.205 +42.104.145.18 +223.184.149.18 +202.168.86.196 +27.60.98.11 +223.231.158.54 +157.35.25.68 +110.226.244.194 +106.77.130.86 +49.35.230.153 +223.186.44.234 +106.220.97.41 +157.38.137.207 +49.34.44.53 +157.48.74.70 +157.37.161.66 +157.48.136.119 +157.41.253.6 +157.34.207.47 +47.29.163.104 +223.230.98.194 +27.58.171.247 +122.161.68.154 +157.40.253.198 +223.231.152.253 +47.11.60.126 +49.35.168.74 +152.58.17.132 +103.26.226.156 +157.42.202.182 +47.11.85.87 +27.56.212.160 +42.106.217.35 +49.35.251.172 +103.179.230.159 +157.47.97.96 +171.76.9.73 +152.57.12.176 +157.48.220.151 +157.34.61.184 +103.168.62.60 +106.206.0.25 +117.99.255.200 +116.206.159.82 +106.211.90.237 +49.43.153.249 +117.98.72.1 +117.96.154.65 +106.207.244.122 +110.224.102.211 +42.105.78.196 +157.39.69.50 +152.58.179.193 +157.34.235.145 +152.57.173.11 +152.58.186.168 +49.37.40.22 +157.42.203.104 +47.9.147.124 +223.189.11.189 +150.129.104.199 +157.34.72.211 +157.42.235.35 +157.42.247.136 +49.37.96.100 +157.33.93.132 +106.196.93.237 +106.196.21.86 +42.108.18.52 +117.99.21.90 +157.45.129.143 +1.38.141.78 +27.59.157.78 +152.58.17.20 +103.179.196.107 +49.14.95.145 +157.40.104.169 +223.231.228.44 +27.61.81.239 +157.51.195.177 +117.99.44.97 +157.35.12.142 +223.182.214.241 +157.34.10.12 +223.230.175.219 +152.57.17.111 +157.41.252.211 +106.194.20.111 +27.61.66.5 +106.217.205.166 +106.221.250.55 +42.109.222.55 +42.111.20.51 +117.209.183.138 +49.36.185.128 +106.77.156.73 +157.34.103.185 +106.207.171.19 +106.211.55.220 +223.190.129.197 +152.58.190.40 +112.79.59.94 +47.11.202.193 +223.238.124.232 +152.57.208.45 +106.198.232.159 +223.227.82.82 +223.179.236.78 +49.34.234.117 +157.38.2.147 +27.123.242.147 +110.224.94.27 +106.76.91.28 +223.187.198.47 +103.220.210.7 +1.187.56.143 +157.34.232.189 +132.154.166.65 +47.15.10.100 +106.219.222.49 +157.38.28.158 +122.173.26.244 +47.11.66.83 +103.179.231.176 +157.33.251.13 +47.9.108.237 +157.41.229.226 +152.58.26.96 +152.58.97.35 +106.207.248.24 +1.187.215.215 +49.42.33.89 +49.43.100.125 +103.91.86.189 +106.78.78.91 +106.193.6.5 +47.11.204.55 +106.220.104.191 +137.97.107.88 +117.98.86.140 +47.15.5.218 +106.205.38.184 +110.227.18.106 +47.11.195.139 +223.189.199.87 +223.231.177.134 +157.33.82.10 +152.58.148.228 +49.34.157.72 +47.11.253.71 +152.58.129.80 +47.15.21.178 +42.105.136.81 +42.105.164.51 +157.33.107.217 +49.36.192.150 +106.221.51.100 +223.238.98.21 +106.206.247.223 +106.195.110.229 +223.185.91.148 +47.9.100.134 +49.36.68.200 +49.42.36.155 +47.9.67.110 +152.58.214.54 +27.61.82.235 +157.48.115.64 +49.34.37.253 +157.39.226.244 +157.45.154.77 +106.195.72.130 +49.36.69.44 +157.39.71.150 +157.48.125.154 +103.155.223.81 +157.48.148.89 +152.58.184.253 +106.195.72.12 +157.38.147.33 +113.193.129.184 +49.43.100.123 +49.35.189.142 +223.186.20.36 +112.79.125.191 +106.208.155.97 +223.187.58.188 +47.29.167.183 +152.58.31.26 +183.83.213.215 +106.219.121.181 +110.226.197.38 +27.57.207.99 +115.187.46.79 +157.33.24.102 +157.46.171.252 +223.225.59.70 +223.230.170.246 +106.216.250.217 +152.58.148.130 +223.187.91.200 +157.42.6.183 +47.15.192.160 +49.15.227.194 +157.48.189.72 +117.98.46.29 +132.154.7.18 +152.57.163.110 +152.58.129.106 +106.217.157.233 +157.37.133.150 +157.50.49.119 +223.187.106.167 +1.38.164.141 +157.38.131.201 +42.108.74.23 +106.66.56.123 +49.15.202.218 +117.234.174.93 +152.58.22.234 +111.92.124.200 +49.35.193.218 +157.37.170.90 +103.42.197.87 +106.211.250.181 +117.99.195.222 +103.194.69.131 +106.203.137.219 +157.45.155.142 +49.34.214.29 +157.41.228.237 +157.35.50.108 +49.15.229.86 +152.58.168.247 +157.33.31.161 +157.51.79.165 +223.188.61.39 +47.9.136.196 +120.138.12.199 +223.186.189.142 +169.149.226.87 +157.48.162.141 +27.57.28.240 +157.38.144.155 +171.51.161.226 +157.48.226.41 +106.206.241.110 +27.60.28.157 +103.41.25.18 +117.98.114.133 +205.254.167.207 +47.247.197.7 +157.51.185.250 +106.207.161.101 +223.176.14.98 +49.14.105.3 +205.253.37.30 +47.15.1.126 +223.185.116.67 +152.58.156.118 +106.221.90.62 +157.42.5.30 +106.220.244.217 +157.50.66.89 +122.161.50.135 +106.76.253.128 +157.44.215.230 +157.33.92.108 +49.35.242.95 +47.15.40.219 +157.48.155.74 +42.105.199.71 +106.206.204.91 +152.57.192.228 +47.11.200.98 +157.34.126.210 +106.197.84.54 +42.105.19.120 +47.9.133.118 +106.197.143.209 +106.206.94.22 +157.40.84.218 +202.14.123.18 +49.43.100.8 +49.42.67.202 +157.46.159.109 +106.196.6.95 +106.67.79.25 +157.32.67.67 +157.42.0.149 +27.63.51.31 +110.227.63.220 +223.237.107.206 +132.154.58.79 +152.58.187.36 +106.215.231.1 +157.42.208.40 +112.79.159.101 +152.57.4.237 +47.15.147.30 +152.58.34.48 +152.58.218.35 +110.226.194.37 +152.57.208.115 +42.110.171.207 +103.62.92.146 +157.34.153.239 +132.154.159.121 +171.76.231.133 +152.58.25.134 +49.35.242.217 +110.224.105.240 +106.76.222.27 +157.42.225.250 +132.154.61.97 +157.38.148.177 +103.166.245.6 +106.76.91.26 +157.35.55.11 +27.61.132.34 +223.189.217.130 +49.36.221.189 +117.99.220.119 +106.216.124.36 +47.15.5.47 +157.41.255.75 +152.57.77.72 +157.41.251.236 +223.239.70.104 +157.34.217.212 +110.224.89.199 +27.63.65.244 +157.34.5.193 +139.167.201.138 +49.32.243.124 +106.77.79.21 +152.57.116.60 +47.9.35.248 +110.224.71.169 +137.97.103.164 +59.89.196.203 +49.36.69.159 +157.38.133.106 +117.98.76.49 +157.35.2.108 +223.187.8.159 +42.108.196.222 +157.37.165.8 +106.221.219.212 +49.35.255.137 +103.179.115.54 +152.58.236.78 +152.58.230.99 +157.41.251.136 +157.35.14.186 +152.57.97.158 +49.37.104.252 +1.187.26.114 +157.51.197.18 +152.57.228.111 +49.42.91.39 +152.58.157.44 +150.107.177.122 +49.42.65.221 +106.211.64.158 +157.37.171.169 +106.213.246.213 +106.196.13.126 +152.57.133.231 +49.37.64.159 +112.79.141.120 +157.50.50.78 +157.41.248.130 +152.58.188.168 +223.181.234.213 +152.58.155.101 +169.149.231.88 +106.210.196.70 +157.38.247.227 +106.216.237.140 +169.149.227.3 +152.58.25.47 +117.255.123.3 +157.38.136.245 +47.9.92.138 +110.224.166.135 +49.32.156.125 +49.207.63.159 +49.37.235.87 +157.40.95.17 +117.98.104.94 +103.149.159.30 +223.190.134.237 +117.99.199.154 +157.45.73.133 +106.213.216.166 +223.188.253.28 +49.15.227.126 +106.206.107.120 +157.34.11.8 +223.236.59.8 +223.186.219.49 +106.78.178.141 +152.58.189.172 +157.47.17.197 +106.208.146.108 +223.187.109.69 +171.79.184.190 +169.149.192.33 +42.104.136.16 +171.76.240.244 +106.78.182.203 +47.9.112.78 +110.225.38.90 +106.66.62.83 +47.15.1.235 +106.217.181.0 +157.48.193.81 +27.63.37.121 +152.58.84.57 +157.38.53.148 +132.154.58.238 +49.42.65.17 +111.92.27.172 +157.50.10.229 +106.220.192.179 +1.39.78.133 +152.58.215.162 +157.38.232.31 +157.51.13.143 +223.238.198.77 +106.79.204.57 +106.195.12.55 +106.220.136.52 +47.11.225.158 +47.29.160.173 +183.83.230.130 +139.167.245.166 +103.178.205.172 +117.98.86.142 +106.207.126.94 +169.149.229.133 +49.205.140.168 +106.208.143.56 +152.58.188.230 +171.79.148.9 +110.224.167.151 +106.198.87.116 +223.180.178.229 +117.98.98.105 +157.47.85.163 +152.58.34.74 +157.34.196.226 +106.222.36.7 +202.71.9.246 +103.166.245.177 +139.167.232.251 +139.167.218.9 +27.61.81.242 +27.63.79.224 +117.98.78.44 +45.118.74.48 +106.76.69.146 +180.188.237.144 +106.78.83.1 +27.60.100.231 +106.222.3.1 +106.206.76.31 +106.214.130.66 +42.104.145.34 +103.193.88.195 +223.239.3.155 +157.42.240.62 +117.99.42.134 +106.216.244.174 +223.189.16.80 +157.41.252.214 +116.72.10.97 +27.62.63.98 +157.47.16.208 +117.226.218.192 +152.58.102.251 +171.79.149.128 +117.96.154.1 +42.106.32.197 +152.57.225.213 +106.211.11.215 +106.77.133.179 +106.207.132.122 +110.226.179.179 +49.35.226.145 +42.105.1.97 +106.195.85.79 +152.58.152.48 +157.42.5.200 +106.193.206.49 +223.190.155.247 +106.194.199.137 +106.217.20.88 +152.57.189.219 +106.196.47.215 +106.216.114.208 +49.36.24.167 +110.224.76.253 +122.161.78.62 +152.58.131.68 +152.57.18.207 +157.38.129.126 +106.204.131.232 +106.207.241.213 +106.76.222.24 +117.234.11.231 +157.34.142.252 +1.39.240.22 +223.187.17.53 +106.66.37.109 +27.97.65.9 +223.187.7.112 +223.225.170.139 +110.225.9.168 +49.15.247.106 +223.238.119.133 +157.42.244.78 +49.37.75.226 +59.95.208.75 +157.49.240.6 +157.33.200.234 +49.43.101.16 +49.32.164.241 +1.39.96.109 +157.34.98.161 +47.29.173.46 +157.48.193.226 +157.48.89.9 +157.42.5.79 +49.43.217.252 +157.33.47.12 +139.167.204.161 +27.59.183.140 +106.206.112.180 +47.15.7.179 +106.222.53.57 +152.58.185.110 +205.253.32.0 +49.14.156.253 +27.60.241.245 +157.47.120.212 +171.76.129.252 +157.40.229.228 +106.208.145.77 +106.76.197.190 +223.188.47.66 +171.79.149.227 +223.189.202.252 +169.149.227.142 +117.233.96.248 +47.29.170.141 +106.51.119.1 +112.79.158.127 +47.9.37.77 +103.177.253.246 +49.42.85.84 +157.35.83.113 +205.253.126.94 +49.35.195.203 +49.14.130.24 +106.207.161.191 +157.34.128.63 +47.9.158.224 +157.34.124.65 +110.224.94.33 +106.220.250.243 +152.58.135.188 +223.186.117.149 +106.216.113.31 +49.42.72.170 +139.167.162.252 +47.29.160.214 +103.85.11.111 +157.33.27.102 +223.225.98.146 +47.9.34.35 +152.58.39.246 +152.58.79.48 +27.56.5.166 +139.167.253.176 +139.167.236.100 +47.31.99.61 +106.194.83.70 +106.207.226.129 +49.34.192.27 +152.57.202.133 +157.32.217.237 +203.192.205.6 +157.38.15.239 +27.63.193.91 +49.43.97.142 +47.11.225.61 +106.204.203.71 +117.209.162.138 +122.173.25.96 +59.89.77.140 +157.48.151.149 +157.46.93.211 +106.66.62.136 +223.180.177.100 +49.36.211.74 +171.76.222.107 +42.104.154.104 +106.194.20.88 +205.253.11.254 +49.14.128.222 +49.35.194.144 +47.15.126.129 +137.97.96.111 +152.57.167.128 +106.208.85.231 +106.76.250.155 +106.66.58.49 +171.76.218.147 +42.106.177.16 +152.58.156.161 +106.221.92.82 +157.32.215.250 +223.233.70.54 +47.15.145.37 +47.247.210.211 +169.149.231.79 +223.187.245.8 +112.79.115.11 +223.181.60.204 +223.187.97.199 +157.48.140.79 +132.154.22.47 +223.182.202.227 +49.15.86.43 +157.41.194.70 +49.34.104.197 +47.9.80.76 +103.186.73.47 +47.11.248.65 +49.34.72.2 +106.206.58.109 +47.31.202.51 +117.99.233.12 +152.58.197.158 +49.34.201.14 +49.34.41.0 +157.33.91.212 +110.224.82.152 +49.36.219.80 +47.9.66.84 +1.38.220.155 +47.9.32.54 +223.225.252.189 +106.211.24.118 +223.233.5.2 +152.58.3.136 +157.34.153.23 +157.47.82.185 +223.186.234.179 +106.216.242.30 +106.220.72.202 +157.34.26.225 +115.96.218.20 +152.57.129.82 +42.105.165.17 +152.58.233.219 +59.178.254.21 +152.58.233.58 +49.34.177.239 +122.162.147.27 +223.231.157.249 +49.33.238.86 +152.58.158.60 +106.210.160.164 +103.40.196.37 +106.194.148.8 +122.173.26.71 +157.39.70.173 +49.43.152.198 +157.34.81.67 +42.105.214.24 +203.115.84.57 +223.227.73.237 +42.111.100.2 +152.58.102.121 +223.238.202.248 +157.35.25.121 +106.207.162.198 +106.222.64.252 +157.42.204.26 +205.253.35.157 +47.11.197.86 +106.217.70.230 +49.34.147.85 +157.34.207.19 +152.58.129.190 +223.233.77.18 +139.167.181.84 +137.97.101.228 +106.217.175.154 +47.9.75.81 +157.49.232.54 +103.40.197.191 +132.154.149.138 +157.39.236.5 +157.45.248.186 +106.213.145.184 +223.189.233.209 +47.15.124.51 +47.11.193.145 +171.61.22.159 +223.187.112.195 +47.15.213.58 +47.29.175.84 +106.221.53.128 +42.106.216.19 +157.34.120.111 +157.34.113.15 +132.154.63.82 +132.154.54.126 +210.89.59.19 +157.49.203.46 +206.84.237.40 +42.104.157.146 +110.227.52.160 +106.197.148.84 +103.21.79.29 +47.9.64.137 +157.49.211.13 +49.37.113.103 +114.31.136.175 +157.34.39.18 +42.105.210.75 +122.161.79.171 +103.68.176.77 +42.105.235.6 +47.9.114.176 +47.9.110.171 +157.35.26.0 +117.217.176.170 +49.42.81.113 +42.105.21.51 +169.149.196.99 +43.247.157.242 +205.253.36.187 +47.11.194.175 +157.46.152.108 +106.206.69.60 +106.205.194.129 +157.47.94.61 +152.58.196.48 +103.178.204.182 +169.149.199.44 +223.226.153.24 +152.58.234.177 +157.34.105.242 +223.179.196.116 +103.168.248.171 +157.41.245.98 +106.220.186.215 +106.197.178.91 +42.105.93.249 +223.189.200.247 +1.187.219.187 +49.15.84.231 +157.48.115.32 +106.221.45.72 +110.224.69.246 +110.224.191.80 +157.38.232.138 +157.40.68.242 +157.38.3.123 +117.96.178.228 +49.35.193.6 +27.61.149.76 +49.35.195.27 +157.47.43.83 +223.231.236.53 +223.190.186.117 +49.15.172.46 +106.193.29.10 +49.15.173.225 +157.33.205.113 +152.58.224.246 +49.32.130.66 +106.221.221.2 +47.29.164.3 +157.35.42.193 +106.195.94.60 +152.58.234.121 +103.232.11.236 +42.111.145.244 +49.36.218.55 +106.213.135.62 +49.34.84.111 +157.38.135.157 +106.77.160.65 +27.59.163.228 +106.221.210.103 +42.105.197.184 +157.49.213.19 +106.76.222.45 +49.15.136.13 +49.42.64.117 +223.238.110.174 +47.11.194.43 +157.35.0.143 +42.105.135.30 +223.188.226.58 +157.34.125.238 +223.238.207.230 +157.35.26.190 +223.238.120.38 +157.44.202.76 +49.42.72.181 +157.39.206.200 +223.227.63.170 +157.47.87.51 +49.34.111.135 +42.105.181.166 +157.51.199.213 +157.33.220.1 +49.15.248.59 +152.58.98.221 +49.37.90.202 +223.189.16.38 +157.48.239.92 +110.224.180.56 +47.9.111.51 +157.48.112.233 +223.233.120.24 +49.35.235.210 +1.39.116.162 +27.61.163.17 +27.63.49.93 +49.35.249.188 +223.130.31.83 +49.205.235.41 +106.195.4.211 +157.48.191.140 +157.50.64.21 +157.35.54.166 +112.79.141.184 +106.216.127.50 +152.58.70.217 +132.154.63.107 +106.196.15.50 +205.253.39.126 +42.104.155.201 +117.99.205.61 +157.34.112.56 +106.205.199.95 +27.63.9.249 +139.167.174.106 +117.237.231.34 +157.51.194.136 +157.49.169.128 +59.89.83.40 +47.247.193.118 +117.99.221.214 +27.61.71.245 +49.34.89.113 +106.195.74.183 +101.0.38.178 +49.35.188.148 +42.104.130.37 +157.48.125.24 +106.198.103.84 +103.199.114.143 +132.154.50.184 +47.9.32.191 +106.206.115.226 +47.11.66.25 +27.63.110.249 +49.35.253.201 +106.206.194.153 +117.98.42.120 +157.32.220.39 +117.99.200.11 +132.154.145.24 +183.83.132.22 +223.187.153.74 +152.58.102.118 +117.202.63.57 +112.79.224.131 +157.42.222.134 +117.246.171.230 +152.58.163.127 +157.42.246.16 +157.34.136.96 +27.97.45.120 +42.105.234.155 +157.45.63.2 +47.29.164.122 +106.223.179.4 +45.249.86.148 +106.217.223.12 +152.58.80.12 +152.58.96.11 +49.36.216.147 +157.38.194.151 +152.58.188.10 +157.38.105.164 +110.226.192.62 +106.204.193.122 +49.34.188.121 +42.104.213.21 +122.161.240.60 +106.221.245.252 +47.29.52.212 +157.41.253.43 +157.47.60.54 +106.206.212.217 +49.14.159.18 +117.234.251.152 +223.176.4.25 +139.167.233.199 +106.216.123.17 +157.42.229.31 +49.14.97.255 +27.60.201.232 +106.198.42.95 +1.39.78.68 +157.39.65.133 +152.58.231.221 +182.68.62.66 +106.78.52.158 +106.210.242.75 +157.42.209.118 +106.196.27.95 +103.190.100.151 +106.203.26.221 +45.249.69.119 +106.222.110.179 +106.215.182.126 +106.194.164.181 +106.208.23.29 +106.203.135.213 +27.61.136.20 +157.47.95.212 +49.36.144.20 +110.224.72.210 +157.44.197.198 +106.196.90.60 +157.39.196.253 +42.105.177.164 +49.42.92.243 +106.216.122.226 +45.250.248.95 +106.194.30.27 +101.0.54.30 +223.187.26.239 +49.35.195.218 +152.58.130.110 +152.59.66.159 +169.149.228.160 +157.40.67.194 +223.230.140.150 +47.9.105.4 +106.192.184.177 +117.99.230.84 +157.34.247.64 +157.51.199.2 +114.31.190.25 +157.33.226.66 +139.167.176.127 +132.154.30.100 +157.41.244.194 +106.207.243.12 +59.99.198.22 +157.35.20.207 +223.238.232.212 +106.78.72.96 +49.14.129.124 +106.78.178.54 +106.66.61.21 +117.97.215.231 +106.221.157.222 +157.35.15.230 +117.99.220.58 +157.34.228.61 +223.233.121.69 +182.69.58.65 +106.66.28.243 +27.61.201.165 +152.58.118.92 +106.193.40.82 +49.36.210.122 +106.208.154.220 +106.203.146.76 +171.79.150.103 +157.39.73.160 +157.42.235.142 +157.34.18.149 +49.34.185.32 +223.187.11.180 +223.227.65.223 +157.35.5.252 +152.58.163.59 +49.32.155.213 +157.48.70.39 +157.35.6.140 +49.43.152.27 +173.252.95.15 +173.252.95.8 +173.252.95.11 +27.60.217.77 +27.0.62.217 +106.205.246.131 +49.34.55.89 +49.36.18.147 +42.111.104.23 +157.50.65.204 +47.11.28.186 +49.205.107.66 +115.248.4.85 +49.15.250.50 +49.37.99.167 +152.58.91.158 +106.216.95.213 +47.29.97.14 +157.32.250.239 +49.37.40.226 +42.111.103.33 +157.38.150.27 +49.36.69.72 +103.140.46.46 +47.15.104.112 +223.238.219.93 +137.97.98.253 +223.187.12.249 +42.109.134.210 +137.97.100.171 +157.46.104.219 +27.57.251.57 +106.205.224.118 +117.98.12.165 +157.38.61.155 +103.241.227.161 +139.167.252.169 +152.57.227.32 +27.62.248.15 +171.51.172.110 +223.228.175.250 +205.253.121.198 +49.34.46.5 +157.48.247.177 +106.213.149.28 +157.32.74.45 +27.62.164.168 +103.24.87.181 +49.43.99.244 +157.35.17.248 +49.35.195.157 +47.247.203.242 +47.29.173.197 +106.222.76.213 +106.206.251.149 +110.224.121.119 +106.223.148.190 +157.33.75.0 +101.0.53.84 +106.206.203.238 +106.193.97.214 +106.208.53.38 +106.196.43.248 +59.92.195.250 +49.14.165.235 +223.239.77.11 +27.255.224.157 +157.50.6.103 +223.239.24.68 +47.9.65.147 +115.246.98.107 +49.37.53.185 +157.34.15.165 +223.238.18.196 +157.42.228.192 +157.35.21.37 +157.49.95.75 +45.248.18.94 +223.180.182.85 +117.237.254.110 +223.239.110.155 +27.62.241.252 +103.159.107.131 +152.58.182.185 +49.35.246.132 +110.224.166.29 +157.42.4.74 +129.211.163.253 +202.78.234.24 +49.42.84.80 +157.33.2.84 +106.203.132.78 +106.223.206.79 +111.92.44.220 +42.108.29.6 +157.34.130.34 +132.154.9.177 +106.196.123.27 +152.58.128.102 +117.99.249.103 +223.238.192.215 +117.217.145.82 +132.154.51.225 +223.233.125.211 +117.99.48.14 +157.49.251.21 +157.38.125.45 +103.160.65.140 +117.230.190.103 +103.198.101.17 +103.44.174.52 +125.62.96.167 +103.200.85.34 +152.58.132.159 +49.207.206.39 +106.221.56.112 +152.58.59.11 +47.31.202.88 +157.34.125.60 +42.108.4.73 +152.58.209.245 +103.211.191.107 +106.211.96.100 +152.58.24.144 +157.38.64.204 +122.161.243.185 +49.42.93.45 +157.40.98.117 +103.148.8.120 +157.50.6.129 +223.230.157.79 +103.42.196.107 +103.181.41.45 +152.58.208.161 +47.9.121.235 +106.76.222.77 +117.204.131.107 +223.187.99.141 +117.99.211.90 +169.149.194.178 +43.241.121.165 +103.41.37.143 +49.35.173.212 +110.227.51.249 +157.42.225.232 +42.107.193.112 +106.216.246.226 +42.110.228.108 +49.36.17.106 +152.58.123.230 +157.42.217.124 +182.79.253.136 +110.224.22.21 +157.33.246.205 +117.98.16.159 +157.46.66.215 +59.95.41.129 +223.227.54.58 +157.32.209.9 +223.186.64.206 +122.173.84.251 +27.61.152.21 +42.105.230.137 +49.37.49.155 +157.46.160.144 +169.149.227.221 +157.38.128.164 +106.206.226.168 +106.195.41.103 +157.47.103.200 +47.9.4.186 +1.187.214.196 +106.77.95.173 +103.203.254.120 +106.195.71.33 +42.105.233.225 +117.98.114.19 +106.221.161.146 +180.188.236.84 +223.228.70.65 +157.33.9.212 +42.105.205.69 +157.45.131.120 +27.60.110.51 +42.108.196.214 +157.41.255.152 +157.42.6.193 +117.215.45.128 +43.229.88.104 +106.211.120.242 +47.29.163.192 +106.211.73.49 +157.47.104.131 +157.47.97.74 +115.98.234.108 +117.204.123.11 +49.14.129.145 +42.105.88.46 +157.45.193.142 +47.9.150.149 +106.217.175.187 +157.34.101.184 +47.9.110.127 +157.40.226.215 +47.11.199.11 +157.33.41.252 +152.58.188.228 +117.98.86.16 +152.58.21.229 +157.35.44.239 +223.237.107.236 +103.177.41.176 +157.39.245.174 +152.58.76.155 +157.42.246.145 +223.239.72.118 +157.38.129.192 +106.221.45.222 +157.47.13.149 +139.167.195.181 +106.78.66.144 +117.225.120.9 +157.47.60.205 +49.14.164.3 +157.48.194.70 +106.211.88.135 +203.187.238.17 +106.79.192.229 +152.58.155.30 +157.45.223.14 +1.39.76.229 +157.32.40.182 +157.38.111.245 +171.79.144.169 +223.239.49.75 +47.29.166.54 +223.231.202.249 +49.37.52.138 +152.57.217.97 +117.99.236.204 +47.9.69.17 +117.97.230.196 +103.85.9.183 +157.47.100.212 +106.214.182.160 +42.105.205.81 +103.140.255.215 +27.123.240.96 +152.57.186.184 +1.38.90.243 +106.216.71.17 +106.202.73.21 +223.196.192.50 +42.110.166.4 +157.41.254.152 +106.216.127.28 +157.38.11.68 +47.11.249.55 +49.36.216.32 +106.203.135.253 +106.211.8.220 +110.224.86.57 +223.196.173.156 +42.109.208.41 +106.76.198.248 +106.196.82.206 +106.206.201.62 +49.36.101.98 +42.110.140.205 +152.57.23.140 +157.45.227.64 +122.161.73.244 +223.238.121.64 +157.37.190.140 +171.76.227.242 +103.223.8.3 +106.221.247.34 +157.39.75.51 +49.36.221.143 +152.57.89.226 +110.227.58.73 +106.197.117.228 +49.37.194.205 +117.210.197.255 +49.36.213.229 +157.35.71.168 +157.44.149.179 +223.228.216.89 +49.14.96.232 +49.35.236.161 +152.58.27.173 +117.99.51.6 +47.15.38.90 +106.206.234.51 +117.249.139.102 +152.58.236.25 +42.106.161.70 +49.42.75.253 +49.43.100.108 +157.47.116.247 +152.58.20.211 +152.58.18.247 +132.154.49.23 +169.149.228.110 +157.40.67.207 +157.50.11.164 +106.195.73.117 +223.189.199.92 +115.187.52.228 +110.224.75.39 +27.63.194.106 +49.14.166.157 +223.178.210.3 +49.37.159.208 +49.37.47.39 +152.58.130.59 +223.179.232.239 +47.31.172.93 +106.197.147.219 +42.108.75.220 +117.98.110.24 +157.41.244.176 +152.58.197.8 +223.231.123.68 +152.58.232.103 +152.57.178.255 +59.89.37.193 +152.58.139.245 +47.15.123.234 +49.42.82.42 +157.41.254.184 +106.205.160.84 +49.34.210.49 +103.168.75.34 +223.238.197.153 +49.47.70.65 +27.63.135.169 +223.187.118.147 +117.98.64.151 +157.34.114.21 +157.33.111.107 +157.38.78.181 +49.14.115.64 +47.9.102.225 +47.29.161.148 +157.42.1.246 +47.15.32.213 +47.11.209.158 +152.58.154.244 +157.41.250.84 +27.62.73.24 +1.38.48.13 +157.38.117.192 +117.229.141.168 +47.9.83.38 +117.98.100.158 +223.227.35.57 +223.231.213.3 +132.154.55.21 +223.179.241.219 +117.202.38.139 +106.207.252.214 +49.156.79.14 +122.161.95.180 +106.213.86.64 +106.211.30.245 +157.48.76.174 +157.38.136.171 +106.207.59.10 +152.57.69.223 +49.36.32.198 +157.40.238.60 +47.15.170.223 +157.32.80.113 +27.63.237.37 +49.42.67.188 +42.106.237.207 +42.106.20.158 +137.97.69.141 +47.11.236.82 +157.49.233.127 +202.14.123.86 +47.15.222.212 +103.35.114.136 +106.221.149.195 +223.239.50.215 +106.196.22.3 +152.58.91.193 +157.35.67.206 +157.35.74.210 +27.63.196.186 +171.76.135.2 +49.43.99.62 +157.34.132.161 +152.58.113.40 +45.249.68.182 +157.45.57.252 +106.205.181.155 +139.167.240.74 +132.154.58.66 +223.233.8.69 +157.41.226.206 +223.187.116.194 +47.11.89.111 +47.11.64.38 +139.167.249.117 +106.194.40.199 +106.197.99.133 +122.161.65.192 +106.198.33.92 +117.98.116.148 +47.9.148.9 +122.168.251.203 +157.41.249.14 +106.223.186.172 +47.15.0.151 +111.92.81.7 +49.42.87.158 +162.216.143.162 +106.217.34.86 +157.42.3.228 +103.91.72.106 +49.36.176.8 +106.77.133.245 +157.44.182.217 +106.220.243.218 +103.242.226.114 +106.78.54.20 +106.196.6.41 +157.35.69.131 +157.38.133.3 +106.76.159.194 +47.9.145.81 +169.149.230.204 +113.21.71.158 +157.50.36.70 +49.34.152.65 +171.60.208.20 +106.203.107.157 +61.0.197.44 +106.213.130.86 +157.35.75.217 +49.204.27.237 +175.101.32.122 +152.58.231.115 +223.238.128.43 +223.238.207.107 +122.182.187.74 +152.58.157.30 +110.224.75.234 +106.205.244.176 +117.98.88.70 +171.78.193.7 +110.226.237.67 +157.49.153.48 +157.34.83.180 +157.45.234.13 +132.154.149.14 +157.47.81.194 +110.224.91.126 +117.204.139.57 +122.168.32.38 +47.11.78.26 +183.82.163.36 +157.48.205.204 +117.98.126.60 +157.40.64.200 +152.58.145.199 +157.34.94.44 +27.56.65.37 +106.197.2.147 +223.225.35.39 +106.221.178.1 +157.38.125.166 +132.154.167.0 +223.225.246.24 +152.57.5.34 +47.15.40.46 +49.43.99.103 +223.237.172.163 +110.225.54.10 +106.195.14.189 +47.9.37.189 +49.32.155.242 +49.36.17.3 +106.215.176.162 +106.196.115.43 +42.105.75.186 +157.39.69.89 +47.9.156.25 +110.227.56.216 +157.32.212.148 +223.233.83.113 +223.186.90.205 +106.206.205.132 +106.204.42.107 +106.216.251.225 +1.39.76.42 +157.45.77.136 +117.99.209.207 +49.37.74.44 +49.35.174.246 +47.9.5.182 +157.50.24.153 +27.57.160.56 +223.184.184.137 +137.97.80.214 +1.39.77.105 +103.183.82.234 +49.36.236.224 +110.224.110.238 +117.99.199.18 +106.196.20.174 +122.177.97.127 +152.58.59.229 +152.58.235.182 +152.57.49.87 +157.39.69.106 +160.238.92.52 +223.225.241.5 +182.64.113.233 +122.174.58.206 +157.35.75.120 +157.45.171.134 +137.97.82.119 +157.32.67.158 +106.78.180.169 +132.154.55.5 +47.15.108.111 +223.228.224.25 +122.175.94.94 +157.39.68.63 +157.38.129.172 +106.66.29.5 +47.29.16.144 +152.58.131.32 +106.197.109.39 +106.220.147.134 +117.98.46.5 +171.60.193.126 +49.37.67.174 +49.36.209.201 +106.204.194.178 +106.217.43.164 +157.46.153.35 +49.35.192.193 +171.76.236.58 +106.207.174.233 +49.204.195.15 +103.240.99.16 +106.77.134.184 +157.48.146.39 +47.9.79.238 +157.49.95.93 +110.224.72.63 +49.34.100.4 +117.96.180.176 +42.107.193.198 +157.32.100.47 +132.154.36.109 +157.48.127.147 +122.161.48.116 +152.57.158.219 +27.59.135.213 +106.193.230.151 +106.206.203.24 +137.97.65.191 +47.31.96.142 +223.226.188.38 +157.41.249.62 +223.182.223.95 +139.167.213.246 +223.239.73.54 +152.58.74.70 +157.35.24.197 +49.36.239.105 +157.35.76.90 +223.189.204.205 +106.211.50.205 +47.11.6.80 +152.58.78.38 +59.89.251.120 +106.216.255.82 +47.29.168.160 +1.38.165.137 +49.43.181.81 +49.42.75.161 +103.199.180.112 +223.225.43.82 +157.41.228.108 +103.158.218.46 +157.37.137.244 +106.79.193.244 +223.231.201.95 +106.207.45.39 +223.187.221.119 +114.31.140.214 +152.58.25.113 +106.208.218.238 +106.213.85.59 +157.38.131.90 +205.253.34.213 +27.63.92.196 +157.48.115.158 +106.76.198.150 +152.58.34.20 +160.202.37.110 +27.63.221.35 +1.38.220.98 +223.187.134.19 +223.225.120.36 +106.220.126.254 +106.221.107.210 +132.154.61.186 +223.189.135.227 +112.79.120.220 +157.38.208.143 +157.49.226.237 +157.38.137.53 +223.178.81.125 +157.34.65.228 +106.204.197.42 +157.34.60.246 +152.58.34.172 +152.58.39.44 +27.60.251.36 +139.167.206.26 +157.35.41.60 +157.48.115.18 +106.192.144.57 +106.217.11.20 +157.34.216.41 +157.50.39.194 +106.223.214.49 +223.187.99.149 +117.253.6.172 +157.34.49.44 +106.211.23.132 +42.105.6.109 +103.211.41.146 +47.15.14.112 +49.36.212.98 +115.96.227.248 +106.216.201.18 +157.35.26.173 +106.202.250.195 +152.58.218.208 +106.200.152.199 +137.97.116.175 +157.38.72.124 +157.42.219.206 +106.207.249.251 +49.32.183.88 +110.224.101.80 +157.51.1.109 +157.32.36.229 +223.228.11.78 +106.197.119.220 +205.253.39.163 +157.42.7.230 +47.29.163.153 +106.206.207.160 +49.36.70.42 +122.161.242.25 +49.34.133.53 +139.167.206.121 +137.97.90.19 +110.224.185.239 +49.43.96.99 +106.206.90.100 +106.206.243.104 +157.32.32.133 +202.8.117.55 +122.173.26.211 +49.14.164.67 +106.211.208.55 +106.208.157.102 +49.35.175.184 +47.9.78.74 +47.9.125.19 +157.35.57.109 +223.225.171.206 +106.221.50.35 +42.104.157.193 +49.47.69.91 +157.41.254.4 +1.187.134.22 +49.43.96.201 +47.31.96.208 +106.216.73.172 +157.38.137.28 +132.154.4.20 +49.42.66.128 +106.221.98.98 +117.225.83.122 +106.206.131.115 +171.51.162.210 +49.42.88.155 +157.41.254.153 +117.99.225.110 +223.189.184.244 +1.39.75.79 +157.46.117.131 +106.204.225.44 +49.34.209.82 +132.154.13.162 +47.15.136.40 +106.221.242.89 +223.228.137.232 +106.76.77.228 +106.216.247.22 +47.29.173.205 +106.207.231.190 +157.38.59.75 +106.207.230.107 +157.38.131.185 +152.58.22.4 +157.47.31.142 +223.189.199.96 +223.187.21.153 +49.35.135.181 +117.205.128.218 +42.105.194.194 +42.105.74.124 +49.36.171.21 +27.56.25.155 +223.238.120.254 +117.96.185.98 +157.32.33.55 +106.195.85.163 +152.58.68.46 +152.58.138.162 +182.48.224.220 +117.98.42.88 +47.29.169.39 +202.142.107.210 +206.84.228.24 +157.35.53.195 +152.58.34.80 +152.58.103.213 +157.41.195.108 +103.81.157.108 +120.138.12.171 +152.58.73.212 +49.43.180.239 +223.230.138.12 +49.35.136.161 +49.204.161.15 +47.9.32.220 +157.39.70.83 +47.29.160.108 +103.199.180.238 +157.46.122.235 +42.111.229.199 +152.57.238.245 +27.63.85.237 +112.79.62.117 +103.161.55.84 +49.42.93.212 +27.59.239.142 +27.62.128.88 +49.42.89.255 +157.40.195.145 +106.193.228.163 +106.217.184.197 +106.196.103.223 +47.15.38.23 +110.225.45.21 +117.201.61.235 +223.187.106.6 +157.41.225.205 +49.37.24.20 +152.58.80.48 +106.203.63.7 +1.187.213.105 +157.32.37.252 +49.34.142.199 +1.38.106.145 +157.38.38.188 +106.211.226.170 +106.193.223.97 +152.58.20.151 +59.91.246.25 +223.180.178.113 +152.58.133.215 +106.204.227.69 +103.238.14.113 +152.57.96.59 +47.9.110.177 +202.142.73.216 +223.186.11.39 +223.231.194.119 +106.66.61.168 +103.167.184.165 +223.187.92.255 +157.34.7.159 +106.206.204.98 +42.105.103.180 +157.40.226.99 +157.41.227.197 +103.15.254.134 +117.99.200.31 +49.37.234.96 +49.36.181.167 +152.58.34.247 +27.62.241.122 +157.41.228.124 +157.34.217.143 +27.122.60.208 +45.120.122.87 +157.38.212.159 +157.41.197.202 +47.11.70.238 +14.102.21.82 +157.42.234.36 +49.42.83.217 +157.47.118.61 +103.238.106.242 +157.38.51.15 +49.14.130.8 +152.58.190.63 +103.50.5.70 +42.105.179.223 +157.40.94.117 +42.105.213.17 +49.35.192.66 +106.66.29.126 +42.105.233.204 +106.216.98.154 +122.163.236.164 +106.194.88.93 +27.62.49.226 +27.60.23.160 +117.98.118.47 +157.51.12.6 +223.182.4.224 +171.60.213.136 +106.204.198.110 +171.50.234.156 +152.58.58.206 +114.31.144.120 +152.58.186.45 +223.187.58.10 +110.224.188.249 +106.76.196.8 +223.237.107.218 +171.76.189.14 +139.167.249.38 +223.189.205.232 +171.79.190.47 +47.15.19.73 +117.99.47.13 +106.204.152.179 +117.98.82.104 +169.149.226.127 +106.79.161.49 +106.216.250.178 +152.58.24.100 +157.41.240.217 +223.188.254.161 +117.209.166.243 +157.34.26.197 +117.98.126.203 +157.35.84.183 +117.229.139.186 +157.38.58.97 +157.48.64.249 +106.207.169.100 +223.189.205.146 +157.41.254.225 +117.212.2.196 +49.37.170.165 +103.52.208.164 +157.45.255.213 +157.35.80.82 +157.40.215.23 +157.38.238.188 +1.38.88.50 +157.49.206.18 +171.61.16.92 +49.35.152.195 +132.154.130.249 +42.111.220.106 +106.204.187.109 +223.190.189.127 +157.34.139.191 +157.48.220.8 +47.15.7.102 +152.57.47.62 +117.99.228.220 +150.129.170.158 +171.76.84.223 +110.227.42.207 +223.225.170.48 +47.11.206.36 +49.42.87.40 +157.48.90.111 +1.38.164.179 +114.134.27.225 +42.104.130.106 +1.187.214.232 +157.37.154.198 +106.205.206.212 +117.99.16.162 +106.216.227.206 +157.34.212.92 +42.105.21.57 +157.42.244.96 +106.216.134.115 +106.201.247.89 +157.40.245.230 +42.110.166.21 +137.97.87.175 +157.40.112.46 +49.37.73.103 +106.203.22.188 +157.45.189.180 +106.79.233.75 +223.233.71.151 +157.39.70.97 +157.32.245.107 +47.15.12.185 +103.15.254.231 +152.58.101.205 +117.99.209.0 +49.37.106.54 +49.14.133.174 +42.106.92.110 +106.221.211.17 +47.15.18.115 +223.186.242.20 +42.105.8.199 +223.225.249.68 +152.58.56.15 +42.106.188.156 +152.58.37.11 +223.231.153.161 +157.38.118.55 +223.181.62.165 +124.253.202.166 +152.58.138.205 +157.40.93.149 +103.172.47.114 +169.149.228.138 +103.70.36.160 +49.36.27.207 +49.37.72.253 +157.34.68.166 +132.154.35.119 +42.106.180.155 +106.217.131.185 +47.31.99.195 +223.237.99.133 +42.108.164.241 +157.34.231.7 +103.116.140.182 +49.43.96.124 +171.48.90.126 +47.11.206.237 +169.149.226.84 +103.238.106.175 +157.32.208.247 +110.227.54.133 +106.216.240.189 +106.201.28.201 +171.76.191.0 +223.179.238.11 +152.58.75.127 +27.61.22.253 +42.104.144.9 +1.38.142.16 +49.34.231.26 +49.14.115.138 +106.198.41.242 +106.204.226.97 +49.34.233.223 +157.41.192.117 +42.105.133.255 +152.57.89.8 +47.31.98.109 +117.99.230.215 +47.9.6.67 +49.37.46.92 +152.58.66.90 +49.37.171.89 +49.15.233.224 +139.167.250.185 +27.59.22.96 +106.194.143.163 +157.50.20.65 +49.35.170.33 +47.15.15.6 +223.185.112.223 +157.48.91.6 +106.211.132.33 +42.106.236.241 +103.211.132.89 +223.189.216.134 +157.48.115.132 +49.32.253.210 +182.77.7.117 +49.34.142.134 +106.210.47.213 +110.226.200.18 +49.34.190.170 +49.37.75.48 +49.36.193.180 +42.105.197.80 +42.105.89.197 +223.178.81.101 +103.157.168.62 +49.43.0.218 +47.11.34.183 +157.32.37.150 +223.191.7.71 +223.190.184.253 +42.105.214.182 +110.227.54.221 +106.213.246.62 +157.48.89.239 +103.226.184.226 +49.36.32.64 +103.179.10.134 +152.58.220.71 +106.208.135.76 +42.105.131.72 +42.109.193.14 +47.11.207.25 +43.249.228.141 +49.36.189.211 +157.40.85.90 +157.34.0.221 +223.238.81.233 +152.58.184.2 +106.77.161.18 +27.60.18.249 +106.206.124.218 +49.15.201.218 +106.205.27.60 +42.110.170.120 +110.226.167.0 +157.41.229.98 +106.206.168.236 +117.225.18.157 +157.47.27.239 +157.41.255.205 +106.198.44.124 +152.57.147.17 +152.58.188.149 +47.31.220.74 +110.224.99.141 +132.154.190.255 +27.60.60.139 +106.195.72.115 +106.220.78.12 +157.42.204.133 +106.203.49.24 +110.227.59.254 +103.159.107.146 +106.215.253.75 +223.187.79.72 +49.37.169.119 +27.63.130.253 +47.15.153.25 +47.29.45.84 +110.224.66.3 +157.33.249.15 +223.227.59.162 +157.34.19.136 +157.38.250.149 +157.42.250.59 +106.220.218.139 +157.50.40.60 +42.105.212.48 +157.49.154.255 +223.238.109.166 +27.60.29.150 +132.154.38.120 +157.39.72.60 +106.204.196.58 +152.58.73.241 +152.57.70.11 +106.211.6.198 +49.35.195.18 +103.130.105.201 +157.40.124.223 +223.231.229.242 +110.224.106.211 +202.14.123.245 +157.44.163.192 +157.51.63.198 +223.187.29.195 +42.105.233.139 +223.188.148.50 +106.221.85.224 +152.57.30.219 +49.37.105.91 +49.15.248.115 +171.76.252.167 +27.57.249.168 +103.52.210.196 +139.167.244.82 +47.29.166.58 +157.35.26.132 +49.35.134.146 +49.36.68.13 +157.32.75.75 +117.236.156.98 +110.227.21.241 +47.15.167.117 +223.187.97.223 +152.57.57.131 +152.58.30.115 +157.38.146.79 +27.255.242.189 +103.225.190.98 +171.79.189.178 +106.216.118.249 +106.205.196.94 +110.224.89.81 +157.40.192.46 +117.98.126.159 +106.206.246.26 +152.58.130.243 +223.186.117.26 +169.149.195.235 +27.63.9.86 +157.47.29.121 +106.204.228.34 +110.224.79.151 +106.194.195.199 +157.35.79.239 +223.225.35.124 +27.61.95.123 +49.47.69.133 +49.36.221.205 +49.15.172.9 +49.34.89.43 +223.186.219.48 +110.224.167.149 +132.154.12.97 +49.36.169.37 +112.79.119.34 +49.14.148.3 +152.57.23.122 +49.15.228.199 +223.237.24.225 +106.217.231.212 +49.35.161.25 +27.57.23.122 +42.108.12.63 +106.197.197.181 +223.228.115.107 +47.9.9.157 +223.239.28.103 +223.185.114.252 +157.35.89.185 +42.108.196.193 +106.210.104.167 +157.38.129.161 +157.34.79.184 +117.98.78.36 +49.204.19.195 +223.227.50.58 +152.58.212.123 +47.9.103.37 +27.63.251.218 +49.43.99.133 +27.122.61.160 +106.192.170.197 +27.63.223.91 +116.68.99.129 +103.206.8.74 +152.58.178.156 +106.208.117.90 +223.186.112.101 +223.228.68.62 +223.181.143.163 +106.195.73.141 +49.35.194.160 +210.89.63.94 +157.40.101.180 +47.29.58.14 +157.48.83.95 +42.105.139.127 +47.15.42.22 +223.187.123.6 +152.57.54.101 +223.235.78.20 +139.167.243.28 +106.221.176.57 +157.38.66.112 +117.233.147.80 +42.105.12.139 +106.197.87.237 +157.39.68.3 +1.38.141.126 +117.230.129.98 +106.210.42.156 +152.57.167.123 +152.58.184.186 +157.48.151.237 +157.38.200.159 +110.224.188.86 +169.149.226.81 +117.225.212.180 +1.187.215.120 +157.49.169.71 +223.180.185.109 +223.239.67.200 +157.42.219.92 +106.210.222.58 +157.48.228.3 +223.231.129.47 +152.58.66.45 +106.221.221.161 +47.29.162.155 +106.207.101.207 +49.35.194.81 +157.40.205.41 +157.33.66.157 +47.9.79.138 +49.37.67.141 +42.105.136.204 +47.29.171.174 +27.63.236.187 +110.226.21.85 +205.253.37.63 +157.34.208.162 +106.223.30.144 +157.51.193.196 +157.40.125.143 +106.77.166.230 +152.57.193.119 +157.40.248.120 +43.241.146.104 +106.196.1.43 +42.106.21.0 +49.43.101.74 +152.58.75.249 +106.211.72.20 +110.227.48.1 +223.187.58.224 +157.47.111.76 +49.15.224.98 +106.205.184.240 +106.210.46.239 +47.29.96.125 +152.58.54.65 +223.178.210.184 +103.55.99.50 +47.9.137.21 +27.123.240.155 +103.57.140.251 +47.29.101.3 +110.224.189.126 +223.185.88.86 +106.221.8.186 +171.76.130.194 +47.9.84.90 +117.96.128.88 +47.9.64.39 +157.33.200.140 +223.188.43.71 +202.43.120.32 +47.15.17.172 +49.36.221.62 +42.105.168.41 +49.36.211.184 +157.32.36.74 +157.41.194.211 +157.38.237.86 +169.149.227.190 +103.82.159.253 +106.206.233.54 +157.50.6.104 +110.226.183.102 +152.58.96.229 +117.99.238.34 +106.193.193.198 +47.9.150.100 +157.39.229.85 +152.58.210.152 +157.35.71.68 +106.220.107.153 +223.182.54.186 +49.43.101.218 +139.167.175.224 +1.39.117.135 +223.231.189.28 +157.38.38.125 +106.206.250.110 +157.38.146.65 +106.216.195.231 +27.56.26.1 +106.204.60.13 +49.36.25.134 +152.58.25.140 +223.181.193.52 +27.63.209.87 +27.255.189.97 +223.227.93.21 +49.42.81.56 +42.109.200.3 +152.58.139.37 +152.58.234.39 +103.179.103.98 +157.42.4.102 +49.35.175.122 +157.42.2.1 +47.15.13.233 +157.39.68.148 +49.36.169.64 +157.34.229.100 +157.39.201.8 +49.37.49.136 +112.79.141.86 +103.217.242.189 +157.40.206.210 +157.38.99.223 +49.37.112.246 +139.167.195.66 +47.9.129.180 +106.193.249.211 +157.48.239.151 +122.161.74.171 +42.108.28.220 +49.36.188.82 +157.48.77.62 +27.60.240.192 +152.58.79.76 +117.255.185.151 +103.183.32.174 +103.151.189.4 +152.58.100.34 +157.38.130.102 +27.56.12.81 +157.32.43.253 +223.227.73.213 +152.57.221.173 +106.197.167.179 +49.35.160.214 +49.37.46.171 +157.45.145.66 +122.182.246.69 +106.223.181.17 +106.196.85.89 +132.154.36.138 +152.58.189.81 +132.154.59.123 +157.38.25.171 +49.205.135.137 +27.62.143.8 +106.197.35.115 +157.48.213.26 +49.43.154.178 +27.58.138.178 +157.48.117.179 +157.41.250.115 +103.165.20.152 +152.58.186.120 +106.194.49.57 +205.253.35.110 +152.58.212.115 +106.206.246.38 +157.41.227.243 +49.36.210.190 +103.135.229.74 +223.178.117.190 +49.34.235.77 +157.38.132.140 +103.164.197.47 +157.34.248.72 +157.38.136.253 +42.104.158.4 +106.198.123.164 +106.207.36.207 +223.187.245.212 +45.116.229.4 +49.34.232.224 +114.31.140.37 +42.104.142.21 +157.34.209.190 +157.45.80.168 +157.38.204.5 +223.238.211.107 +106.216.126.113 +27.61.179.118 +49.43.152.33 +117.99.197.98 +157.34.139.89 +49.34.79.205 +1.38.217.138 +157.45.225.245 +117.230.0.40 +42.106.204.171 +157.32.111.105 +110.227.50.136 +106.216.240.72 +49.14.158.58 +157.42.7.160 +49.42.83.46 +110.224.121.212 +106.203.129.134 +27.62.195.7 +152.57.91.139 +49.37.44.54 +152.57.217.101 +103.113.98.156 +139.5.248.89 +106.216.254.125 +157.51.30.149 +49.42.36.164 +223.239.48.175 +169.149.224.70 +157.48.91.220 +49.15.250.235 +42.105.101.197 +49.36.221.80 +49.42.88.29 +42.105.130.210 +1.38.107.144 +157.38.77.192 +103.5.133.135 +49.14.113.64 +157.35.9.120 +157.50.11.124 +103.98.63.156 +49.35.243.181 +114.31.184.88 +169.149.227.163 +49.14.131.185 +106.216.122.161 +152.58.18.174 +106.77.142.253 +157.38.86.108 +27.59.47.29 +223.228.171.84 +49.43.98.86 +183.82.163.243 +157.41.241.120 +171.60.208.200 +157.47.116.27 +205.253.122.112 +106.196.9.96 +27.63.67.217 +49.15.247.195 +152.58.200.192 +103.87.140.45 +106.195.89.154 +1.39.115.109 +157.41.224.9 +124.253.207.55 +49.35.242.7 +152.58.130.135 +157.51.195.24 +157.45.81.135 +157.41.199.12 +171.76.236.30 +106.211.220.94 +47.9.71.140 +223.182.221.36 +182.69.140.222 +103.171.100.239 +157.50.18.171 +47.29.169.19 +157.38.132.200 +103.244.241.37 +47.31.97.250 +157.35.78.212 +106.221.114.96 +106.198.84.31 +49.37.50.188 +42.105.8.26 +157.32.116.128 +49.36.68.88 +49.36.18.218 +110.224.80.123 +122.173.168.95 +27.56.73.163 +106.77.189.85 +152.58.215.50 +203.192.226.238 +157.35.70.186 +139.167.187.101 +42.108.30.31 +203.88.145.114 +106.79.233.143 +157.38.101.193 +157.35.5.150 +157.35.90.144 +110.227.57.149 +47.11.199.119 +152.58.56.155 +42.110.168.66 +27.60.14.62 +152.58.185.244 +157.48.206.125 +106.221.110.185 +106.196.4.189 +45.64.223.234 +27.59.49.125 +157.34.33.70 +117.209.74.216 +157.49.75.74 +106.208.183.78 +223.181.74.78 +47.9.156.55 +47.9.87.140 +106.76.90.136 +103.186.128.227 +223.185.219.160 +49.43.99.229 +157.48.114.215 +49.34.53.96 +157.34.244.252 +132.154.186.38 +157.35.73.253 +106.196.119.40 +42.104.155.3 +49.34.223.158 +157.33.114.104 +103.214.118.95 +45.119.143.11 +42.106.205.6 +157.48.144.165 +223.182.17.144 +47.29.173.207 +106.193.185.40 +152.58.72.41 +49.37.73.175 +157.35.84.70 +49.42.87.63 +47.9.70.215 +171.48.90.86 +49.36.69.122 +152.58.212.107 +157.48.197.197 +27.60.35.227 +27.60.110.178 +106.195.66.251 +106.216.127.12 +47.15.15.183 +47.9.37.153 +117.99.223.245 +223.238.177.22 +157.32.217.121 +152.58.176.132 +157.38.19.193 +223.187.3.122 +157.40.243.16 +103.92.40.225 +49.37.27.85 +122.164.87.127 +106.216.253.233 +223.239.32.249 +152.57.1.184 +49.37.89.236 +106.221.246.60 +103.85.91.67 +152.58.220.47 +122.173.178.138 +106.217.81.81 +42.105.229.113 +49.37.25.166 +150.107.241.21 +111.92.118.154 +157.32.75.70 +49.36.169.239 +110.224.64.209 +152.58.155.35 +106.220.184.74 +223.181.120.135 +157.48.113.34 +110.227.59.39 +157.35.85.20 +152.58.177.255 +157.49.209.23 +47.15.0.245 +139.167.237.253 +103.238.110.45 +223.187.112.224 +49.35.193.173 +132.154.140.51 +223.231.207.157 +132.154.161.125 +49.204.134.109 +132.154.158.133 +152.58.154.68 +152.57.160.85 +122.172.46.77 +49.35.173.157 +223.187.90.68 +27.63.28.68 +42.105.182.79 +157.33.3.47 +157.48.87.224 +106.216.126.247 +1.22.129.160 +157.38.129.46 +42.105.237.142 +122.161.64.103 +122.162.190.88 +49.42.64.251 +132.154.10.51 +152.57.210.10 +49.35.193.9 +117.99.235.139 +47.29.172.168 +103.89.67.139 +27.56.85.236 +106.221.28.240 +157.32.214.118 +49.34.88.29 +157.41.227.43 +116.75.75.229 +106.221.102.147 +152.58.187.218 +157.51.194.246 +157.44.159.46 +106.196.53.211 +27.57.42.233 +171.79.191.168 +49.34.239.199 +157.38.136.91 +157.32.241.64 +152.57.71.11 +106.211.16.119 +103.175.9.11 +106.77.156.161 +137.97.104.195 +103.134.6.208 +49.42.69.220 +42.105.193.131 +122.171.22.209 +106.194.83.214 +106.206.240.232 +49.43.180.18 +49.34.35.224 +106.206.194.227 +27.62.210.246 +47.11.201.214 +223.176.98.8 +152.57.234.161 +103.135.228.142 +106.213.198.61 +223.191.59.84 +106.77.57.15 +110.226.199.190 +157.44.223.157 +223.186.197.132 +106.197.103.119 +152.58.96.136 +169.149.196.187 +106.198.102.125 +157.35.46.62 +223.176.19.21 +106.220.168.145 +47.11.249.110 +1.38.72.78 +152.57.189.212 +47.9.35.9 +157.45.92.91 +157.42.252.133 +49.35.144.171 +157.35.3.33 +103.211.54.28 +157.34.83.162 +122.162.149.228 +117.198.63.239 +106.192.157.4 +103.188.95.157 +42.109.208.21 +117.196.178.56 +223.233.123.97 +157.45.63.155 +157.51.78.127 +117.209.98.152 +171.76.240.227 +223.238.213.86 +27.61.162.194 +157.48.145.104 +171.48.69.216 +157.50.64.180 +49.36.169.107 +49.37.35.23 +106.220.225.158 +106.216.122.61 +157.51.158.100 +157.44.223.99 +139.167.238.211 +223.238.124.151 +103.69.29.169 +49.43.2.1 +49.35.138.218 +152.58.212.110 +42.111.161.60 +47.15.4.131 +45.249.86.165 +157.38.233.17 +223.182.241.210 +169.149.229.123 +157.41.253.151 +157.45.185.168 +103.189.217.18 +157.38.237.6 +223.233.93.91 +47.15.8.20 +106.204.31.231 +49.34.140.196 +103.70.36.69 +45.125.119.124 +223.238.233.228 +49.36.220.233 +106.216.226.23 +114.31.188.146 +49.36.236.4 +205.253.10.246 +106.192.203.218 +43.241.144.65 +223.237.80.108 +106.217.91.124 +157.44.216.41 +117.98.68.145 +106.193.226.46 +223.178.210.146 +49.42.92.228 +106.204.17.162 +106.214.206.113 +59.99.64.221 +49.34.43.226 +27.5.50.126 +42.105.154.34 +157.40.105.51 +117.99.5.79 +152.58.191.35 +157.35.76.175 +42.105.13.31 +106.221.153.121 +152.58.158.177 +27.56.8.100 +110.224.70.43 +152.58.233.133 +42.111.200.44 +1.38.165.117 +47.29.96.250 +132.154.59.248 +157.38.129.79 +117.235.75.231 +106.195.104.190 +223.186.216.113 +27.62.233.151 +139.167.225.78 +49.36.222.36 +106.223.212.134 +103.80.153.13 +122.182.204.114 +157.42.2.165 +27.255.167.111 +223.181.218.98 +27.63.9.13 +173.252.95.7 +173.252.95.5 +173.252.95.18 +173.252.95.17 +106.223.100.89 +106.208.152.96 +27.62.14.56 +223.187.127.64 +157.50.38.79 +152.57.190.85 +157.33.27.109 +117.221.27.181 +122.164.84.64 +49.43.89.96 +122.163.129.106 +122.175.196.211 +27.56.229.208 +117.213.48.246 +157.51.40.82 +47.9.111.127 +117.99.193.128 +47.11.204.198 +157.46.136.79 +101.0.57.237 +157.32.251.247 +42.108.22.19 +47.31.133.179 +1.187.142.154 +157.34.77.65 +152.58.26.52 +157.34.91.68 +157.41.245.171 +157.39.202.63 +139.167.237.184 +157.38.138.98 +223.179.254.214 +117.254.34.86 +223.178.211.75 +152.58.34.70 +122.176.172.83 +27.56.88.43 +49.36.210.255 +117.99.58.82 +49.37.201.200 +49.42.67.141 +157.49.93.182 +49.35.165.109 +106.197.175.246 +157.45.214.201 +106.216.113.230 +223.178.209.195 +157.41.251.51 +27.63.207.30 +157.41.227.35 +223.188.73.109 +171.76.226.192 +157.34.28.151 +157.42.236.242 +152.58.186.12 +152.58.157.175 +42.106.237.179 +106.76.77.69 +103.245.14.123 +139.167.168.2 +157.48.113.197 +42.105.90.226 +169.149.228.124 +49.14.128.21 +106.76.70.162 +157.34.147.246 +157.40.224.65 +210.56.99.109 +106.76.69.85 +223.178.211.223 +106.76.91.79 +103.115.128.22 +106.216.75.157 +106.195.110.64 +117.98.88.69 +106.213.81.204 +117.214.198.18 +106.198.116.98 +152.58.131.244 +157.46.130.163 +47.29.11.118 +1.38.164.104 +114.31.139.35 +49.34.220.215 +110.224.75.227 +106.216.126.200 +103.184.238.53 +49.37.48.38 +114.134.26.67 +139.167.223.98 +171.76.132.62 +42.105.204.14 +117.211.48.188 +49.36.91.175 +117.228.207.120 +103.181.41.80 +106.192.198.128 +103.70.199.16 +157.34.213.152 +103.182.146.88 +157.38.145.130 +110.224.188.98 +157.45.41.43 +103.174.35.254 +103.110.48.3 +49.32.148.155 +223.189.192.199 +223.190.184.209 +157.42.253.176 +59.89.54.19 +47.9.122.19 +171.76.192.234 +1.39.78.240 +152.58.184.102 +223.185.75.234 +157.34.22.100 +152.57.101.10 +49.156.93.84 +152.57.15.10 +152.57.204.156 +122.161.75.193 +49.35.194.4 +157.38.242.240 +157.35.79.109 +157.32.100.205 +152.58.232.124 +106.194.49.207 +223.186.39.55 +116.72.55.28 +49.34.118.132 +157.34.113.137 +47.9.128.188 +223.187.124.38 +171.50.131.38 +103.42.157.224 +47.11.75.164 +157.38.150.42 +157.42.250.134 +117.99.0.20 +106.221.23.199 +183.83.208.78 +223.189.113.231 +223.233.77.178 +110.227.39.130 +49.34.217.143 +157.42.5.98 +223.190.174.3 +49.37.72.45 +49.43.41.181 +157.34.137.37 +49.43.101.179 +49.42.86.27 +169.149.230.18 +223.181.55.165 +49.36.232.177 +171.49.130.111 +103.182.131.38 +223.231.179.136 +157.41.249.121 +106.197.74.79 +119.42.156.26 +27.61.167.126 +106.221.243.196 +42.110.246.47 +152.58.56.40 +47.11.253.22 +110.224.108.186 +106.205.240.188 +106.208.183.47 +14.102.27.156 +157.47.87.171 +49.34.113.129 +49.36.26.53 +117.205.149.29 +171.50.237.112 +157.41.251.8 +106.196.49.52 +157.42.5.40 +157.35.85.185 +49.15.224.65 +103.211.12.65 +49.34.166.196 +49.34.53.203 +157.34.48.131 +1.39.224.3 +152.58.79.190 +106.203.159.215 +157.48.112.71 +49.36.219.108 +49.43.89.176 +103.40.198.52 +223.185.69.24 +117.234.49.3 +49.42.87.69 +106.211.187.48 +152.58.37.96 +157.51.194.124 +157.35.27.252 +157.41.229.178 +106.77.187.29 +169.149.227.92 +45.123.13.79 +157.33.121.49 +110.224.73.111 +106.76.210.214 +49.32.131.145 +43.241.131.104 +47.29.167.1 +49.15.201.178 +152.58.200.37 +169.149.231.25 +42.111.104.84 +106.223.95.211 +106.208.178.79 +223.233.65.155 +152.58.129.95 +103.176.185.190 +110.226.194.148 +60.254.88.144 +157.40.109.188 +106.76.202.182 +49.42.88.162 +157.51.194.103 +132.154.61.86 +117.98.96.149 +117.98.94.37 +137.97.88.218 +106.216.243.207 +157.33.232.203 +59.88.225.107 +103.218.237.9 +106.222.39.161 +49.34.57.193 +152.58.39.234 +106.194.36.28 +49.36.201.42 +42.108.27.16 +157.38.224.22 +106.207.221.41 +122.161.72.145 +182.68.166.105 +223.238.220.98 +122.162.51.107 +49.34.89.207 +103.220.208.162 +157.41.251.73 +157.35.49.137 +49.37.97.129 +223.181.1.152 +157.39.72.50 +205.253.10.81 +106.79.163.3 +117.245.65.119 +152.58.78.78 +27.62.226.35 +157.42.247.52 +103.95.80.243 +223.225.122.104 +42.106.16.18 +223.182.218.236 +152.57.110.119 +157.34.210.94 +202.164.132.137 +223.233.10.79 +106.196.14.134 +152.57.92.176 +49.37.11.73 +47.9.37.243 +117.99.29.253 +106.78.46.216 +27.62.150.176 +123.201.8.182 +49.35.235.11 +117.99.2.216 +122.171.18.107 +49.42.86.203 +117.99.192.23 +122.161.84.224 +103.38.130.153 +49.36.81.178 +157.34.81.102 +157.34.95.73 +42.108.29.76 +27.59.16.206 +42.106.184.243 +106.216.116.155 +103.81.241.25 +122.167.134.238 +157.35.15.172 +106.195.8.232 +171.76.245.157 +106.211.59.246 +45.113.64.170 +49.43.7.227 +106.203.44.121 +157.35.78.205 +223.187.106.239 +49.35.151.22 +47.11.192.155 +139.167.207.143 +117.205.112.21 +152.58.187.3 +152.58.73.121 +110.227.119.126 +157.41.198.78 +45.250.48.183 +106.196.5.173 +103.173.41.207 +27.63.131.26 +110.225.48.247 +157.38.106.229 +111.92.122.177 +42.105.195.69 +49.37.235.211 +49.36.235.211 +124.253.234.167 +157.49.82.96 +152.58.128.8 +157.38.88.217 +180.188.236.175 +1.38.142.62 +157.47.96.97 +49.15.245.51 +49.37.64.16 +49.43.98.76 +47.11.237.96 +223.233.9.150 +157.38.106.93 +27.63.194.133 +103.210.201.230 +157.41.254.66 +152.58.189.145 +106.221.110.5 +106.195.84.253 +106.216.118.109 +157.40.92.183 +106.220.202.212 +171.51.190.32 +157.35.95.150 +157.51.194.153 +103.41.36.10 +157.35.48.66 +27.58.83.70 +49.36.33.109 +49.37.32.179 +47.9.34.118 +106.221.23.10 +223.189.6.8 +106.195.127.244 +110.224.74.3 +123.201.95.158 +117.98.12.62 +1.39.75.177 +223.231.234.194 +117.99.244.97 +223.178.208.40 +157.32.34.96 +106.195.11.27 +47.29.166.179 +223.187.80.79 +27.60.252.86 +157.41.225.118 +47.31.99.102 +106.194.231.220 +1.38.165.83 +157.40.244.137 +157.34.197.204 +47.11.226.30 +183.82.153.26 +152.58.101.235 +103.161.231.238 +106.194.77.225 +110.224.98.40 +103.41.37.27 +223.178.234.144 +171.60.214.76 +106.196.62.45 +106.206.230.189 +106.213.252.77 +106.219.202.33 +49.42.69.227 +49.42.82.73 +110.224.70.14 +1.39.76.50 +106.79.139.130 +223.239.24.254 +152.58.16.82 +49.37.114.47 +157.33.196.52 +157.46.116.21 +49.43.41.126 +106.195.78.191 +152.57.229.214 +42.104.153.4 +103.218.109.179 +49.35.144.153 +132.154.35.141 +47.9.102.243 +157.32.42.2 +110.224.102.87 +152.58.24.237 +132.154.11.125 +171.79.145.104 +152.58.176.29 +47.247.192.180 +106.222.27.211 +157.35.75.83 +27.61.93.108 +27.60.100.98 +49.35.176.10 +106.193.244.188 +169.149.224.209 +223.176.64.185 +49.35.195.231 +223.238.213.13 +106.208.199.4 +103.254.57.101 +106.193.79.59 +112.79.119.226 +112.79.115.177 +157.47.66.130 +122.168.220.205 +110.224.68.176 +106.204.58.61 +49.37.27.42 +106.76.69.111 +27.60.71.88 +106.194.33.171 +106.211.212.148 +47.11.231.238 +152.58.210.169 +110.224.71.226 +110.224.187.10 +110.225.33.31 +157.38.132.76 +49.36.216.253 +106.197.23.174 +106.221.101.218 +117.99.42.9 +106.78.53.111 +157.46.119.153 +106.195.2.179 +47.11.229.239 +106.193.67.60 +157.38.86.117 +49.37.50.148 +152.58.16.194 +122.180.204.250 +49.32.172.252 +42.106.204.177 +49.34.135.195 +49.35.179.105 +223.239.53.155 +157.38.253.220 +49.43.155.140 +106.221.109.144 +117.98.88.107 +103.184.238.189 +42.109.196.25 +157.47.5.174 +122.161.241.97 +103.179.20.205 +157.34.109.227 +49.43.153.179 +49.36.211.194 +49.34.36.205 +49.36.144.184 +106.216.168.76 +178.248.116.52 +106.211.95.87 +1.39.77.238 +101.0.49.118 +106.193.64.132 +47.9.111.124 +64.233.172.167 +64.233.173.99 +223.239.56.12 +152.58.167.216 +203.115.84.234 +49.35.225.173 +49.34.209.195 +169.149.194.206 +157.42.195.148 +49.36.215.170 +59.89.216.142 +152.57.8.75 +47.11.201.178 +157.48.155.150 +157.39.74.93 +117.96.130.92 +223.187.244.195 +42.108.196.137 +27.57.243.78 +223.187.57.49 +157.38.130.244 +137.97.95.0 +103.112.213.69 +157.42.236.121 +106.193.244.194 +122.172.62.207 +49.36.122.53 +106.78.44.111 +157.35.79.71 +103.172.132.129 +49.37.88.169 +49.36.213.158 +202.142.68.56 +203.212.226.11 +47.15.19.47 +49.36.170.110 +47.15.226.163 +157.34.50.252 +47.9.80.70 +183.82.207.232 +152.58.156.211 +122.178.124.31 +49.36.220.30 +47.15.5.222 +116.68.76.35 +157.41.253.236 +106.220.106.86 +47.247.198.143 +49.36.101.162 +106.210.45.175 +106.221.105.211 +110.224.70.23 +152.57.10.38 +49.34.209.125 +157.35.6.206 +157.44.192.92 +47.31.138.111 +47.11.203.34 +117.99.217.200 +49.42.65.98 +103.183.30.185 +171.51.158.167 +157.47.101.64 +106.215.118.122 +157.40.254.197 +157.41.253.54 +223.187.146.55 +106.208.39.116 +49.36.71.185 +132.154.61.167 +106.193.11.25 +47.15.7.98 +152.58.141.89 +106.194.49.141 +106.223.154.171 +157.34.112.31 +157.38.206.42 +101.0.57.230 +106.207.84.104 +157.38.112.21 +106.206.199.63 +203.115.68.221 +110.224.69.227 +171.51.166.211 +103.179.39.48 +152.57.237.230 +106.200.120.69 +103.155.136.153 +157.47.109.117 +122.177.254.213 +112.79.156.235 +106.211.39.121 +157.34.95.212 +157.42.250.57 +49.32.169.222 +106.205.203.2 +117.96.168.112 +152.58.93.152 +152.58.93.222 +106.192.140.117 +157.38.132.23 +49.36.43.39 +106.205.168.127 +103.38.69.103 +106.203.133.134 +110.227.58.60 +49.37.183.171 +106.200.49.208 +152.58.227.239 +110.226.207.202 +157.37.165.170 +122.184.91.98 +106.206.244.49 +49.34.51.239 +110.226.181.211 +112.79.247.96 +103.205.151.34 +157.42.7.181 +106.203.235.225 +49.34.214.137 +157.35.27.251 +160.238.74.159 +152.58.177.251 +111.92.116.81 +27.97.177.107 +106.205.29.86 +157.35.91.66 +223.223.149.210 +157.32.68.50 +106.216.117.249 +106.215.190.66 +27.7.162.203 +106.194.118.138 +117.98.72.75 +49.34.221.249 +160.238.75.44 +106.204.38.36 +49.34.150.100 +110.224.109.127 +110.224.77.41 +117.230.156.146 +106.202.234.131 +47.247.199.96 +152.58.80.170 +157.40.210.177 +114.134.24.109 +49.36.217.76 +49.34.42.124 +106.206.197.142 +223.188.233.229 +103.69.14.206 +110.227.4.73 +157.42.0.121 +27.63.69.217 +103.70.45.145 +157.32.42.207 +106.211.88.97 +157.41.199.23 +121.46.114.196 +106.203.138.215 +122.161.74.206 +49.43.91.34 +223.186.222.0 +49.37.65.244 +103.18.167.122 +106.210.168.240 +223.233.79.148 +157.32.85.252 +103.80.248.67 +132.154.62.86 +223.238.217.70 +152.57.191.170 +122.174.91.79 +47.9.138.187 +110.227.49.112 +49.34.228.184 +27.56.10.28 +106.221.220.162 +157.34.76.196 +132.154.53.131 +157.33.70.237 +103.140.2.49 +49.34.91.89 +106.207.8.18 +47.11.199.227 +49.36.214.51 +49.37.116.189 +106.216.251.215 +106.221.189.22 +152.58.176.239 +157.34.129.113 +171.76.191.203 +137.97.99.57 +49.34.58.55 +157.46.190.92 +223.189.181.29 +157.39.192.217 +106.194.231.63 +47.15.107.100 +223.189.16.16 +157.50.67.114 +49.42.84.103 +112.79.75.73 +157.34.81.21 +169.149.230.237 +106.210.163.140 +157.50.40.133 +117.210.197.126 +106.215.246.198 +223.238.1.33 +106.76.76.32 +47.15.7.103 +47.9.32.64 +117.249.153.191 +117.98.44.65 +171.48.124.61 +117.98.38.4 +27.60.192.212 +132.154.48.83 +49.37.194.2 +106.196.60.18 +61.14.228.146 +117.230.171.161 +103.173.50.64 +117.98.58.23 +157.42.0.102 +223.237.105.229 +106.217.181.111 +157.38.146.212 +132.154.30.236 +223.231.169.177 +106.205.229.144 +110.224.104.130 +106.207.93.109 +49.43.154.173 +106.216.239.237 +110.225.87.200 +103.157.16.10 +223.187.96.56 +49.36.209.54 +180.188.232.192 +106.207.37.160 +117.205.222.177 +157.35.62.202 +152.58.162.242 +49.206.61.249 +157.45.178.79 +223.225.172.6 +47.9.106.91 +106.198.31.221 +47.9.123.144 +49.204.118.50 +117.98.34.46 +157.47.120.146 +27.62.225.109 +152.58.131.191 +27.63.223.92 +117.99.23.31 +59.89.0.63 +47.11.72.191 +110.224.100.228 +171.76.232.191 +103.146.233.10 +110.224.184.192 +157.41.228.200 +152.58.188.74 +223.225.245.9 +42.105.196.155 +157.39.64.176 +223.238.162.242 +110.227.60.213 +106.203.132.41 +49.37.232.241 +223.190.81.116 +47.29.172.65 +106.208.52.54 +49.43.96.236 +47.31.246.243 +110.226.200.141 +49.36.168.61 +49.14.125.23 +157.35.46.17 +49.206.119.18 +106.198.31.193 +223.189.16.51 +49.37.54.235 +157.45.193.160 +103.56.40.147 +157.47.41.198 +49.36.201.100 +49.36.188.184 +223.187.241.201 +157.33.62.219 +157.35.47.40 +47.9.35.11 +157.40.206.10 +103.81.158.9 +117.98.38.174 +223.189.184.203 +157.34.73.79 +106.211.73.192 +106.197.2.204 +47.11.3.44 +106.77.187.67 +106.66.28.99 +152.58.230.115 +152.57.102.111 +49.36.170.236 +47.9.91.41 +117.97.73.196 +49.34.228.101 +110.224.102.43 +103.66.208.136 +152.57.171.188 +117.99.216.145 +202.168.85.241 +157.32.66.49 +223.233.59.250 +106.220.107.53 +49.35.236.166 +49.36.168.208 +106.215.181.140 +157.48.163.129 +27.61.163.146 +103.100.215.60 +42.105.153.214 +157.40.99.183 +157.33.31.159 +106.216.239.191 +49.34.130.19 +106.205.230.169 +47.31.240.247 +49.43.101.144 +103.166.245.151 +42.104.145.79 +157.34.144.58 +49.35.159.103 +169.149.226.115 +49.37.250.35 +1.38.141.170 +49.204.22.166 +106.195.35.46 +157.34.55.179 +106.216.93.165 +122.177.107.79 +47.15.132.212 +49.34.176.150 +223.239.26.180 +152.58.208.13 +106.192.162.250 +117.199.77.129 +157.34.240.46 +117.98.98.19 +157.38.109.89 +157.34.146.126 +43.242.229.18 +47.11.207.29 +49.37.232.225 +49.34.185.134 +157.41.249.12 +223.233.74.241 +223.233.84.135 +152.58.227.82 +47.11.7.98 +110.226.178.182 +47.9.146.210 +157.42.6.11 +106.217.188.124 +106.216.78.158 +157.47.12.192 +47.9.108.34 +152.58.144.198 +171.48.106.216 +152.58.143.159 +132.154.50.84 +106.222.50.179 +173.252.79.120 +173.252.79.3 +152.58.102.59 +117.205.173.199 +152.58.212.254 +157.50.68.241 +27.62.237.104 +110.224.97.108 +103.201.135.231 +157.39.66.198 +137.97.117.57 +106.213.177.46 +59.91.142.37 +49.42.87.21 +59.99.65.19 +106.216.237.145 +110.225.45.119 +47.9.122.240 +106.194.126.218 +106.204.202.204 +103.199.180.225 +157.38.121.152 +47.11.206.210 +110.224.79.61 +132.154.58.169 +47.11.196.76 +223.190.140.179 +157.42.240.23 +49.37.105.137 +103.136.92.31 +47.29.169.138 +103.176.184.41 +223.187.97.154 +47.11.19.5 +223.238.127.75 +106.221.166.61 +223.190.172.21 +42.106.183.139 +122.172.44.92 +157.32.233.146 +157.45.133.159 +49.42.90.198 +152.57.242.120 +106.203.154.210 +117.214.253.181 +106.220.107.180 +137.97.125.114 +106.193.6.12 +152.58.234.63 +106.197.79.17 +171.48.76.212 +27.56.9.68 +47.11.207.75 +157.41.241.181 +42.105.194.193 +27.63.26.133 +117.98.124.98 +115.98.17.243 +42.105.14.23 +223.233.42.121 +116.68.110.45 +49.37.98.7 +117.96.191.154 +152.57.228.37 +110.224.66.142 +132.154.61.72 +106.205.197.8 +49.43.154.39 +112.79.164.47 +27.60.14.60 +49.37.46.254 +47.9.70.11 +49.249.103.174 +49.37.163.204 +49.37.39.107 +139.167.244.159 +157.35.3.63 +157.38.229.70 +47.31.97.231 +49.44.122.7 +157.39.66.217 +49.37.89.156 +157.34.61.136 +157.39.226.138 +157.38.149.151 +219.91.177.34 +42.111.97.33 +106.208.199.34 +157.41.250.121 +47.31.152.147 +139.167.253.16 +103.43.200.111 +106.220.157.5 +106.79.200.148 +157.34.69.211 +223.238.109.177 +223.189.4.65 +223.226.57.215 +125.62.97.12 +223.231.83.28 +47.15.10.11 +223.225.173.62 +106.192.176.42 +1.187.183.198 +157.38.59.16 +106.208.210.5 +223.189.96.60 +157.39.205.44 +223.181.53.109 +42.105.75.201 +223.181.194.99 +27.62.198.143 +106.208.149.200 +152.57.125.162 +110.224.162.6 +157.51.25.42 +223.178.213.52 +110.227.63.142 +49.34.142.80 +49.15.230.4 +103.85.96.209 +137.97.112.196 +106.216.115.166 +157.35.55.99 +117.99.221.33 +42.107.128.1 +27.59.215.51 +157.51.199.1 +157.45.223.172 +47.29.171.102 +106.215.159.169 +47.15.4.200 +103.250.136.203 +47.9.35.44 +152.58.113.209 +47.29.171.28 +171.79.146.233 +115.99.215.135 +49.37.41.103 +106.196.82.44 +157.35.42.154 +106.194.47.132 +47.11.210.227 +106.192.99.181 +152.58.168.114 +47.29.173.249 +106.211.249.139 +223.186.250.153 +106.211.72.179 +152.57.171.87 +49.44.83.5 +106.206.194.69 +157.35.84.2 +106.76.92.205 +49.36.183.27 +49.15.187.118 +223.187.203.20 +157.38.19.126 +27.63.63.220 +157.38.23.216 +106.212.75.2 +116.73.199.193 +49.34.239.29 +106.221.86.226 +106.198.119.229 +122.163.205.143 +106.207.158.120 +106.207.74.209 +223.231.75.115 +106.204.169.125 +47.11.79.193 +152.58.71.22 +157.37.176.61 +152.57.233.71 +47.9.119.78 +27.56.73.244 +223.191.61.166 +223.233.42.123 +223.228.248.156 +106.194.75.129 +45.127.138.120 +49.37.75.52 +106.216.129.57 +132.154.37.222 +223.239.101.162 +42.109.223.30 +49.43.3.121 +157.45.143.113 +49.14.134.83 +49.42.86.103 +47.11.253.84 +157.46.162.28 +157.39.64.64 +157.49.74.244 +42.105.9.217 +157.35.12.130 +27.61.132.19 +106.205.192.250 +223.233.42.43 +157.33.117.21 +223.233.58.49 +223.238.119.8 +169.149.225.125 +152.58.82.92 +173.252.111.10 +173.252.111.116 +173.252.111.9 +173.252.111.4 +173.252.111.1 +49.14.109.6 +117.98.46.180 +157.40.109.46 +132.154.39.84 +223.231.224.225 +132.154.60.192 +169.149.193.84 +132.154.19.230 +223.176.51.214 +152.57.206.93 +223.180.193.138 +157.41.224.185 +49.32.241.129 +117.99.225.34 +42.111.9.147 +106.203.33.250 +42.105.97.71 +117.99.217.21 +47.9.33.139 +106.213.214.81 +106.204.196.108 +110.224.96.208 +110.224.70.140 +223.176.19.91 +31.13.103.7 +31.13.103.6 +106.192.0.28 +157.39.217.186 +117.99.228.120 +106.66.59.175 +157.37.200.148 +106.205.155.143 +110.224.23.216 +152.58.222.30 +49.34.124.230 +106.77.180.1 +157.32.32.88 +49.44.87.197 +122.174.204.207 +49.14.127.11 +106.66.40.79 +106.220.106.105 +106.217.176.219 +223.186.5.254 +47.15.7.208 +157.38.87.52 +42.111.148.104 +49.205.240.238 +106.222.42.40 +223.239.27.236 +223.186.151.9 +223.231.236.33 +106.221.181.203 +157.39.67.208 +157.39.74.174 +223.189.202.188 +223.189.243.17 +45.114.178.12 +49.15.138.245 +223.237.123.154 +223.176.33.196 +110.224.16.5 +106.51.169.47 +47.29.171.97 +157.47.83.13 +59.178.254.98 +106.205.197.194 +117.98.94.78 +106.211.125.3 +157.40.250.250 +157.49.158.102 +106.211.26.209 +106.221.100.90 +106.213.188.153 +106.221.11.250 +49.36.168.17 +223.237.88.106 +157.41.193.15 +42.108.4.203 +49.14.152.16 +157.38.226.149 +49.34.206.112 +49.34.91.54 +157.50.26.202 +152.58.5.43 +157.38.55.79 +152.58.34.207 +152.58.184.118 +106.197.152.81 +157.34.236.229 +47.9.139.64 +157.40.211.138 +47.29.46.174 +49.37.55.14 +106.208.32.71 +223.190.137.204 +223.239.75.167 +157.49.77.43 +157.37.201.64 +152.58.56.132 +103.177.184.81 +42.105.203.65 +106.208.157.70 +27.62.184.72 +223.238.122.192 +157.34.217.68 +47.9.37.167 +49.36.101.80 +202.71.7.58 +49.36.70.147 +223.228.245.27 +157.38.95.124 +223.233.63.222 +223.187.151.110 +45.119.31.107 +47.15.35.201 +106.192.191.58 +157.34.12.70 +122.164.27.65 +49.156.100.33 +178.248.114.28 +157.47.35.241 +47.9.102.150 +49.205.143.180 +42.106.204.241 +106.221.54.153 +103.42.197.154 +203.28.245.156 +223.239.123.208 +122.161.74.88 +122.179.113.67 +157.45.251.146 +49.42.86.154 +157.33.106.28 +49.42.88.235 +103.176.116.228 +47.11.252.108 +27.63.131.166 +49.42.80.28 +106.79.204.95 +27.56.77.216 +1.39.78.36 +106.66.63.201 +173.252.83.11 +173.252.83.118 +173.252.83.1 +173.252.83.6 +106.205.164.144 +205.253.39.12 +157.33.28.160 +115.187.52.223 +49.37.91.172 +106.213.84.66 +106.205.59.36 +106.216.251.252 +49.36.69.212 +210.89.39.221 +223.225.65.92 +42.110.174.228 +47.11.198.167 +157.39.70.43 +116.75.241.200 +47.29.172.136 +223.233.1.109 +223.187.221.192 +223.187.148.153 +43.249.230.28 +223.239.68.75 +47.15.8.156 +223.176.117.59 +110.227.63.7 +157.51.199.253 +106.76.239.190 +47.11.198.3 +47.29.162.152 +152.58.33.188 +157.38.36.7 +117.215.242.154 +47.11.203.133 +47.29.175.28 +47.15.105.246 +157.33.82.115 +106.221.91.237 +106.221.59.71 +157.39.70.164 +49.36.215.14 +103.217.228.142 +157.34.236.49 +117.98.60.172 +47.9.112.121 +122.161.74.18 +47.11.64.158 +106.217.185.229 +137.59.68.66 +117.230.174.91 +103.205.174.229 +122.167.210.248 +106.66.3.61 +49.36.212.171 +49.43.154.51 +45.112.68.170 +42.105.164.115 +42.105.172.159 +106.214.135.131 +157.38.105.236 +106.207.19.105 +49.37.112.119 +47.11.27.222 +106.194.204.99 +223.238.110.218 +223.229.227.93 +157.39.64.30 +157.33.59.26 +223.189.252.131 +49.36.136.112 +42.110.162.206 +106.206.207.1 +49.36.136.207 +106.76.209.84 +106.196.112.253 +157.44.171.111 +27.60.249.106 +49.36.111.59 +223.179.221.42 +117.233.173.4 +152.58.98.107 +49.37.88.167 +61.0.7.118 +223.176.114.187 +152.58.128.103 +157.39.221.129 +152.57.12.195 +157.38.136.8 +47.11.208.248 +117.209.118.119 +106.221.100.87 +112.79.140.146 +223.176.11.94 +47.15.34.119 +49.42.64.26 +47.247.200.216 +157.38.54.84 +152.58.19.167 +157.38.30.64 +49.36.136.100 +49.33.197.68 +47.9.65.82 +106.223.183.75 +117.213.86.246 +45.250.244.75 +157.51.55.92 +122.161.242.24 +106.195.46.146 +103.214.118.235 +47.11.57.164 +210.89.58.120 +157.39.72.55 +157.34.70.75 +152.58.39.205 +157.34.193.208 +27.60.64.244 +106.216.251.69 +103.61.255.14 +223.187.89.182 +106.66.40.214 +171.79.191.142 +47.15.13.4 +106.66.23.84 +157.40.100.151 +47.11.254.226 +223.182.13.169 +47.29.29.169 +106.194.95.195 +122.173.27.107 +157.50.24.3 +47.15.42.174 +106.195.11.106 +171.60.209.63 +223.228.252.38 +223.186.192.85 +49.37.42.230 +27.60.111.178 +152.57.215.43 +175.101.106.143 +223.180.192.22 +47.11.201.1 +106.66.28.111 +27.57.246.128 +152.58.152.67 +103.89.232.26 +132.154.57.94 +49.35.135.168 +49.37.54.249 +42.108.17.157 +157.37.201.181 +117.98.64.74 +157.38.54.102 +103.100.4.156 +157.38.129.94 +152.57.223.39 +152.58.109.86 +49.44.76.166 +47.29.173.195 +47.15.8.193 +106.205.181.114 +171.76.84.47 +103.59.72.12 +157.38.205.117 +157.32.34.127 +223.186.190.197 +49.35.195.151 +49.36.179.198 +171.76.232.254 +106.211.57.156 +157.32.122.169 +47.15.185.22 +47.11.193.63 +47.29.164.48 +103.184.239.123 +157.32.248.188 +59.89.2.1 +223.191.56.100 +106.76.209.138 +117.197.184.194 +106.195.120.158 +106.192.97.140 +110.224.97.194 +45.251.117.5 +47.29.175.150 +106.193.246.162 +47.11.195.91 +157.49.238.150 +152.58.92.37 +110.224.165.112 +223.238.126.130 +106.211.96.188 +47.9.147.50 +42.111.114.16 +152.58.213.197 +47.11.232.210 +45.250.245.56 +106.205.131.201 +49.14.169.7 +27.62.183.20 +106.203.142.173 +132.154.174.171 +202.43.120.91 +169.149.230.172 +42.105.197.192 +157.40.237.188 +152.58.218.34 +122.176.20.188 +152.57.181.183 +115.246.153.21 +1.38.50.19 +223.233.85.17 +49.15.250.48 +45.119.28.44 +106.206.242.224 +103.169.52.37 +47.29.59.216 +49.35.242.142 +49.36.215.242 +139.167.213.95 +171.51.213.137 +106.221.106.1 +111.125.227.138 +47.11.207.175 +47.15.11.0 +47.11.248.89 +103.163.248.120 +106.196.102.134 +171.79.98.101 +132.154.54.47 +157.41.252.29 +178.248.116.67 +47.11.69.177 +132.154.56.170 +150.129.164.117 +106.216.117.68 +47.29.161.182 +106.222.58.197 +106.216.229.54 +49.204.194.118 +152.58.39.96 +169.149.194.103 +103.181.57.38 +106.216.94.61 +122.179.198.115 +1.38.52.27 +117.99.195.21 +103.89.58.10 +106.217.189.139 +117.99.30.214 +106.198.126.222 +120.138.12.111 +157.46.69.184 +157.47.118.245 +60.254.66.100 +223.176.96.95 +223.239.118.201 +223.225.16.56 +223.181.78.184 +49.14.115.114 +49.35.156.188 +117.98.28.41 +117.97.191.6 +223.227.75.94 +171.79.161.69 +49.34.160.77 +223.225.92.94 +106.76.212.35 +223.181.223.244 +117.99.255.168 +27.56.78.49 +157.38.12.101 +106.198.1.157 +157.49.68.175 +157.46.167.229 +106.66.60.159 +47.247.212.143 +117.99.212.254 +27.63.227.178 +49.14.156.34 +223.187.254.203 +42.105.202.102 +49.34.185.61 +223.238.100.55 +157.41.244.245 +182.68.164.23 +110.226.226.105 +103.253.151.35 +112.79.240.49 +106.220.76.12 +106.216.116.193 +106.207.108.149 +122.182.192.203 +49.37.72.173 +157.33.235.159 +106.76.21.142 +120.138.125.192 +49.37.9.141 +117.99.194.201 +152.58.169.194 +106.221.218.161 +117.98.122.64 +117.237.226.141 +152.58.22.62 +117.193.216.250 +132.154.190.30 +157.38.30.110 +203.76.178.6 +106.220.155.153 +27.56.84.77 +157.41.242.115 +49.44.80.5 +106.213.97.16 +122.172.96.241 +218.248.33.2 +49.37.201.170 +49.37.212.39 +49.35.162.11 +152.58.17.163 +103.133.123.82 +49.34.95.176 +47.11.192.203 +103.179.230.187 +139.167.166.232 +49.36.212.164 +152.57.153.160 +106.194.247.133 +223.190.154.62 +137.97.93.148 +49.32.244.168 +157.45.184.16 +157.44.160.145 +157.41.250.92 +27.56.12.122 +157.38.78.63 +49.47.70.68 +157.38.65.101 +49.14.134.201 +103.112.213.70 +113.21.67.54 +122.164.85.159 +152.58.37.140 +106.198.35.230 +59.93.12.67 +139.167.182.118 +152.58.59.45 +27.61.126.10 +106.195.108.38 +157.42.241.18 +103.153.105.79 +157.38.139.175 +49.37.55.41 +106.205.199.250 +27.56.15.91 +58.84.60.217 +47.9.34.136 +106.221.153.96 +106.207.39.63 +103.41.30.29 +49.36.103.174 +43.250.165.136 +123.201.213.117 +66.220.149.13 +66.220.149.120 +66.220.149.18 +66.220.149.5 +66.220.149.14 +66.220.149.21 +66.220.149.119 +66.220.149.8 +66.220.149.117 +66.220.149.118 +66.220.149.116 +66.220.149.19 +66.220.149.1 +66.220.149.9 +66.220.149.11 +66.220.149.12 +66.220.149.20 +223.238.220.116 +157.40.76.223 +27.60.50.191 +157.45.175.33 +157.46.181.208 +115.187.51.74 +106.193.109.111 +157.51.198.228 +103.248.172.156 +103.183.34.23 +152.58.67.210 +157.44.182.57 +106.193.105.146 +157.33.102.192 +49.37.105.240 +152.58.92.244 +110.224.58.92 +103.179.10.137 +106.210.167.166 +42.111.30.16 +61.3.145.247 +223.187.248.122 +1.38.97.41 +42.105.79.215 +47.29.173.250 +47.11.82.44 +103.135.202.63 +49.204.230.155 +103.75.43.202 +47.11.60.101 +106.205.255.166 +139.167.243.200 +157.32.209.8 +117.235.116.67 +106.211.82.244 +182.64.62.214 +117.98.42.110 +157.39.210.152 +49.206.122.242 +117.207.231.61 +157.39.69.49 +49.36.105.127 +103.198.175.75 +223.230.148.169 +106.208.182.168 +152.58.227.142 +49.34.43.202 +157.38.99.58 +157.45.203.201 +69.171.230.11 +69.171.230.9 +69.171.230.116 +157.33.75.241 +223.189.187.178 +103.199.224.182 +152.57.147.194 +157.38.138.55 +169.149.192.129 +49.42.84.203 +157.34.61.23 +42.104.196.168 +152.58.33.180 +124.123.187.159 +117.239.28.210 +106.192.93.67 +103.247.7.106 +157.34.133.228 +106.203.146.172 +152.58.215.172 +157.38.102.14 +157.49.173.50 +117.211.66.179 +223.187.240.14 +42.108.196.253 +60.254.22.151 +106.221.93.139 +152.58.162.70 +42.111.164.187 +106.195.14.216 +42.110.171.185 +49.34.52.153 +106.198.117.174 +47.9.37.0 +27.97.32.113 +152.58.211.10 +27.111.75.42 +157.48.127.173 +49.36.139.90 +117.228.67.148 +47.29.99.146 +103.220.89.171 +223.225.82.249 +132.154.187.171 +223.238.102.219 +223.238.217.153 +152.58.34.246 +157.49.161.22 +152.58.34.90 +157.51.18.22 +49.15.234.42 +157.42.236.134 +122.173.235.164 +157.35.48.226 +152.57.54.157 +47.29.160.157 +223.178.82.207 +180.188.236.206 +223.185.69.155 +132.154.60.241 +223.227.103.6 +157.38.220.162 +1.38.165.153 +49.36.80.40 +106.216.77.232 +152.58.200.78 +106.196.5.48 +205.253.126.224 +106.194.85.155 +223.237.70.99 +106.216.253.209 +157.41.250.179 +106.205.226.181 +106.196.87.184 +106.77.142.189 +106.194.62.159 +223.189.213.196 +202.168.84.51 +157.38.129.50 +106.195.4.128 +45.117.215.115 +122.171.20.19 +110.224.73.15 +103.92.42.16 +152.57.226.132 +49.32.248.97 +106.220.244.77 +101.0.57.98 +137.97.89.244 +117.255.37.37 +157.49.148.51 +117.98.106.21 +152.58.77.35 +111.92.75.97 +117.230.48.17 +103.81.242.250 +139.167.241.215 +223.187.133.48 +124.123.169.223 +152.58.93.93 +152.58.170.42 +106.216.240.249 +47.11.233.179 +116.206.222.244 +49.43.218.251 +152.58.146.114 +132.154.171.148 +223.237.75.114 +49.43.216.182 +106.204.192.173 +49.204.13.68 +49.37.221.191 +49.14.135.173 +157.34.17.45 +42.105.98.162 +61.0.148.172 +42.105.12.27 +157.41.224.47 +152.58.106.250 +110.224.177.160 +223.177.97.80 +47.15.96.78 +157.38.99.134 +42.105.5.91 +157.41.226.30 +103.127.166.56 +223.227.68.121 +106.216.228.198 +49.32.177.30 +103.178.60.46 +152.58.100.193 +152.58.59.203 +152.58.36.58 +106.192.94.163 +106.195.71.232 +106.198.13.226 +47.15.9.49 +49.35.158.35 +152.58.231.10 +157.38.130.27 +47.11.204.0 +157.34.66.78 +106.203.194.80 +157.40.217.92 +152.58.98.36 +58.84.62.181 +223.191.53.112 +103.144.192.243 +103.41.24.161 +157.32.35.3 +106.216.116.180 +42.107.88.101 +223.238.219.46 +157.51.65.243 +117.225.81.154 +106.193.73.13 +106.206.231.114 +106.78.45.2 +42.105.48.88 +66.220.149.3 +49.42.68.103 +223.187.124.76 +157.35.81.110 +122.171.22.77 +49.43.42.181 +103.209.223.42 +106.211.186.238 +103.127.167.223 +106.77.141.45 +152.58.36.203 +49.36.170.218 +223.228.131.140 +42.105.105.38 +47.31.98.184 +157.45.161.146 +106.221.213.107 +47.9.37.253 +106.205.34.23 +157.45.215.73 +152.58.59.109 +47.15.39.255 +152.58.202.3 +106.220.81.161 +132.154.149.136 +157.32.89.29 +157.40.223.171 +49.37.203.158 +223.185.79.160 +42.105.76.6 +49.36.144.197 +157.41.226.77 +49.37.163.147 +103.173.240.26 +124.253.60.138 +49.37.169.196 +117.98.120.176 +47.11.26.153 +47.11.237.72 +49.43.42.226 +103.66.82.224 +152.58.99.71 +49.15.173.162 +157.41.252.109 +106.79.205.248 +27.63.193.44 +106.221.80.131 +106.194.113.185 +157.33.107.219 +106.211.100.137 +152.58.37.180 +112.79.123.17 +152.57.153.180 +223.189.100.222 +152.58.34.32 +157.49.73.13 +152.58.93.199 +103.113.216.29 +106.211.126.48 +152.58.71.159 +42.110.175.28 +42.104.154.230 +180.188.232.221 +49.36.68.53 +223.231.109.138 +157.41.252.167 +106.217.19.134 +111.92.16.198 +152.58.34.121 +106.220.247.72 +157.45.166.149 +223.189.162.113 +106.194.215.247 +103.154.37.124 +49.32.172.235 +117.99.245.176 +112.79.240.246 +152.58.72.191 +152.58.66.231 +42.105.97.32 +106.193.151.29 +223.187.121.23 +106.205.204.192 +157.35.1.102 +132.154.36.24 +103.104.53.183 +150.129.103.172 +157.38.24.56 +157.35.1.140 +157.35.15.81 +117.228.212.158 +42.106.14.5 +106.220.104.60 +223.189.178.46 +47.9.128.9 +157.48.117.17 +42.105.198.151 +47.15.8.22 +157.34.243.72 +223.231.232.2 +42.111.145.52 +42.106.180.177 +1.39.114.239 +157.35.47.112 +49.37.159.89 +27.60.96.223 +106.205.203.80 +152.57.203.234 +106.206.241.22 +106.203.150.70 +157.47.57.17 +47.11.208.199 +157.39.72.190 +152.57.222.249 +223.188.236.97 +117.97.75.129 +49.34.179.33 +157.35.93.62 +47.15.139.210 +27.56.186.201 +157.51.10.80 +152.58.103.187 +106.204.194.198 +106.198.226.164 +123.136.186.83 +169.149.224.235 +106.220.110.45 +157.41.253.170 +182.70.182.53 +152.58.132.118 +103.40.196.84 +49.205.240.84 +47.29.62.161 +122.161.149.170 +106.196.2.103 +106.215.223.224 +157.32.227.145 +152.58.131.98 +49.37.46.223 +132.154.148.0 +60.254.55.116 +106.210.142.184 +49.35.240.133 +152.58.232.65 +132.154.34.5 +27.63.28.186 +122.161.241.88 +152.57.173.184 +152.58.179.141 +106.216.110.162 +152.57.202.171 +49.34.99.251 +27.62.155.231 +152.58.149.190 +47.11.203.113 +42.105.15.218 +157.35.14.9 +117.98.72.90 +103.85.8.106 +157.42.211.78 +110.227.59.150 +124.123.182.75 +132.154.61.212 +106.77.185.90 +49.42.64.37 +157.51.100.200 +103.133.50.231 +27.58.65.136 +49.37.24.244 +110.224.83.31 +202.8.116.11 +152.57.240.224 +157.38.33.92 +49.43.178.73 +49.37.158.109 +157.51.194.108 +42.111.108.17 +103.102.56.86 +152.57.209.60 +157.32.122.234 +137.97.127.140 +152.58.208.96 +152.58.20.126 +106.216.225.90 +152.58.72.103 +152.58.31.156 +110.226.194.16 +152.58.42.168 +157.33.218.71 +59.88.141.169 +223.177.10.233 +49.35.227.20 +103.97.212.81 +157.37.140.63 +47.31.175.226 +59.89.202.48 +42.108.196.150 +157.39.75.206 +43.251.93.190 +157.34.109.4 +106.222.95.4 +157.51.64.148 +106.194.202.3 +223.238.195.37 +106.203.133.187 +132.154.132.249 +103.70.199.120 +49.44.76.133 +223.231.234.153 +223.190.88.238 +157.38.118.18 +110.225.89.20 +103.72.178.74 +106.211.137.149 +42.105.167.49 +106.221.208.77 +106.216.242.58 +223.188.138.63 +103.157.70.241 +103.211.179.200 +49.37.74.3 +157.33.247.6 +49.42.94.55 +47.29.170.26 +47.11.199.74 +152.58.2.178 +223.233.66.64 +152.58.106.45 +202.142.116.250 +106.220.105.75 +106.197.109.28 +152.58.186.11 +152.58.166.109 +49.36.82.104 +27.62.65.241 +103.29.208.246 +103.219.1.62 +157.51.100.81 +49.37.55.102 +169.149.198.130 +152.58.66.160 +117.193.201.253 +47.11.202.250 +223.237.251.187 +47.9.32.138 +117.237.240.78 +106.194.197.64 +49.37.232.175 +103.203.73.189 +49.43.35.119 +42.106.160.11 +157.40.96.45 +106.195.46.174 +103.87.56.83 +223.233.68.84 +49.35.146.190 +152.57.133.161 +49.14.166.177 +122.161.242.101 +223.238.86.207 +47.31.145.201 +117.99.223.236 +223.233.11.221 +157.34.134.234 +49.205.82.14 +122.163.144.130 +117.212.73.151 +157.38.39.73 +202.142.104.93 +152.58.34.114 +132.154.9.79 +27.62.227.46 +106.208.102.209 +49.43.201.58 +106.206.137.163 +152.58.69.77 +106.193.190.9 +103.210.134.96 +223.227.77.112 +152.57.106.170 +112.79.73.85 +106.194.92.209 +117.202.53.169 +106.193.85.87 +106.194.233.218 +157.51.76.175 +47.9.154.152 +152.58.212.29 +152.58.92.245 +150.129.106.144 +106.194.47.141 +137.97.127.52 +157.45.183.119 +117.99.241.155 +103.59.72.28 +47.29.43.94 +152.58.169.85 +49.37.8.30 +49.34.181.237 +47.11.211.244 +152.57.20.57 +103.179.103.241 +110.224.103.94 +27.61.131.45 +196.12.59.22 +110.224.106.95 +49.37.34.209 +157.48.146.164 +103.70.199.136 +14.102.73.230 +106.193.213.116 +103.107.115.239 +49.36.171.154 +137.97.85.60 +152.58.163.156 +49.36.83.133 +103.158.120.43 +49.43.0.109 +103.187.64.1 +103.225.132.35 +152.58.18.79 +122.161.75.84 +152.58.71.218 +173.252.107.2 +173.252.107.4 +173.252.107.6 +122.171.19.155 +49.36.220.172 +157.51.197.199 +106.193.174.138 +106.216.124.197 +223.176.43.45 +112.79.140.73 +157.45.163.118 +157.47.70.204 +157.49.219.85 +43.254.176.232 +117.98.124.40 +117.233.103.94 +157.47.126.210 +152.58.152.10 +157.32.91.150 +106.205.213.232 +49.36.89.117 +106.197.111.30 +106.204.199.239 +182.65.72.32 +106.216.106.40 +47.31.214.79 +106.77.185.76 +27.60.103.78 +49.34.74.111 +117.99.253.123 +117.98.38.7 +157.34.47.150 +157.47.127.24 +106.205.193.98 +169.149.229.224 +116.72.120.248 +106.200.151.27 +157.49.81.95 +152.58.56.126 +49.32.255.216 +223.237.73.12 +49.36.50.24 +49.37.42.181 +152.58.209.60 +152.58.153.105 +27.57.246.150 +47.11.211.117 +106.220.74.8 +106.208.70.83 +47.9.119.81 +117.99.194.63 +106.222.74.173 +106.200.242.139 +106.195.32.39 +152.58.74.133 +47.29.5.152 +27.59.67.111 +115.98.233.157 +152.57.22.74 +152.58.139.248 +49.156.83.81 +157.40.222.47 +157.35.24.128 +152.58.162.78 +223.180.194.115 +157.32.33.78 +47.11.40.51 +49.37.201.39 +42.110.161.21 +49.43.41.82 +117.99.224.136 +103.170.158.115 +49.37.232.20 +49.37.218.56 +49.205.96.94 +103.200.85.61 +157.49.86.44 +120.88.189.38 +152.58.200.2 +47.11.253.139 +157.33.96.84 +157.35.6.101 +152.58.70.65 +157.41.250.144 +117.99.195.96 +152.58.102.232 +223.233.24.47 +152.58.225.149 +202.142.81.186 +152.58.22.255 +152.57.225.52 +152.57.177.152 +223.189.18.103 +103.251.226.123 +106.76.69.167 +45.124.6.68 +117.219.80.55 +152.58.221.66 +223.189.240.185 +152.58.209.29 +49.34.80.202 +223.233.83.191 +27.62.80.71 +106.215.95.237 +117.99.63.183 +110.227.44.154 +157.38.198.71 +106.76.88.15 +106.219.178.27 +152.58.34.59 +110.225.90.47 +49.35.132.117 +47.15.36.22 +152.58.179.65 +49.36.209.56 +117.97.196.96 +157.38.39.112 +47.11.204.179 +115.96.169.12 +49.37.114.252 +106.202.57.244 +223.238.229.156 +106.197.122.74 +103.138.233.130 +157.51.5.244 +27.62.245.194 +49.37.128.251 +152.58.138.70 +152.58.36.118 +49.37.65.129 +106.211.206.45 +157.41.251.66 +137.97.107.254 +223.177.1.51 +206.84.234.244 +124.123.165.133 +152.58.17.40 +157.50.45.68 +157.34.97.152 +157.33.86.238 +110.224.67.128 +152.58.21.248 +47.29.172.119 +103.40.196.255 +106.203.105.204 +106.222.84.46 +27.56.18.221 +223.231.64.234 +210.56.97.53 +223.182.220.87 +49.37.224.111 +103.244.34.93 +157.49.129.162 +49.34.60.167 +42.106.13.85 +210.89.58.166 +106.196.9.60 +157.51.176.165 +157.32.36.213 +117.220.57.159 +110.227.61.102 +49.15.203.215 +49.34.157.25 +152.58.76.196 +49.36.17.162 +49.37.11.123 +157.41.225.134 +103.85.11.58 +103.251.59.188 +157.35.24.179 +106.221.87.65 +202.131.148.55 +49.32.152.196 +117.213.47.227 +27.60.248.200 +152.58.100.60 +106.197.100.0 +157.38.131.72 +106.66.178.209 +106.76.78.249 +152.58.19.163 +157.37.195.194 +47.29.6.129 +152.57.47.106 +49.34.69.33 +157.34.23.100 +47.29.160.153 +157.45.81.33 +223.130.29.80 +106.213.223.131 +117.228.122.125 +103.185.245.228 +27.56.76.53 +106.196.79.86 +47.9.69.228 +106.210.204.154 +152.58.210.165 +49.36.144.26 +117.221.208.132 +152.58.211.115 +49.37.53.166 +157.46.186.87 +27.0.50.120 +47.29.172.11 +157.48.238.32 +27.63.29.100 +103.83.149.208 +106.196.21.140 +122.179.76.42 +49.37.33.87 +110.225.83.7 +47.11.237.55 +180.188.242.17 +47.11.40.183 +49.34.244.228 +110.224.86.59 +157.41.196.79 +139.167.188.236 +122.161.242.205 +157.34.3.27 +223.235.72.225 +152.58.22.66 +152.58.37.10 +47.9.35.178 +171.76.224.77 +157.44.133.48 +106.195.2.255 +150.107.232.51 +42.106.76.174 +49.34.245.176 +117.221.171.15 +106.194.172.110 +223.231.102.80 +103.185.10.161 +223.238.104.179 +223.187.159.98 +103.145.19.255 +117.222.154.12 +106.194.78.65 +157.32.246.65 +47.11.230.211 +106.220.84.247 +157.37.128.73 +106.201.141.1 +124.253.216.223 +157.48.221.70 +223.187.60.221 +152.57.111.164 +157.33.14.241 +49.36.237.90 +47.11.254.227 +1.38.112.7 +106.204.233.203 +117.221.150.61 +157.46.187.94 +157.32.218.218 +49.42.83.41 +103.181.100.176 +47.11.199.17 +47.31.225.118 +192.140.155.177 +157.46.188.30 +110.224.77.206 +152.58.222.33 +152.58.17.116 +47.15.43.181 +122.179.48.175 +49.44.86.139 +157.49.162.241 +49.43.40.165 +152.58.21.118 +117.98.12.96 +152.58.34.41 +106.197.69.58 +47.29.166.41 +223.229.242.228 +47.15.249.190 +223.233.123.217 +223.228.226.181 +49.14.125.30 +49.43.241.198 +157.40.197.50 +106.196.50.148 +106.222.18.87 +122.161.67.83 +49.37.52.164 +223.228.241.175 +157.33.29.103 +223.228.200.216 +157.47.30.253 +103.221.70.216 +157.35.60.162 +117.96.137.159 +47.11.232.219 +106.220.96.176 +223.233.80.64 +157.46.84.175 +106.220.107.217 +117.247.114.131 +103.146.0.80 +223.233.54.129 +103.179.197.204 +117.230.160.172 +157.32.96.40 +157.39.74.186 +1.39.232.198 +132.154.10.162 +122.171.5.19 +47.11.82.209 +157.47.17.184 +106.216.245.241 +223.231.237.58 +106.79.196.25 +42.106.92.56 +137.97.112.232 +49.34.50.228 +152.58.27.227 +42.110.136.245 +49.34.242.239 +171.50.231.148 +157.35.5.209 +117.99.40.167 +103.79.169.11 +47.31.205.59 +106.203.147.14 +117.223.46.124 +203.81.240.215 +27.61.251.247 +152.58.191.70 +157.35.42.15 +106.206.199.130 +157.42.200.159 +157.42.251.119 +106.207.219.162 +157.38.137.50 +42.105.142.73 +106.206.198.143 +157.49.145.54 +157.48.113.0 +157.51.177.124 +106.192.169.191 +223.186.23.119 +152.58.230.161 +47.9.156.147 +157.38.150.218 +117.98.118.93 +49.34.84.97 +157.49.82.13 +223.189.253.239 +47.15.0.229 +42.105.209.139 +157.38.49.71 +106.195.70.130 +180.188.248.192 +152.57.28.116 +49.42.85.230 +152.57.163.9 +157.40.124.99 +49.14.166.211 +152.57.67.18 +157.47.48.221 +106.195.3.229 +117.98.96.57 +42.111.165.90 +106.221.105.253 +106.76.235.203 +205.253.11.190 +47.15.32.28 +117.251.69.232 +49.14.166.249 +106.219.244.60 +157.45.179.211 +49.43.99.144 +103.87.58.76 +49.36.209.152 +59.97.248.9 +152.58.23.32 +152.58.78.93 +42.106.249.122 +152.58.38.27 +106.204.8.73 +152.58.101.180 +47.11.247.64 +223.233.74.40 +27.60.84.68 +157.42.210.69 +47.11.199.167 +157.45.161.162 +106.206.208.77 +132.154.161.173 +157.35.19.216 +106.220.174.51 +223.225.56.97 +27.63.10.60 +152.58.98.247 +157.38.128.65 +157.48.170.186 +103.41.37.14 +157.49.170.227 +106.210.35.195 +106.194.55.126 +49.42.66.105 +103.250.38.158 +157.45.197.148 +139.167.176.135 +117.200.27.239 +117.255.198.175 +42.110.232.156 +27.56.64.29 +132.154.12.216 +157.38.118.97 +106.79.180.12 +152.58.186.179 +157.38.110.106 +223.181.19.141 +122.161.240.225 +47.31.250.224 +223.191.60.64 +169.149.193.241 +49.15.209.89 +157.45.156.25 +49.34.106.113 +106.216.116.253 +49.37.117.220 +157.38.213.29 +157.38.115.232 +106.217.186.163 +103.211.18.71 +157.46.94.5 +47.11.49.67 +49.37.49.43 +157.41.194.241 +223.187.121.92 +157.48.73.53 +106.211.195.119 +47.11.32.212 +49.36.220.218 +117.98.120.135 +223.238.87.69 +106.221.252.195 +49.14.128.101 +103.16.69.209 +49.43.35.144 +152.57.71.200 +223.228.31.90 +223.238.106.82 +171.61.166.228 +157.39.74.175 +47.9.68.172 +157.38.65.212 +152.58.230.17 +122.174.154.68 +47.31.185.100 +42.110.137.71 +103.219.45.254 +27.61.91.167 +49.44.81.134 +157.51.194.162 +27.61.180.146 +47.11.77.240 +103.206.138.49 +152.58.83.46 +150.129.206.112 +110.226.206.142 +49.36.168.133 +103.175.89.76 +112.79.240.110 +223.186.216.84 +49.36.191.35 +47.31.99.157 +106.76.69.5 +117.99.246.189 +157.42.209.64 +106.221.211.144 +171.76.80.159 +157.32.104.36 +47.247.219.156 +152.58.159.217 +223.225.12.73 +47.11.203.230 +47.11.205.46 +46.3.240.3 +157.38.147.209 +117.219.45.112 +49.44.85.74 +182.79.238.134 +175.178.136.143 +106.206.235.197 +49.206.41.109 +106.221.102.78 +157.40.74.171 +157.44.172.236 +42.110.144.25 +159.138.59.64 +47.29.165.183 +42.105.196.216 +101.226.140.222 +112.97.84.188 +156.59.0.80 +183.30.221.34 +113.95.201.76 +106.76.90.138 +223.184.252.56 +27.115.124.109 +27.115.124.101 +205.198.122.72 +42.105.205.44 +203.160.80.139 +157.48.126.255 +49.34.110.236 +42.105.198.254 +157.42.5.138 +171.51.148.239 +110.224.64.196 +47.11.205.2 +205.253.8.113 +42.107.224.15 +45.64.226.118 +157.35.85.118 +106.221.86.178 +157.38.210.150 +103.183.91.223 +157.39.75.20 +117.97.215.126 +157.34.7.178 +157.45.74.161 +47.11.202.8 +157.38.135.59 +157.40.81.124 +106.217.29.165 +49.43.90.20 +206.84.234.109 +157.38.121.219 +117.253.244.105 +49.36.18.227 +47.11.253.138 +49.36.234.51 +117.194.1.213 +38.128.66.90 +106.207.41.121 +106.197.11.109 +47.29.167.250 +157.33.104.237 +106.200.44.170 +106.217.186.12 +110.224.168.131 +106.203.95.17 +103.183.32.176 +47.29.171.160 +31.13.127.118 +106.206.237.215 +157.40.230.159 +47.29.32.210 +34.80.19.108 +114.31.148.121 +157.32.84.204 +223.229.181.27 +49.43.42.37 +157.39.67.238 +42.110.172.180 +106.208.175.133 +169.149.224.174 +106.221.82.105 +152.57.219.127 +103.174.28.91 +223.186.81.17 +27.59.222.84 +106.76.152.24 +106.205.193.79 +27.56.69.150 +123.201.94.240 +157.33.208.109 +137.97.109.203 +47.29.161.142 +157.38.134.85 +157.40.234.239 +103.184.238.146 +157.45.74.2 +47.31.140.116 +27.60.138.198 +180.188.249.164 +106.216.192.195 +223.187.158.74 +223.233.73.164 +223.239.24.27 +157.39.218.148 +157.48.69.147 +223.188.228.3 +106.193.135.57 +122.173.26.117 +47.11.41.167 +223.180.177.143 +157.40.115.218 +106.216.254.170 +47.29.168.83 +49.35.250.140 +157.32.92.219 +47.29.175.176 +223.187.44.169 +117.98.88.101 +152.58.22.190 +49.42.85.43 +223.186.195.4 +47.31.228.29 +42.105.13.41 +152.58.222.213 +132.154.58.134 +103.172.99.101 +137.97.122.188 +49.36.188.52 +49.37.64.227 +106.51.186.138 +157.35.83.100 +157.35.90.84 +157.44.144.116 +132.154.164.228 +112.79.165.140 +132.154.57.97 +103.189.184.128 +157.34.227.7 +157.35.23.161 +42.106.93.216 +157.41.243.162 +49.34.179.24 +171.61.175.199 +49.34.96.99 +49.34.44.72 +27.56.196.202 +49.32.156.210 +49.156.84.126 +110.224.92.232 +47.15.15.63 +103.183.35.51 +106.77.183.173 +152.57.139.169 +122.170.25.23 +117.237.202.239 +223.237.247.134 +27.61.129.251 +103.178.145.79 +122.177.160.101 +157.45.156.84 +27.59.224.123 +157.45.134.117 +49.37.105.251 +157.33.20.179 +157.38.55.217 +117.97.241.44 +157.40.245.112 +106.210.97.169 +47.9.117.28 +42.111.106.33 +157.35.58.125 +106.197.0.144 +47.11.209.9 +106.216.228.193 +42.106.36.150 +117.252.181.45 +117.99.54.24 +106.211.50.79 +223.190.151.254 +106.194.164.53 +47.15.37.16 +122.162.150.163 +106.216.124.135 +27.63.227.245 +223.179.236.29 +117.99.225.77 +223.227.105.71 +157.32.220.69 +157.39.229.199 +152.58.34.39 +106.196.65.241 +47.29.165.143 +103.162.164.245 +1.39.251.200 +183.82.29.223 +157.34.8.84 +157.38.121.205 +157.41.253.114 +103.151.188.158 +106.206.241.197 +106.222.0.79 +117.197.70.46 +223.238.124.105 +103.170.159.223 +157.34.124.72 +157.45.253.224 +106.203.134.212 +157.46.184.161 +61.1.62.46 +103.39.158.13 +169.149.198.4 +112.79.119.142 +152.58.232.231 +106.204.206.190 +49.14.113.129 +47.15.128.138 +223.228.212.53 +103.143.168.98 +106.205.197.96 +157.39.66.193 +106.216.197.18 +106.206.236.128 +152.58.32.52 +122.163.228.43 +139.167.161.79 +152.58.163.240 +157.45.193.202 +49.35.234.92 +47.15.43.191 +152.58.209.147 +47.11.78.230 +171.48.106.209 +42.105.73.57 +42.111.111.2 +106.207.16.204 +157.38.228.10 +122.161.74.39 +137.97.100.234 +132.154.54.161 +223.228.193.194 +49.15.88.221 +106.194.151.16 +223.238.34.68 +49.207.240.109 +47.31.240.225 +205.253.8.148 +157.34.54.49 +152.58.99.225 +157.45.254.166 +152.57.40.143 +1.39.224.80 +49.34.214.52 +106.76.159.59 +106.216.114.115 +223.188.241.239 +47.9.34.112 +106.196.68.66 +47.29.168.228 +157.41.199.53 +117.99.27.7 +42.106.177.21 +27.62.22.28 +49.35.190.105 +47.11.194.81 +106.205.142.185 +103.226.5.56 +49.14.165.20 +106.210.107.164 +223.239.48.29 +223.187.181.109 +152.57.5.104 +223.130.30.241 +49.36.202.119 +157.47.121.105 +152.58.230.114 +103.176.10.93 +132.154.130.35 +117.228.78.125 +152.58.158.165 +157.119.203.182 +106.222.20.184 +47.9.33.253 +157.32.36.102 +106.211.74.147 +106.197.12.137 +47.15.13.227 +42.108.4.6 +157.34.108.138 +114.31.188.88 +42.106.92.234 +117.233.91.160 +110.224.64.169 +157.35.14.174 +106.211.126.8 +125.62.124.7 +49.36.183.8 +106.207.32.127 +45.249.85.10 +223.187.97.138 +103.240.78.169 +223.233.70.51 +103.167.205.45 +106.196.126.38 +223.225.168.51 +106.192.188.136 +106.203.43.172 +152.58.208.3 +223.187.105.241 +117.237.218.45 +152.58.58.76 +49.36.19.7 +106.211.95.170 +157.34.216.74 +42.105.193.76 +169.149.224.29 +110.226.226.9 +49.36.68.7 +49.15.86.250 +223.238.136.84 +137.59.78.166 +27.61.90.168 +42.111.144.10 +42.105.244.191 +152.58.76.77 +49.35.182.80 +157.45.76.33 +47.11.206.236 +157.33.126.149 +157.47.41.42 +49.44.82.72 +42.108.196.152 +157.38.126.241 +223.176.112.210 +106.210.182.215 +157.45.216.165 +152.58.144.139 +103.100.16.66 +110.224.101.177 +157.48.113.23 +49.32.239.7 +157.32.65.61 +1.187.218.8 +132.154.62.82 +223.225.168.222 +49.37.51.112 +49.15.228.219 +223.231.82.79 +157.41.254.122 +117.98.114.131 +152.57.185.136 +106.209.162.219 +106.216.64.105 +106.206.233.26 +106.222.112.94 +122.173.99.125 +171.48.118.232 +223.187.104.69 +157.39.228.82 +47.29.0.254 +49.14.126.32 +223.225.57.71 +202.142.71.17 +122.178.68.52 +223.239.49.113 +49.14.155.216 +101.0.53.111 +106.193.42.187 +106.196.121.126 +49.37.53.128 +223.239.54.215 +223.130.29.55 +157.42.214.186 +106.51.180.174 +157.38.144.114 +223.189.199.222 +223.237.101.111 +117.214.133.161 +157.40.78.150 +157.46.112.103 +103.183.35.247 +1.187.181.240 +157.41.251.32 +152.58.34.30 +223.187.107.238 +106.204.230.5 +49.15.136.166 +47.11.195.21 +106.78.54.155 +157.38.130.177 +157.38.74.219 +205.253.9.203 +157.35.87.18 +42.108.5.233 +220.158.141.160 +223.187.166.52 +49.128.160.21 +106.76.69.25 +223.225.174.211 +223.189.238.117 +117.99.232.58 +117.237.212.93 +106.203.139.221 +49.37.88.81 +223.238.206.35 +106.216.238.228 +1.39.250.20 +157.38.61.134 +42.110.148.25 +157.50.26.0 +223.238.98.41 +49.36.219.82 +49.15.217.56 +157.34.133.9 +27.56.83.176 +106.204.227.140 +223.238.106.161 +27.62.102.183 +223.237.88.138 +106.195.116.234 +173.252.79.8 +173.252.79.112 +157.51.165.47 +106.193.161.96 +137.97.93.189 +106.206.140.34 +157.40.77.45 +49.14.108.217 +106.221.85.234 +42.111.123.126 +117.96.160.207 +106.216.120.186 +157.35.26.96 +106.197.3.66 +223.190.157.246 +157.45.195.177 +106.217.176.107 +171.76.244.130 +157.38.102.130 +106.214.157.21 +106.213.87.134 +122.179.79.35 +27.56.91.150 +59.153.0.134 +114.79.136.160 +27.61.76.115 +49.43.97.101 +111.92.36.18 +1.38.50.20 +47.11.201.193 +157.34.27.31 +157.48.83.184 +49.43.97.212 +106.77.187.128 +27.63.237.243 +1.38.92.60 +106.216.92.221 +1.38.50.39 +110.226.192.33 +122.177.104.49 +47.9.69.73 +157.40.64.195 +152.58.202.57 +42.108.9.172 +47.29.168.242 +47.9.148.22 +49.14.114.241 +106.216.119.236 +202.142.70.28 +139.167.249.85 +49.36.238.1 +42.108.75.196 +157.35.45.75 +49.34.190.57 +47.11.248.123 +106.216.120.237 +106.220.106.250 +157.38.150.140 +106.221.244.201 +157.45.166.56 +223.233.73.255 +47.29.49.243 +157.42.6.144 +49.32.170.75 +223.187.243.210 +42.110.163.199 +182.65.172.30 +157.47.43.85 +47.9.9.26 +157.40.82.160 +157.34.98.231 +157.42.6.35 +157.39.74.47 +152.57.60.23 +106.205.169.42 +106.221.104.111 +49.37.131.54 +42.105.49.196 +47.11.205.246 +223.231.219.188 +49.35.146.109 +45.115.253.22 +106.221.109.121 +47.9.158.178 +42.108.161.169 +152.58.210.222 +106.215.194.251 +202.43.120.88 +47.15.20.176 +42.109.192.5 +106.194.239.128 +157.35.22.45 +42.105.208.165 +157.33.42.164 +49.36.25.13 +152.58.70.109 +157.35.27.245 +183.83.226.191 +171.48.106.90 +42.111.36.56 +47.11.201.142 +152.58.202.12 +106.198.153.153 +47.31.143.240 +106.221.90.102 +157.38.136.241 +157.40.94.216 +106.192.4.221 +171.76.228.121 +106.77.129.54 +106.205.51.96 +49.37.51.218 +27.59.221.251 +106.221.113.9 +157.39.229.243 +103.212.159.66 +157.49.151.124 +106.197.0.140 +47.11.202.49 +49.206.117.132 +157.34.122.93 +169.149.226.29 +69.63.189.20 +69.63.189.10 +69.63.189.9 +69.63.189.11 +69.63.189.19 +69.63.189.4 +69.63.189.15 +69.63.189.118 +69.63.189.5 +182.48.226.94 +69.63.189.17 +69.63.189.7 +106.207.55.163 +112.79.230.234 +157.35.57.72 +223.239.95.28 +27.59.244.73 +157.33.60.4 +223.231.66.31 +157.35.57.172 +171.51.136.37 +152.58.225.217 +223.238.100.213 +139.167.216.160 +106.194.53.124 +42.105.212.170 +49.35.145.129 +157.38.147.240 +157.39.70.167 +223.231.90.24 +47.9.111.229 +117.237.229.104 +106.194.245.150 +106.208.149.210 +106.66.58.215 +47.11.205.39 +223.181.86.136 +49.34.94.8 +205.253.10.153 +152.57.39.165 +157.33.77.31 +106.216.203.108 +42.105.206.155 +49.35.169.6 +223.225.169.191 +169.149.199.255 +157.35.4.73 +223.239.53.222 +157.38.103.200 +157.32.225.171 +47.29.25.168 +223.238.125.16 +152.58.66.115 +223.189.8.216 +47.9.97.51 +157.51.114.154 +47.11.199.189 +27.63.24.229 +106.217.6.218 +223.239.59.253 +103.161.144.149 +106.79.200.20 +27.97.45.152 +42.105.12.138 +47.29.170.148 +119.82.87.102 +117.99.55.196 +157.47.90.181 +1.187.219.221 +106.211.72.154 +49.37.36.16 +157.35.3.213 +173.252.83.117 +47.29.171.107 +171.51.136.219 +157.40.77.32 +49.34.173.134 +223.230.160.254 +157.41.225.142 +49.42.94.229 +106.194.172.17 +169.149.230.3 +47.15.7.10 +106.222.7.73 +152.58.184.90 +49.35.231.180 +106.211.148.218 +171.60.208.98 +49.36.203.6 +157.32.225.181 +106.217.182.140 +47.9.128.105 +117.99.251.219 +157.38.68.189 +106.78.61.18 +106.204.200.205 +223.227.72.24 +27.61.175.145 +106.76.244.64 +49.36.24.189 +106.202.88.121 +103.59.75.237 +49.42.88.207 +47.15.19.215 +47.15.23.65 +106.216.111.39 +27.61.107.162 +106.221.117.194 +157.33.126.105 +157.51.157.124 +223.187.134.127 +152.58.191.78 +103.41.91.243 +106.221.245.113 +27.97.11.213 +47.31.247.85 +106.195.9.178 +103.85.11.46 +106.221.248.158 +47.15.14.171 +110.224.69.5 +106.216.227.123 +183.82.161.98 +106.206.252.172 +106.211.228.218 +157.38.145.19 +157.32.202.110 +49.204.200.203 +223.181.237.223 +223.181.213.238 +47.9.138.236 +157.38.133.243 +122.172.221.138 +47.9.75.70 +106.221.111.235 +47.29.175.141 +223.239.85.167 +47.9.75.22 +132.154.56.188 +49.32.132.210 +106.217.189.134 +103.103.57.176 +49.37.64.182 +27.97.14.252 +157.51.18.225 +49.37.243.47 +106.206.129.251 +110.224.85.152 +157.48.249.111 +157.49.186.97 +171.76.245.159 +27.61.152.69 +157.50.67.221 +106.206.237.170 +139.167.185.111 +157.38.17.42 +61.2.196.145 +49.14.109.58 +223.237.117.17 +157.38.150.158 +47.11.232.40 +152.57.86.246 +152.58.197.44 +49.156.100.54 +106.77.78.84 +223.239.24.13 +223.239.2.241 +42.106.190.137 +106.195.10.38 +152.58.34.251 +139.167.183.100 +47.15.100.174 +152.57.8.170 +49.36.91.145 +106.196.97.227 +117.246.191.86 +47.29.168.25 +47.11.193.210 +223.190.171.67 +223.231.120.162 +106.221.29.59 +106.197.11.163 +132.154.51.219 +157.38.138.163 +152.58.96.183 +223.187.240.129 +132.154.61.82 +157.38.42.33 +203.115.68.94 +117.241.207.68 +49.156.87.44 +47.29.3.34 +152.57.228.100 +1.187.57.168 +120.88.34.41 +114.31.185.246 +103.171.100.227 +106.197.32.227 +106.216.207.171 +49.42.88.115 +49.14.165.110 +49.37.75.49 +106.221.39.63 +42.105.166.226 +106.202.1.216 +106.208.158.31 +157.35.79.160 +1.39.30.148 +49.15.230.159 +202.45.6.1 +47.31.169.171 +223.228.227.34 +152.57.211.85 +110.226.54.3 +49.42.37.55 +223.227.86.17 +122.167.166.159 +157.49.229.118 +157.32.192.64 +106.203.148.171 +110.224.85.11 +42.107.195.178 +223.187.103.67 +112.79.159.214 +157.40.201.85 +152.58.30.130 +106.203.152.19 +27.60.238.184 +106.222.78.156 +103.182.167.212 +49.43.217.187 +49.35.194.133 +157.40.255.230 +117.99.8.218 +157.34.145.33 +157.39.230.118 +106.211.30.22 +152.58.177.152 +106.206.201.186 +106.66.37.83 +106.195.123.183 +106.198.198.219 +157.48.243.241 +223.186.121.247 +110.227.24.152 +103.183.83.114 +106.203.44.126 +157.35.75.114 +157.32.35.101 +173.252.87.119 +173.252.87.117 +173.252.87.7 +173.252.87.116 +173.252.87.120 +132.154.3.59 +47.15.32.195 +152.58.232.1 +49.15.174.94 +157.33.117.133 +157.49.92.84 +27.62.41.238 +137.97.87.84 +27.109.29.10 +106.216.67.87 +49.36.217.60 +47.15.12.83 +49.36.208.241 +223.230.160.118 +223.227.66.6 +223.178.213.73 +103.59.75.8 +49.36.214.159 +106.195.70.195 +117.99.205.201 +223.228.225.63 +47.11.71.14 +157.34.133.40 +157.33.94.100 +47.9.131.191 +110.224.79.181 +47.11.28.212 +49.42.74.236 +42.105.49.105 +171.76.80.167 +223.189.206.197 +152.58.73.99 +106.213.189.121 +106.206.173.195 +157.45.207.76 +117.98.110.14 +106.208.70.81 +106.216.126.48 +117.225.5.159 +27.58.181.215 +49.37.46.185 +103.92.42.81 +106.195.43.199 +47.9.132.219 +42.105.172.34 +223.233.76.249 +152.58.190.177 +42.105.234.219 +27.57.169.140 +49.44.82.39 +47.31.98.129 +219.91.213.171 +157.35.20.88 +223.188.168.228 +1.187.181.0 +157.47.16.55 +157.41.253.66 +106.208.23.198 +223.187.69.221 +47.31.247.135 +42.111.20.249 +157.49.230.198 +106.208.156.185 +49.36.235.164 +152.58.236.60 +106.211.125.103 +49.43.1.204 +106.207.187.228 +157.41.255.235 +49.204.193.201 +117.97.214.3 +152.58.139.117 +103.172.48.70 +49.35.231.6 +171.76.230.10 +47.15.5.244 +223.181.218.37 +152.58.33.120 +157.47.39.39 +106.51.118.134 +157.33.38.98 +106.223.117.144 +157.39.72.183 +49.34.219.90 +117.235.110.27 +157.49.142.17 +223.176.43.171 +157.38.88.206 +27.63.222.137 +117.97.211.43 +152.58.186.104 +106.76.198.197 +132.154.18.255 +132.154.57.191 +157.38.243.221 +42.111.216.106 +139.167.165.5 +103.251.58.52 +223.182.168.171 +106.220.105.63 +171.76.230.19 +42.105.236.5 +157.33.125.38 +223.186.229.105 +106.211.83.219 +47.15.2.89 +157.35.81.123 +157.39.67.77 +49.34.64.120 +110.224.77.81 +103.238.108.131 +157.49.207.154 +157.32.198.17 +110.226.171.57 +157.49.169.155 +47.11.206.53 +106.216.141.139 +103.149.16.9 +106.78.86.176 +106.76.218.115 +132.154.175.220 +157.38.21.3 +171.76.236.114 +106.217.12.117 +49.42.75.241 +106.216.249.232 +157.38.225.131 +223.238.131.24 +112.79.140.17 +223.231.79.244 +47.9.129.233 +45.116.106.9 +106.222.8.189 +223.238.99.106 +47.29.164.51 +49.43.43.130 +106.217.195.213 +152.57.2.252 +106.203.128.225 +157.38.128.216 +157.48.95.38 +106.208.156.135 +106.197.7.122 +47.29.175.241 +157.33.35.114 +106.221.61.108 +47.15.218.93 +49.42.89.19 +152.58.66.10 +223.188.165.207 +157.38.79.127 +157.45.56.105 +106.207.242.249 +157.45.250.248 +47.29.175.174 +106.198.21.248 +171.51.164.207 +47.9.35.235 +223.182.229.188 +157.41.255.145 +49.43.89.82 +27.60.252.187 +27.63.9.124 +157.39.70.28 +47.31.203.84 +152.58.20.154 +152.57.69.157 +115.96.121.101 +157.32.35.230 +47.9.114.155 +152.57.207.202 +223.237.111.81 +106.222.63.175 +117.98.78.54 +106.78.54.248 +49.35.228.53 +49.33.208.141 +42.111.21.4 +47.247.221.144 +47.15.9.2 +47.9.32.41 +157.41.254.96 +103.56.230.73 +122.161.67.36 +157.38.152.215 +110.224.169.164 +106.76.202.20 +45.249.171.28 +47.29.173.247 +157.35.5.35 +223.186.23.229 +27.56.14.51 +42.105.194.119 +106.195.5.136 +157.41.254.93 +157.39.210.168 +152.58.20.97 +122.179.255.119 +157.33.96.163 +157.35.63.235 +157.41.198.139 +42.105.178.81 +182.77.22.123 +223.231.75.72 +47.29.164.63 +157.35.62.96 +223.239.25.142 +117.221.80.123 +117.219.161.38 +42.105.180.15 +27.62.51.63 +106.198.21.69 +106.200.54.83 +223.230.162.112 +110.224.88.243 +157.35.47.212 +180.188.249.49 +106.217.181.39 +139.167.246.211 +157.34.4.205 +132.154.48.189 +157.47.112.83 +223.187.42.39 +223.228.138.107 +152.58.181.49 +110.224.221.254 +137.97.105.136 +27.61.10.20 +106.195.41.46 +205.253.9.114 +202.142.81.244 +106.221.158.238 +157.38.153.200 +106.216.103.170 +49.15.231.94 +47.9.105.173 +103.183.83.33 +49.37.44.93 +157.45.129.18 +47.15.8.176 +152.57.200.76 +106.221.109.109 +157.40.192.218 +157.38.128.39 +157.51.4.32 +157.35.44.123 +106.217.181.79 +112.79.125.43 +169.149.226.41 +106.207.10.109 +106.216.143.48 +139.167.171.141 +106.76.208.110 +49.15.248.162 +171.79.191.54 +223.187.95.90 +132.154.55.69 +106.206.208.89 +157.34.244.229 +47.15.209.46 +157.46.89.250 +157.38.87.211 +157.38.99.25 +157.39.69.119 +47.11.206.0 +223.187.3.59 +106.215.198.111 +49.15.209.78 +157.48.115.218 +157.48.224.252 +103.25.168.138 +106.195.89.4 +47.9.145.196 +152.58.16.72 +152.58.31.74 +103.160.199.90 +43.250.158.219 +106.215.227.35 +223.180.185.149 +152.57.114.76 +152.58.100.88 +47.11.91.113 +106.207.223.223 +106.193.36.171 +42.105.23.237 +157.38.204.55 +223.190.172.181 +223.182.10.178 +152.58.162.119 +106.76.76.26 +157.38.11.213 +152.58.39.202 +27.60.247.45 +110.226.64.137 +49.35.162.33 +106.213.140.238 +106.205.56.171 +106.211.154.15 +169.149.227.171 +223.188.152.229 +49.15.224.207 +157.42.223.82 +106.213.251.147 +106.66.28.177 +47.9.128.77 +49.34.114.27 +157.48.199.154 +157.34.83.49 +157.42.3.7 +42.105.48.57 +106.215.83.246 +132.154.59.223 +110.225.80.201 +205.253.9.111 +157.42.235.143 +47.29.97.69 +103.36.82.43 +47.31.207.5 +117.99.1.35 +47.15.7.226 +47.15.5.143 +117.96.165.161 +47.9.98.167 +49.34.102.6 +42.110.144.195 +49.34.203.92 +106.77.77.165 +223.187.138.197 +223.237.96.111 +106.223.183.119 +106.194.34.159 +117.99.211.176 +223.238.218.161 +223.189.228.101 +157.38.23.183 +106.216.127.82 +49.36.101.124 +106.195.117.224 +157.32.40.52 +106.222.20.154 +117.99.220.118 +49.43.96.30 +157.48.240.27 +157.35.0.132 +157.33.33.175 +101.0.42.145 +139.167.236.228 +122.162.98.211 +103.203.72.239 +106.196.121.60 +106.206.47.212 +47.9.122.219 +152.58.157.172 +157.38.10.96 +106.192.230.35 +139.167.223.131 +157.34.75.91 +106.200.44.26 +110.227.57.233 +106.205.189.38 +157.34.108.201 +47.15.16.194 +152.58.67.187 +223.187.79.181 +42.110.161.10 +152.58.31.3 +112.79.116.123 +106.196.21.119 +223.190.182.16 +157.48.226.62 +106.211.191.100 +106.66.36.59 +106.192.151.231 +157.47.72.79 +157.39.72.138 +49.42.90.11 +157.51.194.230 +49.35.193.54 +49.32.228.253 +49.36.215.220 +152.57.103.8 +223.187.180.72 +42.104.130.32 +112.79.165.163 +157.42.6.150 +223.230.165.181 +223.187.206.92 +42.111.99.28 +157.38.131.254 +49.36.223.178 +106.194.60.27 +157.51.194.102 +223.227.69.122 +152.58.3.123 +152.58.67.44 +157.32.122.149 +49.15.191.174 +47.29.166.70 +223.196.170.152 +47.9.111.57 +47.9.104.209 +42.105.86.123 +49.34.114.98 +157.39.66.68 +106.77.156.207 +117.230.82.50 +42.110.222.77 +49.32.139.248 +223.182.231.198 +47.11.57.8 +117.99.233.108 +223.187.109.78 +106.216.224.181 +157.37.131.112 +157.34.154.170 +42.109.208.23 +132.154.58.207 +49.14.164.86 +223.188.231.219 +106.192.15.80 +169.149.230.131 +49.34.103.216 +49.37.225.129 +157.38.40.175 +171.79.160.238 +1.187.216.6 +47.11.198.225 +157.47.37.52 +223.187.58.177 +117.234.212.12 +47.9.3.57 +157.35.80.184 +49.36.215.22 +106.208.152.44 +157.47.65.169 +157.35.11.146 +117.230.88.189 +47.11.205.248 +157.41.226.193 +157.46.108.133 +103.240.79.204 +157.47.15.239 +223.237.1.212 +49.35.161.59 +42.105.237.138 +49.44.67.233 +106.206.204.141 +49.35.252.37 +223.237.198.58 +157.34.70.151 +49.15.174.6 +117.99.223.230 +157.38.120.38 +103.119.166.244 +171.51.191.177 +106.211.59.175 +106.198.29.232 +152.57.176.10 +117.99.18.181 +106.216.200.78 +132.154.34.243 +106.196.61.203 +47.15.13.147 +152.57.210.219 +103.203.73.107 +27.62.215.70 +103.241.225.247 +152.58.87.68 +223.176.64.120 +47.9.145.229 +152.58.25.157 +117.98.8.197 +27.61.231.183 +106.76.249.255 +205.253.33.87 +152.58.213.151 +49.32.186.61 +132.154.50.254 +223.176.8.181 +117.99.43.12 +27.63.8.212 +157.51.42.52 +157.34.79.212 +42.111.121.4 +106.196.70.168 +223.184.202.181 +152.58.128.39 +49.36.24.115 +49.35.128.170 +47.9.132.143 +152.58.32.72 +157.41.228.94 +27.56.2.31 +106.76.91.7 +223.230.135.174 +157.45.93.209 +42.105.238.130 +157.34.40.253 +106.195.38.98 +157.38.135.60 +157.38.113.31 +122.171.221.75 +106.207.171.89 +106.206.249.73 +132.154.6.204 +47.11.65.187 +152.58.25.221 +223.178.227.117 +157.38.96.93 +157.34.49.34 +27.61.45.218 +47.31.233.213 +106.221.183.51 +49.15.163.57 +47.15.38.25 +45.115.89.241 +223.189.193.149 +110.224.92.138 +103.218.237.222 +42.108.4.100 +139.167.225.237 +47.9.98.222 +106.197.249.247 +157.40.235.218 +103.41.27.129 +122.162.151.189 +106.77.167.72 +49.44.86.41 +106.206.207.47 +182.79.221.199 +47.11.208.115 +47.11.1.237 +42.105.232.182 +132.154.155.176 +157.34.68.254 +223.225.124.19 +157.35.75.74 +157.39.69.101 +223.180.197.91 +157.42.4.73 +202.168.84.197 +47.11.194.244 +117.235.50.217 +157.38.129.39 +27.63.37.192 +106.223.138.192 +1.38.164.255 +106.221.12.106 +106.79.204.59 +110.224.69.177 +157.38.144.103 +117.214.225.26 +117.221.201.168 +157.33.26.139 +106.194.39.216 +152.57.117.216 +106.221.111.225 +157.33.245.35 +157.38.131.136 +49.42.67.6 +157.34.76.145 +106.208.155.83 +157.38.52.181 +132.154.149.174 +47.15.37.163 +157.45.206.117 +47.29.163.164 +49.44.84.37 +106.66.205.54 +117.99.196.9 +106.216.125.27 +27.56.89.203 +49.34.105.81 +157.38.145.53 +49.42.73.31 +171.76.236.212 +49.42.65.100 +49.15.241.177 +110.226.215.182 +49.36.168.224 +42.105.203.128 +27.63.195.243 +223.225.168.125 +103.200.85.168 +157.38.76.60 +157.35.70.88 +152.58.19.61 +106.216.241.40 +61.3.93.89 +49.34.154.243 +106.216.246.112 +103.108.6.80 +27.62.253.69 +49.35.236.25 +49.42.64.32 +223.187.98.171 +157.39.251.176 +49.42.87.129 +106.208.124.109 +103.199.112.189 +157.33.37.255 +47.11.248.176 +205.253.38.131 +106.78.52.100 +110.227.45.13 +223.230.129.107 +27.97.254.154 +117.249.221.183 +117.99.228.3 +117.99.210.187 +157.34.199.22 +27.60.52.12 +205.253.10.170 +157.40.228.66 +49.35.232.202 +152.58.103.51 +152.58.73.83 +106.223.179.171 +157.41.194.95 +42.110.137.58 +1.39.225.54 +157.34.147.4 +157.38.118.124 +157.32.122.119 +139.167.190.186 +157.35.6.171 +47.29.175.210 +106.222.88.8 +47.247.214.18 +47.31.151.241 +106.221.6.128 +132.154.52.60 +157.48.180.111 +223.178.80.2 +106.196.92.243 +157.35.7.213 +106.217.183.146 +152.58.156.188 +152.57.212.86 +171.76.203.180 +157.33.222.132 +157.42.246.1652401:4900:619e:39c:dd1f:8049:e662:21ae +2a03:2880:31ff:16::face:b00c +2a03:2880:20ff:e::face:b00c +2a03:2880:31ff:4::face:b00c +2a03:2880:ff:d::face:b00c +2a03:2880:31ff:b::face:b00c +2406:2d40:8060:6d10:35e6:32ce:768d:4f29 +2600:1700:2d61:75d0:90fa:1fb8:eb09:7719 +2607:fb91:c19:d3a3:8d2:6da4:9620:f8e4 +107.123.1.48 +2601:243:901:210:aa6:bcff:fe22:8a7f +198.54.106.219 +216.207.143.130 +64.152.247.50 +2600:6c5e:6800:3f:a5b9:fbae:1dd7:d1f2 +2601:188:ce84:11a0:fc20:f0b5:2c9f:ebb5 +2600:100f:a110:a7:c8b8:c9df:3fbf:d0b8 +63.70.5.118 +63.70.5.122 +75.202.81.140 +63.70.5.121 +102.89.22.87 +172.59.213.208 +2600:387:c:6d32::1 +63.70.5.126 +182.239.121.40 +24.182.244.142 +197.210.70.75 +2607:fb91:2132:d290:5cd6:3a52:6a49:6b89 +63.70.5.124 +38.107.226.252 +2600:387:15:2f18::3 +84.239.27.10 +2600:1004:b27e:da74:0:3c:340a:de01 +2607:fb91:32b5:7ee:9d5:1eb9:6db2:53c4 +102.89.22.171 +172.59.208.42 +182.239.87.170 +172.59.219.225 +166.205.87.30 +172.58.231.112 +23.177.40.239 +105.119.3.72 +102.89.34.248 +75.137.54.100 +102.89.44.77 +105.113.18.110 +182.239.121.154 +102.89.23.122 +63.70.5.125 +102.88.81.12 +197.210.28.93 +174.169.206.43 +102.89.34.148 +102.89.34.220 +24.23.222.119 +154.30.145.118 +102.89.23.51 +63.70.5.113 +84.239.27.14 +102.89.32.160 +105.113.83.193 +102.89.23.212 +24.101.181.167 +120.85.107.1752600:387:1:808::64 +2600:387:1:808::64 +2600:387:1:804::79 +120.158.184.220 +49.185.200.101 +185.239.244.90 +185.239.244.117 +185.239.244.84 +185.246.236.31 +45.143.174.238 +185.246.236.98 +185.246.236.55 +185.239.244.54 +45.88.100.12 +185.239.244.206 +86.104.192.185 +185.239.244.68 +86.104.192.155 +185.239.244.159 +45.143.173.188 +86.104.192.36 +185.239.244.80 +86.104.192.222 +185.246.236.5 +185.246.236.61 +86.104.195.236 +185.239.244.83 +86.104.192.195 +185.246.236.45 +185.239.244.113 +86.104.192.167 +185.239.244.53 +185.246.236.49 +185.246.236.12 +185.239.244.0 +86.104.192.157 +185.239.244.77 +86.104.192.190 +185.246.236.123 +86.104.192.174 +185.239.244.50 +86.104.195.237 +185.239.244.101 +185.246.236.95 +86.104.192.164 +185.246.236.85 +185.246.236.76 +185.246.236.56 +185.246.236.116 +86.104.192.154 +86.104.192.156 +185.239.244.62 +185.246.236.1 +185.246.236.47 +185.246.236.150 +185.246.236.15 +84.126.113.207 +141.253.102.21 \ No newline at end of file diff --git a/ip_check.php b/ip_check.php new file mode 100755 index 0000000..9f4da5a --- /dev/null +++ b/ip_check.php @@ -0,0 +1,157 @@ +get_visitor_Info(COSTM_IP_SCORE, CHECK_KEY, SHOW_SITE_COUNTRY); + + $reason = ''; + + CheckPipeline::run(); + + if (!isset($_SESSION['check_result']) || $_SESSION['check_result'] === '') { + $_SESSION['check_result'] = 'false'; + if ($reason === '') { + $reason = '未产生判定结果,默认安全页'; + } + } + $reason = cloak_finalize_reason($reason, $_SESSION['check_result']); + + //echo "
        result:".$_SESSION["check_result"]."
        "; + //$end_time = date("H:i:s"); + //echo "".$begin_time .' | '. $end_time."
        "; + + if( WRITE_LOG == "1") + { + $c_ip = $_SESSION["gcu_ip"]?$_SESSION["gcu_ip"]:$_SERVER['REMOTE_ADDR']; + $fp=fopen(dirname(__FILE__)."/jump.txt","a+"); + fwrite($fp,date("Y-m-d H:i:s").' | 来源判断 | ' . $reason . "|" . $_SESSION["check_result"].' | '.$config_name.' | '.$c_ip.' | '. get_SERVER_value('HTTP_REFERER') ."\n"); + fclose($fp); + } + + // get devices + require_once dirname(__FILE__) . '/Mobile-Detect/src/MobileDetect.php'; + + $detect = new \Detection\MobileDetect; + $deviceType = ($detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'phone') : 'computer'); + if($deviceType == 'tablet') { + $patterns = $detect::getTabletDevices(); + } elseif($deviceType == 'phone') { + $patterns = $detect::getPhoneDevices(); + + } elseif($deviceType == 'computer') { + $patterns = ""; + $model = "PC"; + } + + if($patterns) { + foreach ($patterns as $brand => $pattern) { + if (preg_match('/' . $pattern . '/i', $_SERVER['HTTP_USER_AGENT'], $matches)) { + $model = $brand . ' ' . (isset($matches[1])?$matches[1]:""); + break; + } + } + } + + if (trim($model) == 'iPhone') { + $model = !empty($_COOKIE['imodel'])?strip_tags($_COOKIE['imodel']):"iPhone"; + } + + $logs = array(); + $logs['site_name'] = str_replace("www.", "", $_SERVER['HTTP_HOST']); + $logs['customers_ip'] = $v_info->v_ip; + $logs['country'] = substr($v_info->v_country, 0, 2); + $logs['v_Browser'] = $v_info->v_Browser; + $logs['v_referer'] = $v_info->v_referer; + $logs['Client'] = $v_info->v_Client; + $logs['v_PageURL'] = $v_info->v_curPageURL; + $logs['v_site_server'] = $v_info->v_site_server; + $logs['accept_language'] = $v_info->accept_language; + $logs['visit_md5_code'] = $v_info->visit_md5_code; + $logs['campagin_id'] = $v_info->costm_ip_score; + $logs['result'] = $_SESSION["check_result"]; + $logs['device'] = $model; + $logs['reason'] = $reason; + if ($__cloak_debug_on) { + $__force_risk_dbg = (defined('CLOAK_RISK_NUMBER') && CLOAK_RISK_NUMBER > 0 && CLOAK_RISK_NUMBER <= 90); + CloakDebugPage::setExitPoint(__LINE__, '判定完成 → CloakDebugPage::renderAndExit()(正常截停)', [ + 'check_result' => isset($_SESSION['check_result']) ? $_SESSION['check_result'] : 'false', + 'reason' => $reason, + ]); + CloakDebugPage::renderAndExit([ + 'config_name' => $config_name, + 'check_result' => isset($_SESSION['check_result']) ? $_SESSION['check_result'] : 'false', + 'reason' => $reason, + 'visitor' => $v_info, + 'logs' => $logs, + 'device' => isset($model) ? $model : '', + 'force_risk' => $__force_risk_dbg, + 'mode' => SHOW_SITE_MODE_SWITCH, + 'fp_urls' => defined('DB_FP') ? DB_FP : [], + 'zp_url' => defined('DB_ZP') ? DB_ZP : '', + 'started_at' => $__cloak_debug_started, + 'session' => [ + 'check_result' => $_SESSION['check_result'] ?? '(未设置)', + 'visit_to_1' => $_SESSION['visit_to_1'] ?? '', + 'visit_to_2' => $_SESSION['visit_to_2'] ?? '', + 'visit_to_3' => $_SESSION['visit_to_3'] ?? '', + 'gcuid' => $_SESSION['gcuid'] ?? '', + 'gcu_ip' => $_SESSION['gcu_ip'] ?? '', + ], + ]); + } + + RouteResolver::dispatch([ + 'v_info' => $v_info, + 'logs' => $logs, + 'config_name' => $config_name, + 'reason' => $reason, + 'model' => isset($model) ? $model : '', + ]); + +?> diff --git a/jump.html b/jump.html new file mode 100755 index 0000000..8c7561a --- /dev/null +++ b/jump.html @@ -0,0 +1,43 @@ + + + + + + + \ No newline at end of file diff --git a/jump.txt b/jump.txt new file mode 100755 index 0000000..bc7a4ad --- /dev/null +++ b/jump.txt @@ -0,0 +1,95 @@ +2026-05-24 20:19:53 | 来源判断 | |false | index | 127.0.0.1 | +2026-05-24 20:19:53 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('','1031c4dd4b0c','cloaka.test','2026-05-24 20:19:53','127.0.0.1','', 'false','','off','PC','chrome','https://cloaka.test:443/index.php?clk_ts=1779624149&clk_nonce=fe833f043be432f1&clk_sig=f5f6690067758f79c085c18aab3a36cd781224e1abb3e9ee5436f9132538d373','English','https://worldhomenest.store','PC') +2026-05-24 20:19:59 | 来源判断 | 缓存|false | index | 127.0.0.1 | https://cloaka.test/dashboard +2026-05-24 20:19:59 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('','','cloaka.test','2026-05-24 20:19:59','127.0.0.1','US', 'false','缓存','https://cloaka.test/dashboard','PC','chrome','https://cloaka.test:443/index.php?','English','https://worldhomenest.store','PC') +2026-05-24 20:25:12 | 来源判断 | |false | index | 127.0.0.1 | +2026-05-24 20:25:12 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('','a2ea7ffe92a8','cloaka.test','2026-05-24 20:25:12','127.0.0.1','', 'false','','off','PC','chrome','https://cloaka.test:443/index.php?clk_ts=1779625346&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=e02ebad7ce4fa0a4aeda23cb0cae63dbb70479d352b72fc677293f51c9ae66af','English','https://worldhomenest.store','PC') +2026-05-24 21:07:53 | 来源判断 | |false | index | 127.0.0.1 | +2026-05-24 21:38:24 | 来源判断 | |false | index | 127.0.0.1 | +2026-05-24 21:51:28 | 来源判断 | API响应非JSON|false | index | 127.0.0.1 | +2026-05-24 21:56:56 | 来源判断 | API请求失败:|false | index | 127.0.0.1 | +2026-05-24 21:59:15 | 来源判断 | API请求失败:|false | index | 127.0.0.1 | +2026-05-24 22:02:15 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-24 22:04:28 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-24 22:04:28 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','4ab064600a83','cloaka.test','2026-05-24 22:04:28','127.0.0.1','-', 'false','黑名单','off','PC','chrome','https://cloaka.test:443/index.php?clk_ts=1779631009&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=3698790e84c74380c19b29b0d9bfd0240a933ba54dc0d16625405b37f096b8a1','English','https://worldhomenest.store','PC') +2026-05-24 22:16:41 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-24 22:31:42 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-24 22:35:41 | 来源判断 | 来源限制:未命中已开启广告来源(Facebook)|false | index | 127.0.0.1 | +2026-05-25 02:48:05 | 来源判断 | 来源限制:未命中已开启广告来源(Facebook)|false | index | 127.0.0.1 | +2026-05-25 02:57:31 | 来源判断 | 来源限制:未命中已开启广告来源(Facebook)|false | index | 127.0.0.1 | +2026-05-25 02:57:31 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','','cloaka.test','2026-05-25 02:57:31','127.0.0.1','US', 'false','来源限制:未命中已开启广告来源(Facebook)','','PC','chrome','https://cloaka.test/index.php?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187','English','https://worldhomenest.store','PC') +2026-05-25 03:01:56 | 来源判断 | 来源限制:未命中已开启广告来源(Facebook)|false | index | 127.0.0.1 | +2026-05-25 03:01:56 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','','cloaka.test','2026-05-25 03:01:56','127.0.0.1','US','false','来源限制:未命中已开启广告来源(Facebook)','','PC','chrome','https://cloaka.test/index.php?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187','English','https://worldhomenest.store','PC') +2026-05-25 03:05:20 | 来源判断 | 来源限制:未命中已开启广告来源(Facebook)|false | index | 127.0.0.1 | +2026-05-25 03:05:20 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','','cloaka.test','2026-05-25 03:05:20','127.0.0.1','US','false','来源限制:未命中已开启广告来源(Facebook)','','PC','chrome','https://cloaka.test/index.php?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187','English','https://worldhomenest.store','PC') +2026-05-25 03:33:18 | 来源判断 | 指纹Cookie未写入(已完成前端检测)|false | index | 127.0.0.1 | https://cloaka.test/index?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187 +2026-05-25 03:33:18 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','84f1efe602e2','cloaka.test','2026-05-25 03:33:18','127.0.0.1','US','false','指纹Cookie未写入(已完成前端检测)','https://cloaka.test/index?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187','PC','chrome','https://cloaka.test/index.php?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187&time=1779651198719','English','https://worldhomenest.store','PC') +2026-05-25 03:45:30 | 来源判断 | 指纹Cookie未写入(已完成前端检测)|false | index | 127.0.0.1 | https://cloaka.test/index?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187 +2026-05-25 03:45:30 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','e2f5fc622c3e','cloaka.test','2026-05-25 03:45:30','127.0.0.1','US','false','指纹Cookie未写入(已完成前端检测)','https://cloaka.test/index?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187','PC','chrome','https://cloaka.test/index.php?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187&time=1779651930890','English','https://worldhomenest.store','PC') +2026-05-25 03:57:21 | 来源判断 | 可疑访客:操作系统非IOS或者安卓|false | index | 127.0.0.1 | https://cloaka.test/index?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187 +2026-05-25 03:57:21 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','df32c6c95fb6','cloaka.test','2026-05-25 03:57:21','127.0.0.1','US','false','可疑访客:操作系统非IOS或者安卓','https://cloaka.test/index?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187','PC','chrome','https://cloaka.test/index.php?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187&time=1779652640867','English','https://worldhomenest.store','PC') +2026-05-25 04:05:52 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-25 04:05:52 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','08c02abd8025','cloaka.test','2026-05-25 04:05:52','127.0.0.1','-','false','黑名单','off','PC','chrome','https://cloaka.test/index.php?clk_ts=0&clk_nonce=3cfa5dc8e5cf98a7&clk_sig=954780561396c8b7df3623a21fe1c7a1f362c92e10a540cca4809c2413b9f187','Chinese','https://worldhomenest.store','PC') +2026-05-26 02:02:56 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-05-26 02:02:56','127.0.0.1','','false','','','PC','','/','','','') +2026-05-26 02:17:38 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-26 02:17:38 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','025bc6046566','cloaka.test','2026-05-26 02:17:38','127.0.0.1','-','false','黑名单','off','PC','chrome','https://cloaka.test/index.php?','English','https://worldhomenest.store','PC') +2026-05-26 02:18:16 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-26 02:18:16 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','945dddb376ef','cloaka.test','2026-05-26 02:18:16','127.0.0.1','-','false','黑名单','off','PC','chrome','https://cloaka.test/index.php?','English','https://worldhomenest.store','PC') +2026-05-26 02:18:35 | 来源判断 | 缓存|false | index | 127.0.0.1 | +2026-05-26 02:18:35 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','','cloaka.test','2026-05-26 02:18:35','127.0.0.1','-','false','缓存','','PC','chrome','https://cloaka.test/index.php?','English','https://worldhomenest.store','PC') +2026-05-26 02:18:54 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-26 02:18:54 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','adc58b3764e8','cloaka.test','2026-05-26 02:18:54','127.0.0.1','-','false','黑名单','off','PC','chrome','https://cloaka.test/index.php?','English','https://worldhomenest.store','PC') +2026-05-26 02:34:28 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-05-26 02:34:28','127.0.0.1','','false','','','PC','','/','','','') +2026-05-26 02:36:56 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-05-26 02:36:56','127.0.0.1','','false','','','PC','','/','','','') +2026-05-26 02:39:07 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-26 02:39:07 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','fb5ef3770269','cloaka.test','2026-05-26 02:39:07','127.0.0.1','-','false','黑名单','off','PC','chrome','https://cloaka.test/index.php?','English','https://worldhomenest.store','PC') +2026-05-26 02:39:27 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-26 02:39:28 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','3adc7b9b2b81','cloaka.test','2026-05-26 02:39:28','127.0.0.1','-','false','黑名单','off','PC','chrome','https://cloaka.test/index.php?','English','https://worldhomenest.store','PC') +2026-05-26 02:43:17 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-05-26 02:43:17 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','6d593c89acf1','cloaka.test','2026-05-26 02:43:17','127.0.0.1','-','false','黑名单','off','PC','chrome','https://cloaka.test/index.php?','English','https://worldhomenest.store','PC') +2026-05-26 02:44:28 | 来源判断 | API判定通过|true | index | 127.0.0.1 | +2026-05-26 02:44:28 | 写入数据库 | true | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','98af2b462187','cloaka.test','2026-05-26 02:44:28','127.0.0.1','-','true','','off','PC','chrome','https://cloaka.test/index.php?','English','','PC') +2026-05-26 02:51:29 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-05-26 02:51:29','127.0.0.1','','false','','','PC','','/','','','') +2026-05-26 02:52:41 | 来源判断 | API判定通过|true | index | 127.0.0.1 | +2026-05-26 02:52:41 | 写入数据库 | true | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','07cdbefc93dd','cloaka.test','2026-05-26 02:52:41','127.0.0.1','-','true','','off','PC','chrome','https://cloaka.test/index.php?','English','','PC') +2026-05-26 02:55:19 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-05-26 02:55:19','127.0.0.1','','false','','','PC','','/','','','') +2026-05-26 02:56:48 | 来源判断 | API判定通过|true | index | 127.0.0.1 | +2026-05-26 02:56:48 | 写入数据库 | true | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','d9ee1f0cff7e','cloaka.test','2026-05-26 02:56:48','127.0.0.1','-','true','','off','PC','chrome','https://cloaka.test/index.php?','English','','PC') +2026-05-26 02:57:49 | 来源判断 | API判定通过|true | index | 127.0.0.1 | +2026-05-26 02:57:49 | 写入数据库 | true | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','a332d9695ae9','cloaka.test','2026-05-26 02:57:49','127.0.0.1','-','true','','off','PC','chrome','https://cloaka.test/index.php?','English','','PC') +2026-05-26 02:58:05 | 来源判断 | API判定通过|true | index | 127.0.0.1 | +2026-05-26 02:58:05 | 写入数据库 | true | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','9451a6af27f1','cloaka.test','2026-05-26 02:58:05','127.0.0.1','-','true','','off','PC','chrome','https://cloaka.test/index.php?','English','','PC') +2026-05-26 12:09:55 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-05-26 12:09:55','127.0.0.1','','false','','','PC','','/','','','') +2026-05-26 12:51:31 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-05-26 12:51:31','127.0.0.1','','false','','','PC','','/','','','') +2026-05-26 12:58:27 | 来源判断 | API判定通过|true | index | 127.0.0.1 | +2026-05-26 12:58:27 | 写入数据库 | true | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','f0f613c783b5','cloaka.test','2026-05-26 12:58:27','127.0.0.1','-','true','','off','PC','chrome','https://cloaka.test/index.php?','English','','PC') +2026-05-26 13:01:16 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-05-26 13:01:16','127.0.0.1','','false','','','PC','','/','','','') +2026-05-26 13:12:07 | 来源判断 | API判定通过|true | index | 127.0.0.1 | +2026-05-26 13:12:07 | 写入数据库 | true | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','0c6370dab8fd','cloaka.test','2026-05-26 13:12:07','127.0.0.1','-','true','','off','PC','chrome','https://cloaka.test/index.php?','English','','PC') +2026-06-10 23:05:11 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-10 23:05:11','127.0.0.1','','false','','','PC','','/','','','') +2026-06-10 23:05:59 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-10 23:05:59','127.0.0.1','','false','','','PC','','/','','','') +2026-06-11 00:25:15 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-11 00:25:15','127.0.0.1','','false','','','PC','','/','','','') +2026-06-11 19:28:27 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-11 19:28:27','127.0.0.1','','false','','','PC','','/','','','') +2026-06-11 19:31:05 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-11 19:31:05','127.0.0.1','','false','','','PC','','/','','','') +2026-06-14 00:27:19 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-14 00:27:19','127.0.0.1','','false','','','PC','','/','','','') +2026-06-14 01:29:59 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-14 01:29:59','127.0.0.1','','false','','','PC','','/','','','') +2026-06-14 02:05:06 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-14 02:05:06','127.0.0.1','','false','','','PC','','/','','','') +2026-06-14 02:06:00 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-14 02:06:00','127.0.0.1','','false','','','PC','','/','','','') +2026-06-14 02:28:34 | 来源判断 | 缓存|false | index | 127.0.0.1 | +2026-06-14 02:28:34 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','','cloaka.test','2026-06-14 02:28:34','127.0.0.1','-','false','缓存','','PC','chrome','https://cloaka.test/','English','https://worldhomenest.store','PC') +2026-06-14 02:30:57 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-06-14 02:30:57 | 写入数据库 | false | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','fa0c6342a353','cloaka.test','2026-06-14 02:30:57','127.0.0.1','-','false','黑名单','off','PC','chrome','https://cloaka.test/','English','https://worldhomenest.store','PC') +2026-06-14 03:03:47 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-14 03:03:47','127.0.0.1','','false','','','PC','','/','','','') +2026-06-14 03:04:01 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-14 03:04:01','127.0.0.1','','false','','','PC','','/','','','') +2026-06-14 03:07:20 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-14 03:07:20','127.0.0.1','','false','','','PC','','/','','','','','','','') +2026-06-14 03:23:32 | 来源判断 | 缓存|true | index | 127.0.0.1 | +2026-06-14 03:23:32 | 写入数据库 | true | index | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `fp_url`, `device`) VALUES ('20251108_emoUAVF6S','','cloaka.test','2026-06-14 03:23:32','127.0.0.1','-','true','','','PC','chrome','https://cloaka.test/?utm_campaign={campaignid}&adgroup_id=__CID__&ad_spm_id=t0tTw4MJ6r','English','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36','','en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','{\"total_ms\":0.12,\"stages\":[{\"name\":\"Session快速路径\",\"ms\":0.04}]}','https://www.google.com/','PC') +2026-06-14 11:51:53 | 写入数据库 | | regression_test | INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `fp_url`, `device`) VALUES ('reg_test','','reg.test','2026-06-14 11:51:53','127.0.0.1','','false','','','PC','','/','','','','','','','') +2026-06-14 12:27:29 | 写入数据库 | | regression_test | async=1 +2026-06-14 12:27:29 | 写入数据库 | | regression_test | async=1 +2026-06-14 12:30:13 | 写入数据库 | | regression_test | async=1 +2026-06-14 12:30:13 | 写入数据库 | | regression_test | async=1 +2026-06-14 12:30:50 | 写入数据库 | | regression_test | async=1 +2026-06-14 12:30:50 | 写入数据库 | | regression_test | async=1 +2026-06-14 12:33:28 | 来源判断 | 黑名单|false | index | 127.0.0.1 | +2026-06-14 12:33:28 | 写入数据库 | false | index | async=1 diff --git a/lib/Cloak/CloudflareClient.php b/lib/Cloak/CloudflareClient.php new file mode 100755 index 0000000..6dc2451 --- /dev/null +++ b/lib/Cloak/CloudflareClient.php @@ -0,0 +1,170 @@ +token = $token ?? CloudflareConfig::apiToken(); + $this->accountId = $accountId ?? CloudflareConfig::accountId(); + } + + /** + * @return array{ok:bool,result?:mixed,error?:string,code?:int,http_code?:int} + */ + public function createZone($hostname) + { + $res = $this->request('POST', '/zones', [ + 'name' => $hostname, + 'account' => ['id' => $this->accountId], + 'type' => 'full', + ]); + if (!$res['ok'] && (int) ($res['code'] ?? 0) === 1061) { + return $this->findZoneByName($hostname); + } + return $res; + } + + /** + * @return array{ok:bool,result?:mixed,error?:string,code?:int,http_code?:int} + */ + public function findZoneByName($hostname) + { + $path = '/zones?name=' . rawurlencode($hostname) . '&account.id=' . rawurlencode($this->accountId); + $res = $this->request('GET', $path); + if (!$res['ok']) { + return $res; + } + $zones = $res['result'] ?? []; + if (!is_array($zones) || empty($zones[0])) { + return ['ok' => false, 'error' => 'Zone 不存在']; + } + return ['ok' => true, 'result' => $zones[0]]; + } + + /** + * @return array{ok:bool,result?:mixed,error?:string,code?:int,http_code?:int} + */ + public function getZone($zoneId) + { + return $this->request('GET', '/zones/' . rawurlencode($zoneId)); + } + + /** + * @return array{ok:bool,result?:mixed,error?:string,code?:int,http_code?:int} + */ + public function deleteZone($zoneId) + { + return $this->request('DELETE', '/zones/' . rawurlencode($zoneId)); + } + + /** + * @return array{ok:bool,result?:mixed,error?:string,code?:int,http_code?:int} + */ + public function upsertARecord($zoneId, $fqdn, $ip, $proxied = true) + { + $path = '/zones/' . rawurlencode($zoneId) . '/dns_records?type=A&name=' . rawurlencode($fqdn); + $list = $this->request('GET', $path); + if (!$list['ok']) { + return $list; + } + $records = is_array($list['result'] ?? null) ? $list['result'] : []; + $existing = $records[0] ?? null; + $payload = [ + 'type' => 'A', + 'name' => $fqdn, + 'content' => $ip, + 'proxied' => (bool) $proxied, + 'ttl' => 1, + ]; + if (is_array($existing) && !empty($existing['id'])) { + return $this->request('PATCH', '/zones/' . rawurlencode($zoneId) . '/dns_records/' . rawurlencode($existing['id']), $payload); + } + return $this->request('POST', '/zones/' . rawurlencode($zoneId) . '/dns_records', $payload); + } + + /** + * @return array{ok:bool,result?:mixed,error?:string,code?:int,http_code?:int} + */ + public function setSslFlexible($zoneId) + { + return $this->request('PATCH', '/zones/' . rawurlencode($zoneId) . '/settings/ssl', ['value' => 'flexible']); + } + + /** + * @return array{ok:bool,result?:mixed,error?:string,code?:int,http_code?:int} + */ + public function setAlwaysHttps($zoneId) + { + return $this->request('PATCH', '/zones/' . rawurlencode($zoneId) . '/settings/always_use_https', ['value' => 'on']); + } + + /** + * @return array{ok:bool,result?:mixed,error?:string,code?:int,http_code?:int} + */ + private function request($method, $path, $body = null) + { + $url = 'https://api.cloudflare.com/client/v4' . $path; + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + $headers = [ + 'Authorization: Bearer ' . $this->token, + 'Content-Type: application/json', + ]; + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + if ($body !== null) { + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body, JSON_UNESCAPED_UNICODE)); + } + if (function_exists('cloak_curl_apply_upstream_defaults')) { + cloak_curl_apply_upstream_defaults($ch, 5, 20); + } else { + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($ch, CURLOPT_TIMEOUT, 20); + } + + $raw = curl_exec($ch); + $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); + if ($raw === false) { + $err = curl_error($ch); + $errno = curl_errno($ch); + curl_close($ch); + self::logError($method, $path, 'curl', $errno . ':' . $err, $httpCode); + return ['ok' => false, 'error' => 'API请求失败:' . $err . '(errno:' . $errno . ')', 'http_code' => $httpCode]; + } + curl_close($ch); + + if ($raw === '') { + self::logError($method, $path, 'empty_body', '', $httpCode); + return ['ok' => false, 'error' => 'API响应为空(HTTP ' . $httpCode . ')', 'http_code' => $httpCode]; + } + + $decoded = json_decode($raw, true); + if (!is_array($decoded)) { + self::logError($method, $path, 'non_json', substr($raw, 0, 200), $httpCode); + return ['ok' => false, 'error' => 'API响应非JSON(HTTP ' . $httpCode . ')', 'http_code' => $httpCode]; + } + if (empty($decoded['success'])) { + $msg = $decoded['errors'][0]['message'] ?? '未知错误'; + $code = (int) ($decoded['errors'][0]['code'] ?? 0); + self::logError($method, $path, 'api_error', $msg, $httpCode); + return ['ok' => false, 'error' => $msg, 'code' => $code, 'http_code' => $httpCode]; + } + return ['ok' => true, 'result' => $decoded['result'] ?? null, 'http_code' => $httpCode]; + } + + private static function logError($method, $path, $kind, $detail, $httpCode) + { + $line = date('Y-m-d H:i:s') . ' | Cloudflare ' . $method . ' ' . $path . ' | ' . $kind . ' | HTTP ' . $httpCode . ' | ' . $detail . "\n"; + @file_put_contents(dirname(__DIR__, 2) . '/err.txt', $line, FILE_APPEND); + } +} diff --git a/lib/Cloak/CloudflareConfig.php b/lib/Cloak/CloudflareConfig.php new file mode 100755 index 0000000..a2d9907 --- /dev/null +++ b/lib/Cloak/CloudflareConfig.php @@ -0,0 +1,76 @@ + CLI 回归用覆盖项(enabled / server_ip) */ + private static $testOverrides = []; + + public static function setTestOverrides(array $overrides) + { + self::$testOverrides = $overrides; + } + + public static function clearTestOverrides() + { + self::$testOverrides = []; + } + + public static function apiToken() + { + return defined('CLOUDFLARE_API_TOKEN') ? trim((string) CLOUDFLARE_API_TOKEN) : ''; + } + + public static function accountId() + { + return defined('CLOUDFLARE_ACCOUNT_ID') ? trim((string) CLOUDFLARE_ACCOUNT_ID) : ''; + } + + public static function serverIp() + { + if (array_key_exists('server_ip', self::$testOverrides)) { + return trim((string) self::$testOverrides['server_ip']); + } + return defined('SERVER_IP') ? trim((string) SERVER_IP) : ''; + } + + /** + * Token + Account ID 均已配置时启用 Cloudflare 自动化 + */ + public static function isEnabled() + { + if (array_key_exists('enabled', self::$testOverrides)) { + return (bool) self::$testOverrides['enabled']; + } + return self::apiToken() !== '' && self::accountId() !== ''; + } + + public static function statusLabel($status) + { + $map = [ + 'local' => '本地登记', + 'pending_ns' => '待检测', + 'provisioning' => '配置中', + 'ready' => '已生效', + 'error' => '失败', + ]; + return $map[$status] ?? (string) $status; + } + + public static function parseNameservers($json) + { + if ($json === null || $json === '') { + return []; + } + $decoded = json_decode($json, true); + return is_array($decoded) ? $decoded : []; + } +} + +if (!function_exists('cloak_cloudflare_enabled')) { + function cloak_cloudflare_enabled() + { + return CloudflareConfig::isEnabled(); + } +} diff --git a/lib/Cloak/ContentRewriter.php b/lib/Cloak/ContentRewriter.php new file mode 100755 index 0000000..c763955 --- /dev/null +++ b/lib/Cloak/ContentRewriter.php @@ -0,0 +1,208 @@ +|\>).*/i', $l1, $regs)) { + $I2 = $regs[3]; + } + + if (!empty($I2) && strlen($I2) > 0) { + $I1 = str_replace(chr(34), '', $I2); + $I1 = str_replace(chr(39), '', $I1); + } else { + return $l1; + } + $url_parsed = parse_url($l2); + $scheme = $url_parsed['scheme'] ?? ''; + if ($scheme != '') { + $scheme = $scheme . '://'; + } + $host = $url_parsed['host'] ?? ''; + $l3 = $scheme . $host; + if (strlen($l3) == 0) { + return $l1; + } + $path = dirname($url_parsed['path'] ?? '/'); + if (isset($path[0]) && $path[0] == '\\') { + $path = ''; + } + $pos = strpos($I1, '#'); + if ($pos > 0) { + $I1 = substr($I1, 0, $pos); + } + + if (preg_match('/^(http|https|ftp):(\/\/|\\\\)(([\w\/\\\+\-~`@:%])+\.)+([\w\/\\\.\=\?\+\-~`@\':!%#]|(&)|&)+/i', $I1)) { + return $l1; + } + if (isset($I1[0]) && $I1[0] == '/') { + $I1 = $l3 . $I1; + } elseif (substr($I1, 0, 3) == '../') { + while (substr($I1, 0, 3) == '../') { + $I1 = substr($I1, strlen($I1) - (strlen($I1) - 3), strlen($I1) - 3); + if (strlen($path) > 0) { + $path = dirname($path); + } + } + $I1 = $l3 . $path . '/' . $I1; + } elseif (substr($I1, 0, 2) == './') { + $I1 = $l3 . $path . substr($I1, strlen($I1) - (strlen($I1) - 1), strlen($I1) - 1); + } elseif (strtolower(substr($I1, 0, 7)) == 'mailto:' || strtolower(substr($I1, 0, 11)) == 'javascript:') { + return $l1; + } else { + $I1 = $l3 . $path . '/' . $I1; + } + return str_replace($I2, '"' . $I1 . '"', $l1); + } +} + +/** @deprecated 使用 cloak_resolve_relative_url */ +if (!function_exists('lIIIIl')) { + function lIIIIl($l1, $l2) + { + return cloak_resolve_relative_url($l1, $l2); + } +} + +if (!function_exists('cloak_format_url')) { + function cloak_format_url($l1, $l2) + { + if (preg_match_all('/(]+src=\"([^\"]+)\"[^>]*>)|(]+href=\"([^\"]+)\"[^>]*>)|(]+src=\"([^\"]+)\"[^>]*>)|(]+href=\"([^\"]+)\"[^>]*>)|(]+src=\'([^\']+)\'[^>]*>)|(]+href=\'([^\']+)\'[^>]*>)/i', $l1, $regs)) { + foreach ($regs[0] as $url) { + $l1 = str_replace($url, cloak_resolve_relative_url($url, $l2), $l1); + } + } + return $l1; + } +} + +/** @deprecated 使用 cloak_format_url */ +if (!function_exists('formaturl')) { + function formaturl($l1, $l2) + { + return cloak_format_url($l1, $l2); + } +} + +if (!function_exists('cloak_rewrite_safe_page_html')) { + function cloak_rewrite_safe_page_html($content, $address_caiji, $website) + { + $domain = '/http.*\.\w*\//'; + preg_match($domain, $address_caiji, $res); + $domain_caiji = ''; + foreach ($res as $domain_address) { + $domain_caiji = $domain_address; + } + $surl = 'http://www.xxx.com/'; + $pattern = '/\'/'; + $content = preg_replace($pattern, '"', $content); + $pattern = '/"\/\//'; + $content = preg_replace($pattern, '"http://', $content); + $content = cloak_format_url($content, $surl); + $pattern = '/Copyright.*<.*>/'; + $content = preg_replace($pattern, 'Copyright ' . $website . ' All rights reserved', $content); + $pattern = '/copyright.*<.*>/'; + $content = preg_replace($pattern, 'Copyright ' . $website . ' All rights reserved', $content); + $content = str_replace('http://www.xxx.com/', $domain_caiji, $content); + $preg = '//i'; + return preg_replace($preg, '', $content, -1); + } +} + +/** @deprecated 使用 cloak_rewrite_safe_page_html */ +if (!function_exists('caiji_lujing_buquan')) { + function caiji_lujing_buquan($content, $address_caiji, $website) + { + return cloak_rewrite_safe_page_html($content, $address_caiji, $website); + } +} + +if (!function_exists('cloak_rewrite_fp_page_html')) { + function cloak_rewrite_fp_page_html($content, $address_caiji, $website) + { + $domain = '/http.*\.\w*\//'; + preg_match($domain, $address_caiji, $res); + $domain_caiji = ''; + foreach ($res as $domain_address) { + $domain_caiji = $domain_address; + } + $surl = 'http://www.xxx.com/'; + $pattern = '/\'/'; + $content = preg_replace($pattern, '"', $content); + $pattern = '/"\/\//'; + $content = preg_replace($pattern, '"http://', $content); + $content = cloak_format_url($content, $surl); + $pattern = '/Copyright.*<.*>/'; + $content = preg_replace($pattern, 'Copyright ' . $website . ' All rights reserved', $content); + $pattern = '/copyright.*<.*>/'; + $content = preg_replace($pattern, 'Copyright ' . $website . ' All rights reserved', $content); + $content = str_replace('http://www.xxx.com/', $domain_caiji, $content); + return $content; + } +} + +/** @deprecated 使用 cloak_rewrite_fp_page_html */ +if (!function_exists('caiji_lujing_buquan_fp')) { + function caiji_lujing_buquan_fp($content, $address_caiji, $website) + { + return cloak_rewrite_fp_page_html($content, $address_caiji, $website); + } +} + +if (!function_exists('cloak_has_head_tag')) { + function cloak_has_head_tag($html) + { + if (empty($html)) { + return false; + } + $dom = new DOMDocument(); + libxml_use_internal_errors(true); + $dom->loadHTML($html); + libxml_clear_errors(); + return $dom->getElementsByTagName('head')->length > 0; + } +} + +/** @deprecated 使用 cloak_has_head_tag */ +if (!function_exists('hasHeadTag')) { + function hasHeadTag($html) + { + return cloak_has_head_tag($html); + } +} diff --git a/lib/Cloak/DomainProvisioningService.php b/lib/Cloak/DomainProvisioningService.php new file mode 100755 index 0000000..f0aae5c --- /dev/null +++ b/lib/Cloak/DomainProvisioningService.php @@ -0,0 +1,257 @@ + 'local', + ]); + return [ + 'ok' => true, + 'id' => $id, + 'hostname' => $host, + 'cf_status' => 'local', + 'nameservers' => [], + ]; + } + + $client = self::newClient(); + $zone = $client->createZone($host); + if (!$zone['ok']) { + DomainRepository::updateCloudflareMeta($pdo, $id, [ + 'cf_status' => 'error', + 'cf_error' => $zone['error'] ?? '创建 Zone 失败', + ]); + return [ + 'ok' => false, + 'error' => $zone['error'] ?? 'Cloudflare 创建 Zone 失败', + 'id' => $id, + 'hostname' => $host, + ]; + } + + $result = $zone['result']; + $ns = is_array($result['name_servers'] ?? null) ? $result['name_servers'] : []; + DomainRepository::updateCloudflareMeta($pdo, $id, [ + 'cf_zone_id' => (string) ($result['id'] ?? ''), + 'cf_nameservers' => json_encode($ns, JSON_UNESCAPED_UNICODE), + 'cf_status' => 'pending_ns', + 'cf_error' => '', + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + + return [ + 'ok' => true, + 'id' => $id, + 'hostname' => $host, + 'cf_status' => 'pending_ns', + 'nameservers' => $ns, + ]; + } + + /** + * 手动检测 NS 是否生效,生效后配置 A 记录与 SSL + * + * @return array{ok:bool,status?:string,message?:string,nameservers?:array} + */ + public static function checkAndProvision(PDO $pdo, $domainId) + { + $row = DomainRepository::findById($pdo, $domainId); + if (!$row) { + return ['ok' => false, 'message' => '域名不存在']; + } + + if (!CloudflareConfig::isEnabled()) { + return ['ok' => false, 'message' => '未配置 Cloudflare API,无法检测']; + } + + $client = self::newClient(); + $zoneId = trim((string) ($row['cf_zone_id'] ?? '')); + + if ($zoneId === '') { + $zone = $client->createZone($row['hostname']); + if (!$zone['ok']) { + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'error', + 'cf_error' => $zone['error'] ?? '补创建 Zone 失败', + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + return ['ok' => false, 'message' => $zone['error'] ?? '补创建 Zone 失败']; + } + $result = $zone['result']; + $zoneId = (string) ($result['id'] ?? ''); + $ns = is_array($result['name_servers'] ?? null) ? $result['name_servers'] : []; + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_zone_id' => $zoneId, + 'cf_nameservers' => json_encode($ns, JSON_UNESCAPED_UNICODE), + 'cf_status' => 'pending_ns', + 'cf_error' => '', + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + $row = DomainRepository::findById($pdo, $domainId); + } + + $zoneRes = $client->getZone($zoneId); + if (!$zoneRes['ok']) { + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'error', + 'cf_error' => $zoneRes['error'] ?? '读取 Zone 失败', + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + return ['ok' => false, 'message' => $zoneRes['error'] ?? '读取 Zone 失败']; + } + + $zoneData = $zoneRes['result']; + $status = strtolower((string) ($zoneData['status'] ?? 'pending')); + $ns = CloudflareConfig::parseNameservers($row['cf_nameservers'] ?? ''); + if (empty($ns) && is_array($zoneData['name_servers'] ?? null)) { + $ns = $zoneData['name_servers']; + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_nameservers' => json_encode($ns, JSON_UNESCAPED_UNICODE), + ]); + } + + if ($status !== 'active') { + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'pending_ns', + 'cf_checked_at' => date('Y-m-d H:i:s'), + 'cf_error' => '', + ]); + return [ + 'ok' => true, + 'status' => 'pending_ns', + 'message' => 'Nameserver 尚未生效,请到注册商修改为:' . implode('、', $ns), + 'nameservers' => $ns, + ]; + } + + $serverIp = CloudflareConfig::serverIp(); + if ($serverIp === '') { + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'error', + 'cf_error' => 'SERVER_IP 未配置,无法添加 DNS 记录', + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + return ['ok' => false, 'message' => 'SERVER_IP 未配置,请在 cong.php 中填写服务器公网 IP']; + } + + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'provisioning', + 'cf_error' => '', + ]); + + $host = $row['hostname']; + foreach ([$host, 'www.' . $host] as $fqdn) { + $dns = $client->upsertARecord($zoneId, $fqdn, $serverIp, true); + if (!$dns['ok']) { + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'error', + 'cf_error' => 'DNS 记录失败(' . $fqdn . '): ' . ($dns['error'] ?? ''), + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + return ['ok' => false, 'message' => $dns['error'] ?? 'DNS 配置失败']; + } + } + + $ssl = $client->setSslFlexible($zoneId); + if (!$ssl['ok']) { + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'error', + 'cf_error' => 'SSL Flexible 失败: ' . ($ssl['error'] ?? ''), + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + return ['ok' => false, 'message' => $ssl['error'] ?? 'SSL 配置失败']; + } + + $https = $client->setAlwaysHttps($zoneId); + if (!$https['ok']) { + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'error', + 'cf_error' => 'Always HTTPS 失败: ' . ($https['error'] ?? ''), + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + return ['ok' => false, 'message' => $https['error'] ?? 'Always HTTPS 配置失败']; + } + + DomainRepository::updateCloudflareMeta($pdo, $domainId, [ + 'cf_status' => 'ready', + 'cf_error' => '', + 'cf_checked_at' => date('Y-m-d H:i:s'), + ]); + + return [ + 'ok' => true, + 'status' => 'ready', + 'message' => '域名已生效:A 记录(@/www) 已指向 ' . $serverIp . ',已开启 Flexible SSL 与 Always HTTPS', + 'nameservers' => $ns, + ]; + } + + /** + * 删除本地记录并尝试删除 Cloudflare Zone + * + * @return array{ok:bool,message?:string,warning?:string} + */ + public static function deleteWithCloudflare(PDO $pdo, $domainId) + { + $row = DomainRepository::findById($pdo, $domainId); + if (!$row) { + return ['ok' => false, 'message' => '域名不存在']; + } + + $warning = ''; + $zoneId = trim((string) ($row['cf_zone_id'] ?? '')); + if ($zoneId !== '' && CloudflareConfig::isEnabled()) { + $del = self::newClient()->deleteZone($zoneId); + if (!$del['ok']) { + $warning = 'Cloudflare Zone 删除失败:' . ($del['error'] ?? '未知错误'); + } + } + + DomainRepository::deleteById($pdo, $domainId); + return [ + 'ok' => true, + 'message' => '域名已删除', + 'warning' => $warning, + ]; + } +} diff --git a/lib/Cloak/DomainRepository.php b/lib/Cloak/DomainRepository.php new file mode 100755 index 0000000..e94e4b3 --- /dev/null +++ b/lib/Cloak/DomainRepository.php @@ -0,0 +1,241 @@ +exec( + "CREATE TABLE IF NOT EXISTS `cloak_site_domains` ( + `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `hostname` varchar(255) NOT NULL COMMENT '站点域名,不含协议与路径', + `config_name` varchar(64) NOT NULL DEFAULT '' COMMENT '关联 check_config 配置名', + `cf_zone_id` varchar(64) DEFAULT NULL COMMENT 'Cloudflare Zone ID', + `cf_nameservers` text DEFAULT NULL COMMENT 'Cloudflare NS JSON', + `cf_status` varchar(32) NOT NULL DEFAULT 'local' COMMENT 'Cloudflare 状态', + `cf_error` varchar(500) DEFAULT NULL COMMENT '最近错误', + `cf_checked_at` datetime DEFAULT NULL COMMENT '上次检测时间', + `created_at` timestamp NOT NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`), + UNIQUE KEY `uk_hostname` (`hostname`), + KEY `idx_config_name` (`config_name`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci" + ); + self::ensureCloudflareColumns($pdo); + } + + private static function ensureCloudflareColumns(PDO $pdo) + { + $columns = [ + 'cf_zone_id' => "ADD COLUMN `cf_zone_id` varchar(64) DEFAULT NULL COMMENT 'Cloudflare Zone ID'", + 'cf_nameservers' => "ADD COLUMN `cf_nameservers` text DEFAULT NULL COMMENT 'Cloudflare NS JSON'", + 'cf_status' => "ADD COLUMN `cf_status` varchar(32) NOT NULL DEFAULT 'local' COMMENT 'Cloudflare 状态'", + 'cf_error' => "ADD COLUMN `cf_error` varchar(500) DEFAULT NULL COMMENT '最近错误'", + 'cf_checked_at' => "ADD COLUMN `cf_checked_at` datetime DEFAULT NULL COMMENT '上次检测时间'", + ]; + foreach ($columns as $name => $ddl) { + if (!self::columnExists($pdo, 'cloak_site_domains', $name)) { + $pdo->exec('ALTER TABLE `cloak_site_domains` ' . $ddl); + } + } + } + + private static function columnExists(PDO $pdo, $table, $column) + { + $st = $pdo->prepare( + 'SELECT COUNT(*) FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?' + ); + $st->execute([DB_NAME, $table, $column]); + return (int) $st->fetchColumn() > 0; + } + + private static function selectColumns() + { + return 'id, hostname, config_name, cf_zone_id, cf_nameservers, cf_status, cf_error, cf_checked_at, created_at'; + } + + public static function pdo() + { + return new PDO( + 'mysql:host=127.0.0.1;dbname=' . DB_NAME . ';charset=utf8mb4', + DB_USERNAME, + DB_PASSWORD, + [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC] + ); + } + + public static function normalizeHostname($host) + { + $host = trim((string) $host); + if ($host === '') { + return ''; + } + if (strpos($host, '://') !== false) { + $parsed = parse_url($host, PHP_URL_HOST); + $host = $parsed ?: $host; + } else { + $host = preg_replace('#/.*$#', '', $host); + $host = preg_replace('#:\d+$#', '', $host); + } + $host = strtolower(trim($host, '.')); + if (str_starts_with($host, 'www.')) { + $host = substr($host, 4); + } + return $host; + } + + public static function hostToConfigKey($host) + { + $host = self::normalizeHostname($host); + if ($host === '') { + return 'index'; + } + $key = preg_replace('/[^a-z0-9_-]+/i', '_', $host); + $key = trim($key, '_'); + return $key !== '' ? $key : 'index'; + } + + public static function listAll(PDO $pdo = null) + { + $pdo = $pdo ?: self::pdo(); + self::ensureTable($pdo); + $st = $pdo->query('SELECT ' . self::selectColumns() . ' FROM cloak_site_domains ORDER BY hostname ASC'); + return $st->fetchAll(); + } + + public static function findById(PDO $pdo, $id) + { + self::ensureTable($pdo); + $st = $pdo->prepare('SELECT ' . self::selectColumns() . ' FROM cloak_site_domains WHERE id = ? LIMIT 1'); + $st->execute([(int) $id]); + $row = $st->fetch(); + return $row ?: null; + } + + public static function updateCloudflareMeta(PDO $pdo, $id, array $fields) + { + self::ensureTable($pdo); + $allowed = ['cf_zone_id', 'cf_nameservers', 'cf_status', 'cf_error', 'cf_checked_at']; + $sets = []; + $vals = []; + foreach ($allowed as $key) { + if (array_key_exists($key, $fields)) { + $sets[] = "`{$key}` = ?"; + $vals[] = $fields[$key]; + } + } + if ($sets === []) { + return false; + } + $vals[] = (int) $id; + $sql = 'UPDATE cloak_site_domains SET ' . implode(', ', $sets) . ' WHERE id = ?'; + $st = $pdo->prepare($sql); + $st->execute($vals); + return $st->rowCount() > 0; + } + + public static function findByHostname(PDO $pdo, $hostname) + { + self::ensureTable($pdo); + $host = self::normalizeHostname($hostname); + if ($host === '') { + return null; + } + $st = $pdo->prepare('SELECT ' . self::selectColumns() . ' FROM cloak_site_domains WHERE hostname = ? LIMIT 1'); + $st->execute([$host]); + $row = $st->fetch(); + return $row ?: null; + } + + public static function add(PDO $pdo, $hostname) + { + self::ensureTable($pdo); + $host = self::normalizeHostname($hostname); + if ($host === '' || !preg_match('/^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/i', $host)) { + return ['ok' => false, 'error' => '域名格式无效']; + } + try { + $st = $pdo->prepare('INSERT INTO cloak_site_domains (hostname, config_name) VALUES (?, ?)'); + $st->execute([$host, '']); + return ['ok' => true, 'id' => (int) $pdo->lastInsertId(), 'hostname' => $host]; + } catch (PDOException $e) { + if ((int) $e->getCode() === 23000) { + return ['ok' => false, 'error' => '该域名已存在']; + } + throw $e; + } + } + + public static function deleteById(PDO $pdo, $id) + { + self::ensureTable($pdo); + $st = $pdo->prepare('DELETE FROM cloak_site_domains WHERE id = ?'); + $st->execute([(int) $id]); + return $st->rowCount() > 0; + } + + public static function bindConfigToDomain(PDO $pdo, $configName, $domainId) + { + self::ensureTable($pdo); + $configName = trim($configName); + $domainId = (int) $domainId; + if ($configName === '' || $domainId <= 0) { + return false; + } + $pdo->prepare("UPDATE cloak_site_domains SET config_name = '' WHERE config_name = ?")->execute([$configName]); + $st = $pdo->prepare('UPDATE cloak_site_domains SET config_name = ? WHERE id = ?'); + $st->execute([$configName, $domainId]); + return $st->rowCount() > 0; + } + + public static function clearConfigBinding(PDO $pdo, $configName) + { + self::ensureTable($pdo); + $st = $pdo->prepare("UPDATE cloak_site_domains SET config_name = '' WHERE config_name = ?"); + $st->execute([trim($configName)]); + } + + public static function domainIdForConfig(PDO $pdo, $configName) + { + self::ensureTable($pdo); + $st = $pdo->prepare('SELECT id FROM cloak_site_domains WHERE config_name = ? ORDER BY id ASC LIMIT 1'); + $st->execute([trim($configName)]); + $row = $st->fetch(); + return $row ? (int) $row['id'] : 0; + } + + public static function primaryHostnameForConfig(PDO $pdo, $configName) + { + self::ensureTable($pdo); + $st = $pdo->prepare('SELECT hostname FROM cloak_site_domains WHERE config_name = ? ORDER BY id ASC LIMIT 1'); + $st->execute([trim($configName)]); + $row = $st->fetch(); + return $row ? $row['hostname'] : ''; + } + + public static function resolveConfigNameForHost($host, $baseDir = null) + { + $baseDir = $baseDir ?: dirname(__DIR__, 2); + $norm = self::normalizeHostname($host); + if ($norm !== '') { + try { + $pdo = self::pdo(); + $row = self::findByHostname($pdo, $norm); + if ($row && !empty($row['config_name'])) { + $name = trim($row['config_name']); + if (file_exists($baseDir . '/check_config/' . $name . '_config.php')) { + return $name; + } + } + } catch (Throwable $e) { + } + $key = self::hostToConfigKey($norm); + if (file_exists($baseDir . '/check_config/' . $key . '_config.php')) { + return $key; + } + } + return 'index'; + } +} diff --git a/lib/Cloak/FpUrlHelper.php b/lib/Cloak/FpUrlHelper.php new file mode 100755 index 0000000..fcce0aa --- /dev/null +++ b/lib/Cloak/FpUrlHelper.php @@ -0,0 +1,114 @@ + is_string($all_fp_url) ? (string) $all_fp_url : '', 'now_url' => 0]; + } + + if (isset($_COOKIE['nt']) && is_numeric($_COOKIE['nt'])) { + $ntCookie = (int) $_COOKIE['nt']; + if ($ntCookie >= 1 && $ntCookie <= $num) { + $now_url = $ntCookie; + } + } + + if (!$now_url) { + $match = false; + $nt = 2; + $ot = false; + $handle = @fopen('nt.txt', 'r'); + if ($handle) { + while (!feof($handle)) { + $buffer = fgets($handle); + $bb = explode('||||||', $buffer); + if (trim($bb[0] ?? '') !== $configName) { + continue; + } + if (!isset($bb[1]) || trim($bb[1]) === '') { + continue; + } + $match = true; + $ot = trim($bb[1]); + $nt = trim($bb[1]); + break; + } + fclose($handle); + } + + if ($match) { + if ((int) $nt <= $num) { + $now_url = max(1, (int) $ot); + $nt = (int) $nt + 1; + } else { + $now_url = 1; + $nt = 2; + } + } else { + $now_url = 1; + $nt = 2; + } + + if ($mutateNt) { + write_nt_list($configName, $nt, $ot); + } + } + + if (is_array($all_fp_url)) { + $idx = max(0, min(max(1, (int) $now_url) - 1, $num - 1)); + $fp_url = $all_fp_url[$idx]; + $now_url = $idx + 1; + } else { + $fp_url = (string) $all_fp_url; + } + + if ($mutateNt) { + setCrossDomainCookie('nt', $now_url, 3600 * 24 + time()); + } + + if (defined('KEEP_PARAMS') && KEEP_PARAMS === 'ON' && !empty($_GET) && $fp_url !== '') { + $params = http_build_query($_GET); + $urlParts = parse_url($fp_url); + if (isset($urlParts['query'])) { + $fp_url .= '&' . $params; + } else { + $fp_url .= '?' . $params; + } + } + + return ['url' => (string) $fp_url, 'now_url' => (int) $now_url]; + } + + /** + * 真实页 / 安全页兜底 URL(DB_FP 首项,否则 DB_ZP) + */ + public static function fallbackUrl() + { + $all = DB_FP; + if (is_array($all)) { + foreach ($all as $u) { + if (trim((string) $u) !== '') { + return (string) $u; + } + } + } elseif (is_string($all) && trim($all) !== '') { + return $all; + } + return defined('DB_ZP') ? (string) DB_ZP : ''; + } +} diff --git a/lib/Cloak/Page/FingerprintRedirectRenderer.php b/lib/Cloak/Page/FingerprintRedirectRenderer.php new file mode 100755 index 0000000..4a9828f --- /dev/null +++ b/lib/Cloak/Page/FingerprintRedirectRenderer.php @@ -0,0 +1,21 @@ + + + v_ip); + if ($times + 1 >= AUTO_BLACK_TIMES) { + write_black_list($v_info->v_ip); + } + } + if (!isset($_SESSION['visit_to_3'])) { + $_SESSION['visit_to_3'] = '1'; + } + if (($_SESSION['visit_to_3'] ?? '1') != '3' + && (CLOAK_RISK_NUMBER > 0 && CLOAK_RISK_NUMBER <= 90)) { + // 二次风控:先写 wait 状态,f_check 完成后再更新 result / fp_url(避免 true+空跳转) + $logs['result'] = 'wait'; + $logs['reason'] = '二次风控检测中'; + $logs['fp_url'] = ''; + $log_id = write_log_db($logs); + $riskCtx = [ + 'logs' => $logs, + 'v_info' => $v_info, + 'log_id' => $log_id, + ]; + if (CLOAK_REDIRECT_METHOD == 'curl') { + self::renderRiskCurlInject($riskCtx); + return; + } + RiskPageRenderer::render($riskCtx); + return; + } + + $logs['result'] = 'true'; + $logs['reason'] = ''; + FpPageRenderer::render(['logs' => $logs]); + } + + /** + * @param array $ctx 需含 v_info, log_id + */ + private static function renderRiskCurlInject(array $ctx) + { + extract($ctx, EXTR_SKIP); + $zp_url = DB_ZP; + $html = file_get_content_sstr($zp_url); + $_html = caiji_lujing_buquan($html, $zp_url, $_SERVER['HTTP_HOST']); + ob_start(); + require dirname(__DIR__, 3) . '/cloakjs.php'; + $js_to_inject = ob_get_clean(); + if (hasHeadTag($_html)) { + $new_html = preg_replace('/(]*>)/i', "$1\n" . $js_to_inject, $_html); + } else { + $new_html = $js_to_inject . $_html; + } + echo $new_html; + exit; + } + + private static function echoJsRedirect($zp_url) + { + $zp_url_js = htmlspecialchars($zp_url, ENT_QUOTES, 'UTF-8'); + echo ''; + } +} diff --git a/lib/Cloak/Pipeline/stages/apply_whitelist_blacklist.inc.php b/lib/Cloak/Pipeline/stages/apply_whitelist_blacklist.inc.php new file mode 100755 index 0000000..c592c2c --- /dev/null +++ b/lib/Cloak/Pipeline/stages/apply_whitelist_blacklist.inc.php @@ -0,0 +1,69 @@ + 0) { + $ips_fp_ary = ip_group_list_addresses((int) WHITELIST_GROUP_ID); + } else { + $ips_fp_ary = array_filter(array_map('trim', explode(',', SHOW_SITE_IP)), static function ($v) { + return $v !== ''; + }); + } + $reason = ""; // 判断理由 + + $whiteParamsMatched = false; + if( !empty(WHITE_PARAMS) ) { + $wparams = explode('=', WHITE_PARAMS, 2); + + if(count($wparams) == 2) { + $pk = $wparams[0]; + $pv = $wparams[1]; + } + + if(isset($_GET[$pk]) && strip_tags($_GET[$pk]) == $pv) { + $whiteParamsMatched = true; + + } + } + + $match = false; + if (defined('BLACKLIST_GROUP_ID') && (int) BLACKLIST_GROUP_ID > 0) { + $blEntries = ip_group_list_addresses((int) BLACKLIST_GROUP_ID); + $match = ip_visitor_in_blacklist_entries($v_info->v_ip, $blEntries); + } + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'黑名单检查', $match ? 'fail' : 'pass', $match ? 'IP 在黑名单组内' : '未命中黑名单', [ + 'ip' => $v_info->v_ip, + 'group_id' => defined('BLACKLIST_GROUP_ID') ? BLACKLIST_GROUP_ID : 0, + ]); + } + if ($match) { + $_SESSION["check_result"] = "false"; + $reason = "黑名单"; + if ($__cloak_debug_on) { + cloak_dbg_record(__LINE__,'false', $reason, ['stage' => 'blacklist']); + } + } + + if(in_array($v_info->v_ip, $ips_fp_ary) ) { + $_SESSION["check_result"] = "true"; + $reason = "白名单"; + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'IP 白名单', 'pass', 'IP 在白名单组/列表中'); + cloak_dbg_record(__LINE__,'true', $reason, ['stage' => 'whitelist_ip']); + } + } elseif( !empty(WHITE_PARAMS) ) { + $wparams = explode('=', WHITE_PARAMS, 2); + if(count($wparams) == 2) { + $pk = $wparams[0]; + $pv = $wparams[1]; + } + if(isset($_GET[$pk]) && strip_tags($_GET[$pk]) == $pv) { + $_SESSION["check_result"] = "true"; + $reason = "白名单链接参数"; + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'链接参数白名单', 'pass', WHITE_PARAMS); + cloak_dbg_record(__LINE__,'true', $reason, ['stage' => 'whitelist_params']); + } + } + } elseif ($__cloak_debug_on && !empty(WHITE_PARAMS)) { + cloak_dbg_step(__LINE__,'链接参数白名单', 'skip', '参数不匹配: ' . WHITE_PARAMS); + } diff --git a/lib/Cloak/Pipeline/stages/check_url_args_timeout.inc.php b/lib/Cloak/Pipeline/stages/check_url_args_timeout.inc.php new file mode 100755 index 0000000..4691ad0 --- /dev/null +++ b/lib/Cloak/Pipeline/stages/check_url_args_timeout.inc.php @@ -0,0 +1,134 @@ + 0) { + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'临时链接参数', 'info', 'CLOAK_URL_ARGS_TIMEOUT=' . CLOAK_URL_ARGS_TIMEOUT . ' 分钟,开始检查'); + } + $dir = dirname(__DIR__, 4) . '/args'; + $pattern = '/^' . preg_quote($config_name, '/') . '_\d{10}\.txt$/i'; + $matchedFile = ""; + + if (is_dir($dir)) { + $iterator = new DirectoryIterator($dir); + foreach ($iterator as $file) { + if ($file->isFile() && preg_match($pattern, $file->getFilename())) { + $matchedFile = $file->getFilename(); + break; + } + } + } + + $__url_args_cfg = CloakAdSourceGuard::configFromDefines(); + $__url_args_ctx = CloakAdSourceGuard::buildRequestContext(); + $__url_args_qualifies = CloakAdSourceGuard::shouldStartUrlArgsTimer($__url_args_cfg, $__url_args_ctx); + + if ($__url_args_qualifies) { + if(!$matchedFile) { + $filename = $config_name . '_' . time() . '.txt'; + if(touch($dir . '/' . $filename)) { + $matchedFile = $filename; + } + } + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, '临时链接参数', 'info', '命中广告来源规则,开始/续期有效时长', [ + 'platforms_enabled' => CloakAdSourceGuard::anyPlatformEnabled($__url_args_cfg), + ]); + } + } elseif ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, '临时链接参数', 'skip', '未通过广告来源规则,不启动计时'); + } + + unset($__url_args_cfg, $__url_args_ctx, $__url_args_qualifies); + + if($matchedFile) { + if (preg_match('/_(\d{10})\.txt$/', $matchedFile, $matches)) { + $fileTimestamp = $matches[1]; + $diffMinutes = floor((time() - $fileTimestamp) / 60); + + if ($diffMinutes < CLOAK_URL_ARGS_TIMEOUT) { + $check_result = false; + $reason = "临时链接参数:距离第一次访问过去了" . $diffMinutes . " 分钟"; + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'临时链接参数', 'fail', $reason, ['diff_minutes' => $diffMinutes]); + } + } else { + $check_result = true; + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'临时链接参数', 'pass', '已超过 ' . CLOAK_URL_ARGS_TIMEOUT . ' 分钟,继续后续判定'); + } + } + } + } else { + $check_result = false; + $reason = "临时链接参数:尚未有效访问"; + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'临时链接参数', 'fail', $reason); + } + } + + if(!$check_result) { + $reason = cloak_reason_or($reason, '临时链接参数拦截'); + if (class_exists('CloakPipelineTimer', false)) { + CloakPipelineTimer::finish(); + } + if ($__cloak_debug_on) { + cloak_dbg_record(__LINE__,'false', $reason, ['stage' => 'url_args_timeout']); + CloakDebugPage::setExitPoint(__LINE__, '临时链接参数拦截 → 安全页(DEBUG 提前截停)'); + CloakDebugPage::renderAndExit([ + 'config_name' => $config_name, + 'check_result' => 'false', + 'reason' => $reason, + 'visitor' => $v_info, + 'logs' => [], + 'device' => '', + 'mode' => SHOW_SITE_MODE_SWITCH, + 'fp_urls' => defined('DB_FP') ? DB_FP : [], + 'zp_url' => defined('DB_ZP') ? DB_ZP : '', + 'started_at' => $__cloak_debug_started, + ]); + } + $logs = array(); + $zp_url = DB_ZP; + $logs['site_name'] = str_replace("www.", "", $_SERVER['HTTP_HOST']); + $logs['customers_ip'] = $v_info->v_ip; + $logs['country'] = substr($v_info->v_country, 0, 2); + $logs['v_Browser'] = $v_info->v_Browser; + $logs['v_referer'] = $v_info->v_referer; + $logs['Client'] = $v_info->v_Client; + $logs['v_PageURL'] = $v_info->v_curPageURL; + $logs['v_site_server'] = $v_info->v_site_server; + $logs['accept_language'] = $v_info->accept_language; + $logs['visit_md5_code'] = $v_info->visit_md5_code; + $logs['campagin_id'] = $v_info->costm_ip_score; + $logs['result'] = "false"; + $logs['device'] = ""; + $logs['reason'] = $reason; + $logs['fp_url'] = $zp_url; + write_log_db($logs); + + $redirect_method = CLOAK_REDIRECT_METHOD; + if(!empty($zp_url)) { + if($redirect_method == 'curl') { + $html = file_get_content_sstr($zp_url); + $_html = caiji_lujing_buquan($html, $zp_url, $_SERVER['HTTP_HOST']); + echo $_html; + exit; + } elseif($redirect_method == '302') { + header('Location: ' . $zp_url); + exit; + } elseif ($redirect_method == 'js') { + $zp_url_js = htmlspecialchars($zp_url, ENT_QUOTES, 'UTF-8'); + echo ''; + exit; + } + } + } + } elseif ($__cloak_debug_on && CLOAK_URL_ARGS_TIMEOUT <= 0) { + cloak_dbg_step(__LINE__,'临时链接参数', 'skip', 'CLOAK_URL_ARGS_TIMEOUT=0,已关闭'); + } diff --git a/lib/Cloak/Pipeline/stages/resolve_session_fast_path_hit.inc.php b/lib/Cloak/Pipeline/stages/resolve_session_fast_path_hit.inc.php new file mode 100755 index 0000000..017feaf --- /dev/null +++ b/lib/Cloak/Pipeline/stages/resolve_session_fast_path_hit.inc.php @@ -0,0 +1,9 @@ + 'session_fast_path']); + } diff --git a/lib/Cloak/Pipeline/stages/run_ad_source_guard.inc.php b/lib/Cloak/Pipeline/stages/run_ad_source_guard.inc.php new file mode 100755 index 0000000..0901fd1 --- /dev/null +++ b/lib/Cloak/Pipeline/stages/run_ad_source_guard.inc.php @@ -0,0 +1,71 @@ + defined('CLOAK_AD_FB') && strtoupper(CLOAK_AD_FB) === 'ON', + 'ad_google' => defined('CLOAK_AD_GOOGLE') && strtoupper(CLOAK_AD_GOOGLE) === 'ON', + 'ad_tiktok' => defined('CLOAK_AD_TIKTOK') && strtoupper(CLOAK_AD_TIKTOK) === 'ON', + 'ad_strict' => defined('CLOAK_AD_STRICT') && strtoupper(CLOAK_AD_STRICT) === 'ON', + 'ad_spm_id' => defined('CLOAK_AD_SPM_ID') ? (string) CLOAK_AD_SPM_ID : '', + ]; + + if (CloakAdSourceGuard::anyPlatformEnabled($__ad_guard_cfg)) { + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, '广告来源限制', 'info', '已启用平台检测,开始 evaluate()'); + } + + $__ad_ref_raw = isset($_SERVER['HTTP_REFERER']) ? (string) $_SERVER['HTTP_REFERER'] : ''; + $__ad_ref_parts = parse_url($__ad_ref_raw); + $__ad_ref_q = []; + if (!empty($__ad_ref_parts['query'])) { + parse_str($__ad_ref_parts['query'], $__ad_ref_q); + } + $__ad_query = array_merge($__ad_ref_q, $_GET); + + $__ad_result = CloakAdSourceGuard::evaluate($__ad_guard_cfg, [ + 'referer' => $__ad_ref_raw, + 'query' => $__ad_query, + 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? (string) $_SERVER['HTTP_USER_AGENT'] : '', + ]); + + if ($__ad_result['passed']) { + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, '广告来源限制', 'pass', 'matched_by=' . $__ad_result['matched_by']); + cloak_dbg_record(__LINE__, null, '', [ + 'stage' => 'ad_source_guard', + 'matched_by' => $__ad_result['matched_by'], + ]); + } + } elseif ($__ad_guard_cfg['ad_strict']) { + $_SESSION['check_result'] = 'false'; + $reason = $__ad_result['reason']; + if ($__cloak_debug_on) { + cloak_dbg_record(__LINE__, 'false', $reason, [ + 'stage' => 'ad_source_guard', + 'matched_by' => $__ad_result['matched_by'], + 'strict' => true, + ]); + } + } else { + $reason = cloak_reason_append($reason, $__ad_result['reason']); + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, '广告来源限制', 'warn', $reason, [ + 'matched_by' => $__ad_result['matched_by'], + 'strict' => false, + ]); + cloak_dbg_record(__LINE__, null, $reason, [ + 'stage' => 'ad_source_guard_uncertain', + 'matched_by' => $__ad_result['matched_by'], + ]); + } + } + + unset($__ad_ref_raw, $__ad_ref_parts, $__ad_ref_q, $__ad_query, $__ad_result); + } elseif ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, '广告来源限制', 'skip', '未开启任何广告平台'); + } + + unset($__ad_guard_cfg); + } elseif ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, '广告来源限制', 'skip', 'check_result 已由前置步骤写入: ' . ($_SESSION['check_result'] ?? '')); + } diff --git a/lib/Cloak/Pipeline/stages/run_main_api_fingerprint.inc.php b/lib/Cloak/Pipeline/stages/run_main_api_fingerprint.inc.php new file mode 100755 index 0000000..de0d1fe --- /dev/null +++ b/lib/Cloak/Pipeline/stages/run_main_api_fingerprint.inc.php @@ -0,0 +1,197 @@ +v_referer == "") { + $v_info->v_referer = 'off'; + } + + if(isset($_COOKIE['vbrowser']) && $_COOKIE['vbrowser'] == 'mobile') { + $_SESSION["gcu_Browser"] = 'mobile'; + } else { + $_SESSION["gcu_Browser"] = 'pc'; + } + + if($v_info->v_referer != "") //排除机器访问,赋值给 _COOKIE , _SESSION + { + //echo $v_info->v_referer; + $v_info->get_visit_md5_code(); //生成客户信息md5 + $v_referer_str = $v_info->v_referer; /* && $v_info->accept_language != "Chinese"*/ + if(!empty($v_referer_str) && !empty($v_info->accept_language) /* && $v_info->v_Browser != "unknown" && ( strpos($v_referer_str,"google") || strpos($v_referer_str,"bing") || strpos($v_referer_str,"yahoo") || strpos($v_referer_str,"facebook") || strpos($v_referer_str,"yandex")) */) + { + setCrossDomainCookie("gfuid", $v_info->visit_md5_code, time()+3600*24); + $_SESSION["gcu_country"] = $v_info->v_country; + $_SESSION["gcu_Client"] = $v_info->v_Client; + $_SESSION["gcu_ip"] = $v_info->v_ip; + $_SESSION["gcu_Browser"] = empty($_SESSION["gcu_Browser"])?$v_info->v_Browser:$_SESSION["gcu_Browser"]; + } + $_SESSION["gcuid"] = $v_info->visit_md5_code; + } elseif( !empty($_COOKIE["gfuid"]) ) { + $_SESSION["gcuid"] = $_COOKIE["gfuid"]; + $v_info->v_referer = "COOKIE: " . cloak_current_request_url(); + $v_info->set_visit_md5_code($_COOKIE["gfuid"]); //赋值客户信息md5 + } + + if(!empty($_SESSION["gcuid"]) && !empty($v_info->v_referer)) + { + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'Referer / gcuid', 'pass', 'gcuid 与 referer 均存在,可进入指纹/API 判定', [ + 'gcuid' => $_SESSION['gcuid'], + 'referer' => $v_info->v_referer, + ]); + } + if(strtoupper(CLOAK_ZH_ON) == "ON" || strtoupper(CLOAK_MOBILE_ON) == "ON" || strtoupper(CLOAK_OS_ON) == "ON" || intval(IPHONE_MODEL) > 0 || intval(IS_VIRTUAL) > 0) { + if (class_exists('CloakPipelineTimer', false)) { + CloakPipelineTimer::stage('指纹检测'); + } + + if (cloak_fingerprint_cookies_ready()) { + if ($_COOKIE['cl'] == 'uklot' && is_numeric($_COOKIE['ctime'])) { + $v_info->check_result = 'false'; + $mmr = cloak_fingerprint_mmr_reason(); + $reason = '可疑访客:' . $mmr; + $_SESSION['check_result'] = trim($v_info->check_result); + if ($__cloak_debug_on) { + cloak_dbg_record(__LINE__, trim($v_info->check_result), $reason, ['stage' => 'fingerprint_cookie', 'mmr' => $mmr]); + } + } else { + $v_info->check_result = 'true'; + } + } elseif (cloak_fingerprint_time_param_present()) { + // 已完成指纹跳转(URL 含 time),但 Cookie 未写入:终止再次重定向 + $v_info->check_result = 'false'; + + $reason = cloak_reason_or($reason, '指纹Cookie未写入(已完成前端检测)'); + $_SESSION['check_result'] = 'false'; + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, 'JS 指纹检测', 'fail', 'URL 含 time 但指纹 Cookie 缺失,停止重定向'); + cloak_dbg_record(__LINE__, 'false', $reason, ['stage' => 'fingerprint_cookie_missing']); + } + } else { + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__, 'JS 指纹检测', 'skip', 'DEBUG 跳过指纹 JS 跳转,直接进入 API 判定'); + CloakDebugPage::setFlag('skipped_fingerprint', true); + $v_info->check_result = 'true'; + } else { + FingerprintRedirectRenderer::renderAndExit($config_name); + } + } + } else { + $v_info->check_result = 'true'; + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'JS 指纹检测', 'skip', 'ZH/Mobile/OS/机型检测均为 OFF,跳过指纹'); + } + } + + if($v_info->check_result == 'true') { + if (class_exists('CloakPipelineTimer', false)) { + CloakPipelineTimer::stage('API远程判定'); + } + $__api_return = $v_info->send_visitor_Info_xyz(); // 使用CLOAK判断接口 + if ($__cloak_debug_on) { + if ($__api_return !== null) { + CloakDebugPage::setApiResponse([ + 'called' => true, + 'check_result'=> $v_info->check_result, + 'reason' => $v_info->v_reason, + 'country' => $v_info->v_country, + 'result_raw' => isset($__api_return['result']) ? ($__api_return['result'] ? 'true' : 'false') : '', + 'raw' => $__api_return, + ]); + cloak_dbg_step(__LINE__,'API 远程判定', 'decide', 'API 已返回', [ + 'api_result' => $v_info->check_result, + 'api_reason' => $v_info->v_reason !== '' ? $v_info->v_reason : '(空)', + ]); + } else { + CloakDebugPage::setApiResponse([ + 'called' => false, + 'skip_reason' => '无法获取IP,未调用 API判断IP信息是否安全', + ]); + cloak_dbg_step(__LINE__,'API 远程判定', 'skip', '前置条件不满足,未调用 API', [ + 'v_ip' => $v_info->v_ip, + 'v_Browser' => $v_info->v_Browser, + 'accept_language' => $v_info->accept_language, + ]); + } + } + //echo "
        获取到结果:".$v_info->check_result."
        "; + $_SESSION["gcu_referer"] = $v_info->v_referer; + $_SESSION["gcu_country"] = $v_info->v_country; + $_SESSION['visit_to_2'] = '2'; // 记录接口调用结果缓存 + + if ($__api_return !== null) { + $_SESSION["check_result"] = trim($v_info->check_result); + $reason = cloak_api_reason($__api_return, $_SESSION["check_result"]); + } else { + $_SESSION["check_result"] = "false"; + $reason = cloak_reason_or($reason, 'API未调用:缺少访客信息(ip/Browser/Accept-Language)'); + } + if ($__cloak_debug_on) { + cloak_dbg_record(__LINE__,$_SESSION['check_result'], $reason, [ + 'stage' => 'api_cloak', + 'api_reason' => $v_info->v_reason, + ]); + } + } elseif ($v_info->check_result == 'false') { + $_SESSION["check_result"] = "false"; + $reason = cloak_reason_or($reason, '指纹检测未通过,未调用API'); + } + } else { + $_SESSION["check_result"] = "false"; + $reason = "爬虫"; + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'Referer / gcuid', 'fail', 'gcuid 或 referer 为空,判定为爬虫', [ + 'gcuid' => $_SESSION['gcuid'] ?? '', + 'referer' => $v_info->v_referer, + ]); + cloak_dbg_record(__LINE__,'false', $reason, ['stage' => 'no_referer_or_gcuid']); + } + } + } elseif (($_SESSION['visit_to_2'] ?? '') == '2') { + if (!empty($_SESSION["check_result"])) { + if ($reason === '') { + $reason = ($_SESSION['check_result'] === 'true') + ? 'Session API缓存:判定通过' + : 'Session API缓存:判定拒绝'; + } + } else { + $_SESSION["check_result"] = 'false'; + $reason = cloak_reason_or($reason, 'Session状态异常(visit_to_2=2但无缓存结果),默认安全页'); + } + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'主判定块 (API)', 'skip', 'visit_to_2=2,本块已跳过(' . $reason . ')'); + } + } +} else { + if ($reason === '') { + $reason = ($_SESSION['check_result'] === 'true') + ? '前置规则判定通过(主判定块已跳过)' + : '前置规则判定拒绝(主判定块已跳过)'; + } + if ($__cloak_debug_on) { + cloak_dbg_step(__LINE__,'主判定块 (API)', 'skip', 'check_result 已有值,跳过主判定块'); + cloak_dbg_record(__LINE__,$_SESSION['check_result'] ?? 'false', $reason, ['stage' => 'session_partial']); + } +} diff --git a/lib/Cloak/PipelineTimer.php b/lib/Cloak/PipelineTimer.php new file mode 100755 index 0000000..1c0777e --- /dev/null +++ b/lib/Cloak/PipelineTimer.php @@ -0,0 +1,101 @@ + */ + private static $stages = []; + + /** @var string */ + private static $currentStage = ''; + + /** @var float */ + private static $stageStartedAt = 0.0; + + public static function init() + { + self::$startedAt = microtime(true); + self::$stages = []; + self::$currentStage = ''; + self::$stageStartedAt = 0.0; + } + + public static function stage($name) + { + self::endCurrentStage(); + self::$currentStage = (string) $name; + self::$stageStartedAt = microtime(true); + } + + public static function finish() + { + self::endCurrentStage(); + $totalMs = round((microtime(true) - self::$startedAt) * 1000, 2); + $payload = [ + 'total_ms' => $totalMs, + 'stages' => self::$stages, + ]; + $json = json_encode($payload, JSON_UNESCAPED_UNICODE); + $GLOBALS['__cloak_judge_timing'] = $json; + $GLOBALS['__cloak_judge_timing_text'] = self::formatText($payload); + return $payload; + } + + /** + * @return string + */ + public static function summaryText() + { + if (!empty($GLOBALS['__cloak_judge_timing_text'])) { + return (string) $GLOBALS['__cloak_judge_timing_text']; + } + if (!empty($GLOBALS['__cloak_judge_timing'])) { + $decoded = json_decode((string) $GLOBALS['__cloak_judge_timing'], true); + if (is_array($decoded)) { + return self::formatText($decoded); + } + } + return ''; + } + + /** + * @param array $payload + */ + public static function formatText(array $payload) + { + $parts = []; + if (isset($payload['total_ms'])) { + $parts[] = '总计 ' . $payload['total_ms'] . 'ms'; + } + if (!empty($payload['stages']) && is_array($payload['stages'])) { + foreach ($payload['stages'] as $stage) { + if (!is_array($stage)) { + continue; + } + $name = $stage['name'] ?? ''; + $ms = $stage['ms'] ?? 0; + if ($name !== '') { + $parts[] = $name . ' ' . $ms . 'ms'; + } + } + } + return implode(' | ', $parts); + } + + private static function endCurrentStage() + { + if (self::$currentStage === '' || self::$stageStartedAt <= 0) { + return; + } + self::$stages[] = [ + 'name' => self::$currentStage, + 'ms' => round((microtime(true) - self::$stageStartedAt) * 1000, 2), + ]; + self::$currentStage = ''; + self::$stageStartedAt = 0.0; + } +} diff --git a/lib/Cloak/ReasonHelper.php b/lib/Cloak/ReasonHelper.php new file mode 100755 index 0000000..fb8a320 --- /dev/null +++ b/lib/Cloak/ReasonHelper.php @@ -0,0 +1,54 @@ +v_country = !empty($_SESSION["gcu_country"])?$_SESSION["gcu_country"]:$check_country; + $this->v_ip = $this->getIp(); + $this->v_Browser = $this->getBrowser(); + //$this->v_country = $this->findCityByIp($this->v_ip); + $this->v_referer = $this->getFromPage(); + $this->v_Client = $this->v_isMobile(); + $this->v_curPageURL = $this->curPageURL(); + $this->v_site_server = $this->get_site_server(); + $this->accept_language = $this->get_accept_language(); + + $this->costm_ip_score = $costm_ip_score; + $this->check_key = $check_key; + $this->check_country = $check_country; + + $_SESSION["gcu_country"] = $this->v_country; + $_SESSION["gcu_Client"] = $this->v_Client; + $_SESSION["gcu_ip"] = $this->v_ip; + $_SESSION["gcu_Browser"] = $this->v_Browser; + } + + /** + * 调用远程 cloak API 判定 + * + * @return array|null API 解码结果;前置条件不足时 null + */ + public function send_visitor_Info_xyz() + { + if(!empty($_REQUEST["send"])&& $_REQUEST["send"] ==1) + { + print_r($jsonData); exit(); + } + + if(!empty($this->v_ip)) + { + $return = $this -> cloak_check_curl(); + if (!is_array($return)) { + $return = ['result' => false, 'reason' => 'API响应异常', 'country' => $this->v_country]; + } + $this->check_result = !empty($return['result']) ? "true" : "false"; + $this->v_country = isset($return['country']) ? $return['country'] : $this->v_country; + $this->v_reason = cloak_api_reason($return, $this->check_result); + return $return; + } + return null; + } + + + function cloak_check_curl() + { + $headers = browser_headers(); + // $visit_domain = str_replace('www.', '', $_SERVER['HTTP_HOST']); // 当前网站域名 + // $visit_domain = (is_https() ? "https://" : "http://"). $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + $jsonData['id'] = $this->costm_ip_score; + $jsonData['ip'] = $this->v_ip; + $jsonData['domain'] = $this->v_curPageURL; + $jsonData['country_code'] = $this->check_country; //设置该参数后,将替换"广告策略》访问者地理位置>过滤"的设置,填写国家代码,多个用逗号分隔,如:US,GB,CA,AU,IE,NZ + $jsonData['referer'] = get_SERVER_value('HTTP_REFERER'); + $jsonData['headers'] = json_encode($headers); + $ch = curl_init('www.tiktokba.com/cloak/byApi'); + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + curl_setopt($ch, CURLOPT_USERAGENT, get_SERVER_value('HTTP_USER_AGENT')); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + + curl_setopt($ch, CURLOPT_ENCODING, ""); //Enables compression + curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-type: application/json"]); + curl_setopt($ch, CURLOPT_HTTPHEADER, ["escloak-key: {$this->check_key}"]); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($jsonData)); + curl_setopt($ch, CURLOPT_HEADERFUNCTION, "forward_response_cookies"); //Forward response's cookies to visitor + if ($_COOKIE) {//Forward visitor's cookie to our server + curl_setopt($ch, CURLOPT_COOKIE, encode_visitor_cookies()); + } + $return = curl_exec($ch); + if ($return == false) { + $curl_error = curl_error($ch); + curl_close($ch); + return ['result' => false, 'reason' => 'API请求失败:' . $curl_error, 'country' => '']; + } + curl_close($ch); + $decoded = json_decode($return, true); + if (!is_array($decoded)) { + return ['result' => false, 'reason' => 'API响应失败,请检查API密钥以及广告策略 ID', 'country' => '']; + } + + return $decoded; + } + + // api.ttt.sh API查询国家代码 + public function get_ip_country($client_ip) + { + $str = ""; + //$url = "https://api.ttt.sh/ip/qqwry/".$client_ip."?type=addr"; + //$str = file_get_contents($url); + return $str; + } + + public function set_visit_md5_code($code) + { + $this->visit_md5_code = $code; + } + + public function get_visit_md5_code() + { + $domain = str_replace("www.","",$_SERVER['HTTP_HOST']); + $time = date("YmdHis"); + $ip = $this->getIp(); + $this->visit_md5_code = substr(md5($domain.$time.$ip) , 0 , 12 ); + + return $this->visit_md5_code; + } + + //获取访客ip + public function getIp($type = 0) + { + $type = $type ? 1 : 0; + static $ip = NULL; + if ($ip !== NULL) return $ip[$type]; + if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { // 使用cloudflare 转发的IP地址 + $ip = $_SERVER['HTTP_CF_CONNECTING_IP']; + } else { + if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) { + $ip = getenv('HTTP_CLIENT_IP'); + } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) { + $ip = getenv('HTTP_X_FORWARDED_FOR'); + } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) { + $ip = getenv('REMOTE_ADDR'); + } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) { + $ip = $_SERVER['REMOTE_ADDR']; + } + } + // if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + // $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + // $pos = array_search('unknown',$arr); + // if(false !== $pos) unset($arr[$pos]); + // $ip = trim($arr[0]); + // }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { + // $ip = $_SERVER['HTTP_CLIENT_IP']; + // }elseif (isset($_SERVER['REMOTE_ADDR'])) { + // $ip = $_SERVER['REMOTE_ADDR']; + // } + // IP地址合法验证 + //$long = sprintf("%u",ip2long($ip)); + //$ip = $long ? array($ip, $long) : array('0.0.0.0', 0); + + return $ip; + } + + //客户当前浏览的页面 url(浏览器实际访问地址,含正确 scheme 与 query) + function curPageURL() + { + return cloak_current_request_url(); + } + + //根据ip获取城市、网络运营商等信息 + public function findCityByIp($ip){ + $country_res = @file_get_contents("http://ip.taobao.com/service/getIpInfo.php?ip=".$ip); + $country_json = json_decode($country_res,true); + // Array ( [code] => 0 [data] => Array ( [ip] => 104.223.98.4 [country] => 美国 [area] => [region] => 德克萨斯 [city] => 达拉斯 [county] => XX [isp] => XX [country_id] => US [area_id] => [region_id] => US_143 [city_id] => US_1099 [county_id] => xx [isp_id] => xx ) ) + $country = $country_json["data"]["country"]; + + return $country; + } + + //site_server + function get_site_server() + { + $dqml=getcwd(); + $dpml_ary = explode(DIRECTORY_SEPARATOR, $dqml); + $dqml_str = $dpml_ary[2]; + $dqml_str = substr($dqml_str,0,4); + + return $dqml_str; + } + + //字符串截取函数 + function ip_p_substr($p_bof,$p_eof,$p_str) + { + $p_1=explode($p_bof,$p_str); + $p_e=strpos($p_1[1],$p_eof); + $p_0=substr($p_1[1],0,$p_e); + + return $p_0; + } + + //获取用户浏览器类型 + public function getBrowser(){ + $agent=$_SERVER["HTTP_USER_AGENT"]; + if(strpos($agent,'MSIE')!==false || strpos($agent,'rv:11.0')) //ie11判断 + return "ie"; + + else if(strpos($agent,'Firefox')!==false) + return "firefox"; + + else if(strpos($agent,'Chrome')!==false) + return "chrome"; + + else if(strpos($agent,'Opera')!==false) + return 'opera'; + + else if((strpos($agent,'Chrome')==false)&&strpos($agent,'Safari')!==false) + return 'safari'; + + else + return 'unknown'; + } + + //获取网站来源 + public function getFromPage(){ + if(empty($_SERVER['HTTP_REFERER'])) { + return NULL; + } + else + return $_SERVER['HTTP_REFERER']; + } + + function get_accept_language() + { + $lang = ""; + if(!empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) && isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ) + { + $accept_language = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 4); //只取前4位,这样只判断最优先的语言。如果取前5位,可能出现en,zh的情况,影响判断。 + if (preg_match("/zh-c/i", $accept_language)) + $lang = "Chinese"; + else if (preg_match("/zh/i", $accept_language)) + $lang = "Chinese_Trad"; + else if (preg_match("/en/i", $accept_language)) + $lang = "English"; + else if (preg_match("/fr/i", $accept_language)) + $lang = "French"; + else if (preg_match("/de/i", $accept_language)) + $lang = "German"; + else if (preg_match("/jp/i", $accept_language)) + $lang = "Japanese"; + else if (preg_match("/ko/i", $accept_language)) + $lang = "Korean"; + else if (preg_match("/es/i", $accept_language)) + $lang = "Spanish"; + else if (preg_match("/sv/i", $accept_language)) + $lang = "Swedish"; + else $lang = $_SERVER["HTTP_ACCEPT_LANGUAGE"]; + } + + return $lang; + } + + /*移动端判断*/ + function v_isMobile() + { + // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 + if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) + { + return true; + } + // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息 + if (isset ($_SERVER['HTTP_VIA'])) + { + // 找不到为flase,否则为true + return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false; + } + // 脑残法,判断手机发送的客户端标志,兼容性有待提高 + if (isset ($_SERVER['HTTP_USER_AGENT'])) + { + $clientkeywords = array ('nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile' + ); + // 从HTTP_USER_AGENT中查找手机浏览器的关键字 + if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) + { + return "Mobile"; + } + } + // 协议法,因为有可能不准确,放到最后判断 + if (isset ($_SERVER['HTTP_ACCEPT'])) + { + // 如果只支持wml并且不支持html那一定是移动设备 + // 如果支持wml和html但是wml在html之前则是移动设备 + if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) + { + return "Mobile"; + } + } + return "PC"; + } +} diff --git a/lib/Cloak/VisitorLogAnalytics.php b/lib/Cloak/VisitorLogAnalytics.php new file mode 100644 index 0000000..f52d494 --- /dev/null +++ b/lib/Cloak/VisitorLogAnalytics.php @@ -0,0 +1,441 @@ + $summary, + 'by_result' => $byResult, + 'by_reason' => $byReason, + 'by_country' => $byCountry, + 'by_hour' => $byHour, + 'by_device' => $byDevice, + 'timing' => $timing, + 'compare' => $compare, + 'conclusions' => $conclusions, + ]; + } + + /** + * @param mysqli $conn + * @param array $filters + */ + private static function buildWhere($conn, array $filters) + { + $parts = ['1=1']; + + $dateFrom = trim((string) ($filters['date_from'] ?? '')); + $dateTo = trim((string) ($filters['date_to'] ?? '')); + if ($dateFrom === '' && $dateTo === '') { + $dateTo = date('Y-m-d'); + $dateFrom = date('Y-m-d', strtotime('-6 days')); + } + if ($dateFrom !== '') { + $parts[] = "`visit_date` >= '" . cloak_db_escape($conn, $dateFrom . ' 00:00:00') . "'"; + } + if ($dateTo !== '') { + $parts[] = "`visit_date` <= '" . cloak_db_escape($conn, $dateTo . ' 23:59:59') . "'"; + } + + $domain = trim((string) ($filters['domain'] ?? '')); + if ($domain !== '') { + $parts[] = "`domain` LIKE '%" . cloak_db_escape($conn, $domain) . "%'"; + } + + $campaginId = trim((string) ($filters['campagin_id'] ?? '')); + if ($campaginId !== '') { + $parts[] = "`campagin_id` = '" . cloak_db_escape($conn, $campaginId) . "'"; + } + + return implode(' AND ', $parts); + } + + /** + * @param mysqli $conn + * @param string $where + */ + private static function fetchSummary($conn, $where) + { + $sql = "SELECT + COUNT(*) AS total, + SUM(CASE WHEN `result` = 'true' THEN 1 ELSE 0 END) AS pass_cnt, + SUM(CASE WHEN `result` = 'false' THEN 1 ELSE 0 END) AS block_cnt, + SUM(CASE WHEN `result` = 'wait' THEN 1 ELSE 0 END) AS wait_cnt + FROM `visitor_logs` WHERE {$where}"; + $res = $conn->query($sql); + $row = $res ? $res->fetch_assoc() : []; + + $total = (int) ($row['total'] ?? 0); + $pass = (int) ($row['pass_cnt'] ?? 0); + $block = (int) ($row['block_cnt'] ?? 0); + $wait = (int) ($row['wait_cnt'] ?? 0); + $decided = max(1, $pass + $block); + + return [ + 'total' => $total, + 'pass' => $pass, + 'block' => $block, + 'wait' => $wait, + 'pass_rate' => $total > 0 ? round($pass / $decided * 100, 1) : 0, + 'block_rate' => $total > 0 ? round($block / $decided * 100, 1) : 0, + 'wait_rate' => $total > 0 ? round($wait / $total * 100, 1) : 0, + ]; + } + + /** + * @param mysqli $conn + * @param string $where + * @param string $column + * @param string $labelKey + * @param int $limit + */ + private static function fetchGroup($conn, $where, $column, $labelKey, $limit = 0) + { + $limitSql = $limit > 0 ? ' LIMIT ' . (int) $limit : ''; + $sql = "SELECT `{$column}` AS grp, COUNT(*) AS cnt FROM `visitor_logs` + WHERE {$where} GROUP BY `{$column}` ORDER BY cnt DESC{$limitSql}"; + $res = $conn->query($sql); + $rows = []; + if ($res) { + while ($r = $res->fetch_assoc()) { + $label = trim((string) ($r['grp'] ?? '')); + if ($label === '') { + $label = '(空)'; + } + if ($column === 'result') { + if ($label === 'true') { + $label = '通过'; + } elseif ($label === 'false') { + $label = '拦截'; + } elseif ($label === 'wait') { + $label = '检测中'; + } + } + $rows[] = [ + $labelKey => $label, + 'count' => (int) $r['cnt'], + ]; + } + $res->free(); + } + return $rows; + } + + /** + * @param mysqli $conn + * @param string $where + * @param int $limit + */ + private static function fetchReasonTop($conn, $where, $limit) + { + $limit = (int) $limit; + $sql = "SELECT IFNULL(NULLIF(TRIM(`reason`), ''), '(无理由/通过)') AS reason, COUNT(*) AS cnt + FROM `visitor_logs` WHERE {$where} AND (`result` = 'false' OR `result` = 'wait') + GROUP BY reason ORDER BY cnt DESC LIMIT {$limit}"; + $res = $conn->query($sql); + $rows = []; + $total = 0; + if ($res) { + while ($r = $res->fetch_assoc()) { + $cnt = (int) $r['cnt']; + $total += $cnt; + $rows[] = [ + 'reason' => (string) $r['reason'], + 'count' => $cnt, + ]; + } + $res->free(); + } + foreach ($rows as &$row) { + $row['pct'] = $total > 0 ? round($row['count'] / $total * 100, 1) : 0; + } + unset($row); + return $rows; + } + + /** + * @param mysqli $conn + * @param string $where + */ + private static function fetchByHour($conn, $where) + { + $sql = "SELECT HOUR(`visit_date`) AS hr, COUNT(*) AS cnt + FROM `visitor_logs` WHERE {$where} + GROUP BY hr ORDER BY hr ASC"; + $res = $conn->query($sql); + $map = array_fill(0, 24, 0); + if ($res) { + while ($r = $res->fetch_assoc()) { + $hr = (int) $r['hr']; + if ($hr >= 0 && $hr <= 23) { + $map[$hr] = (int) $r['cnt']; + } + } + $res->free(); + } + $rows = []; + for ($h = 0; $h < 24; $h++) { + $rows[] = ['hour' => sprintf('%02d:00', $h), 'count' => $map[$h]]; + } + return $rows; + } + + /** + * @param mysqli $conn + * @param string $where + * @param int $limit + */ + private static function fetchDeviceTop($conn, $where, $limit) + { + $limit = (int) $limit; + $sql = "SELECT IFNULL(NULLIF(TRIM(`device`), ''), '未知') AS device, COUNT(*) AS cnt + FROM `visitor_logs` WHERE {$where} + GROUP BY device ORDER BY cnt DESC LIMIT {$limit}"; + $res = $conn->query($sql); + $rows = []; + if ($res) { + while ($r = $res->fetch_assoc()) { + $rows[] = [ + 'device' => (string) $r['device'], + 'count' => (int) $r['cnt'], + ]; + } + $res->free(); + } + return $rows; + } + + /** + * @param mysqli $conn + * @param string $where + */ + private static function fetchTimingStats($conn, $where) + { + $sql = "SELECT `judge_timing` FROM `visitor_logs` + WHERE {$where} AND `judge_timing` IS NOT NULL AND `judge_timing` <> '' + ORDER BY `id` DESC LIMIT 500"; + $res = $conn->query($sql); + + $stageTotals = []; + $stageCounts = []; + $totalMsSum = 0; + $totalMsCnt = 0; + + if ($res) { + while ($r = $res->fetch_assoc()) { + $decoded = json_decode((string) ($r['judge_timing'] ?? ''), true); + if (!is_array($decoded)) { + continue; + } + if (isset($decoded['total_ms'])) { + $totalMsSum += (float) $decoded['total_ms']; + $totalMsCnt++; + } + if (!empty($decoded['stages']) && is_array($decoded['stages'])) { + foreach ($decoded['stages'] as $stage) { + if (!is_array($stage)) { + continue; + } + $name = trim((string) ($stage['name'] ?? '')); + if ($name === '') { + continue; + } + $ms = (float) ($stage['ms'] ?? 0); + if (!isset($stageTotals[$name])) { + $stageTotals[$name] = 0; + $stageCounts[$name] = 0; + } + $stageTotals[$name] += $ms; + $stageCounts[$name]++; + } + } + } + $res->free(); + } + + $stages = []; + foreach ($stageTotals as $name => $sum) { + $cnt = max(1, $stageCounts[$name]); + $stages[] = [ + 'stage' => $name, + 'avg_ms' => round($sum / $cnt, 2), + ]; + } + usort($stages, static function ($a, $b) { + return $b['avg_ms'] <=> $a['avg_ms']; + }); + + return [ + 'avg_total_ms' => $totalMsCnt > 0 ? round($totalMsSum / $totalMsCnt, 2) : 0, + 'sample_size' => $totalMsCnt, + 'stages' => $stages, + ]; + } + + /** + * @param mysqli $conn + * @param array $filters + * @param array $currentSummary + */ + private static function fetchCompare($conn, array $filters, array $currentSummary) + { + $dateFrom = trim((string) ($filters['date_from'] ?? '')); + $dateTo = trim((string) ($filters['date_to'] ?? '')); + if ($dateFrom === '' || $dateTo === '') { + $dateTo = date('Y-m-d'); + $dateFrom = date('Y-m-d', strtotime('-6 days')); + } + + $start = strtotime($dateFrom . ' 00:00:00'); + $end = strtotime($dateTo . ' 23:59:59'); + if ($start === false || $end === false || $end < $start) { + return [ + 'prev_total' => 0, + 'pass_rate_delta' => 0, + 'block_rate_delta' => 0, + ]; + } + + $days = max(1, (int) floor(($end - $start) / 86400) + 1); + $prevEnd = date('Y-m-d 23:59:59', $start - 86400); + $prevStart = date('Y-m-d 00:00:00', $start - ($days * 86400)); + + $prevFilters = $filters; + $prevFilters['date_from'] = substr($prevStart, 0, 10); + $prevFilters['date_to'] = substr($prevEnd, 0, 10); + $prevWhere = self::buildWhere($conn, $prevFilters); + $prevSummary = self::fetchSummary($conn, $prevWhere); + + return [ + 'prev_total' => (int) $prevSummary['total'], + 'pass_rate_delta' => round($currentSummary['pass_rate'] - $prevSummary['pass_rate'], 1), + 'block_rate_delta' => round($currentSummary['block_rate'] - $prevSummary['block_rate'], 1), + ]; + } + + /** + * @param array $summary + * @param array $byReason + * @param array $byCountry + * @param array $byHour + * @param array $byDevice + * @param array $timing + * @param array $compare + * @param array $byResult + * @return string[] + */ + private static function buildConclusions(array $summary, array $byReason, array $byCountry, array $byHour, array $byDevice, array $timing, array $compare, array $byResult) + { + $lines = []; + $total = (int) $summary['total']; + + if ($total === 0) { + $lines[] = '所选时间范围内暂无访客日志,请调整筛选条件或确认异步队列已落库。'; + return $lines; + } + + $lines[] = sprintf( + '共记录 %d 次访问,通过率 %.1f%%,拦截率 %.1f%%,检测中占比 %.1f%%。', + $total, + $summary['pass_rate'], + $summary['block_rate'], + $summary['wait_rate'] + ); + + if ($compare['prev_total'] > 0) { + $deltaSign = $compare['pass_rate_delta'] >= 0 ? '上升' : '下降'; + $lines[] = sprintf( + '与上一同等周期(%d 条)相比,通过率%s %.1f 个百分点,拦截率变化 %.1f 个百分点。', + $compare['prev_total'], + $deltaSign, + abs($compare['pass_rate_delta']), + $compare['block_rate_delta'] + ); + } + + if ($byReason !== []) { + $top = $byReason[0]; + $lines[] = sprintf( + '主要拦截/待判定理由为「%s」,占该类记录 %.1f%%(%d 次)。', + $top['reason'], + $top['pct'], + $top['count'] + ); + if (count($byReason) >= 2) { + $second = $byReason[1]; + $lines[] = sprintf('次常见理由:「%s」(%d 次,%.1f%%)。', $second['reason'], $second['count'], $second['pct']); + } + } + + $peakHour = null; + $peakCnt = 0; + foreach ($byHour as $h) { + if ($h['count'] > $peakCnt) { + $peakCnt = $h['count']; + $peakHour = $h['hour']; + } + } + if ($peakHour !== null && $peakCnt > 0) { + $lines[] = sprintf('访问高峰时段为 %s,共 %d 次访问。', $peakHour, $peakCnt); + } + + if ($byCountry !== []) { + $topC = $byCountry[0]; + $countryLabel = $topC['country'] === '(空)' ? '未知国家' : $topC['country']; + $lines[] = sprintf('访客来源以「%s」最多,共 %d 次。', $countryLabel, $topC['count']); + } + + if ($byDevice !== []) { + $lines[] = sprintf('设备分布首位:%s(%d 次)。', $byDevice[0]['device'], $byDevice[0]['count']); + } + + if ($timing['sample_size'] > 0) { + $lines[] = sprintf('判定耗时抽样 %d 条,平均总耗时 %.2f ms。', $timing['sample_size'], $timing['avg_total_ms']); + if (!empty($timing['stages'])) { + $slow = $timing['stages'][0]; + $lines[] = sprintf('最慢阶段为「%s」,平均 %.2f ms。', $slow['stage'], $slow['avg_ms']); + } + } + + if ($summary['block_rate'] > 60) { + $lines[] = '告警:拦截率超过 60%,建议检查 API 配置、黑白名单及广告来源规则是否过严。'; + } + if ($summary['wait_rate'] > 5) { + $lines[] = '告警:检测中(wait)状态占比偏高,可能存在二次风控未完成或 f_check 回调异常。'; + } + + foreach (array_slice($byReason, 0, 3) as $r) { + if ($r['pct'] >= 40 && $total >= 20) { + $lines[] = sprintf('关注:理由「%s」占比达 %.1f%%,建议针对性排查该规则。', $r['reason'], $r['pct']); + break; + } + } + + return $lines; + } +} diff --git a/lib/Cloak/VisitorLogQueue.php b/lib/Cloak/VisitorLogQueue.php new file mode 100644 index 0000000..64c16a5 --- /dev/null +++ b/lib/Cloak/VisitorLogQueue.php @@ -0,0 +1,218 @@ +lPush(self::REDIS_KEY, $payload); + } catch (Throwable $e) { + self::logError('Redis push failed: ' . $e->getMessage()); + } + } + + return self::pushFile($payload); + } + + /** + * @return array + */ + public static function popBatch(int $limit = 100) + { + $limit = max(1, min(500, $limit)); + $jobs = []; + + $redis = self::redisClient(); + if ($redis) { + try { + for ($i = 0; $i < $limit; $i++) { + $raw = $redis->rPop(self::REDIS_KEY); + if ($raw === false || $raw === null) { + break; + } + $decoded = json_decode((string) $raw, true); + if (is_array($decoded)) { + $jobs[] = $decoded; + } + } + if ($jobs !== []) { + return $jobs; + } + } catch (Throwable $e) { + self::logError('Redis pop failed: ' . $e->getMessage()); + } + } + + return self::popFileBatch($limit); + } + + /** + * 请求 shutdown 时轻量 drain(最多 $limit 条) + */ + public static function drain(int $limit = 5) + { + if (!class_exists('VisitorLogWorker', false)) { + require_once __DIR__ . '/VisitorLogWorker.php'; + } + VisitorLogWorker::processBatch($limit); + } + + /** + * @return Redis|null + */ + private static function redisClient() + { + if (self::$redisAvailable === false) { + return null; + } + if (!extension_loaded('redis') || !defined('REDIS_ENABLED') || strtoupper(REDIS_ENABLED) !== 'ON') { + self::$redisAvailable = false; + return null; + } + try { + $r = new Redis(); + $timeout = defined('REDIS_TIMEOUT') ? (float) REDIS_TIMEOUT : 1.0; + if (!@$r->connect(REDIS_HOST, (int) REDIS_PORT, $timeout)) { + self::$redisAvailable = false; + return null; + } + if (defined('REDIS_PASSWORD') && REDIS_PASSWORD !== '') { + $r->auth(REDIS_PASSWORD); + } + self::$redisAvailable = true; + return $r; + } catch (Throwable $e) { + self::$redisAvailable = false; + return null; + } + } + + private static function queueDir() + { + $dir = dirname(__DIR__, 2) . '/storage/' . self::FILE_DIR; + if (!is_dir($dir)) { + @mkdir($dir, 0755, true); + } + return $dir; + } + + private static function pushFile($payload) + { + $dir = self::queueDir(); + $file = $dir . '/pending.ndjson'; + $fp = @fopen($file, 'ab'); + if (!$fp) { + return false; + } + if (flock($fp, LOCK_EX)) { + fwrite($fp, $payload . "\n"); + fflush($fp); + flock($fp, LOCK_UN); + } + fclose($fp); + return true; + } + + /** + * @return array + */ + private static function popFileBatch(int $limit) + { + $dir = self::queueDir(); + $file = $dir . '/pending.ndjson'; + if (!is_file($file)) { + return []; + } + + $fp = @fopen($file, 'c+'); + if (!$fp) { + return []; + } + + $jobs = []; + if (!flock($fp, LOCK_EX)) { + fclose($fp); + return []; + } + + $lines = []; + while (($line = fgets($fp)) !== false) { + $line = trim($line); + if ($line !== '') { + $lines[] = $line; + } + } + + if ($lines === []) { + flock($fp, LOCK_UN); + fclose($fp); + return []; + } + + $take = array_slice($lines, 0, $limit); + $remain = array_slice($lines, $limit); + ftruncate($fp, 0); + rewind($fp); + foreach ($remain as $line) { + fwrite($fp, $line . "\n"); + } + fflush($fp); + flock($fp, LOCK_UN); + fclose($fp); + + foreach ($take as $line) { + $decoded = json_decode($line, true); + if (is_array($decoded)) { + $jobs[] = $decoded; + } + } + + return $jobs; + } + + /** + * @param array $job + * @param string $error + */ + public static function moveToDead(array $job, $error) + { + $dir = self::queueDir() . '/dead'; + if (!is_dir($dir)) { + @mkdir($dir, 0755, true); + } + $job['dead_at'] = date('Y-m-d H:i:s'); + $job['dead_error'] = (string) $error; + $name = $dir . '/' . date('Ymd_His') . '_' . substr(md5(json_encode($job)), 0, 8) . '.json'; + @file_put_contents($name, json_encode($job, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + self::logError('Dead letter: ' . $error); + } + + public static function logError($message) + { + $handle = @fopen(dirname(__DIR__, 2) . '/err.txt', 'a+'); + if ($handle) { + fwrite($handle, date('Y-m-d H:i:s') . ' | VisitorLogQueue | ' . $message . "\n"); + fclose($handle); + } + } +} diff --git a/lib/Cloak/VisitorLogSchema.php b/lib/Cloak/VisitorLogSchema.php new file mode 100755 index 0000000..33a6431 --- /dev/null +++ b/lib/Cloak/VisitorLogSchema.php @@ -0,0 +1,92 @@ + "ALTER TABLE `visitor_logs` ADD COLUMN `user_agent` TEXT NULL COMMENT 'User-Agent 完整值' AFTER `language`", + 'http_referer' => "ALTER TABLE `visitor_logs` ADD COLUMN `http_referer` TEXT NULL COMMENT 'HTTP Referer 完整值' AFTER `user_agent`", + 'accept_language_raw' => "ALTER TABLE `visitor_logs` ADD COLUMN `accept_language_raw` TEXT NULL COMMENT 'Accept-Language 完整值' AFTER `http_referer`", + 'judge_timing' => "ALTER TABLE `visitor_logs` ADD COLUMN `judge_timing` TEXT NULL COMMENT '判定用时 JSON' AFTER `accept_language_raw`", + ]; + foreach ($columns as $name => $ddl) { + if (!self::columnExists($conn, 'visitor_logs', $name)) { + @$conn->query($ddl); + } + } + self::$ensured = true; + } + + /** + * @param mysqli $conn + */ + public static function ensureIndexes($conn) + { + if (self::$indexesEnsured) { + return; + } + $indexes = [ + 'idx_visit_date' => 'ALTER TABLE `visitor_logs` ADD INDEX `idx_visit_date` (`visit_date`)', + 'idx_result' => 'ALTER TABLE `visitor_logs` ADD INDEX `idx_result` (`result`)', + 'idx_domain_date' => 'ALTER TABLE `visitor_logs` ADD INDEX `idx_domain_date` (`domain`, `visit_date`)', + 'idx_country' => 'ALTER TABLE `visitor_logs` ADD INDEX `idx_country` (`country`)', + ]; + foreach ($indexes as $name => $ddl) { + if (!self::indexExists($conn, 'visitor_logs', $name)) { + @$conn->query($ddl); + } + } + self::$indexesEnsured = true; + } + + /** + * @param mysqli $conn + * @param string $table + * @param string $indexName + */ + private static function indexExists($conn, $table, $indexName) + { + $tableEsc = cloak_db_escape($conn, $table); + $indexEsc = cloak_db_escape($conn, $indexName); + $sql = "SHOW INDEX FROM `{$tableEsc}` WHERE Key_name = '{$indexEsc}'"; + if ($res = $conn->query($sql)) { + $exists = $res->num_rows > 0; + $res->free(); + return $exists; + } + return false; + } + + /** + * @param mysqli $conn + * @param string $table + * @param string $column + */ + private static function columnExists($conn, $table, $column) + { + $tableEsc = cloak_db_escape($conn, $table); + $columnEsc = cloak_db_escape($conn, $column); + $sql = "SHOW COLUMNS FROM `{$tableEsc}` LIKE '{$columnEsc}'"; + if ($res = $conn->query($sql)) { + $exists = $res->num_rows > 0; + $res->free(); + return $exists; + } + return false; + } +} diff --git a/lib/Cloak/VisitorLogWorker.php b/lib/Cloak/VisitorLogWorker.php new file mode 100644 index 0000000..a9724c7 --- /dev/null +++ b/lib/Cloak/VisitorLogWorker.php @@ -0,0 +1,226 @@ + $processed, 'failed' => $failed]; + } + + /** + * @param array $job + */ + public static function processJob(array $job) + { + $type = $job['type'] ?? ''; + if ($type === 'insert_full') { + return self::insertFull($job['logs'] ?? []) !== null; + } + if ($type === 'enrich') { + return self::enrich((int) ($job['log_id'] ?? 0), $job['logs'] ?? []); + } + return false; + } + + /** + * @param array $logs + * @return int|null insert_id + */ + public static function insertFull(array $logs) + { + $conn = self::connect(); + if (!$conn) { + return null; + } + VisitorLogSchema::ensureColumns($conn); + VisitorLogSchema::ensureIndexes($conn); + + $data = self::escapeLogs($conn, $logs); + $d = static function ($key) use ($data, $conn) { + return array_key_exists($key, $data) ? $data[$key] : cloak_db_escape($conn, ''); + }; + + $sql = "INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `fp_url`, `device`) VALUES ('" + . $d('campagin_id') . "','" + . $d('visit_md5_code') . "','" + . $d('site_name') . "','" + . ($data['visit_date'] ?? date('Y-m-d H:i:s')) . "','" + . $d('customers_ip') . "','" + . $d('country') . "','" + . $d('result') . "','" + . $d('reason') . "','" + . $d('v_referer') . "','" + . $d('Client') . "','" + . $d('v_Browser') . "','" + . $d('v_PageURL') . "','" + . $d('accept_language') . "','" + . $d('user_agent') . "','" + . $d('http_referer') . "','" + . $d('accept_language_raw') . "','" + . $d('judge_timing') . "','" + . $d('fp_url') . "','" + . $d('device') . "')"; + + if ($conn->query($sql) !== true) { + VisitorLogQueue::logError('insert_full: ' . $conn->error . ' | ' . $sql); + $conn->close(); + return null; + } + $id = (int) $conn->insert_id; + $conn->close(); + return $id > 0 ? $id : null; + } + + /** + * 同步最小 INSERT(二次风控 wait,需立即返回 log_id) + * + * @param array $logs + * @return int|null + */ + public static function insertMinimal(array $logs) + { + $conn = self::connect(); + if (!$conn) { + return null; + } + VisitorLogSchema::ensureColumns($conn); + VisitorLogSchema::ensureIndexes($conn); + + $data = self::escapeLogs($conn, $logs); + $d = static function ($key) use ($data, $conn) { + return array_key_exists($key, $data) ? $data[$key] : cloak_db_escape($conn, ''); + }; + + $sql = "INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `client`, `browser`, `language`, `fp_url`, `device`) VALUES ('" + . $d('campagin_id') . "','" + . $d('visit_md5_code') . "','" + . $d('site_name') . "','" + . date('Y-m-d H:i:s') . "','" + . $d('customers_ip') . "','" + . $d('country') . "','" + . $d('result') . "','" + . $d('reason') . "','" + . $d('Client') . "','" + . $d('v_Browser') . "','" + . $d('accept_language') . "','" + . $d('fp_url') . "','" + . $d('device') . "')"; + + if ($conn->query($sql) !== true) { + VisitorLogQueue::logError('insertMinimal: ' . $conn->error); + $conn->close(); + return null; + } + $id = (int) $conn->insert_id; + $conn->close(); + return $id > 0 ? $id : null; + } + + /** + * @param int $logId + * @param array $logs + */ + public static function enrich($logId, array $logs) + { + if ($logId <= 0) { + return false; + } + $conn = self::connect(); + if (!$conn) { + return false; + } + + $data = self::escapeLogs($conn, $logs); + $sets = []; + $map = [ + 'referer' => 'v_referer', + 'page' => 'v_PageURL', + 'user_agent' => 'user_agent', + 'http_referer' => 'http_referer', + 'accept_language_raw' => 'accept_language_raw', + 'judge_timing' => 'judge_timing', + ]; + foreach ($map as $col => $logKey) { + if (array_key_exists($logKey, $data)) { + $sets[] = "`{$col}`='" . $data[$logKey] . "'"; + } elseif (array_key_exists($col, $data)) { + $sets[] = "`{$col}`='" . $data[$col] . "'"; + } + } + if ($sets === []) { + $conn->close(); + return true; + } + + $sql = 'UPDATE `visitor_logs` SET ' . implode(', ', $sets) . ' WHERE `id`=' . (int) $logId; + $ok = $conn->query($sql) === true; + if (!$ok) { + VisitorLogQueue::logError('enrich: ' . $conn->error); + } + $conn->close(); + return $ok; + } + + /** + * @param mysqli $conn + * @param array $logs + * @return array + */ + private static function escapeLogs($conn, array $logs) + { + $data = []; + foreach ($logs as $key => $value) { + $data[$key] = cloak_db_escape($conn, $value); + } + if (!isset($data['visit_date'])) { + $data['visit_date'] = date('Y-m-d H:i:s'); + } + return $data; + } + + /** + * @return mysqli|null + */ + private static function connect() + { + if (!defined('DB_USERNAME') || !defined('DB_PASSWORD') || !defined('DB_NAME')) { + return null; + } + $conn = @new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); + if ($conn->connect_error) { + VisitorLogQueue::logError('DB connect: ' . $conn->connect_error); + return null; + } + return $conn; + } +} diff --git a/lib/Cloak/VisitorRepository.php b/lib/Cloak/VisitorRepository.php new file mode 100755 index 0000000..99e3a9f --- /dev/null +++ b/lib/Cloak/VisitorRepository.php @@ -0,0 +1,355 @@ +connect_error) { + return []; + } + $out = []; + $sql = 'SELECT ip_address FROM ip_list WHERE group_id = ' . $groupId; + if ($res = $conn->query($sql)) { + while ($row = $res->fetch_assoc()) { + $out[] = $row['ip_address']; + } + $res->free(); + } + $conn->close(); + return $out; + } +} + +if (!function_exists('ip_visitor_matches_list_entry')) { + function ip_visitor_matches_list_entry($visitorIp, $entry) + { + $entry = trim($entry); + if ($entry === '') { + return false; + } + if ($visitorIp === $entry) { + return true; + } + if (mb_substr($entry, -1) === '*') { + return strpos($visitorIp, rtrim($entry, '*')) === 0; + } + return false; + } +} + +if (!function_exists('ip_visitor_in_blacklist_entries')) { + function ip_visitor_in_blacklist_entries($visitorIp, array $entries) + { + foreach ($entries as $buffer) { + if (ip_visitor_matches_list_entry($visitorIp, $buffer)) { + return true; + } + } + return false; + } +} + +if (!function_exists('cloak_visitor_log_request_meta')) { + function cloak_visitor_log_request_meta() + { + return [ + 'user_agent' => get_SERVER_value('HTTP_USER_AGENT'), + 'http_referer' => get_SERVER_value('HTTP_REFERER'), + 'accept_language_raw' => get_SERVER_value('HTTP_ACCEPT_LANGUAGE'), + ]; + } +} + +if (!function_exists('cloak_visitor_log_enrich')) { + function cloak_visitor_log_enrich(array $logs) + { + $meta = cloak_visitor_log_request_meta(); + foreach ($meta as $key => $value) { + if (!array_key_exists($key, $logs) || $logs[$key] === null || $logs[$key] === '') { + $logs[$key] = $value; + } + } + if (empty($logs['judge_timing']) && !empty($GLOBALS['__cloak_judge_timing'])) { + $logs['judge_timing'] = $GLOBALS['__cloak_judge_timing']; + } + return $logs; + } +} + +if (!function_exists('cloak_visitor_log_async_enabled')) { + function cloak_visitor_log_async_enabled() + { + return defined('VISITOR_LOG_ASYNC') && strtoupper(VISITOR_LOG_ASYNC) === 'ON'; + } +} + +if (!function_exists('cloak_visitor_log_register_shutdown_drain')) { + function cloak_visitor_log_register_shutdown_drain() + { + static $registered = false; + if ($registered || !cloak_visitor_log_async_enabled()) { + return; + } + $registered = true; + register_shutdown_function(static function () { + if (function_exists('fastcgi_finish_request')) { + @fastcgi_finish_request(); + } + VisitorLogQueue::drain(5); + }); + } +} + +if (!function_exists('cloak_write_log_db_sync')) { + function cloak_write_log_db_sync($logs) + { + return VisitorLogWorker::insertFull($logs); + } +} + +if (!function_exists('cloak_write_log_db')) { + function cloak_write_log_db($logs) + { + $logs = cloak_visitor_log_enrich($logs); + + if (defined('WRITE_LOG') && WRITE_LOG == '1') { + $my_url = $_SERVER['PHP_SELF'] ?? ''; + $my_file_name = substr($my_url, strrpos($my_url, '/') + 1); + $config_name = str_replace('.php', '', $my_file_name); + $fp = fopen(dirname(__DIR__, 2) . '/jump.txt', 'a+'); + fwrite($fp, date('Y-m-d H:i:s') . ' | 写入数据库 ' . ' | ' . ($_SESSION['check_result'] ?? '') . ' | ' . $config_name . ' | async=' . (cloak_visitor_log_async_enabled() ? '1' : '0') . "\n"); + fclose($fp); + } + + $result = isset($logs['result']) ? (string) $logs['result'] : ''; + + // 二次风控 wait:同步最小 INSERT 获取 log_id,TEXT 字段异步 enrich + if ($result === 'wait') { + $logId = VisitorLogWorker::insertMinimal($logs); + if ($logId === null) { + return cloak_write_log_db_sync($logs); + } + if (cloak_visitor_log_async_enabled()) { + VisitorLogQueue::push([ + 'type' => 'enrich', + 'log_id' => $logId, + 'logs' => $logs, + ]); + } else { + VisitorLogWorker::enrich($logId, $logs); + } + return $logId; + } + + if (!cloak_visitor_log_async_enabled()) { + $conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); + if ($conn->connect_error) { + $error = 'Connection failed: ' . $conn->connect_error; + $handle = fopen(dirname(__DIR__, 2) . '/err.txt', 'a+'); + fwrite($handle, date('Y-m-d H:i:s') . ' | ' . $error . "\n"); + fclose($handle); + return null; + } + VisitorLogSchema::ensureColumns($conn); + $data = []; + foreach ($logs as $key => $value) { + $data[$key] = cloak_db_escape($conn, $value); + } + $d = static function ($key) use ($data, $conn) { + return array_key_exists($key, $data) ? $data[$key] : cloak_db_escape($conn, ''); + }; + $sql = "INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `fp_url`, `device`) VALUES ('" + . $d('campagin_id') . "','" + . $d('visit_md5_code') . "','" + . $d('site_name') . "','" + . date('Y-m-d H:i:s') . "','" + . $d('customers_ip') . "','" + . $d('country') . "','" + . $d('result') . "','" + . $d('reason') . "','" + . $d('v_referer') . "','" + . $d('Client') . "','" + . $d('v_Browser') . "','" + . $d('v_PageURL') . "','" + . $d('accept_language') . "','" + . $d('user_agent') . "','" + . $d('http_referer') . "','" + . $d('accept_language_raw') . "','" + . $d('judge_timing') . "','" + . $d('fp_url') . "','" + . $d('device') . "')"; + if ($conn->query($sql) === true) { + $last_id = $conn->insert_id; + $conn->close(); + return $last_id; + } + $handle = fopen(dirname(__DIR__, 2) . '/err.txt', 'a+'); + fwrite($handle, date('Y-m-d H:i:s') . ' | ' . 'Error: ' . $sql . '
        ' . $conn->error . "\n"); + fclose($handle); + $conn->close(); + return null; + } + + if (!VisitorLogQueue::push(['type' => 'insert_full', 'logs' => $logs])) { + return cloak_write_log_db_sync($logs); + } + cloak_visitor_log_register_shutdown_drain(); + return null; + } +} + +if (!function_exists('write_log_db')) { + function write_log_db($logs) + { + return cloak_write_log_db($logs); + } +} + +if (!function_exists('cloak_howmanytimesbyip')) { + function cloak_howmanytimesbyip($ip) + { + $row = ['total' => 0]; + $conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); + if ($conn->connect_error) { + $handle = fopen(dirname(__DIR__, 2) . '/err.txt', 'a+'); + fwrite($handle, date('Y-m-d H:i:s') . ' | Connection failed: ' . $conn->connect_error . "\n"); + fclose($handle); + return 0; + } + $ipEsc = cloak_db_escape($conn, $ip); + $sql = "SELECT count(*) as `total` FROM `visitor_logs` WHERE `IP`='" . $ipEsc . "'"; + if ($conn->query($sql) == true) { + $result = $conn->query($sql); + $row = $result->fetch_array(); + $conn->close(); + } else { + $handle = fopen(dirname(__DIR__, 2) . '/err.txt', 'a+'); + fwrite($handle, date('Y-m-d H:i:s') . ' | Error: ' . $sql . '
        ' . $conn->error . "\n"); + fclose($handle); + $conn->close(); + return 0; + } + return $row['total']; + } +} + +if (!function_exists('howmanytimesbyip')) { + function howmanytimesbyip($ip) + { + return cloak_howmanytimesbyip($ip); + } +} + +if (!function_exists('cloak_write_black_list')) { + function cloak_write_black_list($ip) + { + if (!defined('BLACKLIST_GROUP_ID') || (int) BLACKLIST_GROUP_ID <= 0) { + return; + } + $gid = (int) BLACKLIST_GROUP_ID; + $conn = @new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); + if ($conn->connect_error) { + return; + } + $stmt = $conn->prepare('INSERT IGNORE INTO ip_list (group_id, ip_address) VALUES (?, ?)'); + if ($stmt) { + $stmt->bind_param('is', $gid, $ip); + $stmt->execute(); + $stmt->close(); + } + $conn->close(); + } +} + +if (!function_exists('write_black_list')) { + function write_black_list($ip) + { + cloak_write_black_list($ip); + } +} + +if (!function_exists('browser_headers')) { + function browser_headers() + { + $headers = []; + foreach ($_SERVER as $name => $value) { + if (preg_match('/^HTTP_/', $name)) { + $name = strtolower(strtr(substr($name, 5), '_', '-')); + $headers[$name] = $value; + } + } + return $headers; + } +} + +if (!function_exists('accept_lang_zh')) { + function accept_lang_zh() + { + if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + return false; + } + $lang = substr((string) $_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 4); + if (preg_match('/zh-c/i', $lang) or preg_match('/zh/i', $lang)) { + return true; + } + return false; + } +} + +if (!function_exists('is_https')) { + function is_https() + { + return cloak_request_is_https(); + } +} diff --git a/lib/CloakAdSourceGuard.php b/lib/CloakAdSourceGuard.php new file mode 100755 index 0000000..073d460 --- /dev/null +++ b/lib/CloakAdSourceGuard.php @@ -0,0 +1,270 @@ + 'utm_source=facebook&utm_medium=paid_social&utm_campaign={{campaign.name}}&utm_content={{ad.name}}&campaign_id={{campaign.id}}&adset_id={{adset.id}}&ad_id={{ad.id}}&site_source={{site_source_name}}&placement={{placement}}', + self::PLATFORM_GOOGLE => 'utm_source=google&utm_medium=cpc&utm_campaign={campaignid}&utm_content={adgroupid}&utm_term={keyword}&ad_id={creative}&network={network}&placement={placement}', + self::PLATFORM_TIKTOK => 'utm_source=tiktok&utm_medium=video_ad&utm_campaign=__CAMPAIGN_ID__&utm_content=__AID__&adgroup_id=__CID__&placement=__PLACEMENT__', + ]; + + private static $multiPlatformParams = [ + self::PLATFORM_FB => 'campaign_id={{campaign.id}}', + self::PLATFORM_GOOGLE => 'utm_campaign={campaignid}', + self::PLATFORM_TIKTOK => 'adgroup_id=__CID__', + ]; + + /** + * @param array $config ad_fb, ad_google, ad_tiktok, ad_strict, ad_spm_id (bool/string) + * @param array $context referer, query, user_agent + * @return array { passed: bool, matched_by: string, reason: string } + */ + public static function evaluate(array $config, array $context) + { + $enabled = self::anyPlatformEnabled($config); + if (!$enabled) { + return ['passed' => true, 'matched_by' => 'guard_disabled', 'reason' => '']; + } + + $query = $context['query'] ?? []; + $referer = strtolower((string) ($context['referer'] ?? '')); + $userAgent = strtolower((string) ($context['user_agent'] ?? '')); + $spmId = trim((string) ($config['ad_spm_id'] ?? '')); + + // 优先级 1:ad_spm_id 强验证 + if ($spmId !== '' && isset($query['ad_spm_id']) && (string) $query['ad_spm_id'] === $spmId) { + return ['passed' => true, 'matched_by' => 'ad_spm_id', 'reason' => '']; + } + + // 优先级 2:clid 或 TikTok 动态宏 + foreach (self::$clidParams as $param) { + if (!empty($query[$param])) { + return ['passed' => true, 'matched_by' => 'clid:' . $param, 'reason' => '']; + } + } + $queryString = self::buildQueryString($query); + foreach (self::$tiktokMacros as $macro) { + if (strpos($queryString, $macro) !== false) { + return ['passed' => true, 'matched_by' => 'tiktok_macro:' . $macro, 'reason' => '']; + } + } + + // 优先级 3:Referer + foreach (self::$refererDomains as $domain) { + if ($referer !== '' && strpos($referer, $domain) !== false) { + return ['passed' => true, 'matched_by' => 'referer:' . $domain, 'reason' => '']; + } + } + + // 优先级 4:User-Agent + foreach (self::$uaPatterns as $pattern) { + if ($userAgent !== '' && strpos($userAgent, $pattern) !== false) { + return ['passed' => true, 'matched_by' => 'ua:' . $pattern, 'reason' => '']; + } + } + + $strict = !empty($config['ad_strict']); + if ($strict) { + return [ + 'passed' => false, + 'matched_by' => 'none', + 'reason' => '来源限制:未命中广告来源验证', + ]; + } + + return [ + 'passed' => false, + 'matched_by' => 'none', + 'reason' => '未确定流量来源', + ]; + } + + /** + * @param array $enabledPlatforms PLATFORM_* 常量列表 + * @param string $spmId + * @return string query 字符串(不含前导 ?) + */ + public static function buildAdLinkQuery(array $enabledPlatforms, $spmId) + { + $spmId = trim((string) $spmId); + if (empty($enabledPlatforms)) { + return $spmId !== '' ? 'ad_spm_id=' . rawurlencode($spmId) : ''; + } + + $parts = []; + if (count($enabledPlatforms) === 1) { + $platform = $enabledPlatforms[0]; + if (isset(self::$fullTemplates[$platform])) { + $parts[] = self::$fullTemplates[$platform]; + } + } else { + foreach ($enabledPlatforms as $platform) { + if (isset(self::$multiPlatformParams[$platform])) { + $parts[] = self::$multiPlatformParams[$platform]; + } + } + } + + if ($spmId !== '') { + $parts[] = 'ad_spm_id=' . rawurlencode($spmId); + } + + return implode('&', $parts); + } + + /** + * 生成 10–12 位随机字母数字 ad_spm_id + */ + public static function generateSpmId() + { + $len = random_int(10, 12); + $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + $max = strlen($chars) - 1; + $id = ''; + for ($i = 0; $i < $len; $i++) { + $id .= $chars[random_int(0, $max)]; + } + return $id; + } + + /** + * @param string $spmId + */ + public static function isValidSpmId($spmId) + { + return (bool) preg_match('/^[A-Za-z0-9]{10,12}$/', (string) $spmId); + } + + /** + * @param array $config + */ + public static function anyPlatformEnabled(array $config) + { + return !empty($config['ad_fb']) + || !empty($config['ad_google']) + || !empty($config['ad_tiktok']); + } + + /** + * 从当前站点配置读取广告来源限制参数 + */ + public static function configFromDefines() + { + return [ + 'ad_fb' => defined('CLOAK_AD_FB') && strtoupper(CLOAK_AD_FB) === 'ON', + 'ad_google' => defined('CLOAK_AD_GOOGLE') && strtoupper(CLOAK_AD_GOOGLE) === 'ON', + 'ad_tiktok' => defined('CLOAK_AD_TIKTOK') && strtoupper(CLOAK_AD_TIKTOK) === 'ON', + 'ad_strict' => defined('CLOAK_AD_STRICT') && strtoupper(CLOAK_AD_STRICT) === 'ON', + 'ad_spm_id' => defined('CLOAK_AD_SPM_ID') ? (string) CLOAK_AD_SPM_ID : '', + ]; + } + + /** + * 合并 Referer query 与 $_GET(与流水线 Guard 一致) + */ + public static function buildMergedRequestQuery(array $get = null) + { + if ($get === null) { + $get = $_GET; + } + $refRaw = isset($_SERVER['HTTP_REFERER']) ? (string) $_SERVER['HTTP_REFERER'] : ''; + $refParts = parse_url($refRaw); + $refQ = []; + if (!empty($refParts['query'])) { + parse_str($refParts['query'], $refQ); + } + return array_merge($refQ, $get); + } + + /** + * 构建 evaluate 用的请求上下文 + */ + public static function buildRequestContext(array $get = null) + { + return [ + 'referer' => isset($_SERVER['HTTP_REFERER']) ? (string) $_SERVER['HTTP_REFERER'] : '', + 'query' => self::buildMergedRequestQuery($get), + 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? (string) $_SERVER['HTTP_USER_AGENT'] : '', + ]; + } + + /** + * 临时链接参数:是否满足开始/续期计时的来源条件 + * 已开启广告来源限制 → 走 4 级优先级规则;未开启 → 兼容旧 clid/ad_spm_id 触发 + */ + public static function shouldStartUrlArgsTimer(array $config, array $context) + { + if (!self::anyPlatformEnabled($config)) { + $query = $context['query'] ?? []; + foreach (array_merge(self::$clidParams, ['ad_spm_id']) as $param) { + if (!empty($query[$param])) { + return true; + } + } + return false; + } + + $result = self::evaluate($config, $context); + return !empty($result['passed']); + } + + /** + * @param array $query + */ + private static function buildQueryString(array $query) + { + if (empty($query)) { + return ''; + } + return http_build_query($query); + } +} diff --git a/lib/CloakDebugPage.php b/lib/CloakDebugPage.php new file mode 100755 index 0000000..675652f --- /dev/null +++ b/lib/CloakDebugPage.php @@ -0,0 +1,626 @@ + $title, + 'status' => $status, + 'detail' => $detail, + 'file' => self::IP_CHECK_FILE, + 'line' => (int)$line, + 'extra' => $extra, + 'at' => microtime(true), + ]; + } + + /** + * 记录 check_result 写入(请从 ip_check.php 使用 cloak_dbg_record(__LINE__, ...) 调用) + */ + public static function record($result, $reason, array $extra = []) + { + $loc = self::callerLoc(); + self::recordAt($loc['line'], $result, $reason, $extra); + } + + /** + * 记录 check_result 写入,指定 ip_check.php 行号 + */ + public static function recordAt($line, $result, $reason, array $extra = []) + { + $stage = isset($extra['stage']) ? (string)$extra['stage'] : 'unknown'; + + $entry = [ + 'result' => $result, + 'reason' => $reason, + 'file' => self::IP_CHECK_FILE, + 'line' => (int)$line, + 'stage' => $stage, + 'extra' => $extra, + 'at' => microtime(true), + ]; + self::$trail[] = $entry; + + $decideDetail = $reason !== '' ? $reason : '(理由为空)'; + if ($result === 'true' || $result === 'false') { + $decideDetail .= ' → check_result=' . $result; + self::$flags['final'] = $entry; + } elseif ($result === null) { + $decideDetail = ($reason !== '' ? $reason : '(理由为空)') . '(未写入 check_result,流程继续)'; + } + + self::$flow[] = [ + 'title' => self::stageTitle($stage), + 'status' => ($result === 'true' || $result === 'false') ? 'decide' : 'warn', + 'detail' => $decideDetail, + 'file' => self::IP_CHECK_FILE, + 'line' => (int)$line, + 'extra' => array_merge($extra, ['check_result' => $result]), + 'at' => microtime(true), + ]; + } + + public static function setApiResponse(array $response) + { + self::$apiResponse = $response; + } + + public static function setFlag($key, $value) + { + self::$flags[$key] = $value; + } + + public static function setExitPoint($line, $label, array $extra = []) + { + self::$exitPoint = [ + 'file' => self::IP_CHECK_FILE, + 'line' => (int)$line, + 'label' => $label, + 'extra' => $extra, + ]; + } + + public static function renderAndExit(array $ctx) + { + $result = (string)($ctx['check_result'] ?? 'false'); + $reason = (string)($ctx['reason'] ?? ''); + $final = self::$flags['final'] ?? null; + $isRealPage = ($result === 'true'); + $elapsed = isset($ctx['started_at']) + ? round((microtime(true) - $ctx['started_at']) * 1000) + : round((microtime(true) - self::$startedAt) * 1000); + + $routeInfo = self::buildRouteInfo($ctx, $result); + $diagnosis = self::buildReasonDiagnosis($reason, $result, $ctx); + $flowHtml = self::buildFlowHtml(); + $trailHtml = self::buildTrailHtml(); + $sessionHtml = self::buildSessionHtml($ctx['session'] ?? []); + + $verdictLabel = $isRealPage ? '真实页 (DB_FP)' : '安全页 (DB_ZP)'; + $verdictClass = $isRealPage ? 'verdict-pass' : 'verdict-block'; + $verdictIcon = $isRealPage ? '✓' : '✕'; + + $finalLoc = $final ? self::formatLoc($final['file'], $final['line']) : '—'; + $finalStage = $final ? htmlspecialchars(self::stageTitle($final['stage'])) : '—'; + $finalReason = $final ? htmlspecialchars($final['reason'] !== '' ? $final['reason'] : '(空)') : '—'; + + $exit = self::$exitPoint; + $exitLoc = $exit ? self::formatLoc($exit['file'], $exit['line']) : self::IP_CHECK_FILE . ':?'; + $exitLabel = $exit ? htmlspecialchars($exit['label']) : 'CloakDebugPage::renderAndExit()'; + + header('Content-Type: text/html; charset=utf-8'); + header('X-Robots-Tag: noindex, nofollow'); + + echo ''; + echo ''; + echo 'Cloak DEBUG — ' . htmlspecialchars($ctx['config_name'] ?? '') . ''; + echo self::styles(); + echo '
        '; + + echo '
        '; + echo '
        DEBUG MODE
        '; + echo '

        流量判定调试报告

        '; + echo '

        配置 ' . htmlspecialchars($ctx['config_name'] ?? '') . ''; + echo ' · 耗时 ' . (int)$elapsed . ' ms · ' . date('Y-m-d H:i:s') . '

        '; + echo '
        '; + + // 流程终止位置(醒目) + echo '
        '; + echo '

        流程终止位置

        '; + echo '
        ' . htmlspecialchars($exitLoc) . '
        '; + echo '

        DEBUG 在此截停执行(' . $exitLabel . '),未继续跳转真实页/安全页。

        '; + echo '
        '; + echo '
        未开启 DEBUG 时下一分支
        ' . htmlspecialchars($routeInfo['next_branch']) . '
        '; + echo '
        预计跳转目标
        ' . htmlspecialchars($routeInfo['dest'] !== '' ? $routeInfo['dest'] : '—') . '
        '; + echo '
        路由条件
        ' . htmlspecialchars($routeInfo['condition']) . '
        '; + echo '
        '; + + echo '
        '; + echo '
        ' . $verdictIcon . '
        '; + echo '
        '; + echo '
        ' . htmlspecialchars($verdictLabel) . '
        '; + echo '
        check_result = ' . htmlspecialchars($result) . '
        '; + echo '
        '; + + // 判断理由 + 空理由诊断 + echo '

        判定结论

        '; + echo '
        当前 $reason
        '; + if ($reason !== '') { + echo htmlspecialchars($reason); + } else { + echo '为空'; + } + echo '
        '; + echo '
        最终写入 check_result
        ' . htmlspecialchars($finalLoc) . '(' . $finalStage . ')
        '; + echo '
        写入时 $reason
        ' . $finalReason . '
        '; + echo '
        '; + if ($diagnosis !== '') { + echo '
        ' . $diagnosis . '
        '; + } + echo '
        '; + + // 完整判断流程 + echo '

        完整判断流程

        '; + echo '

        按 ip_check.php 实际执行顺序展示; 表示写入 check_result, 拦截, 跳过。

        '; + echo $flowHtml !== '' ? $flowHtml : '

        暂无流程记录(请确认 CLOAK_DEBUG_MODE 已保存为 ON)。

        '; + echo '
        '; + + if ($trailHtml !== '') { + echo '

        check_result 写入轨迹

        '; + echo '

        每次对 $_SESSION[\'check_result\'] 的赋值;最后一项为最终判定依据。

        '; + echo $trailHtml . '
        '; + } + + if (self::$apiResponse) { + echo '

        API 判定接口 (cloak_check_curl)

        '; + echo self::buildApiHtml(self::$apiResponse); + echo '
        '; + } + + echo '
        '; + echo '

        Session 状态

        '; + echo $sessionHtml . '
        '; + echo '

        路由预览

        '; + echo '
        SHOW_SITE_MODE
        ' . htmlspecialchars($ctx['mode'] ?? '') . '
        '; + echo '
        visit_to_2
        ' . htmlspecialchars($ctx['session']['visit_to_2'] ?? '—') . ' =2 时跳过 API 块
        '; + echo '
        visit_to_3
        ' . htmlspecialchars($ctx['session']['visit_to_3'] ?? '—') . '
        '; + echo '
        '; + echo '
        '; + + echo '

        访客依据信息

        '; + echo '' . self::buildVisitorRows($ctx) . '
        '; + + echo '

        请求参数

        '; + echo '' . self::buildQueryRows() . '
        '; + + echo '

        配置快照

        '; + echo '' . self::buildConfigRows() . '
        '; + + echo '
        DEBUG 模式 — 生产环境请关闭 CLOAK_DEBUG_MODE
        '; + echo '
        '; + exit; + } + + private static function callerLoc() + { + $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 20); + foreach ($bt as $frame) { + if (empty($frame['file'])) { + continue; + } + if (basename($frame['file']) === self::IP_CHECK_FILE) { + return [ + 'file' => self::IP_CHECK_FILE, + 'line' => (int)($frame['line'] ?? 0), + ]; + } + } + return [ + 'file' => self::IP_CHECK_FILE, + 'line' => 0, + ]; + } + + private static function formatLoc($file, $line) + { + $file = ($file !== '' && $file !== '—') ? $file : self::IP_CHECK_FILE; + if (strpos($file, 'ip_check') !== false) { + $file = self::IP_CHECK_FILE; + } + return $file . ':' . (int)$line; + } + + private static function stageTitle($stage) + { + $map = [ + 'session_fast_path' => 'Session 快速路径', + 'url_args_timeout' => '临时链接参数', + 'blacklist' => '黑名单', + 'whitelist_ip' => 'IP 白名单', + 'whitelist_params' => '链接参数白名单', + 'fingerprint_cookie' => 'JS 指纹 Cookie', + 'api_cloak' => 'API 远程判定', + 'no_referer_or_gcuid' => '无 Referer/gcuid', + 'session_partial' => 'Session 已有结果', + 'main_block_skipped' => '主判定块跳过', + ]; + return isset($map[$stage]) ? $map[$stage] : $stage; + } + + private static function buildRouteInfo(array $ctx, $result) + { + $mode = $ctx['mode'] ?? ''; + $isReal = ($mode !== 'zp') && ((($mode === 'ip_check' && $result !== 'false') || $mode === 'fp')); + $forceRisk = !empty($ctx['force_risk']); + $visit3 = $ctx['session']['visit_to_3'] ?? ''; + + if (!$isReal) { + return [ + 'next_branch' => '安全页分支 (ip_check.php ~859)', + 'dest' => (string)($ctx['zp_url'] ?? ''), + 'condition' => "mode={$mode}, check_result={$result} → false 或 mode=zp", + ]; + } + + if ($forceRisk && $visit3 !== '3') { + return [ + 'next_branch' => '真实页 + 二次风控 (page_666.php / cloakjs)', + 'dest' => self::firstUrl($ctx['fp_urls'] ?? []), + 'condition' => 'check_result!=false 且 CLOAK_RISK_NUMBER>0', + ]; + } + + return [ + 'next_branch' => '真实页 (page_6.php)', + 'dest' => self::firstUrl($ctx['fp_urls'] ?? []), + 'condition' => "mode={$mode}, check_result={$result}", + ]; + } + + private static function buildReasonDiagnosis($reason, $result, array $ctx) + { + if ($reason !== '') { + return ''; + } + + $items = []; + $final = self::$flags['final'] ?? null; + + if (!$final) { + $items[] = '整个流程未记录到任何 check_result 写入点;最终 result 可能来自默认值或未赋值。'; + } elseif ($final['reason'] === '') { + $items[] = '最终写入点 ' . htmlspecialchars(self::formatLoc($final['file'], $final['line'])) . '(' . htmlspecialchars(self::stageTitle($final['stage'])) . ')写入时 $reason 即为空。'; + } + + if (self::$apiResponse) { + $apiReason = self::$apiResponse['reason'] ?? ''; + $apiCalled = !empty(self::$apiResponse['called']); + if ($apiCalled && $apiReason === '') { + $items[] = 'API 接口 cloak_check_curl 已调用,但返回 JSON 中 reason 字段为空(见下方 API 详情)。'; + } elseif (!$apiCalled) { + $items[] = 'API 判定未执行(可能缺少 ip/Browser/Accept-Language,或主判定块被跳过)。'; + } + } + + $visit2 = $ctx['session']['visit_to_2'] ?? ''; + if ($visit2 === '2' && empty(self::$apiResponse['called'])) { + $items[] = '$_SESSION[\'visit_to_2\']=2 导致主判定块(API 调用)被跳过;若同时 check_result 未重建,$reason 会保持初始空字符串。DEBUG 模式已重置 visit_to_*,若仍出现请检查是否在判定前被重新写入。'; + } + + if ($result === 'true') { + $items[] = '生产环境中,进入真实页分支后 ip_check.php:818 会将 $logs[\'reason\'] 清空(注释:访问仿品时没用跳转理由),日志里可能显示空理由,但 DEBUG 截停前应仍能看到写入时的 reason。'; + } + + if (empty($items)) { + $items[] = '$reason 在流程开始时初始化为空字符串,且后续没有任何分支对其赋值。'; + } + + $html = '

        ⚠ $reason 为空 — 溯源分析

          '; + foreach ($items as $item) { + $html .= '
        • ' . $item . '
        • '; + } + $html .= '
        '; + return $html; + } + + private static function buildFlowHtml() + { + if (empty(self::$flow)) { + return ''; + } + $html = '
        '; + $final = self::$flags['final'] ?? null; + foreach (self::$flow as $i => $s) { + $isFinal = $final + && isset($s['extra']['check_result']) + && ($s['extra']['check_result'] === 'true' || $s['extra']['check_result'] === 'false') + && $final['line'] === $s['line'] + && $final['stage'] === ($s['extra']['stage'] ?? ''); + $cls = 'flow-step status-' . htmlspecialchars($s['status']); + if ($isFinal) { + $cls .= ' flow-final'; + } + $html .= '
        '; + $html .= '
        ' . ($i + 1) . '
        '; + $html .= '
        '; + $html .= '
        '; + $html .= '' . htmlspecialchars($s['title']) . ''; + $html .= '' . htmlspecialchars(self::statusLabel($s['status'])) . ''; + $html .= '' . htmlspecialchars(self::formatLoc($s['file'], $s['line'])) . ''; + $html .= '
        '; + if ($s['detail'] !== '') { + $html .= '
        ' . htmlspecialchars($s['detail']) . '
        '; + } + if (!empty($s['extra'])) { + $show = $s['extra']; + unset($show['stage'], $show['check_result']); + if (!empty($show)) { + $html .= '
        ' . htmlspecialchars(json_encode($show, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) . '
        '; + } + } + $html .= '
        '; + } + $html .= '
        '; + return $html; + } + + private static function statusLabel($status) + { + $map = [ + 'pass' => '通过', 'fail' => '拦截', 'skip' => '跳过', + 'warn' => '可疑', 'info' => '信息', 'decide' => '写入结果', + ]; + return isset($map[$status]) ? $map[$status] : $status; + } + + private static function buildTrailHtml() + { + if (empty(self::$trail)) { + return ''; + } + $html = '
        '; + $final = self::$flags['final'] ?? null; + foreach (self::$trail as $e) { + $isFinal = $final && $final['line'] === $e['line'] && $final['stage'] === $e['stage']; + $cls = $isFinal ? ' trail-item final' : ' trail-item'; + $res = $e['result'] !== null ? $e['result'] : '—'; + $html .= '
        '; + $html .= '
        '; + $html .= '' . htmlspecialchars(self::formatLoc($e['file'], $e['line'])) . ''; + $html .= '' . htmlspecialchars(self::stageTitle($e['stage'])) . ''; + if ($e['result'] !== null) { + $html .= '' . htmlspecialchars((string)$res) . ''; + } + $html .= '
        '; + $html .= '
        ' . htmlspecialchars($e['reason'] !== '' ? $e['reason'] : '(理由为空)') . '
        '; + $html .= '
        '; + } + $html .= '
        '; + return $html; + } + + private static function buildApiHtml(array $api) + { + $html = '
        '; + $html .= '
        是否调用
        ' . (!empty($api['called']) ? '是' : '否') . '
        '; + if (!empty($api['skip_reason'])) { + $html .= '
        未调用原因
        ' . htmlspecialchars($api['skip_reason']) . '
        '; + } + $html .= '
        API result
        ' . htmlspecialchars((string)($api['result_raw'] ?? $api['check_result'] ?? '—')) . '
        '; + $html .= '
        API reason
        ' . htmlspecialchars((string)($api['reason'] ?? '—')) . '
        '; + $html .= '
        API country
        ' . htmlspecialchars((string)($api['country'] ?? '—')) . '
        '; + if (!empty($api['curl_error'])) { + $html .= '
        Curl 错误
        ' . htmlspecialchars($api['curl_error']) . '
        '; + } + if (!empty($api['raw'])) { + $html .= '
        原始响应
        ' . htmlspecialchars(is_string($api['raw']) ? $api['raw'] : json_encode($api['raw'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) . '
        '; + } + $html .= '
        '; + return $html; + } + + private static function buildSessionHtml(array $session) + { + if (empty($session)) { + return '

        无 Session 快照

        '; + } + $html = ''; + foreach ($session as $k => $v) { + $html .= ''; + } + $html .= '
        ' . htmlspecialchars((string)$k) . '' . htmlspecialchars(is_scalar($v) ? (string)$v : json_encode($v, JSON_UNESCAPED_UNICODE)) . '
        '; + return $html; + } + + private static function buildVisitorRows(array $ctx) + { + $v = $ctx['visitor'] ?? null; + $rows = [ + 'IP 地址' => $v ? $v->v_ip : ($ctx['logs']['customers_ip'] ?? ''), + '国家/地区' => $v ? $v->v_country : '', + '浏览器' => $v ? $v->v_Browser : ($ctx['logs']['v_Browser'] ?? ''), + '客户端类型' => $v ? $v->v_Client : ($ctx['logs']['Client'] ?? ''), + 'Referer' => $v ? $v->v_referer : ($ctx['logs']['v_referer'] ?? ''), + '当前 URL' => $v ? $v->v_curPageURL : ($ctx['logs']['v_PageURL'] ?? ''), + 'Accept-Language' => $v ? $v->accept_language : ($ctx['logs']['accept_language'] ?? ''), + 'User-Agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '', + 'visit_md5' => $v ? $v->visit_md5_code : ($ctx['logs']['visit_md5_code'] ?? ''), + '设备型号' => $ctx['device'] ?? '', + 'gcuid' => $_SESSION['gcuid'] ?? '', + ]; + return self::rowsHtml($rows); + } + + private static function buildQueryRows() + { + $keys = ['fbclid', 'gclid', 'wbraid', 'gbraid', 'ttclid', 'ad_spm_id']; + $rows = []; + foreach ($keys as $k) { + $rows[$k] = isset($_GET[$k]) ? $_GET[$k] : '(未携带)'; + } + return self::rowsHtml($rows); + } + + private static function buildConfigRows() + { + $map = [ + 'SHOW_SITE_MODE_SWITCH' => defined('SHOW_SITE_MODE_SWITCH') ? SHOW_SITE_MODE_SWITCH : '', + 'SHOW_SITE_COUNTRY' => defined('SHOW_SITE_COUNTRY') ? SHOW_SITE_COUNTRY : '', + 'CLOAK_DEBUG_MODE' => defined('CLOAK_DEBUG_MODE') ? CLOAK_DEBUG_MODE : '', + 'CLOAK_RISK_NUMBER' => defined('CLOAK_RISK_NUMBER') ? CLOAK_RISK_NUMBER : '', + 'CLOAK_RISK_ENHANCED' => defined('CLOAK_RISK_ENHANCED') ? CLOAK_RISK_ENHANCED : '', + 'CLOAK_URL_ARGS_TIMEOUT' => defined('CLOAK_URL_ARGS_TIMEOUT') ? CLOAK_URL_ARGS_TIMEOUT : '', + ]; + return self::rowsHtml($map); + } + + private static function rowsHtml(array $rows) + { + $html = ''; + foreach ($rows as $label => $val) { + $html .= '' . htmlspecialchars((string)$label) . '' . htmlspecialchars((string)$val) . ''; + } + return $html; + } + + private static function firstUrl($urls) + { + if (is_array($urls) && !empty($urls)) { + return (string)$urls[0]; + } + return is_string($urls) ? $urls : ''; + } + + private static function styles() + { + return <<<'CSS' + +CSS; + } +} diff --git a/lib/CloakHttpHelpers.php b/lib/CloakHttpHelpers.php new file mode 100755 index 0000000..bd762c5 --- /dev/null +++ b/lib/CloakHttpHelpers.php @@ -0,0 +1,255 @@ + $value) { + try { + $transmit_string .= "$name=$value; "; + } catch (Exception $e) { + continue; + } + } + return $transmit_string; + } +} + +if (!function_exists('encode_visitor_cookies')) { + function encode_visitor_cookies() + { + return cloak_encode_visitor_cookies(); + } +} + +if (!function_exists('cloak_forward_response_cookies')) { + function cloak_forward_response_cookies($ch, $headerLine) + { + if (preg_match('/^Set-Cookie:/mi', $headerLine, $cookie)) { + header($headerLine, false); + } + return strlen($headerLine); + } +} + +if (!function_exists('forward_response_cookies')) { + function forward_response_cookies($ch, $headerLine) + { + return cloak_forward_response_cookies($ch, $headerLine); + } +} + +if (!function_exists('cloak_write_nt_list')) { + function cloak_write_nt_list($cong_name, $nt, $ot) + { + $cong_name = parse_url($cong_name, PHP_URL_PATH); + $content = $cong_name . '||||||' . $nt . "\n"; + $file = 'nt.txt'; + + if ($ot) { + $handle = @fopen($file, 'r+'); + $search = '/' . $cong_name . '\|\|\|\|\|\|' . $ot . '/'; + $found = false; + $tempContent = ''; + + while (!feof($handle)) { + $line = fgets($handle); + if (preg_match($search, $line)) { + $tempContent .= $content; + $found = true; + } else { + $tempContent .= $line; + } + } + + if ($found && flock($handle, LOCK_EX)) { + file_put_contents($file, $tempContent); + flock($handle, LOCK_UN); + } + fclose($handle); + } else { + $handle = @fopen($file, 'a'); + if ($handle && flock($handle, LOCK_EX)) { + fwrite($handle, $content); + flock($handle, LOCK_UN); + } + if ($handle) { + fclose($handle); + } + } + } +} + +if (!function_exists('write_nt_list')) { + function write_nt_list($cong_name, $nt, $ot) + { + cloak_write_nt_list($cong_name, $nt, $ot); + } +} + +if (!function_exists('cloak_fingerprint_cookie_domain')) { + /** + * 指纹 Cookie 使用的跨子域 domain(与 setCrossDomainCookie 一致) + */ + function cloak_fingerprint_cookie_domain() + { + if (empty($_SERVER['HTTP_HOST'])) { + return ''; + } + + $host_names = explode('.', $_SERVER['HTTP_HOST']); + if (count($host_names) < 2) { + return ''; + } + + return '.' . $host_names[count($host_names) - 2] . '.' . $host_names[count($host_names) - 1]; + } +} + +if (!function_exists('cloak_set_cross_domain_cookie')) { + function cloak_set_cross_domain_cookie($name, $value, $expire) + { + $bottom_host_name = cloak_fingerprint_cookie_domain(); + if ($bottom_host_name === '') { + setcookie($name, $value, $expire, '/'); + return; + } + setcookie($name, $value, $expire, '/', $bottom_host_name); + } +} + +if (!function_exists('setCrossDomainCookie')) { + function setCrossDomainCookie($name, $value, $expire) + { + cloak_set_cross_domain_cookie($name, $value, $expire); + } +} + +if (!function_exists('cloak_fingerprint_time_param_present')) { + /** + * URL 是否已带 time 参数(表示前端指纹页已执行过一次跳转) + */ + function cloak_fingerprint_time_param_present() + { + return isset($_GET['time']) && (string) $_GET['time'] !== ''; + } +} + +if (!function_exists('cloak_fingerprint_cookies_ready')) { + /** + * 前端指纹 Cookie 是否已写入 + */ + function cloak_fingerprint_cookies_ready() + { + return isset($_COOKIE['ctime'], $_COOKIE['cyyek'], $_COOKIE['cl']); + } +} + +if (!function_exists('cloak_fingerprint_mmr_reason')) { + /** + * 根据 mmr Cookie 返回中文拒绝理由 + */ + function cloak_fingerprint_mmr_reason() + { + if (!isset($_COOKIE['mmr'])) { + return '指纹检测未通过(未知原因)'; + } + + $mmrMap = [ + 1 => '语言包含中文', + 2 => 'PC端客户不允许访问', + 3 => '操作系统非IOS或者安卓', + 4 => 'IPHONE 机型不符合要求', + 11 => '非IPHONE机型', + 12 => '自动化/WebDriver', + 13 => '模拟器或虚拟机UA', + 14 => '爬虫Bot UA', + 15 => 'WebGL软件渲染', + 16 => '环境不一致(平台/触摸/窗口)', + 17 => '移动GPU与UA不符', + 18 => '移动端无有效加速度计/陀螺仪', + ]; + + $mmr = (int) $_COOKIE['mmr']; + + return $mmrMap[$mmr] ?? '指纹检测未通过(未知原因)'; + } +} diff --git a/lib/CloakPhpCompat.php b/lib/CloakPhpCompat.php new file mode 100755 index 0000000..7b279f7 --- /dev/null +++ b/lib/CloakPhpCompat.php @@ -0,0 +1,139 @@ += ' . self::MIN_PHP_VERSION . ',当前 ' . PHP_VERSION . ')'; + } + + foreach (self::REQUIRED_EXTENSIONS as $ext) { + if (!extension_loaded($ext)) { + $errors[] = '缺少必需扩展:' . $ext; + } + } + + foreach (self::RECOMMENDED_EXTENSIONS as $ext) { + if (!extension_loaded($ext)) { + $warnings[] = '缺少推荐扩展:' . $ext . '(部分功能将降级)'; + } + } + + return [ + 'ok' => empty($errors), + 'php_version' => PHP_VERSION, + 'errors' => $errors, + 'warnings' => $warnings, + 'extensions' => array_values(array_filter( + array_merge(self::REQUIRED_EXTENSIONS, self::RECOMMENDED_EXTENSIONS), + 'extension_loaded' + )), + ]; + } + + /** + * 对项目 PHP 文件执行 php -l(仅 CLI) + * + * @param string|null $root 项目根目录 + * @return array{ok:bool,failures:array} + */ + public static function lintProject($root = null) + { + $root = $root ?: dirname(__DIR__); + $failures = []; + + if (PHP_SAPI !== 'cli') { + return ['ok' => true, 'failures' => [], 'skipped' => 'not_cli']; + } + + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS) + ); + + $skipDirs = ['vendor', 'node_modules', '.git']; + + foreach ($iterator as $file) { + /** @var SplFileInfo $file */ + if (!$file->isFile() || $file->getExtension() !== 'php') { + continue; + } + $path = $file->getPathname(); + foreach ($skipDirs as $skip) { + if (strpos($path, DIRECTORY_SEPARATOR . $skip . DIRECTORY_SEPARATOR) !== false) { + continue 2; + } + } + + $cmd = escapeshellarg(PHP_BINARY) . ' -l ' . escapeshellarg($path) . ' 2>&1'; + $out = []; + exec($cmd, $out, $code); + if ($code !== 0) { + $failures[] = $path . ': ' . implode(' ', $out); + } + } + + return ['ok' => empty($failures), 'failures' => $failures]; + } +} diff --git a/lib/DbHelper.php b/lib/DbHelper.php new file mode 100755 index 0000000..5358197 --- /dev/null +++ b/lib/DbHelper.php @@ -0,0 +1,70 @@ + 'wait')"; + } +} diff --git a/lib/InstallSchema.php b/lib/InstallSchema.php new file mode 100755 index 0000000..c154bbf --- /dev/null +++ b/lib/InstallSchema.php @@ -0,0 +1,100 @@ +set_charset('utf8mb4')) { + return ['ok' => false, 'error' => '设置字符集 utf8mb4 失败:' . $conn->error]; + } + + foreach (self::statements() as $sql) { + if (!$conn->query($sql)) { + return [ + 'ok' => false, + 'error' => $conn->error, + ]; + } + } + + return [ + 'ok' => true, + 'tables' => ['ip_groups', 'ip_list', 'cloak_site_domains', 'visitor_logs'], + ]; + } +} diff --git a/lib/bootstrap.php b/lib/bootstrap.php new file mode 100755 index 0000000..e9e13a0 --- /dev/null +++ b/lib/bootstrap.php @@ -0,0 +1,25 @@ +alert('密码错误!');window.location='ip_check_edit.php'; "); + exit; +} + +$defaultFrom = date('Y-m-d', strtotime('-6 days')); +$defaultTo = date('Y-m-d'); +?> + + + + + 日志数据分析 + + + + + + +
        +
        +
        +

        日志数据分析

        +

        判定结果、理由、国家与时序分布 · 自动分析结论

        +
        + +
        + +
        数据来源于 visitor_logs 表;若已开启异步写入,日志可能有短暂延迟(取决于队列 Worker 落库进度)。
        + +
        +
        +
        +
        + +
        +
        + +
        +
        + +
        +
        + +
        +
        + +
        +
        +
        +
        + +
        +
        加载中…
        +
        +
        + + + + + diff --git a/mdetect.php b/mdetect.php new file mode 100755 index 0000000..47f3e04 --- /dev/null +++ b/mdetect.php @@ -0,0 +1,27 @@ +isMobile() ? ($detect->isTablet() ? 'tablet' : 'phone') : 'computer'); + +if($deviceType == 'tablet') { + $patterns = $detect::getTabletDevices(); +} elseif($deviceType == 'phone') { + $patterns = $detect::getPhoneDevices(); + +} elseif($deviceType == 'computer') { + $patterns = ""; + $model = "PC"; +} + +if($patterns) { + foreach ($patterns as $brand => $pattern) { + if (preg_match('/' . $pattern . '/i', $_SERVER['HTTP_USER_AGENT'], $matches)) { + $model = $brand . ' ' . $matches[1]; + break; + } + } +} + +echo $model; \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100755 index 0000000..3e98d01 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,12 @@ +location / { + try_files $uri $uri/ @extensionless-php; + index index.html index.htm index.php; +} + +location ~ \.php$ { + try_files $uri =404; +} + +location @extensionless-php { + rewrite ^(.*)$ $1.php last; +} \ No newline at end of file diff --git a/nt.txt b/nt.txt new file mode 100755 index 0000000..e322325 --- /dev/null +++ b/nt.txt @@ -0,0 +1,9 @@ +||||||2 +||||||2 +||||||2 +vip||||||3 +||||||2 +||||||2 +||||||2 +tandard input code||||||2 +index||||||2 diff --git a/page_6.php b/page_6.php new file mode 100755 index 0000000..95b0196 --- /dev/null +++ b/page_6.php @@ -0,0 +1,100 @@ + $param_value) { + // } + $urlParts = parse_url($fp_url); + if(isset($urlParts['query'])) { + $fp_url .= "&" . $params; + } else { + $fp_url .= "?" . $params; + } + } + } + $logs['fp_url'] = $fp_url; + write_log_db($logs); + + $show_content = CLOAK_SHOW_CONTENT; + if($show_content == 'curl') { + $html = file_get_content_sstr($fp_url); + + $_html = caiji_lujing_buquan_fp($html, $fp_url, $_SERVER['HTTP_HOST']); + + echo $_html; + exit; + } elseif($show_content == '302') { + header('location:' . $fp_url . '');exit; + } elseif($show_content == 'js') { +?> + + \ No newline at end of file diff --git a/page_666.php b/page_666.php new file mode 100755 index 0000000..d267e7d --- /dev/null +++ b/page_666.php @@ -0,0 +1,148 @@ + + + + + + Powered By Google + + + + + + \ No newline at end of file diff --git a/resources/cloakjs_enhanced.inc.php b/resources/cloakjs_enhanced.inc.php new file mode 100755 index 0000000..401e945 --- /dev/null +++ b/resources/cloakjs_enhanced.inc.php @@ -0,0 +1,317 @@ + + + diff --git a/resources/fingerprint_redirect.html.php b/resources/fingerprint_redirect.html.php new file mode 100755 index 0000000..a2b22ac --- /dev/null +++ b/resources/fingerprint_redirect.html.php @@ -0,0 +1,42 @@ + + + + + + + + + diff --git a/resources/virtual_device_detect.inc.php b/resources/virtual_device_detect.inc.php new file mode 100644 index 0000000..72fbaff --- /dev/null +++ b/resources/virtual_device_detect.inc.php @@ -0,0 +1,242 @@ + + diff --git a/share/cbwzs4usE6a8yawoq0y.php b/share/cbwzs4usE6a8yawoq0y.php new file mode 100755 index 0000000..d3798b2 --- /dev/null +++ b/share/cbwzs4usE6a8yawoq0y.php @@ -0,0 +1,163 @@ + + + + + + + 访问判断日志 + + + + + + + + +
        +
        +
        +
        +
        + +
        + +
        +
        +
        +
        + +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        + +
        +
        +
        + + + 当前查询数量: +
        +
        +
        + +
        +
        + +
        + + + + + + \ No newline at end of file diff --git a/share_log.php b/share_log.php new file mode 100755 index 0000000..1507ca6 --- /dev/null +++ b/share_log.php @@ -0,0 +1,28 @@ + + + + + + + 访问判断日志 + + + + + + + + +
        +
        +
        +
        +
        + +
        + +
        +
        +
        +
        + +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        + +
        +
        +
        + + + 当前查询数量: +
        +
        +
        + + +
        +
        + +
        + + + + + + \ No newline at end of file diff --git a/storage/visitor_log_queue/.gitkeep b/storage/visitor_log_queue/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/storage/visitor_log_queue/pending.ndjson b/storage/visitor_log_queue/pending.ndjson new file mode 100644 index 0000000..e69de29 diff --git a/table.php b/table.php new file mode 100755 index 0000000..c8d0635 --- /dev/null +++ b/table.php @@ -0,0 +1,477 @@ +alert('密码错误!');window.location='ip_check_edit.php'; "); + //die("输入的密码不正确,请重新输入。"); +} + +?> + + + + + + 访问判断日志 + + + + + + + + +
        +
        +
        +

        访问判断日志

        +

        访客判定记录 · 支持筛选、导出与分页浏览

        +
        + +
        + +
        +
        +
        +
        +
        +
        + +
        + +
        +
        +
        +
        + +
        +
        +
        +
        + +
        +
        +
        +
        + +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        + +
        +
        +
        + 导出 + + +
        +
        +
        +
        + + + + 当前查询数量: +
        +
        + +
        +
        + +
        +
        + + + + + + diff --git a/tem_link.php b/tem_link.php new file mode 100755 index 0000000..0c861a7 --- /dev/null +++ b/tem_link.php @@ -0,0 +1,4 @@ + 0,302 避免 curl 采集外网) + */ +define('SHOW_SITE_MODE_SWITCH', 'ip_check'); +define('SHOW_SITE_IP', ''); +define('BLACKLIST_GROUP_ID', 0); +define('WHITELIST_GROUP_ID', 0); +define('SHOW_SITE_COUNTRY', 'US'); +define('CLOAK_SHOW_CONTENT', '302'); +define('DB_FP', ['https://example.com/fp']); +define('COSTM_IP_SCORE', 'test'); +define('BLACK_LIST', '0'); +define('AUTO_BLACK', 'OFF'); +define('IS_VIRTUAL', '0'); +define('AUTO_BLACK_TIMES', '5'); +define('WHITE_PARAMS', ''); +define('IPHONE_MODEL', 0); +define('SHOW_SITE_MOBILE', 0); +define('SHOW_SITE_OUTPUT', 1); +define('WRITE_LOG', 0); +define('CLOAK_ZH_ON', 'OFF'); +define('CLOAK_OS_ON', 'OFF'); +define('KEEP_PARAMS', 'OFF'); +define('CLOAK_REDIRECT_METHOD', '302'); +define('DB_ZP', 'https://example.com/zp'); +define('CLOAK_MOBILE_ON', 'OFF'); +define('CLOAK_V_REFERER', 'OFF'); +define('CLOAK_RISK_NUMBER', '51'); +define('CLOAK_RISK_ENHANCED', 'OFF'); +define('CLOAK_URL_ARGS_TIMEOUT', '0'); +define('CLOAK_DEBUG_MODE', 'OFF'); diff --git a/tools/fixtures/regression_zp.php b/tools/fixtures/regression_zp.php new file mode 100755 index 0000000..38a9661 --- /dev/null +++ b/tools/fixtures/regression_zp.php @@ -0,0 +1,30 @@ += ' . CloakPhpCompat::MIN_PHP_VERSION, $compat['ok'], implode('; ', $compat['errors'])); +foreach ($compat['warnings'] as $w) { + if ($verbose) { + echo " ! WARN: {$w}\n"; + } +} + +// ── 2. 语法检查 ─────────────────────────────────────────────── +echo "[2] 全项目 php -l\n"; +$lint = CloakPhpCompat::lintProject($root); +reg_assert('所有 PHP 文件语法正确', $lint['ok'], implode("\n ", array_slice($lint['failures'], 0, 5))); + +// ── 3. Bootstrap 链 ─────────────────────────────────────────── +echo "[3] 引导与配置\n"; +require_once $root . '/cong.php'; +require_once $root . '/config/ConfigLoader.php'; +require_once $root . '/lib/bootstrap.php'; + +ConfigLoader::loadByName('index', $root); +reg_assert('ConfigLoader 可加载 index 配置', defined('SHOW_SITE_MODE_SWITCH')); + +reg_assert('bootstrap 已加载 CheckPipeline', class_exists('CheckPipeline', false)); + +// ── 4. ConfigWriter 输出 ────────────────────────────────────── +echo "[4] 后台 ConfigWriter\n"; +require_once $root . '/admin/ConfigWriter.php'; +$sample = ConfigWriter::buildDefineSource('index.php', [ + 'methods' => 'ip_check', 'blacklist_group_id' => 0, 'whitelist_group_id' => 0, + 'country' => 'US', 'show_content' => '302', 'DB_fp' => ['https://x.com/'], + 'costm_ip_score' => 'test', 'auto_black' => 'OFF', 'is_virtual' => '0', + 'auto_black_times' => '5', 'white_params' => '', 'iphone_model' => 0, + 'write_log' => 0, 'zh_on' => 'OFF', 'os_on' => 'OFF', 'keep_params' => 'OFF', + 'redirect_method' => '302', 'DB_zp' => 'https://z.com', 'mobile_on' => 'OFF', + 'v_referer' => 'OFF', 'risk_number' => '0', 'risk_enhanced' => 'OFF', 'url_args_timeout' => '0', + 'debug_mode' => 'OFF', + 'ad_fb' => 'OFF', 'ad_google' => 'OFF', 'ad_tiktok' => 'OFF', 'ad_strict' => 'OFF', 'ad_spm_id' => '', +]); +$tmpCfg = sys_get_temp_dir() . '/cloak_reg_cfg_' . getmypid() . '.php'; +file_put_contents($tmpCfg, $sample); +exec(escapeshellarg(PHP_BINARY) . ' -l ' . escapeshellarg($tmpCfg) . ' 2>&1', $lintOut, $lintCode); +@unlink($tmpCfg); +reg_assert('ConfigWriter 生成合法 PHP', $lintCode === 0, implode(' ', $lintOut)); +reg_assert('ConfigWriter 含 deprecated SHOW_SITE_MOBILE', strpos($sample, 'SHOW_SITE_MOBILE') !== false); +reg_assert('ConfigWriter 含 CLOAK_RISK_ENHANCED', strpos($sample, 'CLOAK_RISK_ENHANCED') !== false); +reg_assert('ConfigWriter 含 CLOAK_AD_FB', strpos($sample, 'CLOAK_AD_FB') !== false); +reg_assert('ConfigWriter 含 CLOAK_AD_SPM_ID', strpos($sample, 'CLOAK_AD_SPM_ID') !== false); + +$adGuardOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_ad_source_guard.php') . ' 2>/dev/null'); +$adGuardJson = json_decode((string) $adGuardOut, true); +reg_assert('广告来源 Guard 验证', ($adGuardJson['ok'] ?? false) === true, (string) $adGuardOut); + +$timerOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_pipeline_timer.php') . ' 2>/dev/null'); +$timerJson = json_decode((string) $timerOut, true); +reg_assert('PipelineTimer 验证', ($timerJson['ok'] ?? false) === true, (string) $timerOut); + +$realVisitorOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_session_real_visitor.php') . ' 2>/dev/null'); +$realVisitorJson = json_decode((string) $realVisitorOut, true); +reg_assert('真实访客 Session 缓存', ($realVisitorJson['ok'] ?? false) === true, (string) $realVisitorOut); + +$reqUrlOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_request_url.php') . ' 2>/dev/null'); +$reqUrlJson = json_decode((string) $reqUrlOut, true); +reg_assert('请求 URL 辅助函数', ($reqUrlJson['ok'] ?? false) === true, (string) $reqUrlOut); + +// ── 5. CheckPipeline 三种模式 ───────────────────────────────── +echo "[5] CheckPipeline 模式\n"; + +function run_pipeline_subprocess($root, $fixtureName) +{ + $fixture = $root . '/tools/fixtures/' . $fixtureName; + $cmd = escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/run_pipeline_fixture.php') + . ' ' . escapeshellarg($fixture) . ' 2>&1'; + exec($cmd, $out, $code); + $json = json_decode(implode("\n", $out), true); + return is_array($json) ? $json : ['error' => implode("\n", $out), 'code' => $code]; +} + +$ipResult = run_pipeline_subprocess($root, 'regression_ip_check.php'); +reg_assert('ip_check + fbclid 产生 check_result', ($ipResult['result'] ?? null) !== null, json_encode($ipResult, JSON_UNESCAPED_UNICODE)); +reg_assert('ip_check 无意外 HTML 输出', (int) ($ipResult['output_len'] ?? -1) === 0); + +$fpResult = run_pipeline_subprocess($root, 'regression_fp.php'); +reg_assert('fp 模式配置生效', ($fpResult['mode'] ?? '') === 'fp', json_encode($fpResult, JSON_UNESCAPED_UNICODE)); + +$zpResult = run_pipeline_subprocess($root, 'regression_zp.php'); +reg_assert('zp 模式配置生效', ($zpResult['mode'] ?? '') === 'zp', json_encode($zpResult, JSON_UNESCAPED_UNICODE)); + +// ── 7. 指纹跳转模板 ─────────────────────────────────────────── +echo "[7] 指纹跳转模板\n"; +require_once $root . '/lib/Cloak/Page/FingerprintRedirectRenderer.php'; +$tpl = $root . '/resources/fingerprint_redirect.html.php'; +reg_assert('指纹模板文件存在', is_readable($tpl)); +$tplBody = file_get_contents($tpl); +reg_assert('模板含 CONFIG_NAME 占位符', strpos($tplBody, '{{CONFIG_NAME}}') !== false); +reg_assert('模板 time 参数存在时停止重定向', strpos($tplBody, "urlParams.has('time')") !== false && strpos($tplBody, 'return;') !== false); +reg_assert('模板在加载 dist 前注册回调', strpos($tplBody, '__cloakFingerprintDone') !== false && strpos($tplBody, '') !== false); + +require_once $root . '/lib/CloakHttpHelpers.php'; +$_GET = ['time' => '1234567890']; +reg_assert('cloak_fingerprint_time_param_present', cloak_fingerprint_time_param_present()); +$_GET = []; +$_COOKIE = ['ctime' => '1', 'cyyek' => 'x', 'cl' => 'oklot']; +reg_assert('cloak_fingerprint_cookies_ready', cloak_fingerprint_cookies_ready()); + +$_SERVER['HTTP_HOST'] = 'shop.example.com'; +reg_assert('cloak_fingerprint_cookie_domain', cloak_fingerprint_cookie_domain() === '.example.com'); + +$_GET = ['c' => 'index']; +ob_start(); +include $root . '/dist/index.php'; +$distJs = ob_get_clean(); +reg_assert('dist/index.php 输出 Cookies.set', strpos($distJs, "fpCookies.set('ctime'") !== false); +reg_assert('dist/index.php 输出指纹完成回调', strpos($distJs, '__cloakFingerprintDone') !== false); +reg_assert('dist/index.php 无 PHP Fatal', stripos($distJs, 'Fatal error') === false); + +$virtualDetectOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_virtual_detect.php') . ' 2>/dev/null'); +$virtualDetectJson = json_decode((string) $virtualDetectOut, true); +reg_assert('虚拟设备检测规则引擎', ($virtualDetectJson['ok'] ?? false) === true, (string) $virtualDetectOut); + +$_COOKIE['mmr'] = '18'; +reg_assert('mmr 18 映射', cloak_fingerprint_mmr_reason() === '移动端无有效加速度计/陀螺仪'); +unset($_COOKIE['mmr']); + +// ── 8. f_check JSON 契约(405) ────────────────────────────── +echo "[8] f_check API 边界\n"; +$fcheckCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg( + '$_SERVER["REQUEST_METHOD"]="GET"; include ' . var_export($root . '/f_check.php', true) . ';' +) . ' 2>/dev/null'; +$fcheckOut = shell_exec($fcheckCmd); +$fcJson = json_decode((string) $fcheckOut, true); +reg_assert('f_check 非 POST 返回 JSON status=error', is_array($fcJson) && ($fcJson['status'] ?? '') === 'error', (string) $fcheckOut); + +$fcheckBadCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg( + '$_SERVER["REQUEST_METHOD"]="POST"; $_POST=[]; include ' . var_export($root . '/f_check.php', true) . ';' +) . ' 2>/dev/null'; +$fcheckBadOut = shell_exec($fcheckBadCmd); +$fcBadJson = json_decode((string) $fcheckBadOut, true); +reg_assert('f_check 无效 hdata 返回 JSON status=error', is_array($fcBadJson) && ($fcBadJson['status'] ?? '') === 'error', (string) $fcheckBadOut); + +// ── 11. 二次风控 cloakjs / RouteResolver ──────────────────────── +echo "[11] 二次风控 (cloakjs / RouteResolver)\n"; + +$riskCmd = escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/run_risk_route_fixture.php') . ' 2>&1'; +exec($riskCmd, $riskOut, $riskCode); +$riskResult = json_decode(implode("\n", $riskOut), true); +reg_assert( + 'RouteResolver 风险系数>0 输出二次风控页', + ($riskResult['risk_page'] ?? false) === true && ($riskResult['has_fatal'] ?? true) === false, + json_encode($riskResult, JSON_UNESCAPED_UNICODE) +); +reg_assert('二次风控页嵌入访客 IP', ($riskResult['has_ip'] ?? false) === true, json_encode($riskResult, JSON_UNESCAPED_UNICODE)); +reg_assert('二次风控页嵌入 log_id', ($riskResult['has_log_id'] ?? false) === true, json_encode($riskResult, JSON_UNESCAPED_UNICODE)); +reg_assert('二次风控页含 f_check.php AJAX', ($riskResult['has_f_check'] ?? false) === true, json_encode($riskResult, JSON_UNESCAPED_UNICODE)); +reg_assert('visit_to_3 缺省时自动初始化', ($riskResult['visit_to_3_was_unset'] ?? false) && ($riskResult['visit_to_3_init'] ?? '') === '1', json_encode($riskResult, JSON_UNESCAPED_UNICODE)); +reg_assert('二次风控首次写库为 wait 非 true', ($riskResult['log_result'] ?? '') === 'wait', json_encode($riskResult, JSON_UNESCAPED_UNICODE)); +reg_assert('cloakjs WebGL extension 空值防护', ($riskResult['webgl_null_guard'] ?? false) === true, json_encode($riskResult, JSON_UNESCAPED_UNICODE)); + +$cloakJsModeOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_cloakjs_mode.php') . ' 2>/dev/null'); +$cloakJsModeJson = json_decode((string) $cloakJsModeOut, true); +reg_assert('cloakjs 基础/加强模式输出', ($cloakJsModeJson['ok'] ?? false) === true, (string) $cloakJsModeOut); + +$v_infoStub = new stdClass(); +$v_infoStub->v_ip = '198.51.100.7'; +$v_infoStub->v_country = 'CA'; +$log_idStub = 778899; +ob_start(); +extract(['v_info' => $v_infoStub, 'log_id' => $log_idStub], EXTR_SKIP); +include $root . '/cloakjs.php'; +$cloakJsOut = ob_get_clean(); +reg_assert('cloakjs 独立渲染含 IP', strpos($cloakJsOut, '198.51.100.7') !== false); +reg_assert('cloakjs 独立渲染含 log_id', strpos($cloakJsOut, '778899') !== false); +reg_assert('cloakjs 默认模式不含 WebGPU 采集', strpos($cloakJsOut, 'getWebGPUFingerprint') === false); +reg_assert('cloakjs 独立渲染无 PHP Fatal', stripos($cloakJsOut, 'Fatal error') === false); + +$ntVerifyCmd = escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_fcheck_nt.php') . ' 2>/dev/null'; +$ntVerifyOut = shell_exec($ntVerifyCmd); +$ntVerifyJson = json_decode((string) $ntVerifyOut, true); +reg_assert('f_check nt.txt 畸形行跳过且 fp 索引合法', ($ntVerifyJson['ok'] ?? false) === true, (string) $ntVerifyOut); + +// ── 12. ConfigLoader / 宝塔部署文件 ─────────────────────────── +echo "[12] ConfigLoader 与宝塔部署\n"; +require_once $root . '/config/ConfigLoader.php'; +reg_assert('ConfigLoader::sanitizeConfigName', ConfigLoader::sanitizeConfigName('ab.php') === 'ab'); +reg_assert('ConfigLoader::sanitizeConfigName 非法回退 index', ConfigLoader::sanitizeConfigName('../x') === 'index'); + +$cfgLoaderOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_config_loader.php') . ' 2>/dev/null'); +$cfgLoaderJson = json_decode((string) $cfgLoaderOut, true); +reg_assert('DomainRepository 规范化', ($cfgLoaderJson['tests']['normalize_strips_www'] ?? false) === true, (string) $cfgLoaderOut); + +$btNginxOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_baota_nginx.php') . ' 2>/dev/null'); +$btNginxJson = json_decode((string) $btNginxOut, true); +reg_assert('宝塔 deploy 模板文件齐全', ($btNginxJson['ok'] ?? false) === true, (string) $btNginxOut); + +$cfDomainOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_cloudflare_domain.php') . ' 2>/dev/null'); +$cfDomainJson = json_decode((string) $cfDomainOut, true); +reg_assert('Cloudflare 域名自动化 Mock 流转', ($cfDomainJson['ok'] ?? false) === true, (string) $cfDomainOut); + +// ── 9. 数据库连通(可选) ───────────────────────────────────── +echo "[9] 数据库\n"; +if (defined('DB_NAME')) { + $conn = @new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME); + if ($conn->connect_error) { + reg_skip('MySQL 连接', $conn->connect_error); + } else { + reg_assert('MySQL 连接', true); + require_once $root . '/lib/Cloak/VisitorLogWorker.php'; + $prev = error_reporting(E_ALL); + $GLOBALS['__cloak_dbg_run'] = 'regression-db-test'; + + $asyncOn = defined('VISITOR_LOG_ASYNC') && strtoupper(VISITOR_LOG_ASYNC) === 'ON'; + $sampleLogs = [ + 'campagin_id' => 'reg_test', + 'visit_md5_code' => 'reg_async_' . substr(md5((string) microtime(true)), 0, 16), + 'site_name' => 'reg.test', + 'customers_ip' => '127.0.0.1', + 'country' => null, + 'result' => 'false', + 'reason' => 'regression', + 'v_referer' => null, + 'Client' => 'PC', + 'v_Browser' => null, + 'v_PageURL' => '/', + 'accept_language' => null, + 'fp_url' => null, + 'device' => null, + ]; + + $logId = @write_log_db($sampleLogs); + if ($asyncOn) { + VisitorLogWorker::processBatch(20); + if ($logId === null) { + $md5Esc = $conn->real_escape_string($sampleLogs['visit_md5_code']); + $res = $conn->query("SELECT `id` FROM `visitor_logs` WHERE `visit_md5_code`='{$md5Esc}' ORDER BY `id` DESC LIMIT 1"); + $row = $res ? $res->fetch_assoc() : null; + $logId = $row ? (int) $row['id'] : null; + } + reg_assert('write_log_db 异步模式 worker 落库', $logId !== null && (int) $logId > 0); + } else { + reg_assert('write_log_db 含 null 字段可正常执行', $logId !== null && (int) $logId > 0); + } + + $waitId = @write_log_db(array_merge($sampleLogs, [ + 'visit_md5_code' => 'reg_wait_' . substr(md5((string) microtime(true)), 0, 16), + 'result' => 'wait', + 'reason' => '二次风控检测中', + 'fp_url' => '', + ])); + reg_assert('write_log_db wait 路径返回 log_id', $waitId !== null && (int) $waitId > 0); + if ($asyncOn) { + VisitorLogWorker::processBatch(20); + } + + error_reporting($prev); + if ($logId) { + $conn->query('DELETE FROM `visitor_logs` WHERE `id` = ' . (int) $logId); + } + if ($waitId) { + $conn->query('DELETE FROM `visitor_logs` WHERE `id` = ' . (int) $waitId); + } + $conn->close(); + } +} else { + reg_skip('MySQL 连接', 'cong.php 未定义 DB_NAME'); +} + +// ── 10. DEBUG 组件 ──────────────────────────────────────────── +echo "[10] DEBUG 组件\n"; +reg_assert('CloakDebugPage 可初始化', class_exists('CloakDebugPage', false)); +CloakDebugPage::init(); +CloakDebugPage::stepAt(__LINE__, 'regression', 'info', 'ok'); +reg_assert('CloakDebugPage::stepAt 可调用', true); + +// ── 汇总 ────────────────────────────────────────────────────── +echo "\n=== 汇总 ===\n"; +echo "通过: {$passed} 失败: {$failed} 跳过: {$skipped}\n"; + +if ($failed > 0) { + echo "\n回归未通过,请修复上述失败项。\n"; + exit(1); +} + +echo "\n全部回归通过。\n"; +exit(0); diff --git a/tools/run_pipeline_fixture.php b/tools/run_pipeline_fixture.php new file mode 100755 index 0000000..78443c7 --- /dev/null +++ b/tools/run_pipeline_fixture.php @@ -0,0 +1,51 @@ + + * 输出 JSON:{mode, result, reason, output_len, error} + */ +$root = dirname(__DIR__); +if ($argc < 2) { + fwrite(STDERR, "usage: run_pipeline_fixture.php \n"); + exit(2); +} + +$fixture = $argv[1]; +if (!is_readable($fixture)) { + echo json_encode(['error' => 'fixture not readable']); + exit(1); +} + +$_SERVER['PHP_SELF'] = '/index.php'; +$_SERVER['HTTP_HOST'] = 'test.local'; +$_SERVER['REMOTE_ADDR'] = '8.8.8.8'; +$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 10.0)'; +$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en-US'; +$_SERVER['SERVER_PORT'] = 443; +$_SERVER['HTTPS'] = 'on'; +$_SERVER['HTTP_REFERER'] = 'https://www.facebook.com/'; +$_GET = ['fbclid' => 'IwAR' . str_repeat('z', 40)]; + +require_once $root . '/cong.php'; +session_start(); +$_SESSION = []; + +include $fixture; + +require_once $root . '/lib/bootstrap.php'; + +$v_info = new visitorInfo(); +$v_info->get_visitor_Info(COSTM_IP_SCORE, CHECK_KEY, SHOW_SITE_COUNTRY); +$reason = ''; +$__cloak_debug_on = defined('CLOAK_DEBUG_MODE') && strtoupper(CLOAK_DEBUG_MODE) === 'ON'; + +ob_start(); +CheckPipeline::run(); +$out = ob_get_clean(); + +echo json_encode([ + 'mode' => SHOW_SITE_MODE_SWITCH, + 'result' => $_SESSION['check_result'] ?? null, + 'reason' => $reason, + 'output_len' => strlen($out), +], JSON_UNESCAPED_UNICODE); diff --git a/tools/run_risk_route_fixture.php b/tools/run_risk_route_fixture.php new file mode 100755 index 0000000..2cff2f2 --- /dev/null +++ b/tools/run_risk_route_fixture.php @@ -0,0 +1,79 @@ + 'true']; + +include $fixture; + +$GLOBALS['__risk_log_captured'] = null; +if (!function_exists('write_log_db')) { + function write_log_db($logs) + { + $GLOBALS['__risk_log_captured'] = $logs; + return 424242; + } +} + +require_once $root . '/lib/bootstrap.php'; + +$v_info = new visitorInfo(); +$v_info->v_ip = '203.0.113.10'; +$v_info->v_country = 'US'; + +$logs = [ + 'site_name' => 'risk.test.local', + 'customers_ip' => $v_info->v_ip, + 'country' => 'US', + 'v_Browser' => 'Chrome', + 'v_referer' => 'https://www.google.com/', + 'Client' => 'PC', + 'v_PageURL' => '/index.php', + 'accept_language' => 'en-US', + 'visit_md5_code' => 'reg_risk_md5', + 'campagin_id' => COSTM_IP_SCORE, + 'result' => 'true', + 'device' => 'PC', + 'reason' => '', +]; + +$visitTo3Before = array_key_exists('visit_to_3', $_SESSION) ? $_SESSION['visit_to_3'] : null; + +ob_start(); +RouteResolver::dispatch([ + 'v_info' => $v_info, + 'logs' => $logs, + 'config_name' => 'index', + 'reason' => '', + 'model' => 'PC', +]); +$out = ob_get_clean(); + +echo json_encode([ + 'risk_page' => strpos($out, 'Powered By Google') !== false, + 'has_ip' => strpos($out, '203.0.113.10') !== false, + 'has_log_id' => strpos($out, '424242') !== false, + 'has_f_check' => strpos($out, 'f_check.php') !== false, + 'webgl_null_guard' => strpos($out, 'dbgExt && typeof') !== false, + 'visit_to_3_init' => $_SESSION['visit_to_3'] ?? null, + 'visit_to_3_was_unset' => $visitTo3Before === null, + 'log_result' => $GLOBALS['__risk_log_captured']['result'] ?? null, + 'log_reason' => $GLOBALS['__risk_log_captured']['reason'] ?? null, + 'log_fp_url' => $GLOBALS['__risk_log_captured']['fp_url'] ?? null, + 'output_len' => strlen($out), + 'has_fatal' => stripos($out, 'Fatal error') !== false, +], JSON_UNESCAPED_UNICODE); diff --git a/tools/verify_ad_source_guard.php b/tools/verify_ad_source_guard.php new file mode 100755 index 0000000..325aa43 --- /dev/null +++ b/tools/verify_ad_source_guard.php @@ -0,0 +1,129 @@ +#!/usr/bin/env php + true, + 'ad_google' => false, + 'ad_tiktok' => false, + 'ad_strict' => false, + 'ad_spm_id' => $spmId, +]; + +// 优先级 1:ad_spm_id 匹配 +$r = CloakAdSourceGuard::evaluate($baseCfg, [ + 'referer' => '', 'query' => ['ad_spm_id' => $spmId], 'user_agent' => '', +]); +vassert('spm_id 匹配放行', $r['passed'] && $r['matched_by'] === 'ad_spm_id'); + +$r = CloakAdSourceGuard::evaluate($baseCfg, [ + 'referer' => '', 'query' => ['ad_spm_id' => 'wrongId12345'], 'user_agent' => '', +]); +vassert('spm_id 不匹配不单独放行', !$r['passed'] || $r['matched_by'] !== 'ad_spm_id'); + +// 优先级 2:clid +$r = CloakAdSourceGuard::evaluate($baseCfg, [ + 'referer' => '', 'query' => ['fbclid' => 'IwAR1234567890123456789012'], 'user_agent' => '', +]); +vassert('fbclid 放行', $r['passed'] && strpos($r['matched_by'], 'clid:') === 0); + +$r = CloakAdSourceGuard::evaluate($baseCfg, [ + 'referer' => '', 'query' => ['utm_campaign' => '__CAMPAIGN_ID__'], 'user_agent' => '', +]); +vassert('TikTok 宏放行', $r['passed'] && strpos($r['matched_by'], 'tiktok_macro:') === 0); + +// 优先级 3:referer +$r = CloakAdSourceGuard::evaluate($baseCfg, [ + 'referer' => 'https://www.facebook.com/ads', 'query' => [], 'user_agent' => '', +]); +vassert('referer facebook 放行', $r['passed'] && strpos($r['matched_by'], 'referer:') === 0); + +// 优先级 4:UA +$r = CloakAdSourceGuard::evaluate($baseCfg, [ + 'referer' => '', 'query' => [], 'user_agent' => 'Mozilla/5.0 TikTok 26.0', +]); +vassert('UA TikTok 放行', $r['passed'] && strpos($r['matched_by'], 'ua:') === 0); + +// 严格模式拦截 +$strictCfg = array_merge($baseCfg, ['ad_strict' => true]); +$r = CloakAdSourceGuard::evaluate($strictCfg, [ + 'referer' => '', 'query' => [], 'user_agent' => 'Mozilla/5.0 Chrome', +]); +vassert('严格模式未命中拦截', !$r['passed'] && $r['reason'] === '来源限制:未命中广告来源验证'); + +// 非严格模式 +$r = CloakAdSourceGuard::evaluate($baseCfg, [ + 'referer' => '', 'query' => [], 'user_agent' => 'Mozilla/5.0 Chrome', +]); +vassert('非严格未命中', !$r['passed'] && $r['reason'] === '未确定流量来源'); + +// guard 未启用 +$r = CloakAdSourceGuard::evaluate([ + 'ad_fb' => false, 'ad_google' => false, 'ad_tiktok' => false, + 'ad_strict' => true, 'ad_spm_id' => $spmId, +], ['referer' => '', 'query' => [], 'user_agent' => '']); +vassert('无平台开启跳过', $r['passed'] && $r['matched_by'] === 'guard_disabled'); + +// 链接拼装:单平台 +$q = CloakAdSourceGuard::buildAdLinkQuery([CloakAdSourceGuard::PLATFORM_FB], $spmId); +vassert('单平台 FB 含完整 UTM', strpos($q, 'utm_source=facebook') !== false && strpos($q, 'campaign_id={{campaign.id}}') !== false); +vassert('单平台含 ad_spm_id', strpos($q, 'ad_spm_id=' . rawurlencode($spmId)) !== false); + +// 链接拼装:多平台 +$q = CloakAdSourceGuard::buildAdLinkQuery([ + CloakAdSourceGuard::PLATFORM_FB, + CloakAdSourceGuard::PLATFORM_GOOGLE, + CloakAdSourceGuard::PLATFORM_TIKTOK, +], $spmId); +vassert('多平台含 FB 代表参数', strpos($q, 'campaign_id={{campaign.id}}') !== false); +vassert('多平台含 Google 代表参数', strpos($q, 'utm_campaign={campaignid}') !== false); +vassert('多平台含 TikTok 代表参数', strpos($q, 'adgroup_id=__CID__') !== false); +vassert('多平台不含完整 FB UTM', strpos($q, 'utm_medium=paid_social') === false); + +// spm 生成 +$id = CloakAdSourceGuard::generateSpmId(); +vassert('generateSpmId 合法', CloakAdSourceGuard::isValidSpmId($id), $id); + +// 临时链接计时触发 +vassert('计时:referer 命中广告来源', CloakAdSourceGuard::shouldStartUrlArgsTimer($baseCfg, [ + 'referer' => 'https://www.facebook.com/', 'query' => [], 'user_agent' => '', +])); +vassert('计时:未命中不启动', !CloakAdSourceGuard::shouldStartUrlArgsTimer($baseCfg, [ + 'referer' => '', 'query' => [], 'user_agent' => 'Mozilla/5.0 Chrome', +])); +vassert('计时:guard 关闭时 clid 仍可触发', CloakAdSourceGuard::shouldStartUrlArgsTimer([ + 'ad_fb' => false, 'ad_google' => false, 'ad_tiktok' => false, + 'ad_strict' => false, 'ad_spm_id' => '', +], ['referer' => '', 'query' => ['gclid' => 'abc'], 'user_agent' => ''])); + +$result = ['ok' => $failed === 0, 'passed' => $passed, 'failed' => $failed]; +echo json_encode($result, JSON_UNESCAPED_UNICODE) . "\n"; +exit($failed > 0 ? 1 : 0); diff --git a/tools/verify_baota_nginx.php b/tools/verify_baota_nginx.php new file mode 100755 index 0000000..f898439 --- /dev/null +++ b/tools/verify_baota_nginx.php @@ -0,0 +1,17 @@ + $ok, + 'tpl' => $tpl, + 'has_inst' => is_readable($inst), +], JSON_UNESCAPED_UNICODE) . "\n"; diff --git a/tools/verify_cloakjs_mode.php b/tools/verify_cloakjs_mode.php new file mode 100755 index 0000000..bd89f25 --- /dev/null +++ b/tools/verify_cloakjs_mode.php @@ -0,0 +1,53 @@ +v_ip = '203.0.113.50'; + $v_infoStub->v_country = 'US'; + $log_idStub = 4242; + ob_start(); + extract(['v_info' => $v_infoStub, 'log_id' => $log_idStub], EXTR_SKIP); + include $root . '/cloakjs.php'; + return ob_get_clean(); +} + +$tests = []; + +$basicOut = render_cloakjs($root, false); +$tests['basic_no_webgpu_fn'] = strpos($basicOut, 'getWebGPUFingerprint') === false; +$tests['basic_no_uaparser_lib'] = strpos($basicOut, 'UAParser.VERSION') === false; +$tests['basic_has_f_check'] = strpos($basicOut, 'f_check.php') !== false; +$tests['basic_has_ip'] = strpos($basicOut, '203.0.113.50') !== false; +$tests['basic_no_canvas_fp'] = strpos($basicOut, 'function cloakCanvasFingerprint') === false; +$tests['basic_no_webgl_deep'] = strpos($basicOut, 'function cloakWebglDeepFingerprint') === false; +$tests['basic_no_enhanced_apply_fn'] = strpos($basicOut, 'function cloakApplyEnhancedFingerprint') === false; +$tests['basic_risk_enhanced_false'] = strpos($basicOut, '__cloakRiskEnhanced = false') !== false; +$tests['basic_nulls_heavy_fields'] = strpos($basicOut, '_0x5aa8d7.set("canvas", null)') !== false; +$tests['basic_no_fatal'] = stripos($basicOut, 'Fatal error') === false; + +// 第二次渲染需在新进程或重置常量不可行;加强模式单独子进程 +$enhCmd = escapeshellarg(PHP_BINARY) . ' -r ' + . escapeshellarg( + '$root=' . var_export($root, true) . ';' + . 'define("CLOAK_RISK_ENHANCED","ON");' + . '$v_info=new stdClass;$v_info->v_ip="203.0.113.51";$v_info->v_country="US";' + . '$log_id=5252;ob_start();include $root."/cloakjs.php";echo ob_get_clean();' + ) . ' 2>&1'; +$enhOut = shell_exec($enhCmd); +$tests['enhanced_has_webgpu_fn'] = strpos((string) $enhOut, 'getWebGPUFingerprint') !== false; +$tests['enhanced_has_uaparser_lib'] = strpos((string) $enhOut, 'UAParser.VERSION') !== false; +$tests['enhanced_has_f_check'] = strpos((string) $enhOut, 'f_check.php') !== false; +$tests['enhanced_has_enhanced_fn'] = strpos((string) $enhOut, 'function cloakApplyEnhancedFingerprint') !== false; +$tests['enhanced_has_canvas_fp'] = strpos((string) $enhOut, 'function cloakCanvasFingerprint') !== false; +$tests['enhanced_risk_enhanced_true'] = strpos((string) $enhOut, '__cloakRiskEnhanced = true') !== false; +$tests['enhanced_no_fatal'] = stripos((string) $enhOut, 'Fatal error') === false; + +echo json_encode(['ok' => !in_array(false, $tests, true), 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n"; diff --git a/tools/verify_cloudflare_domain.php b/tools/verify_cloudflare_domain.php new file mode 100755 index 0000000..4b6dbe4 --- /dev/null +++ b/tools/verify_cloudflare_domain.php @@ -0,0 +1,120 @@ + true, + 'result' => [ + 'id' => 'zone_mock_' . md5($hostname), + 'name_servers' => ['ada.ns.cloudflare.com', 'bob.ns.cloudflare.com'], + ], + ]; + } + + public function getZone($zoneId) + { + return [ + 'ok' => true, + 'result' => [ + 'id' => $zoneId, + 'status' => $this->zoneStatus, + 'name_servers' => ['ada.ns.cloudflare.com', 'bob.ns.cloudflare.com'], + ], + ]; + } + + public function deleteZone($zoneId) + { + $this->deleteCalled = true; + return ['ok' => true, 'result' => ['id' => $zoneId]]; + } + + public function upsertARecord($zoneId, $fqdn, $ip, $proxied = true) + { + $this->upsertCalls[] = compact('zoneId', 'fqdn', 'ip', 'proxied'); + return ['ok' => true, 'result' => ['id' => 'rec_' . md5($fqdn)]]; + } + + public function setSslFlexible($zoneId) + { + return ['ok' => true]; + } + + public function setAlwaysHttps($zoneId) + { + return ['ok' => true]; + } +} + +$tests = []; +$host = 'cf-mock-' . substr(md5((string) microtime(true)), 0, 8) . '.test'; + +try { + $pdo = DomainRepository::pdo(); + DomainRepository::ensureTable($pdo); + + // 未启用 CF:添加后 cf_status=local + CloudflareConfig::clearTestOverrides(); + DomainProvisioningService::clearClientOverride(); + $addLocal = DomainProvisioningService::provisionOnAdd($pdo, $host); + $rowLocal = DomainRepository::findById($pdo, (int) ($addLocal['id'] ?? 0)); + $tests['add_local_cf_status'] = ($addLocal['ok'] ?? false) === true + && ($addLocal['cf_status'] ?? '') === 'local' + && ($rowLocal['cf_status'] ?? '') === 'local'; + DomainRepository::deleteById($pdo, (int) $addLocal['id']); + + // Mock:pending_ns → ready + CloudflareConfig::setTestOverrides(['enabled' => true, 'server_ip' => '203.0.113.10']); + $mock = new MockCloudflareClient(); + DomainProvisioningService::setClientOverride($mock); + + $addCf = DomainProvisioningService::provisionOnAdd($pdo, $host); + $domainId = (int) ($addCf['id'] ?? 0); + $tests['add_cf_pending_ns'] = ($addCf['ok'] ?? false) === true + && ($addCf['cf_status'] ?? '') === 'pending_ns' + && count($addCf['nameservers'] ?? []) === 2; + + $pending = DomainProvisioningService::checkAndProvision($pdo, $domainId); + $tests['check_pending_ns'] = ($pending['ok'] ?? false) === true + && ($pending['status'] ?? '') === 'pending_ns'; + + $mock->zoneStatus = 'active'; + $ready = DomainProvisioningService::checkAndProvision($pdo, $domainId); + $rowReady = DomainRepository::findById($pdo, $domainId); + $tests['check_ready'] = ($ready['ok'] ?? false) === true + && ($ready['status'] ?? '') === 'ready' + && ($rowReady['cf_status'] ?? '') === 'ready' + && count($mock->upsertCalls) === 2; + + $del = DomainProvisioningService::deleteWithCloudflare($pdo, $domainId); + $tests['delete_calls_zone'] = ($del['ok'] ?? false) === true && $mock->deleteCalled === true; + $tests['delete_row_gone'] = DomainRepository::findById($pdo, $domainId) === null; +} catch (Throwable $e) { + $tests['exception'] = false; + $tests['error'] = $e->getMessage(); +} finally { + CloudflareConfig::clearTestOverrides(); + DomainProvisioningService::clearClientOverride(); +} + +$ok = !in_array(false, $tests, true) && !isset($tests['error']); +echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n"; diff --git a/tools/verify_config_loader.php b/tools/verify_config_loader.php new file mode 100755 index 0000000..e7f86ec --- /dev/null +++ b/tools/verify_config_loader.php @@ -0,0 +1,22 @@ + !in_array(false, $tests, true), 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n"; diff --git a/tools/verify_fcheck_nt.php b/tools/verify_fcheck_nt.php new file mode 100755 index 0000000..67e4a48 --- /dev/null +++ b/tools/verify_fcheck_nt.php @@ -0,0 +1,35 @@ + $fp_url === 'https://example.com/fp1' && $idx === 0, + 'fp_url' => $fp_url, + 'idx' => $idx, + 'now_url' => $now_url, +], JSON_UNESCAPED_UNICODE) . "\n"; diff --git a/tools/verify_pipeline_timer.php b/tools/verify_pipeline_timer.php new file mode 100755 index 0000000..ecf273c --- /dev/null +++ b/tools/verify_pipeline_timer.php @@ -0,0 +1,38 @@ +#!/usr/bin/env php + $failed === 0], JSON_UNESCAPED_UNICODE) . "\n"; +exit($failed > 0 ? 1 : 0); diff --git a/tools/verify_request_url.php b/tools/verify_request_url.php new file mode 100755 index 0000000..c185acd --- /dev/null +++ b/tools/verify_request_url.php @@ -0,0 +1,42 @@ + 'shili.buzz', + 'REQUEST_URI' => '/BXSXX.php', + 'HTTPS' => 'off', + 'SERVER_PORT' => '443', + 'HTTP_X_FORWARDED_PROTO' => 'https', +]; +$tests['https_from_forwarded_proto'] = cloak_current_request_url() === 'https://shili.buzz/BXSXX.php'; + +$_SERVER = [ + 'HTTP_HOST' => 'shili.buzz', + 'REQUEST_URI' => '/BXSXX.php?ttclid=abc&clk_sig=x', + 'HTTPS' => 'on', +]; +$tests['full_url_with_query'] = cloak_current_request_url() === 'https://shili.buzz/BXSXX.php?ttclid=abc&clk_sig=x'; + +$_SERVER = [ + 'HTTP_HOST' => 'shili.buzz', + 'REQUEST_URI' => '/BXSXX.php', + 'HTTPS' => 'on', +]; +$tests['no_bare_question_mark'] = substr(cloak_current_request_url(), -1) !== '?'; + +$_SERVER = [ + 'HTTP_HOST' => 'shili.buzz', + 'SCRIPT_NAME' => '/index.php', + 'QUERY_STRING' => 'fbclid=test', + 'HTTPS' => 'on', +]; +unset($_SERVER['REQUEST_URI']); +$tests['fallback_query_string'] = cloak_current_request_url() === 'https://shili.buzz/index.php?fbclid=test'; + +echo json_encode(['ok' => !in_array(false, $tests, true), 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n"; diff --git a/tools/verify_session_real_visitor.php b/tools/verify_session_real_visitor.php new file mode 100755 index 0000000..a9086a5 --- /dev/null +++ b/tools/verify_session_real_visitor.php @@ -0,0 +1,30 @@ +#!/usr/bin/env php + $ok && $cleared], JSON_UNESCAPED_UNICODE) . "\n"; +exit($ok && $cleared ? 0 : 1); diff --git a/tools/verify_virtual_detect.php b/tools/verify_virtual_detect.php new file mode 100644 index 0000000..94f1f0c --- /dev/null +++ b/tools/verify_virtual_detect.php @@ -0,0 +1,53 @@ +"index"];' + . 'include $root . "/cong.php";' + . 'include $root . "/config/ConfigLoader.php";' + . 'ConfigLoader::loadByName("index", $root);' + . 'runkit7_constant_redefine("IS_VIRTUAL", ' . var_export((string) $virtualLevel, true) . ');' + . 'ob_start();include $root."/dist/index.php";echo ob_get_clean();' + ) . ' 2>&1'; + return shell_exec($cmd); +} + +function render_dist_index_simple($root) +{ + $_GET = ['c' => 'index']; + ob_start(); + include $root . '/dist/index.php'; + return ob_get_clean(); +} + +$tests = []; + +$offOut = render_dist_index_simple($root); +$tests['off_no_engine'] = strpos($offOut, 'CloakVirtualDetect') === false; +$tests['off_has_finish'] = strpos($offOut, 'cloakFinishFingerprint') !== false; + +// 临时写入带 IS_VIRTUAL 的配置片段:直接 include 引擎文件测输出 +$engineOut = (function () use ($root) { + ob_start(); + include $root . '/resources/virtual_device_detect.inc.php'; + return ob_get_clean(); +})(); +$tests['engine_has_mobile_only'] = strpos($engineOut, 'mobileOnly') !== false; +$tests['engine_has_sensors'] = strpos($engineOut, 'checkMotionSensors') !== false; +$tests['engine_no_performance_bench'] = strpos($engineOut, 'detectVMByPerformance') === false; +$tests['engine_has_v13'] = strpos($engineOut, "'V13'") !== false; +$tests['engine_has_v24'] = strpos($engineOut, "'V24'") !== false; + +// 若 index 配置 IS_VIRTUAL>0 则 dist 会带引擎;否则仅验证 off 路径 +$onOut = render_dist_index_simple($root); +$tests['dist_has_finish_fn'] = strpos($onOut, 'cloakFinishFingerprint') !== false; +$tests['dist_no_old_inline'] = strpos($onOut, 'isVMByHardware') === false; +$tests['dist_no_fatal'] = stripos($onOut, 'Fatal error') === false; + +echo json_encode(['ok' => !in_array(false, $tests, true), 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n"; diff --git a/tools/visitor_log_worker.php b/tools/visitor_log_worker.php new file mode 100644 index 0000000..e7cf086 --- /dev/null +++ b/tools/visitor_log_worker.php @@ -0,0 +1,30 @@ + 0, 'failed' => 0]; + +for ($i = 0; $i < $rounds; $i++) { + $result = VisitorLogWorker::processBatch($limit); + $total['processed'] += $result['processed']; + $total['failed'] += $result['failed']; + if ($result['processed'] === 0) { + break; + } +} + +if (PHP_SAPI === 'cli') { + echo json_encode([ + 'ok' => true, + 'processed' => $total['processed'], + 'failed' => $total['failed'], + ], JSON_UNESCAPED_UNICODE) . "\n"; +}